mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-03-16 15:51:22 +00:00
Compare commits
225 Commits
push/pdn_b
...
1.3.50
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fbb39dad15 | ||
|
|
418a56c00d | ||
|
|
3935c0b0bd | ||
|
|
9beb183b30 | ||
|
|
6d6618aba7 | ||
|
|
9a031954c7 | ||
|
|
1eaa698956 | ||
|
|
d63712ad95 | ||
|
|
42f49751e1 | ||
|
|
2514d6f412 | ||
|
|
5f26f044bc | ||
|
|
9a7b61d31e | ||
|
|
60c84e36b6 | ||
|
|
6bd229ce33 | ||
|
|
c7e92ed550 | ||
|
|
2f9447d9ca | ||
|
|
e02eaebd65 | ||
|
|
7522538167 | ||
|
|
11e58facda | ||
|
|
e857d944e4 | ||
|
|
b5ddf9007d | ||
|
|
e0f64c4c1a | ||
|
|
046aa868de | ||
|
|
00241930cb | ||
|
|
3347b1da64 | ||
|
|
4909348a0c | ||
|
|
bfafb9a4a2 | ||
|
|
57e6faf5e4 | ||
|
|
c624f51eb0 | ||
|
|
62f5a26a4a | ||
|
|
5f4d6354e0 | ||
|
|
f30f105d9e | ||
|
|
678ef96f95 | ||
|
|
fec917f75b | ||
|
|
5ebe84cc28 | ||
|
|
d2e3856068 | ||
|
|
42b5475d5c | ||
|
|
9704646e04 | ||
|
|
d727fdbd82 | ||
|
|
d2819701f0 | ||
|
|
ff5d08d0d4 | ||
|
|
4e61cc2a13 | ||
|
|
3fa54611bd | ||
|
|
d8372d6fc6 | ||
|
|
643f7449b9 | ||
|
|
95926e57e6 | ||
|
|
60299d328c | ||
|
|
82315c3c0b | ||
|
|
3338231017 | ||
|
|
b1aecd6e7a | ||
|
|
82b2bdd2b0 | ||
|
|
d56291242b | ||
|
|
98da824cbb | ||
|
|
36141fc5ba | ||
|
|
0f12a797c4 | ||
|
|
fb49f8c068 | ||
|
|
a6cd4a99cc | ||
|
|
4a74b1dbb1 | ||
|
|
c08f4ec20a | ||
|
|
c1a29ca7c9 | ||
|
|
608bc45a66 | ||
|
|
82513af976 | ||
|
|
6a9485eeb3 | ||
|
|
eda386710b | ||
|
|
b5401261f5 | ||
|
|
5da441106c | ||
|
|
e3c1e01697 | ||
|
|
28280285a6 | ||
|
|
f0ffb2eb28 | ||
|
|
f387c083aa | ||
|
|
c708efb290 | ||
|
|
d1199f2b68 | ||
|
|
d74cf6f1aa | ||
|
|
8ea35c629e | ||
|
|
34556642dc | ||
|
|
d62a565c6c | ||
|
|
ced11394e3 | ||
|
|
147ba4f511 | ||
|
|
1a468da0d0 | ||
|
|
0af1b565cc | ||
|
|
8cd31284a1 | ||
|
|
806f0114d7 | ||
|
|
10e6d98723 | ||
|
|
beadb09fd2 | ||
|
|
df99e9e3d1 | ||
|
|
0d601d7eb0 | ||
|
|
e19fedc962 | ||
|
|
290ac4f375 | ||
|
|
62c4dd73e7 | ||
|
|
7a07de629b | ||
|
|
101f7a40b5 | ||
|
|
6573fc6bc7 | ||
|
|
ada5a891cb | ||
|
|
863679c9bb | ||
|
|
7bb445f4c1 | ||
|
|
2df0821b1e | ||
|
|
8ea4443495 | ||
|
|
cfd1c1b7ed | ||
|
|
53ad650265 | ||
|
|
b26e9e9745 | ||
|
|
7b81415bba | ||
|
|
2330743e1b | ||
|
|
7b6ae0179b | ||
|
|
a5f119dbef | ||
|
|
e8a90fb622 | ||
|
|
a5a93f2bbe | ||
|
|
a84e93c31f | ||
|
|
a32a37e229 | ||
|
|
57f827e2bb | ||
|
|
e89208e06e | ||
|
|
2648f17faa | ||
|
|
dba7160193 | ||
|
|
0c22204cfb | ||
|
|
54d0798a4c | ||
|
|
030d08ffa7 | ||
|
|
24d014d180 | ||
|
|
a69af2472b | ||
|
|
dfd6974cd5 | ||
|
|
941907dbcf | ||
|
|
6df5136a2a | ||
|
|
b8a1b9d7af | ||
|
|
59b35458cf | ||
|
|
72390032ab | ||
|
|
92ab6b573d | ||
|
|
a81ec9874c | ||
|
|
dbade2ffb2 | ||
|
|
9141fe93a5 | ||
|
|
f12ad0f6ce | ||
|
|
1a72f0d19d | ||
|
|
a2a5507ae2 | ||
|
|
cf32ccb713 | ||
|
|
da73a0d7ed | ||
|
|
da5efe0df0 | ||
|
|
a923a39bed | ||
|
|
fc98d4369f | ||
|
|
070ac124cc | ||
|
|
4cfa52638b | ||
|
|
26f8f0d553 | ||
|
|
deee9124aa | ||
|
|
9adc695e69 | ||
|
|
4389b38331 | ||
|
|
df26f8b695 | ||
|
|
ca09e73d12 | ||
|
|
cdb45eaa2f | ||
|
|
ce2c6b917f | ||
|
|
4d93390e44 | ||
|
|
b42b9955dc | ||
|
|
c0022c3917 | ||
|
|
2649758074 | ||
|
|
2121afa531 | ||
|
|
91fcdf62e8 | ||
|
|
1dc136edce | ||
|
|
192e536837 | ||
|
|
110cedac43 | ||
|
|
d04642d92a | ||
|
|
802196f93a | ||
|
|
2c73665c4a | ||
|
|
86d9d87b16 | ||
|
|
bfe9f7f5c6 | ||
|
|
c8f822fa49 | ||
|
|
2b0f63499c | ||
|
|
91e1cb3cbf | ||
|
|
1b0e46869a | ||
|
|
da8668ad90 | ||
|
|
89dcc4bba6 | ||
|
|
ac16bb21d0 | ||
|
|
ef14310bc2 | ||
|
|
f291b6e775 | ||
|
|
fcaef56459 | ||
|
|
7ff66cf310 | ||
|
|
274d3bd095 | ||
|
|
b1263c57d9 | ||
|
|
9f6559dc44 | ||
|
|
76dc84e51f | ||
|
|
76c6892965 | ||
|
|
6ceb0e5ff6 | ||
|
|
8b6970bad0 | ||
|
|
868fabbe14 | ||
|
|
c05b6bc007 | ||
|
|
5d7f3b78f3 | ||
|
|
8c51795ebb | ||
|
|
b9eb91df45 | ||
|
|
4c77d8b923 | ||
|
|
22ccbd1e68 | ||
|
|
28570a681f | ||
|
|
23c77c4432 | ||
|
|
871cb5708d | ||
|
|
76ebfd4f02 | ||
|
|
dc7763804d | ||
|
|
e087fdff6c | ||
|
|
13b87924ba | ||
|
|
a4f4199314 | ||
|
|
19b3836b88 | ||
|
|
c49fedf84b | ||
|
|
69d794591a | ||
|
|
10c0eedf9d | ||
|
|
7fba7e299d | ||
|
|
25cf276591 | ||
|
|
c0520b9f9d | ||
|
|
f95e9f2057 | ||
|
|
1d33d1bdc1 | ||
|
|
90dbd3bc79 | ||
|
|
213611ee14 | ||
|
|
a731b0e3ab | ||
|
|
9087bdb244 | ||
|
|
c5626b7600 | ||
|
|
7c52292b28 | ||
|
|
02b4370132 | ||
|
|
fef22e58c7 | ||
|
|
255dd2fa74 | ||
|
|
7aba6e36cb | ||
|
|
87e7da4414 | ||
|
|
44fb1dd3e0 | ||
|
|
cdc165c019 | ||
|
|
0713dc3152 | ||
|
|
3b87a770fb | ||
|
|
9d640362ee | ||
|
|
a15e286a44 | ||
|
|
5a82573452 | ||
|
|
b7b152f944 | ||
|
|
d19fdb2008 | ||
|
|
4f27cc0efb | ||
|
|
226bdfe993 | ||
|
|
293eb56a9f | ||
|
|
8442ecc368 |
8539
ChangeLog.md
8539
ChangeLog.md
File diff suppressed because it is too large
Load Diff
1013
build-common/src/com/intellij/util/io/JpsPersistentHashMap.java.192
Normal file
1013
build-common/src/com/intellij/util/io/JpsPersistentHashMap.java.192
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,9 +22,11 @@ import org.jetbrains.kotlin.utils.sure
|
||||
import java.io.File
|
||||
|
||||
open class GeneratedFile(
|
||||
val sourceFiles: Collection<File>,
|
||||
sourceFiles: Collection<File>,
|
||||
val outputFile: File
|
||||
)
|
||||
) {
|
||||
val sourceFiles = sourceFiles.sortedBy { it.path }
|
||||
}
|
||||
|
||||
class GeneratedJvmClass (
|
||||
sourceFiles: Collection<File>,
|
||||
|
||||
@@ -75,12 +75,13 @@ open class LookupStorage(
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun addAll(lookups: Set<Map.Entry<LookupSymbol, Collection<String>>>, allPaths: Set<String>) {
|
||||
val pathToId = allPaths.keysToMap { addFileIfNeeded(File(it)) }
|
||||
fun addAll(lookups: MultiMap<LookupSymbol, String>, allPaths: Set<String>) {
|
||||
val pathToId = allPaths.sorted().keysToMap { addFileIfNeeded(File(it)) }
|
||||
|
||||
for ((lookupSymbol, paths) in lookups) {
|
||||
for (lookupSymbol in lookups.keySet().sorted()) {
|
||||
val key = LookupSymbolKey(lookupSymbol.name, lookupSymbol.scope)
|
||||
val fileIds = paths.mapTo(HashSet<Int>()) { pathToId[it]!! }
|
||||
val paths = lookups[lookupSymbol]!!
|
||||
val fileIds = paths.mapTo(TreeSet()) { pathToId[it]!! }
|
||||
fileIds.addAll(lookupMap[key] ?: emptySet())
|
||||
lookupMap[key] = fileIds
|
||||
}
|
||||
@@ -227,4 +228,11 @@ class LookupTrackerImpl(private val delegate: LookupTracker) : LookupTracker {
|
||||
}
|
||||
}
|
||||
|
||||
data class LookupSymbol(val name: String, val scope: String)
|
||||
data class LookupSymbol(val name: String, val scope: String) : Comparable<LookupSymbol> {
|
||||
override fun compareTo(other: LookupSymbol): Int {
|
||||
val scopeCompare = scope.compareTo(other.scope)
|
||||
if (scopeCompare != 0) return scopeCompare
|
||||
|
||||
return name.compareTo(other.name)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.progress.CompilationCanceledStatus
|
||||
import org.jetbrains.kotlin.synthetic.SAM_LOOKUP_NAME
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.flattenTo
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
import kotlin.collections.HashSet
|
||||
@@ -126,7 +127,7 @@ fun LookupStorage.update(
|
||||
|
||||
removeLookupsFrom(filesToCompile.asSequence() + removedFiles.asSequence())
|
||||
|
||||
addAll(lookupTracker.lookups.entrySet(), lookupTracker.pathInterner.values)
|
||||
addAll(lookupTracker.lookups, lookupTracker.pathInterner.values)
|
||||
}
|
||||
|
||||
data class DirtyData(
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.EnumeratorStringDescriptor
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import org.jetbrains.annotations.TestOnly
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.io.File
|
||||
|
||||
abstract class BasicMap<K : Comparable<K>, V>(
|
||||
storageFile: File,
|
||||
keyDescriptor: KeyDescriptor<K>,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) {
|
||||
protected val storage: LazyStorage<K, V>
|
||||
private val nonCachingStorage = System.getProperty("kotlin.jps.non.caching.storage")?.toBoolean() ?: false
|
||||
|
||||
init {
|
||||
storage = if (nonCachingStorage) {
|
||||
NonCachingLazyStorage(storageFile, keyDescriptor, valueExternalizer)
|
||||
} else {
|
||||
CachingLazyStorage(storageFile, keyDescriptor, valueExternalizer)
|
||||
}
|
||||
}
|
||||
|
||||
fun clean() {
|
||||
storage.clean()
|
||||
}
|
||||
|
||||
fun flush(memoryCachesOnly: Boolean) {
|
||||
storage.flush(memoryCachesOnly)
|
||||
}
|
||||
|
||||
fun close() {
|
||||
storage.close()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
fun dump(): String {
|
||||
return with(StringBuilder()) {
|
||||
with(Printer(this)) {
|
||||
println(this@BasicMap::class.java.simpleName)
|
||||
pushIndent()
|
||||
|
||||
for (key in storage.keys.sorted()) {
|
||||
println("${dumpKey(key)} -> ${dumpValue(storage[key]!!)}")
|
||||
}
|
||||
|
||||
popIndent()
|
||||
}
|
||||
|
||||
this
|
||||
}.toString()
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
protected abstract fun dumpKey(key: K): String
|
||||
|
||||
@TestOnly
|
||||
protected abstract fun dumpValue(value: V): String
|
||||
}
|
||||
|
||||
abstract class BasicStringMap<V>(
|
||||
storageFile: File,
|
||||
keyDescriptor: KeyDescriptor<String>,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) : BasicMap<String, V>(storageFile, keyDescriptor, valueExternalizer) {
|
||||
constructor(
|
||||
storageFile: File,
|
||||
valueExternalizer: DataExternalizer<V>
|
||||
) : this(storageFile, EnumeratorStringDescriptor.INSTANCE, valueExternalizer)
|
||||
|
||||
override fun dumpKey(key: String): String = key
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import com.intellij.util.io.PersistentHashMap
|
||||
import java.io.File
|
||||
|
||||
|
||||
/**
|
||||
* It's lazy in a sense that PersistentHashMap is created only on write
|
||||
*/
|
||||
class CachingLazyStorage<K, V>(
|
||||
private val storageFile: File,
|
||||
private val keyDescriptor: KeyDescriptor<K>,
|
||||
private val valueExternalizer: DataExternalizer<V>
|
||||
) : LazyStorage<K, V> {
|
||||
@Volatile
|
||||
private var storage: PersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): PersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
if (storageFile.exists()) {
|
||||
storage = createMap()
|
||||
return storage
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): PersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
|
||||
return storage!!
|
||||
}
|
||||
|
||||
override val keys: Collection<K>
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
override operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
override operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
override operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
override fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendData(key, { valueExternalizer.save(it, value) })
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun clean() {
|
||||
try {
|
||||
storage?.close()
|
||||
} catch (ignored: Throwable) {
|
||||
}
|
||||
|
||||
PersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
storage = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun flush(memoryCachesOnly: Boolean) {
|
||||
val existingStorage = storage ?: return
|
||||
|
||||
if (memoryCachesOnly) {
|
||||
if (existingStorage.isDirty) {
|
||||
existingStorage.dropMemoryCaches()
|
||||
}
|
||||
} else {
|
||||
existingStorage.force()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun close() {
|
||||
storage?.close()
|
||||
}
|
||||
|
||||
private fun createMap(): PersistentHashMap<K, V> = PersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import java.io.File
|
||||
|
||||
internal open class ClassOneToManyMap(
|
||||
storageFile: File
|
||||
) : BasicStringMap<Collection<String>>(storageFile, StringCollectionExternalizer) {
|
||||
override fun dumpValue(value: Collection<String>): String = value.dumpCollection()
|
||||
|
||||
fun add(key: FqName, value: FqName) {
|
||||
storage.append(key.asString(), listOf(value.asString()))
|
||||
}
|
||||
|
||||
operator fun get(key: FqName): Collection<FqName> =
|
||||
storage[key.asString()]?.map(::FqName) ?: setOf()
|
||||
|
||||
operator fun set(key: FqName, values: Collection<FqName>) {
|
||||
if (values.isEmpty()) {
|
||||
remove(key)
|
||||
return
|
||||
}
|
||||
|
||||
storage[key.asString()] = values.map(FqName::asString)
|
||||
}
|
||||
|
||||
fun remove(key: FqName) {
|
||||
storage.remove(key.asString())
|
||||
}
|
||||
|
||||
fun removeValues(key: FqName, removed: Set<FqName>) {
|
||||
val notRemoved = this[key].filter { it !in removed }
|
||||
this[key] = notRemoved
|
||||
}
|
||||
}
|
||||
|
||||
internal class SubtypesMap(storageFile: File) : ClassOneToManyMap(storageFile)
|
||||
internal class SupertypesMap(storageFile: File) : ClassOneToManyMap(storageFile)
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
interface LazyStorage<K, V> {
|
||||
val keys: Collection<K>
|
||||
operator fun contains(key: K): Boolean
|
||||
operator fun get(key: K): V?
|
||||
operator fun set(key: K, value: V)
|
||||
fun remove(key: K)
|
||||
fun append(key: K, value: V)
|
||||
fun clean()
|
||||
fun flush(memoryCachesOnly: Boolean)
|
||||
fun close()
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import java.io.File
|
||||
|
||||
internal class LookupMap(storage: File) : BasicMap<LookupSymbolKey, Collection<Int>>(storage, LookupSymbolKeyDescriptor, IntCollectionExternalizer) {
|
||||
override fun dumpKey(key: LookupSymbolKey): String = key.toString()
|
||||
|
||||
override fun dumpValue(value: Collection<Int>): String = value.toString()
|
||||
|
||||
fun add(name: String, scope: String, fileId: Int) {
|
||||
storage.append(LookupSymbolKey(name, scope), listOf(fileId))
|
||||
}
|
||||
|
||||
operator fun get(key: LookupSymbolKey): Collection<Int>? = storage[key]
|
||||
|
||||
operator fun set(key: LookupSymbolKey, fileIds: Set<Int>) {
|
||||
storage[key] = fileIds
|
||||
}
|
||||
|
||||
fun remove(key: LookupSymbolKey) {
|
||||
storage.remove(key)
|
||||
}
|
||||
|
||||
val keys: Collection<LookupSymbolKey>
|
||||
get() = storage.keys
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.io.DataExternalizer
|
||||
import com.intellij.util.io.KeyDescriptor
|
||||
import com.intellij.util.io.JpsPersistentHashMap
|
||||
import java.io.File
|
||||
|
||||
|
||||
class NonCachingLazyStorage<K, V>(
|
||||
private val storageFile: File,
|
||||
private val keyDescriptor: KeyDescriptor<K>,
|
||||
private val valueExternalizer: DataExternalizer<V>
|
||||
) : LazyStorage<K, V> {
|
||||
@Volatile
|
||||
private var storage: JpsPersistentHashMap<K, V>? = null
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageIfExists(): JpsPersistentHashMap<K, V>? {
|
||||
if (storage != null) return storage
|
||||
|
||||
if (storageFile.exists()) {
|
||||
storage = createMap()
|
||||
return storage
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
private fun getStorageOrCreateNew(): JpsPersistentHashMap<K, V> {
|
||||
if (storage == null) {
|
||||
storage = createMap()
|
||||
}
|
||||
|
||||
return storage!!
|
||||
}
|
||||
|
||||
override val keys: Collection<K>
|
||||
get() = getStorageIfExists()?.allKeysWithExistingMapping ?: listOf()
|
||||
|
||||
override operator fun contains(key: K): Boolean =
|
||||
getStorageIfExists()?.containsMapping(key) ?: false
|
||||
|
||||
override operator fun get(key: K): V? =
|
||||
getStorageIfExists()?.get(key)
|
||||
|
||||
override operator fun set(key: K, value: V) {
|
||||
getStorageOrCreateNew().put(key, value)
|
||||
}
|
||||
|
||||
override fun remove(key: K) {
|
||||
getStorageIfExists()?.remove(key)
|
||||
}
|
||||
|
||||
override fun append(key: K, value: V) {
|
||||
getStorageOrCreateNew().appendDataWithoutCache(key, value)
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun clean() {
|
||||
try {
|
||||
storage?.close()
|
||||
} catch (ignored: Throwable) {
|
||||
}
|
||||
|
||||
JpsPersistentHashMap.deleteFilesStartingWith(storageFile)
|
||||
storage = null
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun flush(memoryCachesOnly: Boolean) {
|
||||
val existingStorage = storage ?: return
|
||||
|
||||
if (memoryCachesOnly) {
|
||||
if (existingStorage.isDirty) {
|
||||
existingStorage.dropMemoryCaches()
|
||||
}
|
||||
} else {
|
||||
existingStorage.force()
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
override fun close() {
|
||||
storage?.close()
|
||||
}
|
||||
|
||||
private fun createMap(): JpsPersistentHashMap<K, V> =
|
||||
JpsPersistentHashMap(storageFile, keyDescriptor, valueExternalizer)
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import java.io.File
|
||||
|
||||
open class RelativeFileToPathConverter(baseDirFile: File?) : FileToPathConverter {
|
||||
private val baseDirPath = baseDirFile?.canonicalFile?.invariantSeparatorsPath
|
||||
|
||||
override fun toPath(file: File): String {
|
||||
val path = file.canonicalFile.invariantSeparatorsPath
|
||||
return when {
|
||||
baseDirPath != null && path.startsWith(baseDirPath) ->
|
||||
PROJECT_DIR_PLACEHOLDER + path.substring(baseDirPath.length)
|
||||
else -> path
|
||||
}
|
||||
}
|
||||
|
||||
override fun toFile(path: String): File =
|
||||
when {
|
||||
path.startsWith(PROJECT_DIR_PLACEHOLDER) -> {
|
||||
val basePath = baseDirPath ?: error("Could not get project root dir")
|
||||
File(basePath + path.substring(PROJECT_DIR_PLACEHOLDER.length))
|
||||
}
|
||||
else -> File(path)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
private const val PROJECT_DIR_PLACEHOLDER = "${'$'}PROJECT_DIR$"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2010-2017 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import org.jetbrains.kotlin.incremental.dumpCollection
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import java.io.File
|
||||
|
||||
internal class SourceToJvmNameMap(
|
||||
storageFile: File,
|
||||
pathConverter: FileToPathConverter
|
||||
) : AbstractSourceToOutputMap<JvmClassName>(JvmClassNameTransformer, storageFile, pathConverter)
|
||||
|
||||
internal class SourceToFqNameMap(
|
||||
storageFile: File,
|
||||
pathConverter: FileToPathConverter
|
||||
) : AbstractSourceToOutputMap<FqName>(FqNameTransformer, storageFile, pathConverter)
|
||||
|
||||
internal abstract class AbstractSourceToOutputMap<Name>(
|
||||
private val nameTransformer: NameTransformer<Name>,
|
||||
storageFile: File,
|
||||
private val pathConverter: FileToPathConverter
|
||||
) : BasicStringMap<Collection<String>>(storageFile, PathStringDescriptor, StringCollectionExternalizer) {
|
||||
fun clearOutputsForSource(sourceFile: File) {
|
||||
remove(pathConverter.toPath(sourceFile))
|
||||
}
|
||||
|
||||
fun add(sourceFile: File, className: Name) {
|
||||
storage.append(pathConverter.toPath(sourceFile), listOf(nameTransformer.asString(className)))
|
||||
}
|
||||
|
||||
fun contains(sourceFile: File): Boolean =
|
||||
pathConverter.toPath(sourceFile) in storage
|
||||
|
||||
operator fun get(sourceFile: File): Collection<Name> =
|
||||
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asName)
|
||||
|
||||
fun getFqNames(sourceFile: File): Collection<FqName> =
|
||||
storage[pathConverter.toPath(sourceFile)].orEmpty().map(nameTransformer::asFqName)
|
||||
|
||||
override fun dumpValue(value: Collection<String>) =
|
||||
value.dumpCollection()
|
||||
|
||||
private fun remove(path: String) {
|
||||
storage.remove(path)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.incremental.storage
|
||||
|
||||
import com.intellij.util.containers.MultiMap
|
||||
import org.jetbrains.kotlin.TestWithWorkingDir
|
||||
import org.jetbrains.kotlin.incremental.LookupStorage
|
||||
import org.jetbrains.kotlin.incremental.LookupSymbol
|
||||
import org.jetbrains.kotlin.incremental.testingUtils.assertEqualDirectories
|
||||
import org.junit.Test
|
||||
import java.io.File
|
||||
|
||||
class RelocatableCachesTest : TestWithWorkingDir() {
|
||||
@Test
|
||||
fun testLookupStorageAddAllReversedFiles() {
|
||||
val originalRoot = workingDir.resolve("original")
|
||||
fillLookupStorage(originalRoot, reverseFiles = false, reverseLookups = false)
|
||||
val reversedFilesOrderRoot = workingDir.resolve("reversedFiles")
|
||||
fillLookupStorage(reversedFilesOrderRoot, reverseFiles = true, reverseLookups = false)
|
||||
assertEqualDirectories(originalRoot, reversedFilesOrderRoot, forgiveExtraFiles = false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLookupStorageAddAllReversedLookups() {
|
||||
val originalRoot = workingDir.resolve("original")
|
||||
fillLookupStorage(originalRoot, reverseFiles = false, reverseLookups = false)
|
||||
val reversedLookupsOrderRoot = workingDir.resolve("reversedLookups")
|
||||
fillLookupStorage(reversedLookupsOrderRoot, reverseFiles = false, reverseLookups = true)
|
||||
assertEqualDirectories(originalRoot, reversedLookupsOrderRoot, forgiveExtraFiles = false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testLookupStorageAddAllReversedFilesReversedLookups() {
|
||||
val originalRoot = workingDir.resolve("original")
|
||||
fillLookupStorage(originalRoot, reverseFiles = false, reverseLookups = false)
|
||||
val reversedFilesReversedLookupsOrderRoot = workingDir.resolve("reversedFilesReversedLookupsOrderRoot")
|
||||
fillLookupStorage(reversedFilesReversedLookupsOrderRoot, reverseFiles = true, reverseLookups = true)
|
||||
assertEqualDirectories(originalRoot, reversedFilesReversedLookupsOrderRoot, forgiveExtraFiles = false)
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills lookup storage in [projectRoot] with N fq-names,
|
||||
* where i_th fq-name myscope_i.MyClass_i has lookups for previous fq-names (from 0 to i-1)
|
||||
*/
|
||||
private fun fillLookupStorage(projectRoot: File, reverseFiles: Boolean, reverseLookups: Boolean) {
|
||||
val storageRoot = projectRoot.storageRoot
|
||||
val fileToPathConverter = RelativeFileToPathConverter(projectRoot)
|
||||
val lookupStorage = LookupStorage(storageRoot, fileToPathConverter)
|
||||
val files = LinkedHashSet<String>()
|
||||
val symbols = LinkedHashSet<LookupSymbol>()
|
||||
val lookups = MultiMap.createOrderedSet<LookupSymbol, String>()
|
||||
|
||||
for (i in 0..10) {
|
||||
val newSymbol = LookupSymbol(name = "MyClass_$i", scope = "myscope_$i")
|
||||
val newSourcePath = projectRoot.resolve("src/${newSymbol.asRelativePath()}").canonicalFile.invariantSeparatorsPath
|
||||
symbols.add(newSymbol)
|
||||
|
||||
for (lookedUpSymbol in symbols) {
|
||||
lookups.putValue(lookedUpSymbol, newSourcePath)
|
||||
}
|
||||
|
||||
files.add(newSourcePath)
|
||||
}
|
||||
|
||||
val filesToAdd = if (reverseFiles) files.reversedSet() else files
|
||||
val lookupsToAdd = if (reverseLookups) lookups.reversedMultiMap() else lookups
|
||||
lookupStorage.addAll(lookupsToAdd, filesToAdd)
|
||||
lookupStorage.flush(memoryCachesOnly = false)
|
||||
}
|
||||
|
||||
private val File.storageRoot: File
|
||||
get() = resolve("storage")
|
||||
|
||||
private fun <K, V> MultiMap<K, V>.reversedMultiMap(): MultiMap<K, V> {
|
||||
val newMap = MultiMap.createOrderedSet<K, V>()
|
||||
for ((key, values) in entrySet().reversedSet()) {
|
||||
newMap.putValues(key, values.reversed())
|
||||
}
|
||||
return newMap
|
||||
}
|
||||
|
||||
private fun <T> Set<T>.reversedSet(): LinkedHashSet<T> =
|
||||
reversed().toCollection(LinkedHashSet(size))
|
||||
|
||||
private fun LookupSymbol.asRelativePath(): String =
|
||||
if (scope.isBlank()) name else scope.replace('.', '/') + '/' + name
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import org.jetbrains.org.objectweb.asm.ClassReader
|
||||
import org.jetbrains.org.objectweb.asm.util.TraceClassVisitor
|
||||
import org.junit.Assert
|
||||
import org.junit.Assert.assertNotNull
|
||||
import org.junit.ComparisonFailure
|
||||
import java.io.*
|
||||
import java.util.*
|
||||
import java.util.zip.CRC32
|
||||
@@ -71,7 +72,15 @@ fun assertEqualDirectories(expected: File, actual: File, forgiveExtraFiles: Bool
|
||||
}
|
||||
}
|
||||
|
||||
Assert.assertEquals(expectedString, actualString)
|
||||
if (expectedString != actualString) {
|
||||
val message: String? = null
|
||||
throw ComparisonFailure(
|
||||
message,
|
||||
expectedString.replaceFirst(DIR_ROOT_PLACEHOLDER, expected.canonicalPath),
|
||||
actualString.replaceFirst(DIR_ROOT_PLACEHOLDER, actual.canonicalPath)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun File.checksumString(): String {
|
||||
@@ -80,6 +89,8 @@ private fun File.checksumString(): String {
|
||||
return java.lang.Long.toHexString(crc32.value)
|
||||
}
|
||||
|
||||
private const val DIR_ROOT_PLACEHOLDER = "<DIR_ROOT_PLACEHOLDER>"
|
||||
|
||||
private fun getDirectoryString(dir: File, interestingPaths: List<String>): String {
|
||||
val buf = StringBuilder()
|
||||
val p = Printer(buf)
|
||||
@@ -108,7 +119,7 @@ private fun getDirectoryString(dir: File, interestingPaths: List<String>): Strin
|
||||
}
|
||||
|
||||
|
||||
p.println(".")
|
||||
p.println(DIR_ROOT_PLACEHOLDER)
|
||||
addDirContent(dir)
|
||||
|
||||
for (path in interestingPaths) {
|
||||
|
||||
@@ -9,7 +9,7 @@ buildscript {
|
||||
extra["defaultSnapshotVersion"] = "1.3-SNAPSHOT"
|
||||
|
||||
// when updating please also update JPS artifacts configuration: https://jetbrains.quip.com/zzGUAYSJ6gv3/JPS-Build-update-bootstrap
|
||||
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.3.50-dev-526", onlySuccessBootstrap = false))
|
||||
kotlinBootstrapFrom(BootstrapOption.TeamCity("1.3.50-eap-71", projectExtId = "Kotlin_1350_Compiler", onlySuccessBootstrap = false))
|
||||
|
||||
repositories {
|
||||
bootstrapKotlinRepo?.let(::maven)
|
||||
@@ -122,30 +122,19 @@ extra["JDK_9"] = jdkPath("9")
|
||||
extra["JDK_10"] = jdkPath("10")
|
||||
extra["JDK_11"] = jdkPath("11")
|
||||
|
||||
gradle.taskGraph.beforeTask() {
|
||||
// allow opening the project without setting up all env variables (see KT-26413)
|
||||
if (!kotlinBuildProperties.isInIdeaSync) {
|
||||
checkJDK()
|
||||
}
|
||||
|
||||
var jdkChecked: Boolean = false
|
||||
fun checkJDK() {
|
||||
if (jdkChecked) {
|
||||
return
|
||||
val missingEnvVars = JdkMajorVersion.values()
|
||||
.filter { it.isMandatory() && extra[it.name] == jdkNotFoundConst }
|
||||
.mapTo(ArrayList()) { it.name }
|
||||
|
||||
if (missingEnvVars.isNotEmpty()) {
|
||||
throw GradleException("Required environment variables are missing: ${missingEnvVars.joinToString()}")
|
||||
}
|
||||
|
||||
val unpresentJdks = JdkMajorVersion.values()
|
||||
.filter { it.isMandatory() }
|
||||
.map { it.name }
|
||||
.filter { extra[it] == jdkNotFoundConst }
|
||||
.toList()
|
||||
|
||||
if (unpresentJdks.isNotEmpty()) {
|
||||
throw GradleException("Please set environment variable" +
|
||||
(if (unpresentJdks.size > 1) "s" else "") +
|
||||
": " + unpresentJdks.joinToString() +
|
||||
" to point to corresponding JDK installation.")
|
||||
}
|
||||
|
||||
jdkChecked = true
|
||||
}
|
||||
|
||||
rootProject.apply {
|
||||
@@ -182,7 +171,7 @@ extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.ktor-network"] = "1.0.1"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
extra["versions.kotlin-native"] = "1.3.50-dev-11052"
|
||||
extra["versions.kotlin-native"] = "1.3.50"
|
||||
}
|
||||
|
||||
val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild
|
||||
@@ -407,6 +396,9 @@ allprojects {
|
||||
configurations.findByName("kotlinCompilerClasspath")?.let {
|
||||
dependencies.add(it.name, files(bootstrapCompilerClasspath))
|
||||
}
|
||||
|
||||
configurations.findByName("kotlinCompilerPluginClasspath")
|
||||
?.exclude("org.jetbrains.kotlin", "kotlin-scripting-compiler-embeddable")
|
||||
}
|
||||
|
||||
// Aggregate task for build related checks
|
||||
@@ -731,9 +723,14 @@ fun jdkPath(version: String): String {
|
||||
|
||||
|
||||
fun Project.configureJvmProject(javaHome: String, javaVersion: String) {
|
||||
val currentJavaHome = File(System.getProperty("java.home")!!).canonicalPath
|
||||
val shouldFork = !currentJavaHome.startsWith(File(javaHome).canonicalPath)
|
||||
|
||||
tasks.withType<JavaCompile> {
|
||||
if (name != "compileJava9Java") {
|
||||
options.isFork = true
|
||||
sourceCompatibility = javaVersion
|
||||
targetCompatibility = javaVersion
|
||||
options.isFork = shouldFork
|
||||
options.forkOptions.javaHome = file(javaHome)
|
||||
options.compilerArgs.add("-proc:none")
|
||||
options.encoding = "UTF-8"
|
||||
@@ -749,6 +746,27 @@ fun Project.configureJvmProject(javaHome: String, javaVersion: String) {
|
||||
tasks.withType<Test> {
|
||||
executable = File(javaHome, "bin/java").canonicalPath
|
||||
}
|
||||
|
||||
plugins.withId("java-base") {
|
||||
configureShadowJarSubstitutionInCompileClasspath()
|
||||
}
|
||||
}
|
||||
|
||||
fun Project.configureShadowJarSubstitutionInCompileClasspath() {
|
||||
val substitutionMap = mapOf(":kotlin-reflect" to ":kotlin-reflect-api")
|
||||
|
||||
fun configureSubstitution(substitution: DependencySubstitution) {
|
||||
val requestedProject = (substitution.requested as? ProjectComponentSelector)?.projectPath ?: return
|
||||
val replacementProject = substitutionMap[requestedProject] ?: return
|
||||
substitution.useTarget(project(replacementProject), "Non-default shadow jars should not be used in compile classpath")
|
||||
}
|
||||
|
||||
sourceSets.all {
|
||||
val compileClasspathConfig = configurations.getByName(compileClasspathConfigurationName)
|
||||
compileClasspathConfig.resolutionStrategy.dependencySubstitution {
|
||||
all(::configureSubstitution)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tasks.create("findShadowJarsInClasspath").doLast {
|
||||
@@ -756,12 +774,19 @@ tasks.create("findShadowJarsInClasspath").doLast {
|
||||
sortedBy { it.path }.forEach { println(indent + it.relativeTo(rootProject.projectDir)) }
|
||||
}
|
||||
|
||||
val mainJars = hashSetOf<File>()
|
||||
val shadowJars = hashSetOf<File>()
|
||||
for (project in rootProject.allprojects) {
|
||||
project.withJavaPlugin {
|
||||
project.sourceSets.forEach { sourceSet ->
|
||||
val jarTask = project.tasks.findByPath(sourceSet.jarTaskName) as? Jar
|
||||
jarTask?.outputFile?.let { mainJars.add(it) }
|
||||
}
|
||||
}
|
||||
for (task in project.tasks) {
|
||||
when (task) {
|
||||
is ShadowJar -> {
|
||||
shadowJars.add(fileFrom(task.archivePath))
|
||||
shadowJars.add(fileFrom(task.outputFile))
|
||||
}
|
||||
is ProGuardTask -> {
|
||||
shadowJars.addAll(task.outputs.files.toList())
|
||||
@@ -770,7 +795,8 @@ tasks.create("findShadowJarsInClasspath").doLast {
|
||||
}
|
||||
}
|
||||
|
||||
println("Shadow jars:")
|
||||
shadowJars.removeAll(mainJars)
|
||||
println("Shadow jars that might break incremental compilation:")
|
||||
shadowJars.printSorted()
|
||||
|
||||
fun Project.checkConfig(configName: String) {
|
||||
@@ -784,7 +810,14 @@ tasks.create("findShadowJarsInClasspath").doLast {
|
||||
}
|
||||
|
||||
for (project in rootProject.allprojects) {
|
||||
project.checkConfig("compileClasspath")
|
||||
project.checkConfig("testCompileClasspath")
|
||||
project.sourceSetsOrNull?.forEach { sourceSet ->
|
||||
project.checkConfig(sourceSet.compileClasspathConfigurationName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val Jar.outputFile: File
|
||||
get() = archiveFile.get().asFile
|
||||
|
||||
val Project.sourceSetsOrNull: SourceSetContainer?
|
||||
get() = convention.findPlugin(JavaPluginConvention::class.java)?.sourceSets
|
||||
|
||||
@@ -112,6 +112,11 @@ samWithReceiver {
|
||||
fun Project.`samWithReceiver`(configure: org.jetbrains.kotlin.samWithReceiver.gradle.SamWithReceiverExtension.() -> Unit): Unit =
|
||||
extensions.configure("samWithReceiver", configure)
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
tasks["build"].dependsOn(":prepare-deps:build")
|
||||
|
||||
allprojects {
|
||||
|
||||
8
buildSrc/gradle.properties.as36
Normal file
8
buildSrc/gradle.properties.as36
Normal file
@@ -0,0 +1,8 @@
|
||||
org.gradle.jvmargs=-Duser.country=US -Dkotlin.daemon.jvm.options=-Xmx1600m -Dfile.encoding=UTF-8
|
||||
|
||||
cacheRedirectorEnabled=true
|
||||
|
||||
#buildSrc.kotlin.repo=https://jcenter.bintray.com
|
||||
#buildSrc.kotlin.version=1.1.50
|
||||
|
||||
intellijUltimateEnabled=false
|
||||
@@ -65,6 +65,23 @@ repositories {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
|
||||
ivy {
|
||||
url = URI("https://dl.bintray.com/kotlin/as/")
|
||||
|
||||
patternLayout {
|
||||
artifact("[artifact]-[revision]-$androidStudioOs.[ext]")
|
||||
}
|
||||
|
||||
credentials {
|
||||
username = System.getenv("AS_BINTRAY_USER_NAME")
|
||||
password = System.getenv("AS_BINTRAY_API_KEY")
|
||||
}
|
||||
|
||||
metadataSources {
|
||||
artifact()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
maven("https://www.jetbrains.com/intellij-repository/$intellijReleaseType")
|
||||
@@ -94,7 +111,8 @@ val repoDir = File(customDepsRepoDir, customDepsOrg)
|
||||
|
||||
dependencies {
|
||||
if (androidStudioRelease != null) {
|
||||
val extension = if (androidStudioOs == "linux" && androidStudioRelease.startsWith("3.5"))
|
||||
val extension = if (androidStudioOs == "linux" &&
|
||||
(androidStudioRelease.startsWith("3.5") || androidStudioRelease.startsWith("3.6")))
|
||||
"tar.gz"
|
||||
else
|
||||
"zip"
|
||||
|
||||
@@ -23,6 +23,17 @@ if (flags.includeCidrPlugins) {
|
||||
logger.info("NOT including CIDR plugins in buildSrc/settings.gradle")
|
||||
}
|
||||
|
||||
if (flags.hasKotlinUltimate) {
|
||||
logger.info("Including extension for IJ Ultimate in buildSrc/settings.gradle")
|
||||
include ":prepare-deps:lldb-frontend"
|
||||
include ":prepare-deps:native-debug-plugin"
|
||||
project(":prepare-deps:lldb-frontend").projectDir = file("${flags.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/lldb-frontend")
|
||||
project(":prepare-deps:native-debug-plugin").projectDir = file("${flags.propertiesProvider.rootProjectDir}/kotlin-ultimate/buildSrc/prepare-deps/native-debug-plugin")
|
||||
} else {
|
||||
logger.info("Not including extension for IJ Ultimate in buildSrc/settings.gradle")
|
||||
}
|
||||
|
||||
|
||||
class LocalBuildPropertiesProvider {
|
||||
private Settings settings
|
||||
private Properties localProperties = new Properties()
|
||||
@@ -57,8 +68,11 @@ class LocalBuildProperties {
|
||||
|
||||
boolean includeCidrPlugins
|
||||
|
||||
boolean hasKotlinUltimate
|
||||
|
||||
LocalBuildProperties(Settings settings) {
|
||||
propertiesProvider = new LocalBuildPropertiesProvider(settings)
|
||||
includeCidrPlugins = propertiesProvider.getBoolean('cidrPluginsEnabled') && new File(propertiesProvider.rootProjectDir, 'kotlin-ultimate').exists()
|
||||
hasKotlinUltimate = new File(propertiesProvider.rootProjectDir, 'kotlin-ultimate').exists()
|
||||
includeCidrPlugins = propertiesProvider.getBoolean('cidrPluginsEnabled') && hasKotlinUltimate
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ enum class Ide(val platform: Platform) : CompatibilityPredicate {
|
||||
AS32(Platform.P181),
|
||||
AS33(Platform.P182),
|
||||
AS34(Platform.P183),
|
||||
AS35(Platform.P183);
|
||||
AS35(Platform.P183),
|
||||
AS36(Platform.P192);
|
||||
|
||||
val kind = Kind.values().first { it.shortName == name.take(2) }
|
||||
val version = name.dropWhile { !it.isDigit() }.toInt()
|
||||
|
||||
@@ -57,9 +57,7 @@ class KotlinBuildProperties(
|
||||
val useBootstrapStdlib: Boolean
|
||||
get() = isInJpsBuildIdeaSync || getBoolean("kotlin.build.useBootstrapStdlib", false)
|
||||
|
||||
val kotlinUltimateExists: Boolean = propertiesProvider.rootProjectDir.resolve("kotlin-ultimate").exists()
|
||||
|
||||
val includeCidrPlugins: Boolean = kotlinUltimateExists && getBoolean("cidrPluginsEnabled")
|
||||
private val kotlinUltimateExists: Boolean = propertiesProvider.rootProjectDir.resolve("kotlin-ultimate").exists()
|
||||
|
||||
val isTeamcityBuild: Boolean = getBoolean("teamcity") || System.getenv("TEAMCITY_VERSION") != null
|
||||
|
||||
@@ -72,6 +70,10 @@ class KotlinBuildProperties(
|
||||
return kotlinUltimateExists && (explicitlyEnabled || isTeamcityBuild)
|
||||
}
|
||||
|
||||
val includeCidrPlugins: Boolean = kotlinUltimateExists && getBoolean("cidrPluginsEnabled")
|
||||
|
||||
val includeUltimate: Boolean = kotlinUltimateExists && (isTeamcityBuild || intellijUltimateEnabled)
|
||||
|
||||
val postProcessing: Boolean get() = isTeamcityBuild || getBoolean("kotlin.build.postprocessing", true)
|
||||
|
||||
val relocation: Boolean get() = postProcessing
|
||||
|
||||
@@ -19,7 +19,9 @@ val packagesToRelocate =
|
||||
"org.picocontainer",
|
||||
"org.jline",
|
||||
"org.fusesource",
|
||||
"kotlinx.coroutines")
|
||||
"kotlinx.coroutines",
|
||||
"net.jpountz",
|
||||
"one.util.streamex")
|
||||
|
||||
// The shaded compiler "dummy" is used to rewrite dependencies in projects that are used with the embeddable compiler
|
||||
// on the runtime and use some shaded dependencies from the compiler
|
||||
|
||||
@@ -484,7 +484,9 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
protected void generateInitializers(@NotNull Function0<ExpressionCodegen> createCodegen) {
|
||||
NotNullLazyValue<ExpressionCodegen> codegen = LockBasedStorageManager.NO_LOCKS.createLazyValue(createCodegen);
|
||||
|
||||
for (KtDeclaration declaration : ((KtDeclarationContainer) element).getDeclarations()) {
|
||||
List<KtDeclaration> declarations = ((KtDeclarationContainer) element).getDeclarations();
|
||||
for (int i = 0; i < declarations.size(); i++) {
|
||||
KtDeclaration declaration = declarations.get(i);
|
||||
if (declaration instanceof KtProperty) {
|
||||
if (shouldInitializeProperty((KtProperty) declaration)) {
|
||||
generateNopSeparatorIfNeeded(codegen);
|
||||
@@ -501,7 +503,11 @@ public abstract class MemberCodegen<T extends KtPureElement/* TODO: & KtDeclarat
|
||||
generateNopSeparatorIfNeeded(codegen);
|
||||
|
||||
ExpressionCodegen expressionCodegen = codegen.invoke();
|
||||
expressionCodegen.gen(body, Type.VOID_TYPE);
|
||||
Type bodyExpressionType = Type.VOID_TYPE;
|
||||
if (i == declarations.size() - 1 && this instanceof ScriptCodegen) {
|
||||
bodyExpressionType = expressionCodegen.expressionType(body);
|
||||
}
|
||||
expressionCodegen.gen(body, bodyExpressionType);
|
||||
expressionCodegen.markLineNumber(declaration, true);
|
||||
nopSeparatorNeeded = true;
|
||||
}
|
||||
|
||||
@@ -1071,15 +1071,17 @@ class MethodInliner(
|
||||
//remove next template:
|
||||
// aload x
|
||||
// LDC paramName
|
||||
// INTRINSICS_CLASS_NAME.checkParameterIsNotNull(...)
|
||||
// INTRINSICS_CLASS_NAME.checkParameterIsNotNull/checkNotNullParameter(...)
|
||||
private fun removeClosureAssertions(node: MethodNode) {
|
||||
val toDelete = arrayListOf<AbstractInsnNode>()
|
||||
InsnSequence(node.instructions).filterIsInstance<MethodInsnNode>().forEach { methodInsnNode ->
|
||||
if (methodInsnNode.name == "checkParameterIsNotNull" && methodInsnNode.owner == IntrinsicMethods.INTRINSICS_CLASS_NAME) {
|
||||
if (methodInsnNode.owner == IntrinsicMethods.INTRINSICS_CLASS_NAME &&
|
||||
(methodInsnNode.name == "checkParameterIsNotNull" || methodInsnNode.name == "checkNotNullParameter")
|
||||
) {
|
||||
val prev = methodInsnNode.previous
|
||||
assert(Opcodes.LDC == prev?.opcode) { "'checkParameterIsNotNull' should go after LDC but $prev" }
|
||||
assert(Opcodes.LDC == prev?.opcode) { "'${methodInsnNode.name}' should go after LDC but $prev" }
|
||||
val prevPev = methodInsnNode.previous.previous
|
||||
assert(Opcodes.ALOAD == prevPev?.opcode) { "'checkParameterIsNotNull' should be invoked on local var, but $prev" }
|
||||
assert(Opcodes.ALOAD == prevPev?.opcode) { "'${methodInsnNode.name}' should be invoked on local var, but $prev" }
|
||||
|
||||
toDelete.add(prevPev)
|
||||
toDelete.add(prev)
|
||||
|
||||
@@ -819,6 +819,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
||||
receiverTypeAndTypeParameters.receiverType
|
||||
}
|
||||
!isIrBackend && kind == OwnerKind.ERASED_INLINE_CLASS -> {
|
||||
writeFormalTypeParameters(directMember.typeParameters, sw)
|
||||
(directMember.containingDeclaration as ClassDescriptor).defaultType
|
||||
}
|
||||
else -> {
|
||||
|
||||
@@ -16,10 +16,6 @@ import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
interface CommonPlatform : TargetPlatform {
|
||||
@JvmDefault
|
||||
override val platformName: String
|
||||
get() = "Default"
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val INSTANCE: CommonPlatform = CommonPlatforms.CompatCommonPlatform
|
||||
|
||||
@@ -128,6 +128,18 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
)
|
||||
var newInference: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xinline-classes",
|
||||
description = "Enable experimental inline classes"
|
||||
)
|
||||
var inlineClasses: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xpolymorphic-signature",
|
||||
description = "Enable experimental support for @PolymorphicSignature (MethodHandle/VarHandle)"
|
||||
)
|
||||
var polymorphicSignature: Boolean by FreezableVar(false)
|
||||
|
||||
@Argument(
|
||||
value = "-Xlegacy-smart-cast-after-try",
|
||||
description = "Allow var smart casts despite assignment in try block"
|
||||
@@ -324,6 +336,15 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
if (newInference) {
|
||||
put(LanguageFeature.NewInference, LanguageFeature.State.ENABLED)
|
||||
put(LanguageFeature.SamConversionPerArgument, LanguageFeature.State.ENABLED)
|
||||
put(LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType, LanguageFeature.State.ENABLED)
|
||||
}
|
||||
|
||||
if (inlineClasses) {
|
||||
put(LanguageFeature.InlineClasses, LanguageFeature.State.ENABLED)
|
||||
}
|
||||
|
||||
if (polymorphicSignature) {
|
||||
put(LanguageFeature.PolymorphicSignature, LanguageFeature.State.ENABLED)
|
||||
}
|
||||
|
||||
if (legacySmartCastAfterTry) {
|
||||
@@ -362,19 +383,30 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
|
||||
val featuresThatForcePreReleaseBinaries = mutableListOf<LanguageFeature>()
|
||||
|
||||
var standaloneSamConversionFeaturePassedExplicitly = false
|
||||
var functionReferenceWithDefaultValueFeaturePassedExplicitly = false
|
||||
for ((feature, state) in internalArguments.filterIsInstance<ManualLanguageFeatureSetting>()) {
|
||||
put(feature, state)
|
||||
if (state == LanguageFeature.State.ENABLED && feature.forcesPreReleaseBinariesIfEnabled()) {
|
||||
featuresThatForcePreReleaseBinaries += feature
|
||||
}
|
||||
|
||||
if (feature == LanguageFeature.SamConversionPerArgument) {
|
||||
standaloneSamConversionFeaturePassedExplicitly = true
|
||||
when (feature) {
|
||||
LanguageFeature.SamConversionPerArgument ->
|
||||
standaloneSamConversionFeaturePassedExplicitly = true
|
||||
|
||||
LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType ->
|
||||
functionReferenceWithDefaultValueFeaturePassedExplicitly = true
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
|
||||
if (!standaloneSamConversionFeaturePassedExplicitly && this[LanguageFeature.NewInference] == LanguageFeature.State.ENABLED) {
|
||||
put(LanguageFeature.SamConversionPerArgument, LanguageFeature.State.ENABLED)
|
||||
if (this[LanguageFeature.NewInference] == LanguageFeature.State.ENABLED) {
|
||||
if (!standaloneSamConversionFeaturePassedExplicitly)
|
||||
put(LanguageFeature.SamConversionPerArgument, LanguageFeature.State.ENABLED)
|
||||
|
||||
if (!functionReferenceWithDefaultValueFeaturePassedExplicitly)
|
||||
put(LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType, LanguageFeature.State.ENABLED)
|
||||
}
|
||||
|
||||
if (featuresThatForcePreReleaseBinaries.isNotEmpty()) {
|
||||
|
||||
@@ -53,18 +53,15 @@ abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEn
|
||||
createState()
|
||||
}) as IReplStageState<*>
|
||||
|
||||
open fun getInvokeWrapper(context: ScriptContext): InvokeWrapper? = null
|
||||
|
||||
open fun overrideScriptArgs(context: ScriptContext): ScriptArgsWithTypes? = null
|
||||
|
||||
open fun compileAndEval(script: String, context: ScriptContext): Any? {
|
||||
val codeLine = nextCodeLine(context, script)
|
||||
val state = getCurrentState(context)
|
||||
val result = replEvaluator.compileAndEval(state, codeLine, scriptArgs = overrideScriptArgs(context))
|
||||
return when (result) {
|
||||
is ReplEvalResult.ValueResult -> result.value
|
||||
is ReplEvalResult.UnitResult -> null
|
||||
is ReplEvalResult.Error -> throw ScriptException(result.message)
|
||||
is ReplEvalResult.Incomplete -> throw ScriptException("error: incomplete code")
|
||||
is ReplEvalResult.HistoryMismatch -> throw ScriptException("Repl history mismatch at line: ${result.lineNo}")
|
||||
return asJsr223EvalResult {
|
||||
replEvaluator.compileAndEval(state, codeLine, overrideScriptArgs(context), getInvokeWrapper(context))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,17 +80,29 @@ abstract class KotlinJsr223JvmScriptEngineBase(protected val myFactory: ScriptEn
|
||||
|
||||
open fun eval(compiledScript: CompiledKotlinScript, context: ScriptContext): Any? {
|
||||
val state = getCurrentState(context)
|
||||
val result = try {
|
||||
replEvaluator.eval(state, compiledScript.compiledData, scriptArgs = overrideScriptArgs(context))
|
||||
return asJsr223EvalResult {
|
||||
replEvaluator.eval(state, compiledScript.compiledData, overrideScriptArgs(context), getInvokeWrapper(context))
|
||||
}
|
||||
catch (e: Exception) {
|
||||
}
|
||||
|
||||
private fun asJsr223EvalResult(body: () -> ReplEvalResult): Any? {
|
||||
val result = try {
|
||||
body()
|
||||
} catch (e: Exception) {
|
||||
throw ScriptException(e)
|
||||
}
|
||||
|
||||
return when (result) {
|
||||
is ReplEvalResult.ValueResult -> result.value
|
||||
is ReplEvalResult.UnitResult -> null
|
||||
is ReplEvalResult.Error -> throw ScriptException(result.message)
|
||||
is ReplEvalResult.Error ->
|
||||
when {
|
||||
result is ReplEvalResult.Error.Runtime && result.cause != null ->
|
||||
throw ScriptException(result.cause)
|
||||
result is ReplEvalResult.Error.CompileTime && result.location != null ->
|
||||
throw ScriptException(result.message, result.location.path, result.location.line, result.location.column)
|
||||
else -> throw ScriptException(result.message)
|
||||
}
|
||||
is ReplEvalResult.Incomplete -> throw ScriptException("error: incomplete code")
|
||||
is ReplEvalResult.HistoryMismatch -> throw ScriptException("Repl history mismatch at line: ${result.lineNo}")
|
||||
}
|
||||
|
||||
@@ -25,7 +25,10 @@ object CommonPlatforms {
|
||||
defaultJsPlatform.single(),
|
||||
defaultKonanPlatform.single()
|
||||
)
|
||||
), org.jetbrains.kotlin.analyzer.common.CommonPlatform
|
||||
), org.jetbrains.kotlin.analyzer.common.CommonPlatform {
|
||||
override val platformName: String
|
||||
get() = "Default"
|
||||
}
|
||||
|
||||
val defaultCommonPlatform: TargetPlatform
|
||||
get() = CompatCommonPlatform
|
||||
|
||||
@@ -24,7 +24,10 @@ object KonanPlatforms {
|
||||
)
|
||||
object CompatKonanPlatform : TargetPlatform(setOf(DefaultSimpleKonanPlatform)),
|
||||
// Needed for backward compatibility, because old code uses INSTANCEOF checks instead of calling extensions
|
||||
org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform {}
|
||||
org.jetbrains.kotlin.resolve.konan.platform.KonanPlatform {
|
||||
override val platformName: String
|
||||
get() = "Native"
|
||||
}
|
||||
|
||||
val defaultKonanPlatform: TargetPlatform
|
||||
get() = CompatKonanPlatform
|
||||
|
||||
@@ -16,10 +16,6 @@ import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
interface KonanPlatform : TargetPlatform {
|
||||
@JvmDefault
|
||||
override val platformName: String
|
||||
get() = "Native"
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val INSTANCE: KonanPlatform = KonanPlatforms.CompatKonanPlatform
|
||||
|
||||
@@ -293,6 +293,11 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
fun addKotlinSourceRoots(rootDirs: List<File>) {
|
||||
val roots = rootDirs.map { KotlinSourceRoot(it.absolutePath, isCommon = false) }
|
||||
sourceFiles += createSourceFilesFromSourceRoots(configuration, project, roots)
|
||||
}
|
||||
|
||||
fun createPackagePartProvider(scope: GlobalSearchScope): JvmPackagePartProvider {
|
||||
return JvmPackagePartProvider(configuration.languageVersionSettings, scope).apply {
|
||||
addRoots(initialRoots, configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY))
|
||||
|
||||
@@ -459,7 +459,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
environment: KotlinCoreEnvironment,
|
||||
targetDescription: String?
|
||||
): AnalysisResult? {
|
||||
if (result is AnalysisResult.RetryWithAdditionalJavaRoots) {
|
||||
if (result is AnalysisResult.RetryWithAdditionalRoots) {
|
||||
val configuration = environment.configuration
|
||||
|
||||
val oldReadOnlyValue = configuration.isReadOnly
|
||||
@@ -471,6 +471,10 @@ object KotlinToJVMBytecodeCompiler {
|
||||
environment.updateClasspath(result.additionalJavaRoots.map { JavaSourceRoot(it, null) })
|
||||
}
|
||||
|
||||
if (result.additionalKotlinRoots.isNotEmpty()) {
|
||||
environment.addKotlinSourceRoots(result.additionalKotlinRoots)
|
||||
}
|
||||
|
||||
KotlinJavaPsiFacade.getInstance(environment.project).clearPackageCaches()
|
||||
|
||||
// Clear all diagnostic messages
|
||||
@@ -562,7 +566,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
|
||||
val analysisResult = analyzerWithCompilerReport.analysisResult
|
||||
|
||||
return if (!analyzerWithCompilerReport.hasErrors() || analysisResult is AnalysisResult.RetryWithAdditionalJavaRoots)
|
||||
return if (!analyzerWithCompilerReport.hasErrors() || analysisResult is AnalysisResult.RetryWithAdditionalRoots)
|
||||
analysisResult
|
||||
else
|
||||
null
|
||||
|
||||
@@ -21,7 +21,9 @@ import java.lang.reflect.*
|
||||
import java.util.*
|
||||
|
||||
private object ClassTraversalCache {
|
||||
private val cache = ContainerUtil.newConcurrentMap<Class<*>, ClassInfo>()
|
||||
private val cache =
|
||||
if (System.getProperty("idea.system.path") != null) ContainerUtil.newConcurrentMap<Class<*>, ClassInfo>()
|
||||
else ContainerUtil.createConcurrentWeakKeySoftValueMap<Class<*>, ClassInfo>()
|
||||
|
||||
fun getClassInfo(c: Class<*>): ClassInfo {
|
||||
val classInfo = cache.get(c)
|
||||
|
||||
@@ -187,13 +187,14 @@ fun Iterable<String>.filterExtractProps(vararg groups: OptionsGroup, prefix: Str
|
||||
data class DaemonJVMOptions(
|
||||
var maxMemory: String = "",
|
||||
var maxPermSize: String = "",
|
||||
var maxMetaspaceSize: String = "",
|
||||
var reservedCodeCacheSize: String = "",
|
||||
var jvmParams: MutableCollection<String> = arrayListOf()
|
||||
) : OptionsGroup {
|
||||
|
||||
override val mappers: List<PropMapper<*, *, *>>
|
||||
get() = listOf(StringPropMapper(this, DaemonJVMOptions::maxMemory, listOf("Xmx"), mergeDelimiter = ""),
|
||||
StringPropMapper(this, DaemonJVMOptions::maxPermSize, listOf("XX:MaxPermSize"), mergeDelimiter = "="),
|
||||
StringPropMapper(this, DaemonJVMOptions::maxMetaspaceSize, listOf("XX:MaxMetaspaceSize"), mergeDelimiter = "="),
|
||||
StringPropMapper(this, DaemonJVMOptions::reservedCodeCacheSize, listOf("XX:ReservedCodeCacheSize"), mergeDelimiter = "="),
|
||||
restMapper)
|
||||
|
||||
@@ -279,11 +280,13 @@ fun configureDaemonJVMOptions(opts: DaemonJVMOptions,
|
||||
val targetOptions = if (inheritMemoryLimits) opts else DaemonJVMOptions()
|
||||
val otherArgs = jvmArguments.filterExtractProps(targetOptions.mappers, prefix = "-")
|
||||
|
||||
if (inheritMemoryLimits && opts.maxMemory.isBlank()) {
|
||||
val maxMemBytes = Runtime.getRuntime().maxMemory()
|
||||
// rounding up
|
||||
val maxMemMegabytes = maxMemBytes / (1024 * 1024) + if (maxMemBytes % (1024 * 1024) == 0L) 0 else 1
|
||||
opts.maxMemory = "${maxMemMegabytes}m"
|
||||
if (inheritMemoryLimits) {
|
||||
if (opts.maxMemory.isBlank()) {
|
||||
val maxMemBytes = Runtime.getRuntime().maxMemory()
|
||||
// rounding up
|
||||
val maxMemMegabytes = maxMemBytes / (1024 * 1024) + if (maxMemBytes % (1024 * 1024) == 0L) 0 else 1
|
||||
opts.maxMemory = "${maxMemMegabytes}m"
|
||||
}
|
||||
}
|
||||
|
||||
if (inheritOtherJvmOptions) {
|
||||
@@ -365,7 +368,7 @@ private fun String.memToBytes(): Long? =
|
||||
|
||||
|
||||
private val daemonJVMOptionsMemoryProps =
|
||||
listOf(DaemonJVMOptions::maxMemory, DaemonJVMOptions::maxPermSize, DaemonJVMOptions::reservedCodeCacheSize)
|
||||
listOf(DaemonJVMOptions::maxMemory, DaemonJVMOptions::maxPermSize, DaemonJVMOptions::maxMetaspaceSize, DaemonJVMOptions::reservedCodeCacheSize)
|
||||
|
||||
infix fun DaemonJVMOptions.memorywiseFitsInto(other: DaemonJVMOptions): Boolean =
|
||||
daemonJVMOptionsMemoryProps
|
||||
|
||||
@@ -8,11 +8,8 @@ package org.jetbrains.kotlin.daemon.experimental
|
||||
import com.intellij.util.containers.StringInterner
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.kotlin.daemon.EventManager
|
||||
import org.jetbrains.kotlin.daemon.common.*
|
||||
import org.jetbrains.kotlin.daemon.common.experimental.CompilerCallbackServicesFacadeClientSide
|
||||
import org.jetbrains.kotlin.daemon.common.DummyProfiler
|
||||
import org.jetbrains.kotlin.daemon.common.Profiler
|
||||
import org.jetbrains.kotlin.daemon.common.withMeasure
|
||||
import org.jetbrains.kotlin.daemon.common.withMeasureBlocking
|
||||
import org.jetbrains.kotlin.incremental.components.LookupInfo
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.incremental.components.Position
|
||||
@@ -20,7 +17,7 @@ import org.jetbrains.kotlin.incremental.components.ScopeKind
|
||||
|
||||
|
||||
class RemoteLookupTrackerClient(
|
||||
val facade: CompilerCallbackServicesFacadeClientSide,
|
||||
val facade: CompilerCallbackServicesFacadeAsync,
|
||||
eventManager: EventManager,
|
||||
val profiler: Profiler = DummyProfiler()
|
||||
) : LookupTracker {
|
||||
|
||||
@@ -1017,6 +1017,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest {
|
||||
runTest("compiler/testData/ir/irText/expressions/kt30020.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt30796.kt")
|
||||
public void testKt30796() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/kt30796.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("lambdaInCAO.kt")
|
||||
public void testLambdaInCAO() throws Exception {
|
||||
runTest("compiler/testData/ir/irText/expressions/lambdaInCAO.kt");
|
||||
|
||||
@@ -1159,6 +1159,34 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/annotations/functionalTypes")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class FunctionalTypes extends AbstractFirDiagnosticsSmokeTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInFunctionalTypes() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/annotations/functionalTypes"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("nonParenthesizedAnnotationsWithError.kt")
|
||||
public void testNonParenthesizedAnnotationsWithError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/nonParenthesizedAnnotationsWithError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nonParenthesizedAnnotationsWithoutError.kt")
|
||||
public void testNonParenthesizedAnnotationsWithoutError() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/nonParenthesizedAnnotationsWithoutError.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("parenthesizedAnnotations.kt")
|
||||
public void testParenthesizedAnnotations() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/annotations/functionalTypes/parenthesizedAnnotations.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/annotations/options")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
@@ -1679,6 +1707,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/expectedTypeAsSubtypeOfFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("functionReferenceWithDefaultValueAsOtherFunctionType.kt")
|
||||
public void testFunctionReferenceWithDefaultValueAsOtherFunctionType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/functionReferenceWithDefaultValueAsOtherFunctionType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("functionReferenceWithDefaultValueAsOtherFunctionType_enabled.kt")
|
||||
public void testFunctionReferenceWithDefaultValueAsOtherFunctionType_enabled() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/functionReferenceWithDefaultValueAsOtherFunctionType_enabled.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt15439_completeCall.kt")
|
||||
public void testKt15439_completeCall() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/kt15439_completeCall.kt");
|
||||
@@ -1694,6 +1732,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/kt31981.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt32256.kt")
|
||||
public void testKt32256() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/kt32256.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt7430_wrongClassOnLHS.kt")
|
||||
public void testKt7430_wrongClassOnLHS() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/kt7430_wrongClassOnLHS.kt");
|
||||
@@ -1739,6 +1782,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/subtypeArgumentFromRHSForReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("suspendCallableReference.kt")
|
||||
public void testSuspendCallableReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/suspendCallableReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typealiases.kt")
|
||||
public void testTypealiases() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/typealiases.kt");
|
||||
@@ -9503,6 +9551,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/inference/cannotCompleteResolveWithFunctionLiterals.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedInProjectedFlexibleType.kt")
|
||||
public void testCapturedInProjectedFlexibleType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/capturedInProjectedFlexibleType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("coerceFunctionLiteralToSuspend.kt")
|
||||
public void testCoerceFunctionLiteralToSuspend() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/coerceFunctionLiteralToSuspend.kt");
|
||||
@@ -9673,6 +9726,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/inference/kt3184.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt32434.kt")
|
||||
public void testKt32434() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/kt32434.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt6175.kt")
|
||||
public void testKt6175() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/kt6175.kt");
|
||||
@@ -10164,6 +10222,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/operationsOnIntegerValueTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveJavaTypeWithStarProjection.kt")
|
||||
public void testRecursiveJavaTypeWithStarProjection() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/recursiveJavaTypeWithStarProjection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("returnLambdaFromLambda.kt")
|
||||
public void testReturnLambdaFromLambda() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/returnLambdaFromLambda.kt");
|
||||
|
||||
@@ -45,7 +45,10 @@ object JvmPlatforms {
|
||||
)
|
||||
object CompatJvmPlatform : TargetPlatform(setOf(UNSPECIFIED_SIMPLE_JVM_PLATFORM)),
|
||||
// Needed for backward compatibility, because old code uses INSTANCEOF checks instead of calling extensions
|
||||
org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform {}
|
||||
org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform {
|
||||
override val platformName: String
|
||||
get() = "JVM"
|
||||
}
|
||||
}
|
||||
|
||||
class JdkPlatform(val targetVersion: JvmTarget) : JvmPlatform() {
|
||||
|
||||
@@ -16,10 +16,6 @@ import org.jetbrains.kotlin.resolve.TargetPlatform
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
interface JvmPlatform : TargetPlatform {
|
||||
@JvmDefault
|
||||
override val platformName: String
|
||||
get() = "JVM"
|
||||
|
||||
companion object {
|
||||
@JvmField
|
||||
val INSTANCE: JvmPlatform = JvmPlatforms.CompatJvmPlatform
|
||||
|
||||
@@ -67,10 +67,11 @@ open class AnalysisResult protected constructor(
|
||||
val exception: Throwable
|
||||
) : AnalysisResult(bindingContext, ErrorUtils.getErrorModule())
|
||||
|
||||
class RetryWithAdditionalJavaRoots(
|
||||
class RetryWithAdditionalRoots(
|
||||
bindingContext: BindingContext,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
val additionalJavaRoots: List<File>,
|
||||
val additionalKotlinRoots: List<File>,
|
||||
val addToEnvironment: Boolean = true
|
||||
) : AnalysisResult(bindingContext, moduleDescriptor)
|
||||
|
||||
|
||||
@@ -8,10 +8,12 @@ package org.jetbrains.kotlin.analyzer
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.ModificationTracker
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
|
||||
open class KotlinModificationTrackerService {
|
||||
open val modificationTracker: ModificationTracker = ModificationTracker.NEVER_CHANGED
|
||||
open val outOfBlockModificationTracker: ModificationTracker = ModificationTracker.NEVER_CHANGED
|
||||
open fun fileModificationTracker(file: KtFile): ModificationTracker = ModificationTracker.NEVER_CHANGED
|
||||
|
||||
companion object {
|
||||
private val NEVER_CHANGE_TRACKER_SERVICE = KotlinModificationTrackerService()
|
||||
|
||||
@@ -268,6 +268,8 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, FqName> EXPERIMENTAL_UNSIGNED_LITERALS = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, FqName> EXPERIMENTAL_UNSIGNED_LITERALS_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
// Const
|
||||
DiagnosticFactory0<PsiElement> CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT = DiagnosticFactory0.create(ERROR);
|
||||
DiagnosticFactory0<PsiElement> CONST_VAL_WITH_GETTER = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
@@ -159,6 +159,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS, "Unsigned literals are experimental and their usages should be marked with ''@{0}'' or ''@UseExperimental({0}::class)''", TO_STRING);
|
||||
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, "Unsigned literals are experimental and their usages must be marked with ''@{0}'' or ''@UseExperimental({0}::class)''", TO_STRING);
|
||||
|
||||
MAP.put(NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES, "Non-parenthesized annotations on function types without receiver aren't yet supported (see KT-31734 for details)");
|
||||
|
||||
MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING);
|
||||
MAP.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members");
|
||||
MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter");
|
||||
|
||||
@@ -34,6 +34,9 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
|
||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYield
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getPrevSiblingIgnoringWhitespaceAndComments
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasSuspendModifier
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
import org.jetbrains.kotlin.resolve.PossiblyBareType.bare
|
||||
import org.jetbrains.kotlin.resolve.PossiblyBareType.type
|
||||
@@ -69,6 +72,9 @@ class TypeResolver(
|
||||
private val platformToKotlinClassMap: PlatformToKotlinClassMap,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
) {
|
||||
private val isNonParenthesizedAnnotationsOnFunctionalTypesEnabled =
|
||||
languageVersionSettings.getFeatureSupport(LanguageFeature.NonParenthesizedAnnotationsOnFunctionalTypes) == LanguageFeature.State.ENABLED
|
||||
|
||||
open class TypeTransformerForTests {
|
||||
open fun transformType(kotlinType: KotlinType): KotlinType? = null
|
||||
}
|
||||
@@ -129,12 +135,54 @@ class TypeResolver(
|
||||
internal fun KtElementImplStub<*>.getAllModifierLists(): Array<out KtDeclarationModifierList> =
|
||||
getStubOrPsiChildren(KtStubElementTypes.MODIFIER_LIST, KtStubElementTypes.MODIFIER_LIST.arrayFactory)
|
||||
|
||||
// TODO: remove this method and its usages in 1.4
|
||||
private fun checkNonParenthesizedAnnotationsOnFunctionalType(
|
||||
typeElement: KtFunctionType,
|
||||
annotationEntries: List<KtAnnotationEntry>,
|
||||
trace: BindingTrace
|
||||
) {
|
||||
val lastAnnotationEntry = annotationEntries.lastOrNull()
|
||||
val isAnnotationsGroupedUsingBrackets =
|
||||
lastAnnotationEntry?.getNextSiblingIgnoringWhitespaceAndComments()?.node?.elementType == KtTokens.RBRACKET
|
||||
val hasAnnotationParentheses = lastAnnotationEntry?.valueArgumentList != null
|
||||
val isFunctionalTypeStartingWithParentheses = typeElement.firstChild is KtParameterList
|
||||
val hasSuspendModifierBeforeParentheses =
|
||||
typeElement.getPrevSiblingIgnoringWhitespaceAndComments().run { this is KtDeclarationModifierList && hasSuspendModifier() }
|
||||
|
||||
if (lastAnnotationEntry != null &&
|
||||
isFunctionalTypeStartingWithParentheses &&
|
||||
!hasAnnotationParentheses &&
|
||||
!isAnnotationsGroupedUsingBrackets &&
|
||||
!hasSuspendModifierBeforeParentheses
|
||||
) {
|
||||
trace.report(Errors.NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES.on(lastAnnotationEntry))
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveTypeAnnotations(c: TypeResolutionContext, modifierListsOwner: KtElementImplStub<*>): Annotations {
|
||||
val modifierLists = modifierListsOwner.getAllModifierLists()
|
||||
|
||||
var result = Annotations.EMPTY
|
||||
var isSplitModifierList = false
|
||||
|
||||
if (!isNonParenthesizedAnnotationsOnFunctionalTypesEnabled) {
|
||||
val targetType = when (modifierListsOwner) {
|
||||
is KtNullableType -> modifierListsOwner.innerType
|
||||
is KtTypeReference -> modifierListsOwner.typeElement
|
||||
else -> null
|
||||
}
|
||||
val annotationEntries = when (modifierListsOwner) {
|
||||
is KtNullableType -> modifierListsOwner.modifierList?.annotationEntries
|
||||
is KtTypeReference -> modifierListsOwner.annotationEntries
|
||||
else -> null
|
||||
}
|
||||
|
||||
// `targetType.stub == null` means that we don't apply this check for files that are built with stubs (that aren't opened in IDE and not in compile time)
|
||||
if (targetType is KtFunctionType && targetType.stub == null && annotationEntries != null) {
|
||||
checkNonParenthesizedAnnotationsOnFunctionalType(targetType, annotationEntries, c.trace)
|
||||
}
|
||||
}
|
||||
|
||||
for (modifierList in modifierLists) {
|
||||
if (isSplitModifierList) {
|
||||
c.trace.report(MODIFIER_LIST_NOT_ALLOWED.on(modifierList))
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls
|
||||
|
||||
import com.intellij.psi.util.PsiUtil
|
||||
import org.jetbrains.kotlin.builtins.UnsignedTypes
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionInvokeDescriptor
|
||||
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.INVOKE_ON_FUNCTION_TYPE
|
||||
@@ -147,6 +147,21 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CallableReferencesDefaultArgumentUsed::class.java -> {
|
||||
require(diagnostic is CallableReferencesDefaultArgumentUsed) {
|
||||
"diagnostic ($diagnostic) should have type CallableReferencesDefaultArgumentUsed"
|
||||
}
|
||||
|
||||
diagnostic.argument.psiExpression?.let {
|
||||
trace.report(
|
||||
UNSUPPORTED_FEATURE.on(
|
||||
it, LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType to context.languageVersionSettings
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||
import org.jetbrains.kotlin.resolve.calls.util.FakeCallableDescriptorForObject
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.types.StubType
|
||||
import org.jetbrains.kotlin.types.TypeApproximator
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
|
||||
@@ -47,7 +48,8 @@ class CoroutineInferenceSession(
|
||||
private val argumentTypeResolver: ArgumentTypeResolver,
|
||||
private val doubleColonExpressionResolver: DoubleColonExpressionResolver,
|
||||
private val deprecationResolver: DeprecationResolver,
|
||||
private val moduleDescriptor: ModuleDescriptor
|
||||
private val moduleDescriptor: ModuleDescriptor,
|
||||
private val typeApproximator: TypeApproximator
|
||||
) : ManyCandidatesResolver<CallableDescriptor>(
|
||||
psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns
|
||||
) {
|
||||
@@ -220,7 +222,7 @@ class CoroutineInferenceSession(
|
||||
return ResolvedAtomCompleter(
|
||||
resultSubstitutor, context, kotlinToResolvedCallTransformer,
|
||||
expressionTypingServices, argumentTypeResolver, doubleColonExpressionResolver, builtIns,
|
||||
deprecationResolver, moduleDescriptor, context.dataFlowValueFactory
|
||||
deprecationResolver, moduleDescriptor, context.dataFlowValueFactory, typeApproximator
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ class KotlinResolutionCallbacksImpl(
|
||||
psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter,
|
||||
callComponents, builtIns, topLevelCallContext, stubsForPostponedVariables, trace,
|
||||
kotlinToResolvedCallTransformer, expressionTypingServices, argumentTypeResolver,
|
||||
doubleColonExpressionResolver, deprecationResolver, moduleDescriptor
|
||||
doubleColonExpressionResolver, deprecationResolver, moduleDescriptor, typeApproximator
|
||||
)
|
||||
} else {
|
||||
null
|
||||
|
||||
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerLiteralTypeConstructor
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
|
||||
@@ -69,7 +68,8 @@ class KotlinToResolvedCallTransformer(
|
||||
private val moduleDescriptor: ModuleDescriptor,
|
||||
private val dataFlowValueFactory: DataFlowValueFactory,
|
||||
private val builtIns: KotlinBuiltIns,
|
||||
private val typeSystemContext: TypeSystemInferenceExtensionContextDelegate
|
||||
private val typeSystemContext: TypeSystemInferenceExtensionContextDelegate,
|
||||
private val typeApproximator: TypeApproximator
|
||||
) {
|
||||
companion object {
|
||||
private val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC
|
||||
@@ -126,7 +126,8 @@ class KotlinToResolvedCallTransformer(
|
||||
|
||||
val ktPrimitiveCompleter = ResolvedAtomCompleter(
|
||||
resultSubstitutor, context, this, expressionTypingServices, argumentTypeResolver,
|
||||
doubleColonExpressionResolver, builtIns, deprecationResolver, moduleDescriptor, dataFlowValueFactory
|
||||
doubleColonExpressionResolver, builtIns, deprecationResolver, moduleDescriptor, dataFlowValueFactory,
|
||||
typeApproximator
|
||||
)
|
||||
|
||||
if (!ErrorUtils.isError(candidate.candidateDescriptor)) {
|
||||
@@ -207,7 +208,7 @@ class KotlinToResolvedCallTransformer(
|
||||
return storedResolvedCall
|
||||
}
|
||||
}
|
||||
return NewResolvedCallImpl(completedSimpleAtom, resultSubstitutor, diagnostics)
|
||||
return NewResolvedCallImpl(completedSimpleAtom, resultSubstitutor, diagnostics, typeApproximator)
|
||||
}
|
||||
|
||||
fun runCallCheckers(resolvedCall: ResolvedCall<*>, callCheckerContext: CallCheckerContext) {
|
||||
@@ -606,7 +607,8 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>() : ResolvedCall<D>
|
||||
class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
val resolvedCallAtom: ResolvedCallAtom,
|
||||
substitutor: NewTypeSubstitutor?,
|
||||
private var diagnostics: Collection<KotlinCallDiagnostic>
|
||||
private var diagnostics: Collection<KotlinCallDiagnostic>,
|
||||
private val typeApproximator: TypeApproximator
|
||||
) : NewAbstractResolvedCall<D>() {
|
||||
var isCompleted = false
|
||||
private set
|
||||
@@ -699,7 +701,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
// this code is very suspicious. Now it is very useful for BE, because they cannot do nothing with captured types,
|
||||
// but it seems like temporary solution.
|
||||
candidateDescriptor.substitute(resolvedCallAtom.substitutor).substituteAndApproximateCapturedTypes(
|
||||
substitutor ?: FreshVariableNewTypeSubstitutor.Empty
|
||||
substitutor ?: FreshVariableNewTypeSubstitutor.Empty, typeApproximator
|
||||
)
|
||||
else ->
|
||||
candidateDescriptor
|
||||
@@ -708,7 +710,7 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
|
||||
typeArguments = resolvedCallAtom.substitutor.freshVariables.map {
|
||||
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
|
||||
TypeApproximator(substituted.constructor.builtIns)
|
||||
typeApproximator
|
||||
.approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
|
||||
?: substituted
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.canBeResolvedWithoutDeprecation
|
||||
import org.jetbrains.kotlin.types.DeferredType
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
import org.jetbrains.kotlin.types.TypeApproximator
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -72,7 +73,8 @@ class NewResolutionOldInference(
|
||||
private val syntheticScopes: SyntheticScopes,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val coroutineInferenceSupport: CoroutineInferenceSupport,
|
||||
private val deprecationResolver: DeprecationResolver
|
||||
private val deprecationResolver: DeprecationResolver,
|
||||
private val typeApproximator: TypeApproximator
|
||||
) {
|
||||
sealed class ResolutionKind {
|
||||
abstract internal fun createTowerProcessor(
|
||||
@@ -170,7 +172,9 @@ class NewResolutionOldInference(
|
||||
}
|
||||
|
||||
val dynamicScope = dynamicCallableDescriptors.createDynamicDescriptorScope(context.call, context.scope.ownerDescriptor)
|
||||
val scopeTower = ImplicitScopeTowerImpl(context, dynamicScope, syntheticScopes, context.call.createLookupLocation())
|
||||
val scopeTower = ImplicitScopeTowerImpl(
|
||||
context, dynamicScope, syntheticScopes, context.call.createLookupLocation(), typeApproximator
|
||||
)
|
||||
|
||||
val shouldUseOperatorRem = languageVersionSettings.supportsFeature(LanguageFeature.OperatorRem)
|
||||
val isBinaryRemOperator = isBinaryRemOperator(context.call)
|
||||
@@ -353,7 +357,8 @@ class NewResolutionOldInference(
|
||||
val resolutionContext: ResolutionContext<*>,
|
||||
override val dynamicScope: MemberScope,
|
||||
override val syntheticScopes: SyntheticScopes,
|
||||
override val location: LookupLocation
|
||||
override val location: LookupLocation,
|
||||
override val typeApproximator: TypeApproximator
|
||||
) : ImplicitScopeTower {
|
||||
private val cache = HashMap<ReceiverValue, ReceiverValueWithSmartCastInfo>()
|
||||
|
||||
|
||||
@@ -106,7 +106,10 @@ class PSICallResolver(
|
||||
return OverloadResolutionResultsImpl.nameNotFound()
|
||||
}
|
||||
|
||||
return convertToOverloadResolutionResults(context, result, tracingStrategy)
|
||||
val overloadResolutionResults = convertToOverloadResolutionResults<D>(context, result, tracingStrategy)
|
||||
return overloadResolutionResults.also {
|
||||
clearCacheForApproximationResults()
|
||||
}
|
||||
}
|
||||
|
||||
// actually, `D` is at least FunctionDescriptor, but right now because of CallResolver it isn't possible change upper bound for `D`
|
||||
@@ -133,7 +136,16 @@ class PSICallResolver(
|
||||
val result = kotlinCallResolver.resolveGivenCandidates(
|
||||
scopeTower, resolutionCallbacks, kotlinCall, calculateExpectedType(context), givenCandidates, context.collectAllCandidates
|
||||
)
|
||||
return convertToOverloadResolutionResults(context, result, tracingStrategy)
|
||||
val overloadResolutionResults = convertToOverloadResolutionResults<D>(context, result, tracingStrategy)
|
||||
return overloadResolutionResults.also {
|
||||
clearCacheForApproximationResults()
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearCacheForApproximationResults() {
|
||||
// Mostly, we approximate captured or some other internal types that don't live longer than resolve for a call,
|
||||
// so it's quite useless to preserve cache for longer time
|
||||
typeApproximator.clearCache()
|
||||
}
|
||||
|
||||
private fun resolveToDeprecatedMod(
|
||||
@@ -375,6 +387,7 @@ class PSICallResolver(
|
||||
override val isDebuggerContext: Boolean get() = context.isDebuggerContext
|
||||
override val isNewInferenceEnabled: Boolean get() = context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
|
||||
override val lexicalScope: LexicalScope get() = context.scope
|
||||
override val typeApproximator: TypeApproximator get() = this@PSICallResolver.typeApproximator
|
||||
private val cache = HashMap<ReceiverParameterDescriptor, ReceiverValueWithSmartCastInfo>()
|
||||
|
||||
override fun getImplicitReceiver(scope: LexicalScope): ReceiverValueWithSmartCastInfo? {
|
||||
|
||||
@@ -50,7 +50,8 @@ class ResolvedAtomCompleter(
|
||||
private val builtIns: KotlinBuiltIns,
|
||||
private val deprecationResolver: DeprecationResolver,
|
||||
private val moduleDescriptor: ModuleDescriptor,
|
||||
private val dataFlowValueFactory: DataFlowValueFactory
|
||||
private val dataFlowValueFactory: DataFlowValueFactory,
|
||||
private val typeApproximator: TypeApproximator
|
||||
) {
|
||||
private val topLevelCallCheckerContext = CallCheckerContext(topLevelCallContext, deprecationResolver, moduleDescriptor)
|
||||
private val topLevelTrace = topLevelCallCheckerContext.trace
|
||||
@@ -142,7 +143,7 @@ class ResolvedAtomCompleter(
|
||||
}
|
||||
|
||||
val approximatedReturnType =
|
||||
TypeApproximator(builtIns).approximateDeclarationType(
|
||||
typeApproximator.approximateDeclarationType(
|
||||
returnType,
|
||||
local = true,
|
||||
languageVersionSettings = topLevelCallContext.languageVersionSettings
|
||||
|
||||
@@ -52,6 +52,7 @@ class LateinitLowering(val context: CommonBackendContext) : FileLoweringPass {
|
||||
name = oldField.name
|
||||
}.also { newField ->
|
||||
newField.parent = oldField.parent
|
||||
newField.correspondingPropertySymbol = declaration.symbol
|
||||
declaration.backingField = newField
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ private val kotlinCoroutinesPackageFqn = kotlinPackageFqn.child(Name.identifier(
|
||||
fun IrType.isFunction(): Boolean = this.isClassWithNamePrefix("Function", kotlinPackageFqn)
|
||||
fun IrType.isKFunction(): Boolean = this.isClassWithNamePrefix("KFunction", kotlinReflectionPackageFqn)
|
||||
fun IrType.isSuspendFunction(): Boolean = this.isClassWithNamePrefix("SuspendFunction", kotlinCoroutinesPackageFqn)
|
||||
fun IrType.isKSuspendFunction(): Boolean = this.isClassWithNamePrefix("KSuspendFunction", kotlinReflectionPackageFqn)
|
||||
|
||||
private fun IrType.isClassWithNamePrefix(prefix: String, packageFqName: FqName): Boolean {
|
||||
val classifier = classifierOrNull ?: return false
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
@@ -35,11 +36,14 @@ import org.jetbrains.kotlin.psi2ir.containsNull
|
||||
import org.jetbrains.kotlin.psi2ir.findSingleFunction
|
||||
import org.jetbrains.kotlin.psi2ir.intermediate.safeCallOnDispatchReceiver
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.NewCommonSuperTypeCalculator
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.checkers.PrimitiveNumericComparisonInfo
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.checker.intersectTypes
|
||||
import org.jetbrains.kotlin.types.isDynamic
|
||||
import org.jetbrains.kotlin.types.isError
|
||||
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||
@@ -190,9 +194,28 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
|
||||
}
|
||||
}
|
||||
|
||||
private fun getResultTypeForElvis(expression: KtExpression): KotlinType {
|
||||
val binaryExpression = KtPsiUtil.safeDeparenthesize(expression)
|
||||
val expressionType = context.bindingContext.getType(binaryExpression)!!
|
||||
if (binaryExpression !is KtBinaryExpression || binaryExpression.operationToken != KtTokens.ELVIS) return expressionType
|
||||
|
||||
val inferredType = getResolvedCall(binaryExpression)!!.resultingDescriptor.returnType!!
|
||||
|
||||
// OI has a rather complex bug with constraint system for special call for '?:' that breaks IR-based back-ends.
|
||||
// In NI this bug is fixed.
|
||||
if (context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) return inferredType
|
||||
|
||||
if (!inferredType.isError) return inferredType
|
||||
|
||||
// Infer type for elvis manually. Take into account possibly nested elvises.
|
||||
val rightType = getResultTypeForElvis(binaryExpression.right!!).unwrap()
|
||||
val leftType = getResultTypeForElvis(binaryExpression.left!!).unwrap()
|
||||
val leftNNType = intersectTypes(listOf(leftType, context.builtIns.anyType))
|
||||
return NewCommonSuperTypeCalculator.commonSuperType(listOf(rightType, leftNNType))
|
||||
}
|
||||
|
||||
private fun generateElvis(expression: KtBinaryExpression): IrExpression {
|
||||
val specialCallForElvis = getResolvedCall(expression)!!
|
||||
val resultType = specialCallForElvis.resultingDescriptor.returnType!!.toIrType()
|
||||
val resultType = getResultTypeForElvis(expression).toIrType()
|
||||
val irArgument0 = expression.left!!.genExpr()
|
||||
val irArgument1 = expression.right!!.genExpr()
|
||||
|
||||
|
||||
@@ -91,20 +91,6 @@ private fun createJavaFileStub(project: Project, packageFqName: FqName, files: C
|
||||
|
||||
override fun isPhysical() = false
|
||||
|
||||
override fun appendMirrorText(indentLevel: Int, buffer: StringBuilder) {
|
||||
if (files.size == 1) {
|
||||
LOG.error("Mirror text should never be calculated for light classes generated from a single file")
|
||||
}
|
||||
super.appendMirrorText(indentLevel, buffer)
|
||||
}
|
||||
|
||||
override fun getMirror(): PsiElement {
|
||||
if (files.size == 1) {
|
||||
LOG.error("Mirror element should never be calculated for light classes generated from a single file")
|
||||
}
|
||||
return super.getMirror()
|
||||
}
|
||||
|
||||
override fun getText(): String {
|
||||
return files.singleOrNull()?.text ?: super.getText()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.asJava.classes;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.SimpleModificationTracker;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
import com.intellij.psi.impl.PsiImplUtil;
|
||||
import com.intellij.psi.impl.light.LightMethod;
|
||||
import com.intellij.psi.impl.source.PsiExtensibleClass;
|
||||
import com.intellij.psi.scope.ElementClassHint;
|
||||
import com.intellij.psi.scope.NameHint;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.util.CachedValueProvider;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.SmartList;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.util.ObjectUtils.notNull;
|
||||
|
||||
// Copy of ClassInnerStuffCache with custom list of caching dependencies
|
||||
@SuppressWarnings({"WeakerAccess", "Java8MapApi"})
|
||||
public class KotlinClassInnerStuffCache {
|
||||
private final PsiExtensibleClass myClass;
|
||||
private final SimpleModificationTracker myTracker = new SimpleModificationTracker();
|
||||
private final List<Object> dependencies;
|
||||
|
||||
public KotlinClassInnerStuffCache(@NotNull PsiExtensibleClass aClass, @NotNull List<Object> externalDependencies) {
|
||||
myClass = aClass;
|
||||
|
||||
dependencies = new SmartList<>();
|
||||
dependencies.addAll(externalDependencies);
|
||||
dependencies.add(myTracker);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiMethod[] getConstructors() {
|
||||
return copy(CachedValuesManager.getCachedValue(myClass, () -> makeResult(PsiImplUtil.getConstructors(myClass))));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiField[] getFields() {
|
||||
return copy(CachedValuesManager.getCachedValue(myClass, () -> makeResult(getAllFields())));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiMethod[] getMethods() {
|
||||
return copy(CachedValuesManager.getCachedValue(myClass, () -> makeResult(getAllMethods())));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiClass[] getInnerClasses() {
|
||||
return copy(CachedValuesManager.getCachedValue(myClass, () -> makeResult(getAllInnerClasses())));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiField findFieldByName(String name, boolean checkBases) {
|
||||
if (checkBases) {
|
||||
return PsiClassImplUtil.findFieldByName(myClass, name, true);
|
||||
}
|
||||
else {
|
||||
return CachedValuesManager.getCachedValue(myClass, () -> makeResult(getFieldsMap())).get(name);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public PsiMethod[] findMethodsByName(String name, boolean checkBases) {
|
||||
if (checkBases) {
|
||||
return PsiClassImplUtil.findMethodsByName(myClass, name, true);
|
||||
}
|
||||
else {
|
||||
return copy(notNull(CachedValuesManager.getCachedValue(myClass, () -> makeResult(getMethodsMap())).get(name), PsiMethod.EMPTY_ARRAY));
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiClass findInnerClassByName(String name, boolean checkBases) {
|
||||
if (checkBases) {
|
||||
return PsiClassImplUtil.findInnerByName(myClass, name, true);
|
||||
}
|
||||
else {
|
||||
return CachedValuesManager.getCachedValue(myClass, () -> makeResult(getInnerClassesMap())).get(name);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiMethod getValuesMethod() {
|
||||
return myClass.isEnum() && myClass.getName() != null ? CachedValuesManager.getCachedValue(myClass, () -> makeResult(makeValuesMethod())) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiMethod getValueOfMethod() {
|
||||
return myClass.isEnum() && myClass.getName() != null ? CachedValuesManager.getCachedValue(myClass, () -> makeResult(makeValueOfMethod())) : null;
|
||||
}
|
||||
|
||||
private static <T> T[] copy(T[] value) {
|
||||
return value.length == 0 ? value : value.clone();
|
||||
}
|
||||
|
||||
// This method is modified
|
||||
private <T> CachedValueProvider.Result<T> makeResult(T value) {
|
||||
return CachedValueProvider.Result.create(value, dependencies);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiField[] getAllFields() {
|
||||
List<PsiField> own = myClass.getOwnFields();
|
||||
List<PsiField> ext = PsiAugmentProvider.collectAugments(myClass, PsiField.class);
|
||||
return ArrayUtil.mergeCollections(own, ext, PsiField.ARRAY_FACTORY);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiMethod[] getAllMethods() {
|
||||
List<PsiMethod> own = myClass.getOwnMethods();
|
||||
List<PsiMethod> ext = PsiAugmentProvider.collectAugments(myClass, PsiMethod.class);
|
||||
return ArrayUtil.mergeCollections(own, ext, PsiMethod.ARRAY_FACTORY);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private PsiClass[] getAllInnerClasses() {
|
||||
List<PsiClass> own = myClass.getOwnInnerClasses();
|
||||
List<PsiClass> ext = PsiAugmentProvider.collectAugments(myClass, PsiClass.class);
|
||||
return ArrayUtil.mergeCollections(own, ext, PsiClass.ARRAY_FACTORY);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<String, PsiField> getFieldsMap() {
|
||||
PsiField[] fields = getFields();
|
||||
if (fields.length == 0) return Collections.emptyMap();
|
||||
|
||||
Map<String, PsiField> cachedFields = new THashMap<>();
|
||||
for (PsiField field : fields) {
|
||||
String name = field.getName();
|
||||
if (!cachedFields.containsKey(name)) {
|
||||
cachedFields.put(name, field);
|
||||
}
|
||||
}
|
||||
return cachedFields;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<String, PsiMethod[]> getMethodsMap() {
|
||||
PsiMethod[] methods = getMethods();
|
||||
if (methods.length == 0) return Collections.emptyMap();
|
||||
|
||||
Map<String, List<PsiMethod>> collectedMethods = ContainerUtil.newHashMap();
|
||||
for (PsiMethod method : methods) {
|
||||
List<PsiMethod> list = collectedMethods.get(method.getName());
|
||||
if (list == null) {
|
||||
collectedMethods.put(method.getName(), list = ContainerUtil.newSmartList());
|
||||
}
|
||||
list.add(method);
|
||||
}
|
||||
|
||||
Map<String, PsiMethod[]> cachedMethods = ContainerUtil.newTroveMap();
|
||||
for (Map.Entry<String, List<PsiMethod>> entry : collectedMethods.entrySet()) {
|
||||
List<PsiMethod> list = entry.getValue();
|
||||
cachedMethods.put(entry.getKey(), list.toArray(PsiMethod.EMPTY_ARRAY));
|
||||
}
|
||||
return cachedMethods;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Map<String, PsiClass> getInnerClassesMap() {
|
||||
PsiClass[] classes = getInnerClasses();
|
||||
if (classes.length == 0) return Collections.emptyMap();
|
||||
|
||||
Map<String, PsiClass> cachedInners = new THashMap<>();
|
||||
for (PsiClass psiClass : classes) {
|
||||
String name = psiClass.getName();
|
||||
if (name == null) {
|
||||
Logger.getInstance(KotlinClassInnerStuffCache.class).error(psiClass);
|
||||
}
|
||||
else if (!(psiClass instanceof ExternallyDefinedPsiElement) || !cachedInners.containsKey(name)) {
|
||||
cachedInners.put(name, psiClass);
|
||||
}
|
||||
}
|
||||
return cachedInners;
|
||||
}
|
||||
|
||||
private PsiMethod makeValuesMethod() {
|
||||
return getSyntheticMethod("public static " + myClass.getName() + "[] values() { }");
|
||||
}
|
||||
|
||||
private PsiMethod makeValueOfMethod() {
|
||||
return getSyntheticMethod("public static " + myClass.getName() + " valueOf(java.lang.String name) throws java.lang.IllegalArgumentException { }");
|
||||
}
|
||||
|
||||
private PsiMethod getSyntheticMethod(String text) {
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(myClass.getProject());
|
||||
PsiMethod method = factory.createMethodFromText(text, myClass);
|
||||
return new LightMethod(myClass.getManager(), method, myClass) {
|
||||
@Override
|
||||
public int getTextOffset() {
|
||||
return myClass.getTextOffset();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public void dropCaches() {
|
||||
myTracker.incModificationCount();
|
||||
}
|
||||
|
||||
private static final String VALUES_METHOD = "values";
|
||||
private static final String VALUE_OF_METHOD = "valueOf";
|
||||
|
||||
// Copy of PsiClassImplUtil.processDeclarationsInEnum for own cache class
|
||||
public static boolean processDeclarationsInEnum(@NotNull PsiScopeProcessor processor,
|
||||
@NotNull ResolveState state,
|
||||
@NotNull KotlinClassInnerStuffCache innerStuffCache) {
|
||||
ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);
|
||||
if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) {
|
||||
NameHint nameHint = processor.getHint(NameHint.KEY);
|
||||
if (nameHint == null || VALUES_METHOD.equals(nameHint.getName(state))) {
|
||||
PsiMethod method = innerStuffCache.getValuesMethod();
|
||||
if (method != null && !processor.execute(method, ResolveState.initial())) return false;
|
||||
}
|
||||
if (nameHint == null || VALUE_OF_METHOD.equals(nameHint.getName(state))) {
|
||||
PsiMethod method = innerStuffCache.getValueOfMethod();
|
||||
if (method != null && !processor.execute(method, ResolveState.initial())) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -20,16 +20,18 @@ import com.intellij.navigation.ItemPresentationProviders
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.impl.PsiClassImplUtil
|
||||
import com.intellij.psi.impl.light.AbstractLightClass
|
||||
import com.intellij.psi.impl.source.ClassInnerStuffCache
|
||||
import com.intellij.psi.impl.source.PsiExtensibleClass
|
||||
import com.intellij.psi.scope.PsiScopeProcessor
|
||||
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
||||
import org.jetbrains.kotlin.asJava.classes.KotlinClassInnerStuffCache.processDeclarationsInEnum
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightFieldImpl
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethodImpl
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
|
||||
abstract class KtLightClassBase protected constructor(manager: PsiManager)
|
||||
: AbstractLightClass(manager, KotlinLanguage.INSTANCE), KtLightClass, PsiExtensibleClass {
|
||||
private val myInnersCache = ClassInnerStuffCache(this)
|
||||
protected open val myInnersCache = KotlinClassInnerStuffCache(
|
||||
this, listOf(KotlinModificationTrackerService.getInstance(manager.project).outOfBlockModificationTracker))
|
||||
|
||||
override fun getDelegate() = clsDelegate
|
||||
|
||||
@@ -61,7 +63,7 @@ abstract class KtLightClassBase protected constructor(manager: PsiManager)
|
||||
processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement
|
||||
): Boolean {
|
||||
if (isEnum) {
|
||||
if (!PsiClassImplUtil.processDeclarationsInEnum(processor, state, myInnersCache)) return false
|
||||
if (!processDeclarationsInEnum(processor, state, myInnersCache)) return false
|
||||
}
|
||||
|
||||
return super.processDeclarations(processor, state, lastParent, place)
|
||||
|
||||
@@ -19,7 +19,7 @@ package org.jetbrains.kotlin.asJava.classes
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
|
||||
// light class for top level or (inner/nested of top level) source declarations
|
||||
open class KtLightClassImpl(
|
||||
open class KtLightClassImpl @JvmOverloads constructor(
|
||||
classOrObject: KtClassOrObject,
|
||||
forceUsingOldLightClasses: Boolean = false
|
||||
) : KtLightClassForSourceDeclaration(classOrObject, forceUsingOldLightClasses) {
|
||||
|
||||
@@ -9,10 +9,7 @@ import com.intellij.psi.*
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||
import org.jetbrains.kotlin.asJava.elements.KtLightSimpleModifierList
|
||||
import org.jetbrains.kotlin.asJava.elements.LightParameter
|
||||
import org.jetbrains.kotlin.asJava.elements.*
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.codegen.coroutines.SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME
|
||||
@@ -26,11 +23,12 @@ internal class KtUltraLightSuspendContinuationParameter(
|
||||
private val support: KtUltraLightSupport,
|
||||
method: KtLightMethod
|
||||
) : LightParameter(SUSPEND_FUNCTION_COMPLETION_PARAMETER_NAME, PsiType.NULL, method, method.language),
|
||||
KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiParameter> {
|
||||
KtLightParameter,
|
||||
KtUltraLightElementWithNullabilityAnnotation<KtParameter, PsiParameter> {
|
||||
|
||||
override val kotlinTypeForNullabilityAnnotation: KotlinType? get() = ktType
|
||||
override val psiTypeForNullabilityAnnotation: PsiType? get() = psiType
|
||||
override val kotlinOrigin: KtDeclaration? = null
|
||||
override val kotlinOrigin: KtParameter? = null
|
||||
override val clsDelegate: PsiParameter
|
||||
get() = throw IllegalStateException("Cls delegate shouldn't be loaded for ultra-light PSI!")
|
||||
|
||||
@@ -68,7 +66,7 @@ internal class KtUltraLightSuspendContinuationParameter(
|
||||
|
||||
internal abstract class KtUltraLightParameter(
|
||||
name: String,
|
||||
override val kotlinOrigin: KtDeclaration?,
|
||||
override val kotlinOrigin: KtParameter?,
|
||||
protected val support: KtUltraLightSupport,
|
||||
method: KtLightMethod
|
||||
) : org.jetbrains.kotlin.asJava.elements.LightParameter(
|
||||
@@ -76,7 +74,7 @@ internal abstract class KtUltraLightParameter(
|
||||
PsiType.NULL,
|
||||
method,
|
||||
method.language
|
||||
), KtUltraLightElementWithNullabilityAnnotation<KtDeclaration, PsiParameter> {
|
||||
), KtUltraLightElementWithNullabilityAnnotation<KtParameter, PsiParameter>, KtLightParameter {
|
||||
|
||||
override fun isEquivalentTo(another: PsiElement?): Boolean = kotlinOrigin == another
|
||||
|
||||
@@ -137,7 +135,7 @@ internal abstract class KtUltraLightParameter(
|
||||
|
||||
internal abstract class KtAbstractUltraLightParameterForDeclaration(
|
||||
name: String,
|
||||
kotlinOrigin: KtDeclaration?,
|
||||
kotlinOrigin: KtParameter?,
|
||||
support: KtUltraLightSupport,
|
||||
method: KtLightMethod,
|
||||
protected val containingDeclaration: KtCallableDeclaration
|
||||
@@ -192,12 +190,11 @@ internal class KtUltraLightReceiverParameter(
|
||||
|
||||
internal class KtUltraLightParameterForDescriptor(
|
||||
private val descriptor: ParameterDescriptor,
|
||||
kotlinOrigin: KtDeclaration?,
|
||||
support: KtUltraLightSupport,
|
||||
method: KtLightMethod
|
||||
) : KtUltraLightParameter(
|
||||
if (descriptor.name.isSpecial) "\$self" else descriptor.name.identifier,
|
||||
kotlinOrigin, support, method
|
||||
null, support, method
|
||||
) {
|
||||
override val kotlinType: KotlinType?
|
||||
get() = descriptor.type
|
||||
|
||||
@@ -223,11 +223,11 @@ fun KtUltraLightClass.createGeneratedMethodFromDescriptor(
|
||||
val wrapper = KtUltraLightMethodForDescriptor(descriptor, lightMethod, lightMemberOrigin, support, this)
|
||||
|
||||
descriptor.extensionReceiverParameter?.let { receiver ->
|
||||
lightMethod.addParameter(KtUltraLightParameterForDescriptor(receiver, kotlinOrigin, support, wrapper))
|
||||
lightMethod.addParameter(KtUltraLightParameterForDescriptor(receiver, support, wrapper))
|
||||
}
|
||||
|
||||
for (valueParameter in descriptor.valueParameters) {
|
||||
lightMethod.addParameter(KtUltraLightParameterForDescriptor(valueParameter, kotlinOrigin, support, wrapper))
|
||||
lightMethod.addParameter(KtUltraLightParameterForDescriptor(valueParameter, support, wrapper))
|
||||
}
|
||||
|
||||
lightMethod.setMethodReturnType {
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind
|
||||
|
||||
interface KtLightElement<out T : KtElement, out D : PsiElement> : PsiElement {
|
||||
@@ -48,6 +49,10 @@ interface KtLightMember<out D : PsiMember> : PsiMember, KtLightDeclaration<KtDec
|
||||
|
||||
interface KtLightField : PsiField, KtLightMember<PsiField>, PsiVariableEx
|
||||
|
||||
interface KtLightParameter : PsiParameter, KtLightDeclaration<KtParameter, PsiParameter> {
|
||||
val method: KtLightMethod
|
||||
}
|
||||
|
||||
interface KtLightMethod : PsiAnnotationMethod, KtLightMember<PsiMethod> {
|
||||
val isDelegated: Boolean
|
||||
get() = lightMemberOrigin?.originKind == JvmDeclarationOriginKind.DELEGATION
|
||||
|
||||
@@ -61,7 +61,7 @@ open class KtLightMethodImpl protected constructor(
|
||||
protected open fun buildParametersForList(): List<PsiParameter> {
|
||||
val clsParameters by lazyPub { clsDelegate.parameterList.parameters }
|
||||
return (dummyDelegate?.parameterList?.parameters ?: clsParameters).mapIndexed { index, dummyParameter ->
|
||||
KtLightParameter(
|
||||
KtLightParameterImpl(
|
||||
dummyParameter,
|
||||
{ clsParameters.getOrNull(index) },
|
||||
index,
|
||||
|
||||
@@ -16,19 +16,16 @@ import com.intellij.util.IncorrectOperationException
|
||||
import org.jetbrains.annotations.NonNls
|
||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
|
||||
class KtLightParameter(
|
||||
internal class KtLightParameterImpl(
|
||||
private val dummyDelegate: PsiParameter,
|
||||
private val clsDelegateProvider: () -> PsiParameter?,
|
||||
private val index: Int,
|
||||
method: KtLightMethod
|
||||
) : LightParameter(dummyDelegate.name ?: "p$index", dummyDelegate.type, method, KotlinLanguage.INSTANCE),
|
||||
KtLightDeclaration<KtParameter, PsiParameter> {
|
||||
KtLightDeclaration<KtParameter, PsiParameter>, KtLightParameter {
|
||||
|
||||
private val lazyDelegate by lazyPub { clsDelegateProvider() ?: dummyDelegate }
|
||||
|
||||
@@ -104,7 +101,7 @@ class KtLightParameter(
|
||||
val kotlinOrigin = kotlinOrigin
|
||||
if (kotlinOrigin?.isEquivalentTo(another) == true) return@Computable true
|
||||
|
||||
if (another is KtLightParameter && kotlinOrigin != null) {
|
||||
if (another is KtLightParameterImpl && kotlinOrigin != null) {
|
||||
kotlinOrigin == another.kotlinOrigin && clsDelegate == another.clsDelegate
|
||||
}
|
||||
else {
|
||||
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.asJava.elements;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
// Based on com.intellij.psi.impl.light.LightParameter
|
||||
public class LightParameter extends LightVariableBuilder implements PsiParameter {
|
||||
public static final LightParameter[] EMPTY_ARRAY = new LightParameter[0];
|
||||
|
||||
private final String myName;
|
||||
private final KtLightMethod myDeclarationScope;
|
||||
private final boolean myVarArgs;
|
||||
|
||||
public LightParameter(@NotNull String name, @NotNull PsiType type, @NotNull KtLightMethod declarationScope, Language language) {
|
||||
this(name, type, declarationScope, language, type instanceof PsiEllipsisType);
|
||||
}
|
||||
|
||||
public LightParameter(@NotNull String name, @NotNull PsiType type, @NotNull KtLightMethod declarationScope, Language language, boolean isVarArgs) {
|
||||
super(declarationScope.getManager(), name, type, language);
|
||||
myName = name;
|
||||
myDeclarationScope = declarationScope;
|
||||
myVarArgs = isVarArgs;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KtLightMethod getDeclarationScope() {
|
||||
return myDeclarationScope;
|
||||
}
|
||||
|
||||
public KtLightMethod getMethod() {
|
||||
return myDeclarationScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof JavaElementVisitor) {
|
||||
((JavaElementVisitor)visitor).visitParameter(this);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Light Parameter";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVarArgs() {
|
||||
return myVarArgs;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.asJava.elements
|
||||
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.psi.*
|
||||
|
||||
// Based on com.intellij.psi.impl.light.LightParameter
|
||||
open class LightParameter @JvmOverloads constructor(
|
||||
private val myName: String,
|
||||
type: PsiType,
|
||||
val method: KtLightMethod,
|
||||
language: Language?,
|
||||
private val myVarArgs: Boolean = type is PsiEllipsisType
|
||||
) : LightVariableBuilder(method.manager, myName, type, language),
|
||||
PsiParameter {
|
||||
override fun getDeclarationScope(): KtLightMethod = method
|
||||
|
||||
override fun accept(visitor: PsiElementVisitor) {
|
||||
if (visitor is JavaElementVisitor) {
|
||||
visitor.visitParameter(this)
|
||||
}
|
||||
}
|
||||
|
||||
override fun toString(): String = "Light Parameter"
|
||||
|
||||
override fun isVarArgs(): Boolean = myVarArgs
|
||||
|
||||
override fun getName(): String = myName
|
||||
|
||||
companion object {
|
||||
val EMPTY_ARRAY = arrayOfNulls<LightParameter>(0)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -509,24 +509,36 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
}
|
||||
|
||||
private boolean parseTypeModifierList() {
|
||||
return doParseModifierList(null, TYPE_MODIFIER_KEYWORDS, DEFAULT, TokenSet.EMPTY);
|
||||
return doParseModifierList(null, TYPE_MODIFIER_KEYWORDS, TYPE_CONTEXT, TokenSet.EMPTY);
|
||||
}
|
||||
|
||||
private boolean parseTypeArgumentModifierList() {
|
||||
return doParseModifierList(null, TYPE_ARGUMENT_MODIFIER_KEYWORDS, NO_ANNOTATIONS, TokenSet.create(COMMA, COLON, GT));
|
||||
}
|
||||
|
||||
private boolean doParseModifierList(
|
||||
private boolean doParseModifierListBody(
|
||||
@Nullable Consumer<IElementType> tokenConsumer,
|
||||
@NotNull TokenSet modifierKeywords,
|
||||
@NotNull AnnotationParsingMode annotationParsingMode,
|
||||
@NotNull TokenSet noModifiersBefore
|
||||
) {
|
||||
PsiBuilder.Marker list = mark();
|
||||
boolean empty = true;
|
||||
PsiBuilder.Marker beforeAnnotationMarker;
|
||||
while (!eof()) {
|
||||
if (at(AT) && annotationParsingMode.allowAnnotations) {
|
||||
parseAnnotationOrList(annotationParsingMode);
|
||||
beforeAnnotationMarker = mark();
|
||||
|
||||
boolean isAnnotationParsed = parseAnnotationOrList(annotationParsingMode);
|
||||
|
||||
if (!isAnnotationParsed && !annotationParsingMode.withSignificantWhitespaceBeforeArguments) {
|
||||
beforeAnnotationMarker.rollbackTo();
|
||||
// try parse again, but with significant whitespace
|
||||
doParseModifierListBody(tokenConsumer, modifierKeywords, WITH_SIGNIFICANT_WHITESPACE_BEFORE_ARGUMENTS, noModifiersBefore);
|
||||
empty = false;
|
||||
break;
|
||||
} else {
|
||||
beforeAnnotationMarker.drop();
|
||||
}
|
||||
}
|
||||
else if (tryParseModifier(tokenConsumer, noModifiersBefore, modifierKeywords)) {
|
||||
// modifier advanced
|
||||
@@ -536,6 +548,25 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
}
|
||||
empty = false;
|
||||
}
|
||||
|
||||
return empty;
|
||||
}
|
||||
|
||||
private boolean doParseModifierList(
|
||||
@Nullable Consumer<IElementType> tokenConsumer,
|
||||
@NotNull TokenSet modifierKeywords,
|
||||
@NotNull AnnotationParsingMode annotationParsingMode,
|
||||
@NotNull TokenSet noModifiersBefore
|
||||
) {
|
||||
PsiBuilder.Marker list = mark();
|
||||
|
||||
boolean empty = doParseModifierListBody(
|
||||
tokenConsumer,
|
||||
modifierKeywords,
|
||||
annotationParsingMode,
|
||||
noModifiersBefore
|
||||
);
|
||||
|
||||
if (empty) {
|
||||
list.drop();
|
||||
}
|
||||
@@ -796,8 +827,27 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
|
||||
parseTypeArgumentList();
|
||||
|
||||
if (at(LPAR)) {
|
||||
boolean whitespaceAfterAnnotation = WHITE_SPACE_OR_COMMENT_BIT_SET.contains(myBuilder.rawLookup(-1));
|
||||
boolean shouldBeParsedNextAsFunctionalType = at(LPAR) && whitespaceAfterAnnotation && mode.withSignificantWhitespaceBeforeArguments;
|
||||
|
||||
if (at(LPAR) && !shouldBeParsedNextAsFunctionalType) {
|
||||
myExpressionParsing.parseValueArgumentList();
|
||||
|
||||
/*
|
||||
* There are two problem cases relating to parsing of annotations on a functional type:
|
||||
* - Annotation on a functional type was parsed correctly with the capture parentheses of the functional type,
|
||||
* e.g. @Anno () -> Unit
|
||||
* ^ Parse error only here: Type expected
|
||||
* - It wasn't parsed, e.g. @Anno (x: kotlin.Any) -> Unit
|
||||
* ^ Parse error: Expecting ')'
|
||||
*
|
||||
* In both cases, parser should rollback to start parsing of annotation and tries parse it with significant whitespace.
|
||||
* A marker is set here which means that we must to rollback.
|
||||
*/
|
||||
if (mode.typeContext && (getLastToken() != RPAR || at(ARROW))) {
|
||||
annotation.done(ANNOTATION_ENTRY);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
annotation.done(ANNOTATION_ENTRY);
|
||||
|
||||
@@ -1995,7 +2045,7 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
else if (at(LPAR)) {
|
||||
PsiBuilder.Marker functionOrParenthesizedType = mark();
|
||||
|
||||
// This may be a function parameter list or just a prenthesized type
|
||||
// This may be a function parameter list or just a parenthesized type
|
||||
advance(); // LPAR
|
||||
parseTypeRefContents(TokenSet.EMPTY).drop(); // parenthesized types, no reference element around it is needed
|
||||
|
||||
@@ -2423,20 +2473,28 @@ public class KotlinParsing extends AbstractKotlinParsing {
|
||||
}
|
||||
|
||||
enum AnnotationParsingMode {
|
||||
DEFAULT(false, true),
|
||||
FILE_ANNOTATIONS_BEFORE_PACKAGE(true, true),
|
||||
FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(true, true),
|
||||
NO_ANNOTATIONS(false, false);
|
||||
DEFAULT(false, true, false, false),
|
||||
FILE_ANNOTATIONS_BEFORE_PACKAGE(true, true, false, false),
|
||||
FILE_ANNOTATIONS_WHEN_PACKAGE_OMITTED(true, true, false, false),
|
||||
TYPE_CONTEXT(false, true, true, false),
|
||||
WITH_SIGNIFICANT_WHITESPACE_BEFORE_ARGUMENTS(false, true, true, true),
|
||||
NO_ANNOTATIONS(false, false, false, false);
|
||||
|
||||
boolean isFileAnnotationParsingMode;
|
||||
boolean allowAnnotations;
|
||||
boolean withSignificantWhitespaceBeforeArguments;
|
||||
boolean typeContext;
|
||||
|
||||
AnnotationParsingMode(
|
||||
boolean isFileAnnotationParsingMode,
|
||||
boolean allowAnnotations
|
||||
boolean allowAnnotations,
|
||||
boolean typeContext,
|
||||
boolean withSignificantWhitespaceBeforeArguments
|
||||
) {
|
||||
this.isFileAnnotationParsingMode = isFileAnnotationParsingMode;
|
||||
this.allowAnnotations = allowAnnotations;
|
||||
this.typeContext = typeContext;
|
||||
this.withSignificantWhitespaceBeforeArguments = withSignificantWhitespaceBeforeArguments;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.PsiBuilderFactory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.parsing.KotlinParser;
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtFileElementType;
|
||||
@@ -42,10 +41,6 @@ public class KtBlockCodeFragmentType extends KtFileElementType {
|
||||
|
||||
@Override
|
||||
protected ASTNode doParseContents(@NotNull ASTNode chameleon, @NotNull PsiElement psi) {
|
||||
if (StringsKt.isBlank(chameleon.getText())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Project project = psi.getProject();
|
||||
Language languageForParser = getLanguageForParser(psi);
|
||||
PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, null, languageForParser, chameleon.getChars());
|
||||
|
||||
@@ -46,6 +46,9 @@ class KtClassBody : KtElementImplStub<KotlinPlaceHolderStub<KtClassBody>>, KtDec
|
||||
val properties: List<KtProperty>
|
||||
get() = getStubOrPsiChildrenAsList(KtStubElementTypes.PROPERTY)
|
||||
|
||||
val functions: List<KtFunction>
|
||||
get() = getStubOrPsiChildrenAsList(KtStubElementTypes.FUNCTION)
|
||||
|
||||
val enumEntries: List<KtEnumEntry>
|
||||
get() = getStubOrPsiChildrenAsList(KtStubElementTypes.ENUM_ENTRY).filterIsInstance<KtEnumEntry>()
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.PsiBuilderFactory;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import kotlin.text.StringsKt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.parsing.KotlinParser;
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtFileElementType;
|
||||
@@ -42,10 +41,6 @@ public class KtExpressionCodeFragmentType extends KtFileElementType {
|
||||
|
||||
@Override
|
||||
protected ASTNode doParseContents(@NotNull ASTNode chameleon, @NotNull PsiElement psi) {
|
||||
if (StringsKt.isBlank(chameleon.getText())) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Project project = psi.getProject();
|
||||
Language languageForParser = getLanguageForParser(psi);
|
||||
PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, null, languageForParser, chameleon.getChars());
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.*
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.resolve.calls.components.CreateFreshVariablesSubstitutor.createToFreshVariableSubstitutorAndAddInitialConstraints
|
||||
@@ -180,7 +181,9 @@ class CallableReferencesCandidateFactory(
|
||||
expectedType
|
||||
)
|
||||
|
||||
if (defaults != 0) {
|
||||
if (defaults != 0 &&
|
||||
!callComponents.languageVersionSettings.supportsFeature(LanguageFeature.FunctionReferenceWithDefaultValueAsOtherType)
|
||||
) {
|
||||
diagnostics.add(CallableReferencesDefaultArgumentUsed(argument, candidateDescriptor, defaults))
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ class CallableReferenceResolver(
|
||||
)
|
||||
}
|
||||
diagnosticsHolder.addDiagnosticIfNotNull(diagnostic)
|
||||
chosenCandidate.diagnostics.forEach { diagnosticsHolder.addDiagnostic(it) }
|
||||
chosenCandidate.freshSubstitutor = toFreshSubstitutor
|
||||
} else {
|
||||
if (candidates.isEmpty()) {
|
||||
|
||||
@@ -68,13 +68,16 @@ fun CallableDescriptor.substitute(substitutor: NewTypeSubstitutor): CallableDesc
|
||||
return substitute(TypeSubstitutor.create(wrappedSubstitution))
|
||||
}
|
||||
|
||||
fun CallableDescriptor.substituteAndApproximateCapturedTypes(substitutor: NewTypeSubstitutor): CallableDescriptor {
|
||||
fun CallableDescriptor.substituteAndApproximateCapturedTypes(
|
||||
substitutor: NewTypeSubstitutor,
|
||||
typeApproximator: TypeApproximator
|
||||
): CallableDescriptor {
|
||||
val wrappedSubstitution = object : TypeSubstitution() {
|
||||
override fun get(key: KotlinType): TypeProjection? = null
|
||||
|
||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) =
|
||||
substitutor.safeSubstitute(topLevelType.unwrap()).let { substitutedType ->
|
||||
TypeApproximator(builtIns).approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation)
|
||||
typeApproximator.approximateToSuperType(substitutedType, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation)
|
||||
?: substitutedType
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,10 +100,14 @@ abstract class AbstractTypeCheckerContextForConstraintSystem : AbstractTypeCheck
|
||||
return null
|
||||
}
|
||||
|
||||
return if (projection.getVariance() == TypeVariance.OUT)
|
||||
projection.getType().takeIf { it is SimpleTypeMarker && isMyTypeVariable(it) }?.asSimpleType()
|
||||
else
|
||||
null
|
||||
return if (projection.getVariance() == TypeVariance.OUT) {
|
||||
val type = projection.getType()
|
||||
when {
|
||||
type is SimpleTypeMarker && isMyTypeVariable(type) -> type.asSimpleType()
|
||||
type is FlexibleTypeMarker && isMyTypeVariable(type.lowerBound()) -> type.asFlexibleType()?.lowerBound()
|
||||
else -> null
|
||||
}
|
||||
} else null
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability
|
||||
import org.jetbrains.kotlin.resolve.scopes.*
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeApproximator
|
||||
|
||||
interface ImplicitScopeTower {
|
||||
val lexicalScope: LexicalScope
|
||||
@@ -42,6 +43,8 @@ interface ImplicitScopeTower {
|
||||
val isDebuggerContext: Boolean
|
||||
|
||||
val isNewInferenceEnabled: Boolean
|
||||
|
||||
val typeApproximator: TypeApproximator
|
||||
}
|
||||
|
||||
interface ScopeTowerLevel {
|
||||
|
||||
@@ -83,6 +83,7 @@ internal class MemberScopeTowerLevel(
|
||||
|
||||
private val syntheticScopes = scopeTower.syntheticScopes
|
||||
private val isNewInferenceEnabled = scopeTower.isNewInferenceEnabled
|
||||
private val typeApproximator = scopeTower.typeApproximator
|
||||
|
||||
private fun collectMembers(
|
||||
getMembers: ResolutionScope.(KotlinType?) -> Collection<CallableDescriptor>
|
||||
@@ -108,9 +109,11 @@ internal class MemberScopeTowerLevel(
|
||||
|
||||
if (dispatchReceiver.possibleTypes.isNotEmpty()) {
|
||||
if (unstableCandidates == null) {
|
||||
result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() })
|
||||
result.retainAll(result.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes(typeApproximator) })
|
||||
} else {
|
||||
result.addAll(unstableCandidates.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes() })
|
||||
result.addAll(
|
||||
unstableCandidates.selectMostSpecificInEachOverridableGroup { descriptor.approximateCapturedTypes(typeApproximator) }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,10 +132,9 @@ internal class MemberScopeTowerLevel(
|
||||
* So method get has signature get(Int): Capture(*). If we also have smartcast to MutableList<String>, then there is also method get(Int): String.
|
||||
* And we should chose get(Int): String.
|
||||
*/
|
||||
private fun CallableDescriptor.approximateCapturedTypes(): CallableDescriptor {
|
||||
private fun CallableDescriptor.approximateCapturedTypes(approximator: TypeApproximator): CallableDescriptor {
|
||||
if (!isNewInferenceEnabled) return this
|
||||
|
||||
val approximator = TypeApproximator(builtIns)
|
||||
val wrappedSubstitution = object : TypeSubstitution() {
|
||||
override fun get(key: KotlinType): TypeProjection? = null
|
||||
override fun prepareTopLevelType(topLevelType: KotlinType, position: Variance) = when (position) {
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.types.checker.NewCapturedType
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
|
||||
import org.jetbrains.kotlin.types.model.*
|
||||
import org.jetbrains.kotlin.types.model.CaptureStatus.*
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
|
||||
@@ -123,6 +124,10 @@ class TypeApproximator(builtIns: KotlinBuiltIns) : AbstractTypeApproximator(Clas
|
||||
|
||||
abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionContext) : TypeSystemInferenceExtensionContext by ctx {
|
||||
|
||||
private class ApproximationResult(val type: KotlinTypeMarker?)
|
||||
|
||||
private val cacheForIncorporationConfigToSuperDirection = ConcurrentHashMap<KotlinTypeMarker, ApproximationResult>()
|
||||
private val cacheForIncorporationConfigToSubtypeDirection = ConcurrentHashMap<KotlinTypeMarker, ApproximationResult>()
|
||||
|
||||
private val referenceApproximateToSuperType = this::approximateSimpleToSuperType
|
||||
private val referenceApproximateToSubType = this::approximateSimpleToSubType
|
||||
@@ -140,23 +145,69 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
fun approximateToSubType(type: KotlinTypeMarker, conf: TypeApproximatorConfiguration): KotlinTypeMarker? =
|
||||
approximateToSubType(type, conf, -type.typeDepth())
|
||||
|
||||
fun clearCache() {
|
||||
cacheForIncorporationConfigToSubtypeDirection.clear()
|
||||
cacheForIncorporationConfigToSuperDirection.clear()
|
||||
}
|
||||
|
||||
private fun checkExceptionalCases(
|
||||
type: KotlinTypeMarker, depth: Int, conf: TypeApproximatorConfiguration, toSuper: Boolean
|
||||
): ApproximationResult? {
|
||||
return when {
|
||||
type is TypeUtils.SpecialType ->
|
||||
null.toApproximationResult()
|
||||
|
||||
type.isError() ->
|
||||
// todo -- fix builtIns. Now builtIns here is DefaultBuiltIns
|
||||
(if (conf.errorType) null else type.defaultResult(toSuper)).toApproximationResult()
|
||||
|
||||
depth > 3 ->
|
||||
type.defaultResult(toSuper).toApproximationResult()
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun KotlinTypeMarker?.toApproximationResult(): ApproximationResult = ApproximationResult(this)
|
||||
|
||||
private inline fun cachedValue(
|
||||
type: KotlinTypeMarker,
|
||||
conf: TypeApproximatorConfiguration,
|
||||
toSuper: Boolean,
|
||||
approximate: () -> KotlinTypeMarker?
|
||||
): KotlinTypeMarker? {
|
||||
// Approximator depends on a configuration, so cache should take it into account
|
||||
// Here, we cache only types for configuration "from incorporation", which is used most intensively
|
||||
if (conf !is TypeApproximatorConfiguration.IncorporationConfiguration) return approximate()
|
||||
|
||||
val cache = if (toSuper) cacheForIncorporationConfigToSuperDirection else cacheForIncorporationConfigToSubtypeDirection
|
||||
return cache.getOrPut(type, { approximate().toApproximationResult() }).type
|
||||
}
|
||||
|
||||
private fun approximateToSuperType(type: KotlinTypeMarker, conf: TypeApproximatorConfiguration, depth: Int): KotlinTypeMarker? {
|
||||
if (type is TypeUtils.SpecialType) return null
|
||||
return approximateTo(
|
||||
prepareType(type), conf, { upperBound() },
|
||||
referenceApproximateToSuperType, depth
|
||||
)
|
||||
checkExceptionalCases(type, depth, conf, toSuper = true)?.let { return it.type }
|
||||
|
||||
return cachedValue(type, conf, toSuper = true) {
|
||||
approximateTo(
|
||||
prepareType(type), conf, { upperBound() },
|
||||
referenceApproximateToSuperType, depth
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun approximateToSubType(type: KotlinTypeMarker, conf: TypeApproximatorConfiguration, depth: Int): KotlinTypeMarker? {
|
||||
if (type is TypeUtils.SpecialType) return null
|
||||
return approximateTo(
|
||||
prepareType(type), conf, { lowerBound() },
|
||||
referenceApproximateToSubType, depth
|
||||
)
|
||||
checkExceptionalCases(type, depth, conf, toSuper = false)?.let { return it.type }
|
||||
|
||||
return cachedValue(type, conf, toSuper = false) {
|
||||
approximateTo(
|
||||
prepareType(type), conf, { lowerBound() },
|
||||
referenceApproximateToSubType, depth
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// comments for case bound = upperBound, approximateTo = toSuperType
|
||||
// Don't call this method directly, it should be used only in approximateToSuperType/approximateToSubType (use these methods instead)
|
||||
// This method contains detailed implementation only for type approximation, it doesn't check exceptional cases and doesn't use cache
|
||||
private fun approximateTo(
|
||||
type: KotlinTypeMarker,
|
||||
conf: TypeApproximatorConfiguration,
|
||||
@@ -334,13 +385,6 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
toSuper: Boolean,
|
||||
depth: Int
|
||||
): KotlinTypeMarker? {
|
||||
if (type.isError()) {
|
||||
// todo -- fix builtIns. Now builtIns here is DefaultBuiltIns
|
||||
return if (conf.errorType) null else type.defaultResult(toSuper)
|
||||
}
|
||||
|
||||
if (depth > 3) return type.defaultResult(toSuper)
|
||||
|
||||
if (type.argumentsCount() != 0) {
|
||||
return approximateParametrizedType(type, conf, toSuper, depth + 1)
|
||||
}
|
||||
@@ -386,12 +430,15 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
toSuper: Boolean,
|
||||
depth: Int
|
||||
): KotlinTypeMarker? {
|
||||
val approximatedOriginalType = approximateTo(type.original(), conf, toSuper, depth)
|
||||
val originalType = type.original()
|
||||
val approximatedOriginalType =
|
||||
if (toSuper) approximateToSuperType(originalType, conf, depth) else approximateToSubType(originalType, conf, depth)
|
||||
|
||||
return if (conf.definitelyNotNullType) {
|
||||
approximatedOriginalType?.makeDefinitelyNotNullOrNotNull()
|
||||
} else {
|
||||
if (toSuper)
|
||||
(approximatedOriginalType ?: type.original()).withNullability(false)
|
||||
(approximatedOriginalType ?: originalType).withNullability(false)
|
||||
else
|
||||
type.defaultResult(toSuper)
|
||||
}
|
||||
@@ -523,8 +570,8 @@ abstract class AbstractTypeApproximator(val ctx: TypeSystemInferenceExtensionCon
|
||||
return type.replaceArguments(newArgumentsList)
|
||||
}
|
||||
|
||||
private fun SimpleTypeMarker.defaultResult(toSuper: Boolean) = if (toSuper) nullableAnyType() else {
|
||||
if (isMarkedNullable()) nullableNothingType() else nothingType()
|
||||
private fun KotlinTypeMarker.defaultResult(toSuper: Boolean) = if (toSuper) nullableAnyType() else {
|
||||
if (this is SimpleTypeMarker && isMarkedNullable()) nullableNothingType() else nothingType()
|
||||
}
|
||||
|
||||
// Any? or Any!
|
||||
|
||||
2
compiler/testData/cli/js/jsExtraHelp.out
vendored
2
compiler/testData/cli/js/jsExtraHelp.out
vendored
@@ -22,6 +22,7 @@ where advanced options include:
|
||||
-Xdump-perf=<path> Dump detailed performance statistics to the specified file
|
||||
-Xeffect-system Enable experimental language feature: effect system
|
||||
-Xexperimental=<fq.name> Enable and propagate usages of experimental API for marker annotation with the given fully qualified name
|
||||
-Xinline-classes Enable experimental inline classes
|
||||
-Xintellij-plugin-root=<path> Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found
|
||||
-Xlegacy-smart-cast-after-try Allow var smart casts despite assignment in try block
|
||||
-Xlist-phases List backend phases
|
||||
@@ -38,6 +39,7 @@ where advanced options include:
|
||||
-Xphases-to-validate-after Validate backend state after these phases
|
||||
-Xphases-to-validate-before Validate backend state before these phases
|
||||
-Xplugin=<path> Load plugins from the given classpath
|
||||
-Xpolymorphic-signature Enable experimental support for @PolymorphicSignature (MethodHandle/VarHandle)
|
||||
-Xprofile-phases Profile backend phases
|
||||
-Xproper-ieee754-comparisons Generate proper IEEE 754 comparisons in all cases if values are statically known to be of primitive numeric types
|
||||
-Xread-deserialized-contracts Enable reading of contracts from metadata
|
||||
|
||||
2
compiler/testData/cli/jvm/extraHelp.out
vendored
2
compiler/testData/cli/jvm/extraHelp.out
vendored
@@ -84,6 +84,7 @@ where advanced options include:
|
||||
-Xdump-perf=<path> Dump detailed performance statistics to the specified file
|
||||
-Xeffect-system Enable experimental language feature: effect system
|
||||
-Xexperimental=<fq.name> Enable and propagate usages of experimental API for marker annotation with the given fully qualified name
|
||||
-Xinline-classes Enable experimental inline classes
|
||||
-Xintellij-plugin-root=<path> Path to the kotlin-compiler.jar or directory where IntelliJ configuration files can be found
|
||||
-Xlegacy-smart-cast-after-try Allow var smart casts despite assignment in try block
|
||||
-Xlist-phases List backend phases
|
||||
@@ -100,6 +101,7 @@ where advanced options include:
|
||||
-Xphases-to-validate-after Validate backend state after these phases
|
||||
-Xphases-to-validate-before Validate backend state before these phases
|
||||
-Xplugin=<path> Load plugins from the given classpath
|
||||
-Xpolymorphic-signature Enable experimental support for @PolymorphicSignature (MethodHandle/VarHandle)
|
||||
-Xprofile-phases Profile backend phases
|
||||
-Xproper-ieee754-comparisons Generate proper IEEE 754 comparisons in all cases if values are statically known to be of primitive numeric types
|
||||
-Xread-deserialized-contracts Enable reading of contracts from metadata
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
$TESTDATA_DIR$/functionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-Xnew-inference
|
||||
11
compiler/testData/cli/jvm/functionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference.kt
vendored
Normal file
11
compiler/testData/cli/jvm/functionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference.kt
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
fun foo(a: String, b: Int = 5): String {
|
||||
return a + b
|
||||
}
|
||||
|
||||
fun bar1(body: (String) -> String): String {
|
||||
return body("something")
|
||||
}
|
||||
|
||||
fun test() {
|
||||
bar1(::foo)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
OK
|
||||
@@ -0,0 +1,4 @@
|
||||
$TESTDATA_DIR$/functionReferenceWithDefaultValuesFeatureIsEnabledWithNewInference.kt
|
||||
-d
|
||||
$TEMP_DIR$
|
||||
-XXLanguage\:+NewInference
|
||||
@@ -0,0 +1,10 @@
|
||||
warning: ATTENTION!
|
||||
This build uses unsafe internal compiler arguments:
|
||||
|
||||
-XXLanguage:+NewInference
|
||||
|
||||
This mode is not recommended for production use,
|
||||
as no stability/compatibility guarantees are given on
|
||||
compiler or generated code. Use it at your own risk!
|
||||
|
||||
OK
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun foo(s: String = "kotlin", vararg t: String): Boolean {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND: JS
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun foo(vararg a: String, result: String = "OK"): String =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
|
||||
fun foo(x: String, y: Char = 'K'): String = x + y
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun foo(x: String = "O", vararg y: String): String =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND: JS, JVM_IR
|
||||
|
||||
fun foo(vararg l: Long, s: String = "OK"): String =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun call0(f: (String) -> String, x: String): String = f(x)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND: JS
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
|
||||
fun foo(x: String, y: String = "K"): String = x + y
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// !LANGUAGE: +NewInference
|
||||
// !LANGUAGE: +NewInference +FunctionReferenceWithDefaultValueAsOtherType
|
||||
// IGNORE_BACKEND: JS
|
||||
|
||||
fun foo(x: Int, s: Int, vararg y: CharSequence = arrayOf("Aaa")): String =
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// !LANGUAGE: +InlineClasses
|
||||
// IGNORE_BACKEND: JS, JS_IR, NATIVE
|
||||
// KJS_WITH_FULL_RUNTIME
|
||||
// WITH_RUNTIME
|
||||
|
||||
data class RGBA(val rgba: Int)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user