mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-05-05 00:21:29 +00:00
Compare commits
246 Commits
spec-tests
...
build-1.3.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e05f01d550 | ||
|
|
ad94bad919 | ||
|
|
17f3e1f45b | ||
|
|
9b0262a326 | ||
|
|
4aa748741c | ||
|
|
a09b75356a | ||
|
|
781b6af1d0 | ||
|
|
e977174cb6 | ||
|
|
e03ff13a57 | ||
|
|
4a279a2ae2 | ||
|
|
4d6aee014c | ||
|
|
eee8621cd9 | ||
|
|
f72e62553f | ||
|
|
023194b792 | ||
|
|
a9dbb3c5b5 | ||
|
|
b7c6313114 | ||
|
|
42c841caf7 | ||
|
|
47d8f81ae3 | ||
|
|
224ba97dbe | ||
|
|
8285c9984d | ||
|
|
16ba022b4d | ||
|
|
370dcaf0f3 | ||
|
|
d12711d41a | ||
|
|
e189133357 | ||
|
|
3e764d93fa | ||
|
|
38c23f5b43 | ||
|
|
3769c67bd1 | ||
|
|
496b74b414 | ||
|
|
1bfddfef09 | ||
|
|
31c92c9415 | ||
|
|
53fa11884d | ||
|
|
829771231d | ||
|
|
4879e656ce | ||
|
|
c1455e3da0 | ||
|
|
53170e9199 | ||
|
|
e6ebfb96ec | ||
|
|
02d1ffe9c7 | ||
|
|
42bd1e5811 | ||
|
|
7b34f83429 | ||
|
|
c12208ac4f | ||
|
|
5d68860e9f | ||
|
|
27bb4d0b2e | ||
|
|
5fc55df31e | ||
|
|
7def0ccba8 | ||
|
|
f47ad82a73 | ||
|
|
cfed5b351a | ||
|
|
2e4e2f67bb | ||
|
|
dab23322fd | ||
|
|
7c00d2ba82 | ||
|
|
14aab280c2 | ||
|
|
489d80c249 | ||
|
|
ef50f25db1 | ||
|
|
a3dfa28374 | ||
|
|
95cdc94fbb | ||
|
|
ffa298ea34 | ||
|
|
ba00df846e | ||
|
|
b8cb533b39 | ||
|
|
8b6096f312 | ||
|
|
19f01b98df | ||
|
|
cf8184e9c9 | ||
|
|
eb813678fc | ||
|
|
8c96111e16 | ||
|
|
02fc21b7ff | ||
|
|
f3be367962 | ||
|
|
6d62f21d60 | ||
|
|
54698544d9 | ||
|
|
9365ff6dcf | ||
|
|
200dde8cb4 | ||
|
|
da06af2fee | ||
|
|
e3fa388dfe | ||
|
|
9434babe9f | ||
|
|
61f48da6e8 | ||
|
|
46420d60f0 | ||
|
|
cb3371ba2e | ||
|
|
6b660fe466 | ||
|
|
d0231351ec | ||
|
|
ec8e8cb23c | ||
|
|
c0c63bdc98 | ||
|
|
0786555650 | ||
|
|
b11e31d275 | ||
|
|
15d28a75a9 | ||
|
|
62dcae008c | ||
|
|
fbeded85e6 | ||
|
|
5e4ff87244 | ||
|
|
560c65c50f | ||
|
|
a23fb03bd9 | ||
|
|
b96fcce096 | ||
|
|
503a042b29 | ||
|
|
649b74ab7f | ||
|
|
623c7673e1 | ||
|
|
76b7dcfdaf | ||
|
|
73e3cfe3a4 | ||
|
|
45cbd792ac | ||
|
|
ebaca7a4d8 | ||
|
|
8e45f79a0e | ||
|
|
d91881acf4 | ||
|
|
206d53d35a | ||
|
|
8585f69b27 | ||
|
|
738108e9c9 | ||
|
|
c84a4e8640 | ||
|
|
0526298b37 | ||
|
|
7e766a1413 | ||
|
|
bb77d673a0 | ||
|
|
ed85927abf | ||
|
|
690b84e2e8 | ||
|
|
2bba568dd6 | ||
|
|
d432ea7df5 | ||
|
|
81f4a090f6 | ||
|
|
7a17bccf23 | ||
|
|
6528826ea7 | ||
|
|
902dfe0815 | ||
|
|
207bd4e1b9 | ||
|
|
d2d603b3bd | ||
|
|
536e135c66 | ||
|
|
56768ff7ea | ||
|
|
6f05bafeb3 | ||
|
|
ec852452b0 | ||
|
|
61ba1c875a | ||
|
|
15f9895088 | ||
|
|
95d338db0d | ||
|
|
ca065eedce | ||
|
|
61fcc1cbd2 | ||
|
|
0e480fd040 | ||
|
|
c8788d93a3 | ||
|
|
7c24ed6152 | ||
|
|
d666d2b186 | ||
|
|
91da355f49 | ||
|
|
bdb7683887 | ||
|
|
066ce5464a | ||
|
|
7bc607c851 | ||
|
|
e12c7c8f59 | ||
|
|
3b2272ce6a | ||
|
|
5c998b7a33 | ||
|
|
cfbc44f97f | ||
|
|
224360aa2d | ||
|
|
aef162b1d2 | ||
|
|
2f7eedd568 | ||
|
|
b22102d252 | ||
|
|
e20fbee48c | ||
|
|
3ee7134540 | ||
|
|
462c5dea53 | ||
|
|
0c13f4b1fc | ||
|
|
9975ec9d0d | ||
|
|
ecb56ebedc | ||
|
|
eb2e37f8d2 | ||
|
|
d9e46fef61 | ||
|
|
1ebb5145de | ||
|
|
1db0643460 | ||
|
|
46ea87217f | ||
|
|
0cc405a02f | ||
|
|
a102cbe469 | ||
|
|
78b02e5efa | ||
|
|
277694a733 | ||
|
|
4f0128f3ca | ||
|
|
5ee77a02ea | ||
|
|
7146f79bc9 | ||
|
|
56310ae159 | ||
|
|
fe72bc494e | ||
|
|
4ac8a18367 | ||
|
|
db7b4e29c4 | ||
|
|
9b1d498663 | ||
|
|
19656f7884 | ||
|
|
64556720e1 | ||
|
|
fa240df089 | ||
|
|
79dc998331 | ||
|
|
1c8580109b | ||
|
|
6d579d59d9 | ||
|
|
93209bf67b | ||
|
|
6c3ab15b03 | ||
|
|
3ee521700e | ||
|
|
e8a30fb648 | ||
|
|
734c894d37 | ||
|
|
b5a8258bef | ||
|
|
4247ecba2e | ||
|
|
0aa9edd833 | ||
|
|
57bf604350 | ||
|
|
5102c5b820 | ||
|
|
666b23dc92 | ||
|
|
302be0a5d2 | ||
|
|
a4d9f4c112 | ||
|
|
299cdf79cd | ||
|
|
543eabbd5f | ||
|
|
50c25e2852 | ||
|
|
9e327b932c | ||
|
|
988ee456f5 | ||
|
|
a9d32b17ff | ||
|
|
e3429c7997 | ||
|
|
55a7ae6acb | ||
|
|
73cead421e | ||
|
|
899917585b | ||
|
|
d3fd16a491 | ||
|
|
a19790c16a | ||
|
|
3d6579e5a5 | ||
|
|
eaca460d80 | ||
|
|
686bc8af83 | ||
|
|
6c539e6b73 | ||
|
|
8be1aba2c8 | ||
|
|
b27b22e30f | ||
|
|
2946237005 | ||
|
|
de242623d7 | ||
|
|
b5dcfb2c5a | ||
|
|
c6d560b2e6 | ||
|
|
02e38b6e22 | ||
|
|
7b662a2fe3 | ||
|
|
99b6ee5ee3 | ||
|
|
b653d81bfe | ||
|
|
97084112b3 | ||
|
|
8a54ab3dd2 | ||
|
|
ee74bdacc0 | ||
|
|
c12b784e5b | ||
|
|
f0555ab5df | ||
|
|
cac8f3ace3 | ||
|
|
d331c7d376 | ||
|
|
ad4671ed5f | ||
|
|
7cc4c606a1 | ||
|
|
009e33ed72 | ||
|
|
2d83ceb980 | ||
|
|
966dd3ee24 | ||
|
|
efdb19772b | ||
|
|
7accee269b | ||
|
|
012b8f76a0 | ||
|
|
01551d1bad | ||
|
|
be2c670c09 | ||
|
|
a3ebd0751c | ||
|
|
9d013254a4 | ||
|
|
15045d2512 | ||
|
|
fa9cf694dd | ||
|
|
d849bde003 | ||
|
|
5694726f04 | ||
|
|
d277ddb38c | ||
|
|
3d6c735538 | ||
|
|
8165d07346 | ||
|
|
2a58d137e2 | ||
|
|
b6f2cc125a | ||
|
|
40f2823278 | ||
|
|
aa6d3c3fbe | ||
|
|
469230016e | ||
|
|
ce55ae31b5 | ||
|
|
703dd28553 | ||
|
|
3249a82f33 | ||
|
|
c5d590cbfd | ||
|
|
1fe369bf84 | ||
|
|
33246782dc | ||
|
|
49c539eb39 | ||
|
|
1a8dbc07ed | ||
|
|
6c0750e975 |
8164
ChangeLog.md
8164
ChangeLog.md
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.metadata.js.JsProtoBuf
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.name.parentOrNull
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||
import org.jetbrains.kotlin.serialization.js.JsSerializerProtocol
|
||||
import java.io.DataInput
|
||||
@@ -41,6 +42,7 @@ open class IncrementalJsCache(
|
||||
private const val TRANSLATION_RESULT_MAP = "translation-result"
|
||||
private const val INLINE_FUNCTIONS = "inline-functions"
|
||||
private const val HEADER_FILE_NAME = "header.meta"
|
||||
private const val PACKAGE_META_FILE = "packages-meta"
|
||||
|
||||
fun hasHeaderFile(cachesDir: File) = File(cachesDir, HEADER_FILE_NAME).exists()
|
||||
}
|
||||
@@ -49,8 +51,10 @@ open class IncrementalJsCache(
|
||||
override val dirtyOutputClassesMap = registerMap(DirtyClassesFqNameMap(DIRTY_OUTPUT_CLASSES.storageFile))
|
||||
private val translationResults = registerMap(TranslationResultMap(TRANSLATION_RESULT_MAP.storageFile, pathConverter))
|
||||
private val inlineFunctions = registerMap(InlineFunctionsMap(INLINE_FUNCTIONS.storageFile, pathConverter))
|
||||
private val packageMetadata = registerMap(PackageMetadataMap(PACKAGE_META_FILE.storageFile))
|
||||
|
||||
private val dirtySources = hashSetOf<File>()
|
||||
private val dirtyPackages = hashSetOf<String>()
|
||||
|
||||
private val headerFile: File
|
||||
get() = File(cachesDir, HEADER_FILE_NAME)
|
||||
@@ -63,6 +67,11 @@ open class IncrementalJsCache(
|
||||
}
|
||||
|
||||
override fun markDirty(removedAndCompiledSources: Collection<File>) {
|
||||
removedAndCompiledSources.forEach { sourceFile ->
|
||||
sourceToClassesMap[sourceFile].forEach {
|
||||
dirtyPackages += it.parentOrNull()?.asString() ?: ""
|
||||
}
|
||||
}
|
||||
super.markDirty(removedAndCompiledSources)
|
||||
dirtySources.addAll(removedAndCompiledSources)
|
||||
}
|
||||
@@ -95,6 +104,11 @@ open class IncrementalJsCache(
|
||||
for ((srcFile, inlineDeclarations) in incrementalResults.inlineFunctions) {
|
||||
inlineFunctions.process(srcFile, inlineDeclarations, changesCollector)
|
||||
}
|
||||
|
||||
for ((packageName, metadata) in incrementalResults.packageMetadata) {
|
||||
packageMetadata.put(packageName, metadata)
|
||||
dirtyPackages.remove(packageName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerOutputForFile(srcFile: File, name: FqName) {
|
||||
@@ -108,19 +122,31 @@ open class IncrementalJsCache(
|
||||
inlineFunctions.remove(it)
|
||||
}
|
||||
removeAllFromClassStorage(dirtyOutputClassesMap.getDirtyOutputClasses(), changesCollector)
|
||||
dirtyPackages.forEach {
|
||||
packageMetadata.remove(it)
|
||||
}
|
||||
dirtySources.clear()
|
||||
dirtyOutputClassesMap.clean()
|
||||
dirtyPackages.clear()
|
||||
}
|
||||
|
||||
fun nonDirtyPackageParts(): Map<File, TranslationResultValue> =
|
||||
hashMapOf<File, TranslationResultValue>().apply {
|
||||
for (path in translationResults.keys()) {
|
||||
val file = File(path)
|
||||
for (file in translationResults.keys()) {
|
||||
|
||||
if (file !in dirtySources) {
|
||||
put(file, translationResults[file]!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun packageMetadata(): Map<String, ByteArray> = hashMapOf<String, ByteArray>().apply {
|
||||
for (fqNameString in packageMetadata.keys()) {
|
||||
if (fqNameString !in dirtyPackages) {
|
||||
put(fqNameString, packageMetadata[fqNameString]!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private object TranslationResultValueExternalizer : DataExternalizer<TranslationResultValue> {
|
||||
@@ -155,7 +181,8 @@ private object TranslationResultValueExternalizer : DataExternalizer<Translation
|
||||
private class TranslationResultMap(
|
||||
storageFile: File,
|
||||
private val pathConverter: FileToPathConverter
|
||||
) : BasicStringMap<TranslationResultValue>(storageFile, TranslationResultValueExternalizer) {
|
||||
) :
|
||||
BasicStringMap<TranslationResultValue>(storageFile, TranslationResultValueExternalizer) {
|
||||
override fun dumpValue(value: TranslationResultValue): String =
|
||||
"Metadata: ${value.metadata.md5()}, Binary AST: ${value.binaryAst.md5()}, InlineData: ${value.inlineData.md5()}"
|
||||
|
||||
@@ -167,8 +194,8 @@ private class TranslationResultMap(
|
||||
operator fun get(sourceFile: File): TranslationResultValue? =
|
||||
storage[pathConverter.toPath(sourceFile)]
|
||||
|
||||
fun keys(): Collection<String> =
|
||||
storage.keys
|
||||
fun keys(): Collection<File> =
|
||||
storage.keys.map { pathConverter.toFile(it) }
|
||||
|
||||
fun remove(sourceFile: File, changesCollector: ChangesCollector) {
|
||||
val path = pathConverter.toPath(sourceFile)
|
||||
@@ -182,7 +209,7 @@ private class TranslationResultMap(
|
||||
}
|
||||
}
|
||||
|
||||
fun getProtoData(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData> {
|
||||
fun getProtoData(sourceFile: File, metadata: ByteArray): Map<ClassId, ProtoData> {
|
||||
val classes = hashMapOf<ClassId, ProtoData>()
|
||||
val proto = ProtoBuf.PackageFragment.parseFrom(metadata, JsSerializerProtocol.extensionRegistry)
|
||||
val nameResolver = NameResolverImpl(proto.strings, proto.qualifiedNames)
|
||||
@@ -228,4 +255,35 @@ private class InlineFunctionsMap(
|
||||
|
||||
override fun dumpValue(value: Map<String, Long>): String =
|
||||
value.dumpMap { java.lang.Long.toHexString(it) }
|
||||
}
|
||||
|
||||
private object ByteArrayExternalizer : DataExternalizer<ByteArray> {
|
||||
override fun save(output: DataOutput, value: ByteArray) {
|
||||
output.writeInt(value.size)
|
||||
output.write(value)
|
||||
}
|
||||
|
||||
override fun read(input: DataInput): ByteArray {
|
||||
val size = input.readInt()
|
||||
val array = ByteArray(size)
|
||||
input.readFully(array)
|
||||
return array
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class PackageMetadataMap(storageFile: File) : BasicStringMap<ByteArray>(storageFile, ByteArrayExternalizer) {
|
||||
fun put(packageName: String, newMetadata: ByteArray) {
|
||||
storage[packageName] = newMetadata
|
||||
}
|
||||
|
||||
fun remove(packageName: String) {
|
||||
storage.remove(packageName)
|
||||
}
|
||||
|
||||
fun keys() = storage.keys
|
||||
|
||||
operator fun get(packageName: String) = storage[packageName]
|
||||
|
||||
override fun dumpValue(value: ByteArray): String = "Package metadata: ${value.md5()}"
|
||||
}
|
||||
@@ -18,4 +18,7 @@ class IncrementalDataProviderFromCache(private val cache: IncrementalJsCache) :
|
||||
|
||||
override val metadataVersion: IntArray
|
||||
get() = JsMetadataVersion.INSTANCE.toArray() // TODO: store and load correct metadata version
|
||||
|
||||
override val packageMetadata: Map<String, ByteArray>
|
||||
get() = cache.packageMetadata()
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ private fun kjsmToString(kjsmFile: File): String {
|
||||
}
|
||||
|
||||
private fun sourceMapFileToString(sourceMapFile: File, generatedJsFile: File): String {
|
||||
val sourceMapParseResult = SourceMapParser.parse(StringReader(sourceMapFile.readText()))
|
||||
val sourceMapParseResult = SourceMapParser.parse(sourceMapFile.readText())
|
||||
return when (sourceMapParseResult) {
|
||||
is SourceMapSuccess -> {
|
||||
val bytesOut = ByteArrayOutputStream()
|
||||
|
||||
@@ -155,10 +155,10 @@ extra["versions.org.springframework"] = "4.2.0.RELEASE"
|
||||
extra["versions.jflex"] = "1.7.0"
|
||||
extra["versions.markdown"] = "0.1.25"
|
||||
extra["versions.trove4j"] = "1.0.20181211"
|
||||
extra["versions.kotlin-native-shared"] = "1.0-dev-50"
|
||||
extra["versions.kotlin-native-shared"] = "1.0-dev-89"
|
||||
|
||||
if (!project.hasProperty("versions.kotlin-native")) {
|
||||
extra["versions.kotlin-native"] = "1.3-dev-9780"
|
||||
extra["versions.kotlin-native"] = "1.3-eap-10415"
|
||||
}
|
||||
|
||||
val isTeamcityBuild = project.hasProperty("teamcity") || System.getenv("TEAMCITY_VERSION") != null
|
||||
@@ -381,6 +381,11 @@ allprojects {
|
||||
dependencies.add(it.name, files(bootstrapCompilerClasspath))
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheRedirectorEnabled()) {
|
||||
logger.info("Redirecting repositories for $displayName")
|
||||
repositories.redirect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,7 +494,12 @@ tasks {
|
||||
create("scriptingTest") {
|
||||
dependsOn("dist")
|
||||
dependsOn(":kotlin-script-util:test")
|
||||
dependsOn(":kotlin-scripting-jvm-host:test")
|
||||
dependsOn(":kotlin-scripting-compiler:test")
|
||||
dependsOn(":kotlin-scripting-jvm-host-test:test")
|
||||
dependsOn(":kotlin-scripting-jsr223-test:test")
|
||||
dependsOn(":kotlin-scripting-jvm-host-test:embeddableTest")
|
||||
dependsOn(":kotlin-scripting-jsr223-test:embeddableTest")
|
||||
dependsOn(":kotlin-main-kts-test:test")
|
||||
}
|
||||
|
||||
create("compilerTest") {
|
||||
@@ -730,12 +740,3 @@ tasks.create("findShadowJarsInClasspath").doLast {
|
||||
project.checkConfig("testCompileClasspath")
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
afterEvaluate {
|
||||
if (cacheRedirectorEnabled()) {
|
||||
logger.info("Redirecting repositories for $displayName")
|
||||
repositories.redirect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ fun parse(project: Project, libraries: List<PLibrary>, context: ParserContext):
|
||||
*/
|
||||
private val CONFIGURATION_MAPPING = mapOf(
|
||||
listOf("runtime") to Scope.RUNTIME,
|
||||
listOf("compile") to Scope.COMPILE,
|
||||
listOf("compile", "embedded") to Scope.COMPILE,
|
||||
listOf("compileOnly") to Scope.PROVIDED
|
||||
)
|
||||
|
||||
@@ -317,7 +317,12 @@ private val SourceSet.isTestSourceSet: Boolean
|
||||
|| name.endsWith("Tests")
|
||||
|
||||
private fun getKotlinOptions(kotlinCompileTask: Any): PSourceRootKotlinOptions? {
|
||||
val compileArguments = kotlinCompileTask.invokeInternal("getSerializedCompilerArguments") as List<String>
|
||||
val compileArguments = run {
|
||||
val method = kotlinCompileTask::class.java.getMethod("getSerializedCompilerArguments")
|
||||
method.isAccessible = true
|
||||
method.invoke(kotlinCompileTask) as List<String>
|
||||
}
|
||||
|
||||
fun parseBoolean(name: String) = compileArguments.contains("-$name")
|
||||
fun parseString(name: String) = compileArguments.dropWhile { it != "-$name" }.drop(1).firstOrNull()
|
||||
|
||||
|
||||
@@ -65,7 +65,8 @@ import static org.jetbrains.kotlin.codegen.CodegenUtilKt.isToArrayFromCollection
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isEffectivelyInlineOnly;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineWithReified;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.*;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmSyntheticAnnotation;
|
||||
@@ -388,7 +389,8 @@ public class AsmUtil {
|
||||
flags |= getVarargsFlag(functionDescriptor);
|
||||
flags |= getDeprecatedAccessFlag(functionDescriptor);
|
||||
if (deprecationResolver.isDeprecatedHidden(functionDescriptor) ||
|
||||
(functionDescriptor.isSuspend()) && functionDescriptor.getVisibility().equals(Visibilities.PRIVATE)) {
|
||||
isInlineWithReified(functionDescriptor) ||
|
||||
functionDescriptor.isSuspend() && functionDescriptor.getVisibility().equals(Visibilities.PRIVATE)) {
|
||||
flags |= ACC_SYNTHETIC;
|
||||
}
|
||||
return flags;
|
||||
@@ -526,7 +528,7 @@ public class AsmUtil {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
|
||||
if (isEffectivelyInlineOnly(memberDescriptor)) {
|
||||
if (isInlineOnlyPrivateInBytecode(memberDescriptor)) {
|
||||
return ACC_PRIVATE;
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen<KtPureClassOrObject
|
||||
);
|
||||
}
|
||||
else {
|
||||
propertyCodegen.generatePrimaryConstructorProperty(p, propertyDescriptor);
|
||||
propertyCodegen.generatePrimaryConstructorProperty(propertyDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ public class ConstructorCodegen {
|
||||
ConstructorContext constructorContext = context.intoConstructor(constructorDescriptor, typeMapper);
|
||||
|
||||
functionCodegen.generateMethod(
|
||||
JvmDeclarationOriginKt.OtherOrigin(constructor, constructorDescriptor),
|
||||
JvmDeclarationOriginKt.OtherOrigin(constructorDescriptor),
|
||||
constructorDescriptor, constructorContext,
|
||||
new FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@Override
|
||||
|
||||
@@ -76,6 +76,7 @@ import static org.jetbrains.kotlin.descriptors.ModalityKt.isOverridable;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorToSourceUtils.getSourceFromDescriptor;
|
||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isEffectivelyInlineOnly;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.InlineClassManglingRulesKt.shouldHideConstructorDueToInlineClassTypeValueParameters;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
|
||||
@@ -1153,10 +1154,10 @@ public class FunctionCodegen {
|
||||
|
||||
// $default methods are never private to be accessible from other class files (e.g. inner) without the need of synthetic accessors
|
||||
// $default methods are never protected to be accessible from subclass nested classes
|
||||
int visibilityFlag = Visibilities.isPrivate(functionDescriptor.getVisibility()) ||
|
||||
isEffectivelyInlineOnly(functionDescriptor) ?
|
||||
AsmUtil.NO_FLAG_PACKAGE_PRIVATE : Opcodes.ACC_PUBLIC;
|
||||
int flags = visibilityFlag | getDeprecatedAccessFlag(functionDescriptor) | ACC_SYNTHETIC;
|
||||
int visibilityFlag =
|
||||
Visibilities.isPrivate(functionDescriptor.getVisibility()) || isInlineOnlyPrivateInBytecode(functionDescriptor)
|
||||
? AsmUtil.NO_FLAG_PACKAGE_PRIVATE : Opcodes.ACC_PUBLIC;
|
||||
int flags = visibilityFlag | getDeprecatedAccessFlag(functionDescriptor) | ACC_SYNTHETIC;
|
||||
if (!(functionDescriptor instanceof ConstructorDescriptor &&
|
||||
!InlineClassesUtilsKt.isInlineClass(functionDescriptor.getContainingDeclaration()))
|
||||
) {
|
||||
|
||||
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaForKotlinOverridePropertyDescriptor
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.hasPlatformDependentAnnotation
|
||||
@@ -42,18 +44,27 @@ class DescriptorBasedFunctionHandleForJvm(
|
||||
override val mightBeIncorrectCode: Boolean
|
||||
get() = state.classBuilderMode.mightBeIncorrectCode
|
||||
|
||||
override fun hashCode(): Int = descriptor.containerEntityForEqualityAndHashCode().hashCode() + 31 * asmMethod.hashCode()
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (other !is DescriptorBasedFunctionHandleForJvm) return false
|
||||
override fun hashCode(): Int =
|
||||
(descriptor.containerEntityForEqualityAndHashCode().hashCode() * 31 +
|
||||
descriptor.isJavaForKotlinOverrideProperty.hashCode()) * 31 +
|
||||
asmMethod.hashCode()
|
||||
|
||||
return asmMethod == other.asmMethod &&
|
||||
descriptor.containerEntityForEqualityAndHashCode() == other.descriptor.containerEntityForEqualityAndHashCode()
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
|
||||
return other is DescriptorBasedFunctionHandleForJvm &&
|
||||
asmMethod == other.asmMethod &&
|
||||
descriptor.containerEntityForEqualityAndHashCode() == other.descriptor.containerEntityForEqualityAndHashCode() &&
|
||||
descriptor.isJavaForKotlinOverrideProperty == other.descriptor.isJavaForKotlinOverrideProperty
|
||||
}
|
||||
}
|
||||
|
||||
private fun FunctionDescriptor.containerEntityForEqualityAndHashCode(): Any =
|
||||
(containingDeclaration as? ClassDescriptor)?.typeConstructor ?: containingDeclaration
|
||||
|
||||
private val FunctionDescriptor.isJavaForKotlinOverrideProperty: Boolean
|
||||
get() = this is PropertyAccessorDescriptor && correspondingProperty is JavaForKotlinOverridePropertyDescriptor
|
||||
|
||||
private fun CallableMemberDescriptor.isJvmDefaultOrPlatformDependent() =
|
||||
hasJvmDefaultAnnotation() || hasPlatformDependentAnnotation()
|
||||
|
||||
|
||||
@@ -106,17 +106,24 @@ public class PropertyCodegen {
|
||||
);
|
||||
}
|
||||
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
|
||||
genDestructuringDeclaration(entry, propertyDescriptor);
|
||||
if (!UnderscoreUtilKt.isSingleUnderscore(entry)) {
|
||||
genDestructuringDeclaration((PropertyDescriptor) variableDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
public void generateInPackageFacade(@NotNull DeserializedPropertyDescriptor deserializedProperty) {
|
||||
assert context instanceof MultifileClassFacadeContext : "should be called only for generating facade: " + context;
|
||||
gen(null, deserializedProperty, null, null);
|
||||
|
||||
genBackingFieldAndAnnotations(deserializedProperty);
|
||||
|
||||
if (!isConstOrHasJvmFieldAnnotation(deserializedProperty)) {
|
||||
generateGetter(deserializedProperty, null);
|
||||
generateSetter(deserializedProperty, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void gen(
|
||||
@Nullable KtProperty declaration,
|
||||
@NotNull KtProperty declaration,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@Nullable KtPropertyAccessor getter,
|
||||
@Nullable KtPropertyAccessor setter
|
||||
@@ -125,15 +132,15 @@ public class PropertyCodegen {
|
||||
kind == OwnerKind.DEFAULT_IMPLS || kind == OwnerKind.ERASED_INLINE_CLASS
|
||||
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
|
||||
|
||||
genBackingFieldAndAnnotations(declaration, descriptor);
|
||||
genBackingFieldAndAnnotations(descriptor);
|
||||
|
||||
boolean isDefaultGetterAndSetter = isDefaultAccessor(getter) && isDefaultAccessor(setter);
|
||||
|
||||
if (isAccessorNeeded(declaration, descriptor, getter, isDefaultGetterAndSetter)) {
|
||||
generateGetter(declaration, descriptor, getter);
|
||||
generateGetter(descriptor, getter);
|
||||
}
|
||||
if (isAccessorNeeded(declaration, descriptor, setter, isDefaultGetterAndSetter)) {
|
||||
generateSetter(declaration, descriptor, setter);
|
||||
generateSetter(descriptor, setter);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,29 +148,23 @@ public class PropertyCodegen {
|
||||
return accessor == null || !accessor.hasBody();
|
||||
}
|
||||
|
||||
private void genDestructuringDeclaration(
|
||||
@NotNull KtDestructuringDeclarationEntry entry,
|
||||
@NotNull PropertyDescriptor descriptor
|
||||
) {
|
||||
private void genDestructuringDeclaration(@NotNull PropertyDescriptor descriptor) {
|
||||
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DEFAULT_IMPLS
|
||||
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
|
||||
|
||||
if (UnderscoreUtilKt.isSingleUnderscore(entry)) return;
|
||||
genBackingFieldAndAnnotations(descriptor);
|
||||
|
||||
genBackingFieldAndAnnotations(entry, descriptor);
|
||||
|
||||
generateGetter(entry, descriptor, null);
|
||||
generateSetter(entry, descriptor, null);
|
||||
generateGetter(descriptor, null);
|
||||
generateSetter(descriptor, null);
|
||||
}
|
||||
|
||||
private void genBackingFieldAndAnnotations(@Nullable KtNamedDeclaration declaration, @NotNull PropertyDescriptor descriptor) {
|
||||
private void genBackingFieldAndAnnotations(@NotNull PropertyDescriptor descriptor) {
|
||||
// Fields and '$annotations' methods for non-private const properties are generated in the multi-file facade
|
||||
boolean isBackingFieldOwner = descriptor.isConst() && !Visibilities.isPrivate(descriptor.getVisibility())
|
||||
? !(context instanceof MultifileClassPartContext)
|
||||
: CodegenContextUtil.isImplementationOwner(context, descriptor);
|
||||
|
||||
assert declaration != null : "Declaration is null: " + descriptor + " (context=" + context + ")";
|
||||
generateBackingField(declaration, descriptor, isBackingFieldOwner);
|
||||
generateBackingField(descriptor, isBackingFieldOwner);
|
||||
generateSyntheticMethodIfNeeded(descriptor, isBackingFieldOwner);
|
||||
}
|
||||
|
||||
@@ -174,7 +175,7 @@ public class PropertyCodegen {
|
||||
* @see JvmCodegenUtil#couldUseDirectAccessToProperty
|
||||
*/
|
||||
private boolean isAccessorNeeded(
|
||||
@Nullable KtProperty declaration,
|
||||
@NotNull KtProperty declaration,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
@Nullable KtPropertyAccessor accessor,
|
||||
boolean isDefaultGetterAndSetter
|
||||
@@ -186,8 +187,6 @@ public class PropertyCodegen {
|
||||
// Don't generate accessors for interface properties with default accessors in DefaultImpls
|
||||
if (kind == OwnerKind.DEFAULT_IMPLS && isDefaultAccessor) return false;
|
||||
|
||||
if (declaration == null) return true;
|
||||
|
||||
// Delegated or extension properties can only be referenced via accessors
|
||||
if (declaration.hasDelegate() || declaration.getReceiverTypeReference() != null) return true;
|
||||
|
||||
@@ -203,7 +202,7 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
// Non-const properties from multifile classes have accessors regardless of visibility
|
||||
if (isNonConstTopLevelPropertyInMultifileClass(declaration, descriptor)) return true;
|
||||
if (isTopLevelPropertyInMultifileClass(declaration, descriptor)) return true;
|
||||
|
||||
// Private class properties have accessors only in cases when those accessors are non-trivial
|
||||
if (Visibilities.isPrivate(descriptor.getVisibility())) {
|
||||
@@ -212,6 +211,7 @@ public class PropertyCodegen {
|
||||
|
||||
// Non-private properties with private setter should not be generated for trivial properties
|
||||
// as the class will use direct field access instead
|
||||
//noinspection ConstantConditions
|
||||
if (accessor != null && accessor.isSetter() && Visibilities.isPrivate(descriptor.getSetter().getVisibility())) {
|
||||
return !isDefaultAccessor;
|
||||
}
|
||||
@@ -219,12 +219,11 @@ public class PropertyCodegen {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isNonConstTopLevelPropertyInMultifileClass(
|
||||
private static boolean isTopLevelPropertyInMultifileClass(
|
||||
@NotNull KtProperty declaration,
|
||||
@NotNull PropertyDescriptor descriptor
|
||||
) {
|
||||
return !descriptor.isConst() &&
|
||||
descriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor &&
|
||||
return descriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor &&
|
||||
JvmFileClassUtilKt.isInsideJvmMultifileClassFile(declaration);
|
||||
}
|
||||
|
||||
@@ -244,12 +243,12 @@ public class PropertyCodegen {
|
||||
}
|
||||
}
|
||||
|
||||
public void generatePrimaryConstructorProperty(@NotNull KtParameter parameter, @NotNull PropertyDescriptor descriptor) {
|
||||
genBackingFieldAndAnnotations(parameter, descriptor);
|
||||
public void generatePrimaryConstructorProperty(@NotNull PropertyDescriptor descriptor) {
|
||||
genBackingFieldAndAnnotations(descriptor);
|
||||
|
||||
if (areAccessorsNeededForPrimaryConstructorProperty(descriptor, context.getContextKind())) {
|
||||
generateGetter(parameter, descriptor, null);
|
||||
generateSetter(parameter, descriptor, null);
|
||||
generateGetter(descriptor, null);
|
||||
generateSetter(descriptor, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,17 +311,14 @@ public class PropertyCodegen {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void generateBackingField(
|
||||
@NotNull KtNamedDeclaration p,
|
||||
@NotNull PropertyDescriptor descriptor,
|
||||
boolean isBackingFieldOwner
|
||||
) {
|
||||
private void generateBackingField(@NotNull PropertyDescriptor descriptor, boolean isBackingFieldOwner) {
|
||||
if (isJvmInterface(descriptor.getContainingDeclaration()) || kind == OwnerKind.DEFAULT_IMPLS ||
|
||||
kind == OwnerKind.ERASED_INLINE_CLASS) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isDelegate = p instanceof KtProperty && ((KtProperty) p).hasDelegate();
|
||||
@SuppressWarnings("deprecation")
|
||||
boolean isDelegate = descriptor.isDelegated();
|
||||
|
||||
Object defaultValue;
|
||||
if (isDelegate) {
|
||||
@@ -341,7 +337,7 @@ public class PropertyCodegen {
|
||||
return;
|
||||
}
|
||||
|
||||
generateBackingField(p, descriptor, isDelegate, defaultValue, isBackingFieldOwner);
|
||||
generateBackingField(descriptor, isDelegate, defaultValue, isBackingFieldOwner);
|
||||
}
|
||||
|
||||
// Annotations on properties are stored in bytecode on an empty synthetic method. This way they're still
|
||||
@@ -364,7 +360,6 @@ public class PropertyCodegen {
|
||||
}
|
||||
|
||||
private void generateBackingField(
|
||||
@NotNull KtNamedDeclaration element,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
boolean isDelegate,
|
||||
@Nullable Object defaultValue,
|
||||
@@ -390,8 +385,7 @@ public class PropertyCodegen {
|
||||
modifiers |= ACC_SYNTHETIC;
|
||||
}
|
||||
|
||||
KotlinType kotlinType = isDelegate ? getDelegateTypeForProperty((KtProperty) element, propertyDescriptor, bindingContext)
|
||||
: propertyDescriptor.getType();
|
||||
KotlinType kotlinType = isDelegate ? getDelegateTypeForProperty(propertyDescriptor, bindingContext) : propertyDescriptor.getType();
|
||||
Type type = typeMapper.mapType(kotlinType);
|
||||
|
||||
ClassBuilder builder = v;
|
||||
@@ -419,7 +413,7 @@ public class PropertyCodegen {
|
||||
|
||||
if (isBackingFieldOwner) {
|
||||
FieldVisitor fv = builder.newField(
|
||||
JvmDeclarationOriginKt.OtherOrigin(element, propertyDescriptor), modifiers, name, type.getDescriptor(),
|
||||
JvmDeclarationOriginKt.OtherOrigin(propertyDescriptor), modifiers, name, type.getDescriptor(),
|
||||
isDelegate ? null : typeMapper.mapFieldSignature(kotlinType, propertyDescriptor), defaultValue
|
||||
);
|
||||
|
||||
@@ -431,22 +425,25 @@ public class PropertyCodegen {
|
||||
|
||||
@NotNull
|
||||
public static KotlinType getDelegateTypeForProperty(
|
||||
@NotNull KtProperty p,
|
||||
@NotNull PropertyDescriptor propertyDescriptor,
|
||||
@NotNull BindingContext bindingContext
|
||||
) {
|
||||
KotlinType delegateType = null;
|
||||
|
||||
ResolvedCall<FunctionDescriptor> provideDelegateResolvedCall =
|
||||
bindingContext.get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, propertyDescriptor);
|
||||
KtExpression delegateExpression = p.getDelegateExpression();
|
||||
|
||||
KtProperty property = (KtProperty) DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor);
|
||||
KtExpression delegateExpression = property != null ? property.getDelegateExpression() : null;
|
||||
|
||||
KotlinType delegateType;
|
||||
if (provideDelegateResolvedCall != null) {
|
||||
delegateType = provideDelegateResolvedCall.getResultingDescriptor().getReturnType();
|
||||
}
|
||||
else if (delegateExpression != null) {
|
||||
delegateType = bindingContext.getType(delegateExpression);
|
||||
}
|
||||
else {
|
||||
delegateType = null;
|
||||
}
|
||||
|
||||
if (delegateType == null) {
|
||||
// Delegation convention is unresolved
|
||||
@@ -469,51 +466,49 @@ public class PropertyCodegen {
|
||||
return false;
|
||||
}
|
||||
|
||||
private void generateGetter(
|
||||
@Nullable KtNamedDeclaration p, @NotNull PropertyDescriptor descriptor, @Nullable KtPropertyAccessor getter
|
||||
) {
|
||||
generateAccessor(p, getter, descriptor.getGetter() != null
|
||||
? descriptor.getGetter()
|
||||
: DescriptorFactory.createDefaultGetter(descriptor, Annotations.Companion.getEMPTY()));
|
||||
private void generateGetter(@NotNull PropertyDescriptor descriptor, @Nullable KtPropertyAccessor getter) {
|
||||
generateAccessor(
|
||||
getter,
|
||||
descriptor.getGetter() != null ? descriptor.getGetter() : DescriptorFactory.createDefaultGetter(
|
||||
descriptor, Annotations.Companion.getEMPTY()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void generateSetter(
|
||||
@Nullable KtNamedDeclaration p, @NotNull PropertyDescriptor descriptor, @Nullable KtPropertyAccessor setter
|
||||
) {
|
||||
private void generateSetter(@NotNull PropertyDescriptor descriptor, @Nullable KtPropertyAccessor setter) {
|
||||
if (!descriptor.isVar()) return;
|
||||
|
||||
generateAccessor(p, setter, descriptor.getSetter() != null
|
||||
? descriptor.getSetter()
|
||||
: DescriptorFactory.createDefaultSetter(
|
||||
descriptor, Annotations.Companion.getEMPTY(), Annotations.Companion.getEMPTY()
|
||||
));
|
||||
generateAccessor(
|
||||
setter,
|
||||
descriptor.getSetter() != null ? descriptor.getSetter() : DescriptorFactory.createDefaultSetter(
|
||||
descriptor, Annotations.Companion.getEMPTY(), Annotations.Companion.getEMPTY()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private void generateAccessor(
|
||||
@Nullable KtNamedDeclaration p,
|
||||
@Nullable KtPropertyAccessor accessor,
|
||||
@NotNull PropertyAccessorDescriptor accessorDescriptor
|
||||
) {
|
||||
private void generateAccessor(@Nullable KtPropertyAccessor accessor, @NotNull PropertyAccessorDescriptor descriptor) {
|
||||
if (context instanceof MultifileClassFacadeContext &&
|
||||
(Visibilities.isPrivate(accessorDescriptor.getVisibility()) ||
|
||||
AsmUtil.getVisibilityAccessFlag(accessorDescriptor) == Opcodes.ACC_PRIVATE)) {
|
||||
(Visibilities.isPrivate(descriptor.getVisibility()) ||
|
||||
AsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
FunctionGenerationStrategy strategy;
|
||||
if (accessor == null || !accessor.hasBody()) {
|
||||
if (p instanceof KtProperty && ((KtProperty) p).hasDelegate()) {
|
||||
strategy = new DelegatedPropertyAccessorStrategy(state, accessorDescriptor);
|
||||
@SuppressWarnings("deprecation")
|
||||
boolean isDelegated = descriptor.getCorrespondingProperty().isDelegated();
|
||||
if (isDelegated) {
|
||||
strategy = new DelegatedPropertyAccessorStrategy(state, descriptor);
|
||||
}
|
||||
else {
|
||||
strategy = new DefaultPropertyAccessorStrategy(state, accessorDescriptor);
|
||||
strategy = new DefaultPropertyAccessorStrategy(state, descriptor);
|
||||
}
|
||||
}
|
||||
else {
|
||||
strategy = new FunctionGenerationStrategy.FunctionDefault(state, accessor);
|
||||
}
|
||||
|
||||
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(accessor != null ? accessor : p, accessorDescriptor), accessorDescriptor, strategy);
|
||||
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(descriptor), descriptor, strategy);
|
||||
}
|
||||
|
||||
private static class DefaultPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased {
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.codegen.AsmUtil.getVisibilityAccessFlag;
|
||||
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isNonDefaultInterfaceMember;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isEffectivelyInlineOnly;
|
||||
import static org.jetbrains.kotlin.resolve.inline.InlineOnlyKt.isInlineOnlyPrivateInBytecode;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmDefaultAnnotation;
|
||||
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.isCallableMemberWithJvmDefaultAnnotation;
|
||||
import static org.jetbrains.org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
@@ -693,7 +693,7 @@ public abstract class CodegenContext<T extends DeclarationDescriptor> {
|
||||
boolean withinInline,
|
||||
boolean isSuperCall
|
||||
) {
|
||||
if (isEffectivelyInlineOnly(unwrappedDescriptor)) return false;
|
||||
if (isInlineOnlyPrivateInBytecode(unwrappedDescriptor)) return false;
|
||||
|
||||
return isSuperCall && withinInline ||
|
||||
(accessFlag & ACC_PRIVATE) != 0 ||
|
||||
|
||||
@@ -995,7 +995,7 @@ private fun findSafelyReachableReturns(methodNode: MethodNode, sourceFrames: Arr
|
||||
|
||||
if (!insn.isMeaningful || insn.opcode in SAFE_OPCODES || insn.isInvisibleInDebugVarInsn(methodNode) ||
|
||||
isInlineMarker(insn)) {
|
||||
setOf()
|
||||
setOf<Int>()
|
||||
} else null
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ open class SuspendFunctionGenerationStrategy(
|
||||
state: GenerationState,
|
||||
protected val originalSuspendDescriptor: FunctionDescriptor,
|
||||
protected val declaration: KtFunction,
|
||||
private val containingClassInternalName: String,
|
||||
protected val containingClassInternalName: String,
|
||||
private val constructorCallNormalizationMode: JVMConstructorCallNormalizationMode,
|
||||
protected val functionCodegen: FunctionCodegen
|
||||
) : FunctionGenerationStrategy.CodegenBased(state) {
|
||||
@@ -53,16 +53,7 @@ open class SuspendFunctionGenerationStrategy(
|
||||
override fun wrapMethodVisitor(mv: MethodVisitor, access: Int, name: String, desc: String): MethodVisitor {
|
||||
if (access and Opcodes.ACC_ABSTRACT != 0) return mv
|
||||
|
||||
val stateMachineBuilder = CoroutineTransformerMethodVisitor(
|
||||
mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState,
|
||||
isForNamedFunction = true,
|
||||
element = declaration,
|
||||
diagnostics = state.diagnostics,
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
|
||||
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
|
||||
languageVersionSettings = languageVersionSettings
|
||||
)
|
||||
val stateMachineBuilder = createStateMachineBuilder(mv, access, name, desc)
|
||||
|
||||
val forInline = state.bindingContext[CodegenBinding.CAPTURES_CROSSINLINE_LAMBDA, originalSuspendDescriptor] == true
|
||||
// Both capturing and inline functions share the same suffix, however, inline functions can also be capturing
|
||||
@@ -95,6 +86,24 @@ open class SuspendFunctionGenerationStrategy(
|
||||
) else stateMachineBuilder
|
||||
}
|
||||
|
||||
protected fun createStateMachineBuilder(
|
||||
mv: MethodVisitor,
|
||||
access: Int,
|
||||
name: String,
|
||||
desc: String
|
||||
): CoroutineTransformerMethodVisitor {
|
||||
return CoroutineTransformerMethodVisitor(
|
||||
mv, access, name, desc, null, null, containingClassInternalName, this::classBuilderForCoroutineState,
|
||||
isForNamedFunction = true,
|
||||
element = declaration,
|
||||
diagnostics = state.diagnostics,
|
||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
|
||||
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
|
||||
languageVersionSettings = languageVersionSettings
|
||||
)
|
||||
}
|
||||
|
||||
private fun containingClassInternalNameOrNull() =
|
||||
originalSuspendDescriptor.containingDeclaration.safeAs<ClassDescriptor>()?.let(state.typeMapper::mapClass)?.internalName
|
||||
|
||||
|
||||
@@ -5,20 +5,30 @@
|
||||
|
||||
package org.jetbrains.kotlin.codegen.coroutines
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.FunctionCodegen
|
||||
import org.jetbrains.kotlin.codegen.FunctionGenerationStrategy
|
||||
import org.jetbrains.kotlin.codegen.TransformationMethodVisitor
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.findReceiverOfInvoke
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.surroundInvokesWithSuspendMarkers
|
||||
import org.jetbrains.kotlin.codegen.inline.isInvokeOnLambda
|
||||
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
|
||||
import org.jetbrains.kotlin.codegen.optimization.fixStack.FixStackMethodTransformer
|
||||
import org.jetbrains.kotlin.codegen.optimization.transformer.MethodTransformer
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.JVMConstructorCallNormalizationMode
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtFunction
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||
import org.jetbrains.org.objectweb.asm.tree.*
|
||||
import org.jetbrains.org.objectweb.asm.tree.analysis.SourceInterpreter
|
||||
|
||||
// For named suspend function we generate two methods:
|
||||
// 1) to use as noinline function, which have state machine
|
||||
@@ -44,7 +54,10 @@ class SuspendInlineFunctionGenerationStrategy(
|
||||
if (access and Opcodes.ACC_ABSTRACT != 0) return mv
|
||||
|
||||
return MethodNodeCopyingMethodVisitor(
|
||||
super.wrapMethodVisitor(mv, access, name, desc), access, name, desc,
|
||||
SurroundSuspendParameterCallsWithSuspendMarkersMethodVisitor(
|
||||
createStateMachineBuilder(mv, access, name, desc),
|
||||
access, name, desc, containingClassInternalName, originalSuspendDescriptor.valueParameters
|
||||
), access, name, desc,
|
||||
newMethod = { origin, newAccess, newName, newDesc ->
|
||||
functionCodegen.newMethod(origin, newAccess, newName, newDesc, null, null)
|
||||
}, keepAccess = false
|
||||
@@ -78,3 +91,39 @@ class MethodNodeCopyingMethodVisitor(
|
||||
else access or Opcodes.ACC_PRIVATE and Opcodes.ACC_PUBLIC.inv() and Opcodes.ACC_PROTECTED.inv()
|
||||
}
|
||||
}
|
||||
|
||||
private class SurroundSuspendParameterCallsWithSuspendMarkersMethodVisitor(
|
||||
delegate: MethodVisitor,
|
||||
access: Int,
|
||||
name: String,
|
||||
desc: String,
|
||||
private val thisName: String,
|
||||
private val valueParameters: List<ValueParameterDescriptor>
|
||||
): TransformationMethodVisitor(delegate, access, name, desc, null, null) {
|
||||
override fun performTransformations(methodNode: MethodNode) {
|
||||
fun AbstractInsnNode.index() = methodNode.instructions.indexOf(this)
|
||||
fun AbstractInsnNode.isInlineSuspendParameter(): Boolean {
|
||||
if (this !is VarInsnNode) return false
|
||||
val index = `var` - (if (methodNode.access and Opcodes.ACC_STATIC != 0) 0 else 1)
|
||||
return opcode == Opcodes.ALOAD && index < valueParameters.size && InlineUtil.isInlineParameter(valueParameters[index]) &&
|
||||
valueParameters[index].type.isSuspendFunctionType
|
||||
}
|
||||
|
||||
FixStackMethodTransformer().transform(thisName, methodNode)
|
||||
|
||||
val sourceFrames = MethodTransformer.analyze(thisName, methodNode, SourceInterpreter())
|
||||
|
||||
val noinlineInvokes = arrayListOf<Pair<AbstractInsnNode, AbstractInsnNode>>()
|
||||
|
||||
for (insn in methodNode.instructions.asSequence()) {
|
||||
if (insn.opcode != Opcodes.INVOKEINTERFACE) continue
|
||||
insn as MethodInsnNode
|
||||
if (!isInvokeOnLambda(insn.owner, insn.name)) continue
|
||||
val frame = sourceFrames[insn.index()] ?: continue
|
||||
val aload = findReceiverOfInvoke(frame, insn).takeIf { it?.isInlineSuspendParameter() == true } as? VarInsnNode ?: continue
|
||||
noinlineInvokes.add(insn to aload)
|
||||
}
|
||||
|
||||
surroundInvokesWithSuspendMarkers(methodNode, noinlineInvokes)
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,9 @@ import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.codegen.coroutines.DEBUG_METADATA_ANNOTATION_ASM_TYPE
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isCapturedSuspendLambda
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isCoroutineSuperClass
|
||||
import org.jetbrains.kotlin.codegen.coroutines.isResumeImplMethodName
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.CoroutineTransformer
|
||||
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmCodegenStringTable
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.kotlin.load.kotlin.FileBasedKotlinClass
|
||||
@@ -141,7 +143,7 @@ class AnonymousObjectTransformer(
|
||||
superClassName,
|
||||
allCapturedParamBuilder.listCaptured()
|
||||
)
|
||||
loop@for (next in methodsToTransform) {
|
||||
loop@ for (next in methodsToTransform) {
|
||||
val deferringVisitor =
|
||||
when {
|
||||
coroutineTransformer.shouldSkip(next) -> continue@loop
|
||||
@@ -162,9 +164,15 @@ class AnonymousObjectTransformer(
|
||||
}
|
||||
|
||||
deferringMethods.forEach { method ->
|
||||
val continuationToRemove = CoroutineTransformer.findFakeContinuationConstructorClassName(method.intermediate)
|
||||
val oldContinuationName = coroutineTransformer.oldContinuationFrom(method.intermediate)
|
||||
coroutineTransformer.replaceFakesWithReals(method.intermediate)
|
||||
removeFinallyMarkers(method.intermediate)
|
||||
method.visitEnd()
|
||||
if (continuationToRemove != null && coroutineTransformer.safeToRemoveContinuationClass(method.intermediate)) {
|
||||
transformationResult.addClassToRemove(continuationToRemove)
|
||||
innerClassNodes.removeIf { it.name == oldContinuationName }
|
||||
}
|
||||
}
|
||||
|
||||
SourceMapper.flushToClassBuilder(sourceMapper, classBuilder)
|
||||
@@ -238,7 +246,14 @@ class AnonymousObjectTransformer(
|
||||
|
||||
private fun writeOuterInfo(visitor: ClassVisitor) {
|
||||
val info = inliningContext.callSiteInfo
|
||||
visitor.visitOuterClass(info.ownerClassName, info.functionName, info.functionDesc)
|
||||
// Since $$forInline functions are not generated if retransformation is the last one (i.e. call site is not inline)
|
||||
// link to the function in OUTERCLASS field becomes invalid. However, since $$forInline function always has no-inline
|
||||
// companion without the suffix, use it.
|
||||
if (info.isSuspend && info.isInlineOrInsideInline) {
|
||||
visitor.visitOuterClass(info.ownerClassName, info.functionName?.removeSuffix(FOR_INLINE_SUFFIX), info.functionDesc)
|
||||
} else {
|
||||
visitor.visitOuterClass(info.ownerClassName, info.functionName, info.functionDesc)
|
||||
}
|
||||
}
|
||||
|
||||
private fun inlineMethodAndUpdateGlobalResult(
|
||||
@@ -282,7 +297,8 @@ class AnonymousObjectTransformer(
|
||||
transformationInfo.oldClassName,
|
||||
sourceNode.name,
|
||||
if (isConstructor) transformationInfo.newConstructorDescriptor else sourceNode.desc,
|
||||
inliningContext.callSiteInfo.isInlineOrInsideInline
|
||||
inliningContext.callSiteInfo.isInlineOrInsideInline,
|
||||
isSuspendFunctionOrLambda(sourceNode)
|
||||
), null
|
||||
)
|
||||
|
||||
@@ -292,6 +308,12 @@ class AnonymousObjectTransformer(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun isSuspendFunctionOrLambda(sourceNode: MethodNode): Boolean =
|
||||
(sourceNode.desc.endsWith(";Lkotlin/coroutines/Continuation;)Ljava/lang/Object;") ||
|
||||
sourceNode.desc.endsWith(";Lkotlin/coroutines/experimental/Continuation;)Ljava/lang/Object;")) &&
|
||||
(CoroutineTransformer.findFakeContinuationConstructorClassName(sourceNode) != null ||
|
||||
languageVersionSettings.isResumeImplMethodName(sourceNode.name.removeSuffix(FOR_INLINE_SUFFIX)))
|
||||
|
||||
private fun generateConstructorAndFields(
|
||||
classBuilder: ClassBuilder,
|
||||
allCapturedBuilder: ParametersBuilder,
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.codegen.inline
|
||||
|
||||
class InlineCallSiteInfo(val ownerClassName: String, val functionName: String?, val functionDesc: String?, val isInlineOrInsideInline: Boolean)
|
||||
class InlineCallSiteInfo(
|
||||
val ownerClassName: String,
|
||||
val functionName: String?,
|
||||
val functionDesc: String?,
|
||||
val isInlineOrInsideInline: Boolean,
|
||||
val isSuspend: Boolean
|
||||
)
|
||||
@@ -153,7 +153,7 @@ class MethodInliner(
|
||||
LocalVariablesSorter(
|
||||
resultNode.access,
|
||||
resultNode.desc,
|
||||
resultNode
|
||||
wrapWithMaxLocalCalc(resultNode)
|
||||
), AsmTypeRemapper(remapper, result)
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -122,7 +122,11 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
|
||||
val signature = codegen.state.typeMapper.mapSignatureSkipGeneric(context.functionDescriptor, context.contextKind)
|
||||
return InlineCallSiteInfo(
|
||||
parentCodegen.className, signature.asmMethod.name, signature.asmMethod.descriptor, compilationContextFunctionDescriptor.isInlineOrInsideInline()
|
||||
parentCodegen.className,
|
||||
signature.asmMethod.name,
|
||||
signature.asmMethod.descriptor,
|
||||
compilationContextFunctionDescriptor.isInlineOrInsideInline(),
|
||||
compilationContextFunctionDescriptor.isSuspend
|
||||
)
|
||||
}
|
||||
|
||||
@@ -171,7 +175,7 @@ class PsiSourceCompilerForInline(private val codegen: ExpressionCodegen, overrid
|
||||
codegen.parentCodegen.className
|
||||
else
|
||||
state.typeMapper.mapImplementationOwner(descriptor).internalName,
|
||||
if (isLambda) emptyList() else additionalInnerClasses,
|
||||
if (isLambda) emptyList<ClassDescriptor>() else additionalInnerClasses,
|
||||
isLambda
|
||||
)
|
||||
|
||||
|
||||
@@ -215,6 +215,13 @@ class CoroutineTransformer(
|
||||
fun unregisterClassBuilder(continuationClassName: String) =
|
||||
(inliningContext as RegeneratedClassContext).continuationBuilders.remove(continuationClassName)
|
||||
|
||||
// If tail-call optimization took place, we do not need continuation class anymore, unless it is used by $$forInline method
|
||||
fun safeToRemoveContinuationClass(method: MethodNode): Boolean = !generateForInline && !isStateMachine(method)
|
||||
|
||||
fun oldContinuationFrom(method: MethodNode): String? =
|
||||
methods.find { it.name == method.name + FOR_INLINE_SUFFIX && it.desc == method.desc }
|
||||
?.let { findFakeContinuationConstructorClassName(it) }
|
||||
|
||||
companion object {
|
||||
fun findFakeContinuationConstructorClassName(node: MethodNode): String? {
|
||||
val marker = node.instructions.asSequence().firstOrNull(::isBeforeFakeContinuationConstructorCallMarker) ?: return null
|
||||
|
||||
@@ -96,5 +96,11 @@ open class AggregatedReplStageState<T1, T2>(val state1: IReplStageState<T1>, val
|
||||
override fun getNextLineNo() = state1.getNextLineNo()
|
||||
|
||||
override val currentGeneration: Int get() = state1.currentGeneration
|
||||
|
||||
override fun dispose() {
|
||||
state2.dispose()
|
||||
state1.dispose()
|
||||
super.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,18 +60,21 @@ open class BasicReplStageHistory<T>(override val lock: ReentrantReadWriteLock =
|
||||
|
||||
override fun resetTo(id: ILineId): Iterable<ILineId> {
|
||||
lock.write {
|
||||
val idx = indexOfFirst { it.id == id }
|
||||
if (idx < 0) throw java.util.NoSuchElementException("Cannot rest to inexistent line ${id.no}")
|
||||
return if (idx < lastIndex) {
|
||||
val removed = asSequence().drop(idx + 1).map { it.id }.toList()
|
||||
removeRange(idx + 1, size)
|
||||
currentGeneration.incrementAndGet()
|
||||
removed
|
||||
}
|
||||
else {
|
||||
currentGeneration.incrementAndGet()
|
||||
emptyList()
|
||||
}
|
||||
return tryResetTo(id) ?: throw NoSuchElementException("Cannot reset to non-existent line ${id.no}")
|
||||
}
|
||||
}
|
||||
|
||||
protected fun tryResetTo(id: ILineId): List<ILineId>? {
|
||||
val idx = indexOfFirst { it.id == id }
|
||||
if (idx < 0) return null
|
||||
return if (idx < lastIndex) {
|
||||
val removed = asSequence().drop(idx + 1).map { it.id }.toList()
|
||||
removeRange(idx + 1, size)
|
||||
currentGeneration.incrementAndGet()
|
||||
removed
|
||||
} else {
|
||||
currentGeneration.incrementAndGet()
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,13 +20,11 @@ import java.io.File
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.write
|
||||
|
||||
class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
|
||||
baseClasspath: Iterable<File>,
|
||||
baseClassloader: ClassLoader? = Thread.currentThread().contextClassLoader,
|
||||
private val fallbackScriptArgs: ScriptArgsWithTypes? = null,
|
||||
repeatingMode: ReplRepeatingMode = ReplRepeatingMode.REPEAT_ONLY_MOST_RECENT
|
||||
open class GenericReplCompilingEvaluatorBase(
|
||||
val compiler: ReplCompiler,
|
||||
val evaluator: ReplEvaluator,
|
||||
private val fallbackScriptArgs: ScriptArgsWithTypes? = null
|
||||
) : ReplFullEvaluator {
|
||||
private val evaluator = GenericReplEvaluator(baseClasspath, baseClassloader, fallbackScriptArgs, repeatingMode)
|
||||
|
||||
override fun createState(lock: ReentrantReadWriteLock): IReplStageState<*> = AggregatedReplStageState(compiler.createState(lock), evaluator.createState(lock), lock)
|
||||
|
||||
@@ -75,7 +73,7 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
|
||||
}
|
||||
|
||||
override fun eval(state: IReplStageState<*>, compileResult: ReplCompileResult.CompiledClasses, scriptArgs: ScriptArgsWithTypes?, invokeWrapper: InvokeWrapper?): ReplEvalResult =
|
||||
evaluator.eval(state, compileResult, scriptArgs, invokeWrapper)
|
||||
evaluator.eval(state, compileResult, scriptArgs, invokeWrapper)
|
||||
|
||||
override fun check(state: IReplStageState<*>, codeLine: ReplCodeLine): ReplCheckResult = compiler.check(state, codeLine)
|
||||
|
||||
@@ -93,12 +91,24 @@ class GenericReplCompilingEvaluator(val compiler: ReplCompiler,
|
||||
private val evaluator: ReplEvaluator,
|
||||
private val defaultScriptArgs: ScriptArgsWithTypes?) : Evaluable {
|
||||
override fun eval(scriptArgs: ScriptArgsWithTypes?, invokeWrapper: InvokeWrapper?): ReplEvalResult =
|
||||
evaluator.eval(state, compiledCode, scriptArgs ?: defaultScriptArgs, invokeWrapper)
|
||||
evaluator.eval(state, compiledCode, scriptArgs ?: defaultScriptArgs, invokeWrapper)
|
||||
}
|
||||
}
|
||||
|
||||
class GenericReplCompilingEvaluator(
|
||||
compiler: ReplCompiler,
|
||||
baseClasspath: Iterable<File>,
|
||||
baseClassloader: ClassLoader? = Thread.currentThread().contextClassLoader,
|
||||
fallbackScriptArgs: ScriptArgsWithTypes? = null,
|
||||
repeatingMode: ReplRepeatingMode = ReplRepeatingMode.REPEAT_ONLY_MOST_RECENT
|
||||
) : GenericReplCompilingEvaluatorBase(
|
||||
compiler,
|
||||
GenericReplEvaluator(baseClasspath, baseClassloader, fallbackScriptArgs, repeatingMode),
|
||||
fallbackScriptArgs
|
||||
)
|
||||
|
||||
private fun AggregatedReplStageState<*, *>.adjustHistories(): Iterable<ILineId>? =
|
||||
state2.history.peek()?.let {
|
||||
state1.history.resetTo(it.id)
|
||||
}
|
||||
state2.history.peek()?.let {
|
||||
state1.history.resetTo(it.id)
|
||||
}
|
||||
?: state1.history.reset()
|
||||
|
||||
@@ -90,7 +90,8 @@ sealed class ReplCompileResult : Serializable {
|
||||
val classes: List<CompiledClassData>,
|
||||
val hasResult: Boolean,
|
||||
val classpathAddendum: List<File>,
|
||||
val type: String?
|
||||
val type: String?,
|
||||
val data: Any? // TODO: temporary; migration to new scripting infrastructure
|
||||
) : ReplCompileResult() {
|
||||
companion object { private val serialVersionUID: Long = 2L }
|
||||
}
|
||||
|
||||
@@ -61,6 +61,9 @@ interface IReplStageState<T> {
|
||||
fun <StateT : IReplStageState<*>> asState(target: Class<out StateT>): StateT =
|
||||
if (target.isAssignableFrom(this::class.java)) this as StateT
|
||||
else throw IllegalArgumentException("$this is not an expected instance of IReplStageState")
|
||||
|
||||
fun dispose() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ import org.jetbrains.kotlin.js.facade.TranslationUnit;
|
||||
import org.jetbrains.kotlin.js.facade.exceptions.TranslationException;
|
||||
import org.jetbrains.kotlin.js.sourceMap.SourceFilePathResolver;
|
||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion;
|
||||
import org.jetbrains.kotlin.name.FqName;
|
||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
|
||||
import org.jetbrains.kotlin.psi.KtFile;
|
||||
import org.jetbrains.kotlin.serialization.js.ModuleKind;
|
||||
@@ -73,6 +74,7 @@ import org.jetbrains.kotlin.utils.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jetbrains.kotlin.cli.common.ExitCode.COMPILATION_ERROR;
|
||||
import static org.jetbrains.kotlin.cli.common.ExitCode.OK;
|
||||
@@ -144,6 +146,15 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
}
|
||||
Arrays.sort(allSources);
|
||||
|
||||
Set<FqName> dirtyPackages = nonCompiledSources.values().stream().map(KtFile::getPackageFqName).collect(Collectors.toSet());
|
||||
Map<FqName, byte[]> packageMetadata = new HashMap<>();
|
||||
for (Map.Entry<String, byte[]> e : incrementalDataProvider.getPackageMetadata().entrySet()) {
|
||||
FqName name = new FqName(e.getKey());
|
||||
if (!dirtyPackages.contains(name)) {
|
||||
packageMetadata.put(name, e.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
List<TranslationUnit> translationUnits = new ArrayList<>();
|
||||
for (i = 0; i < allSources.length; i++) {
|
||||
KtFile nonCompiled = nonCompiledSources.get(allSources[i]);
|
||||
@@ -155,7 +166,7 @@ public class K2JSCompiler extends CLICompiler<K2JSCompilerArguments> {
|
||||
translationUnits.add(new TranslationUnit.BinaryAst(translatedValue.getBinaryAst(), translatedValue.getInlineData()));
|
||||
}
|
||||
}
|
||||
return translator.translateUnits(reporter, translationUnits, mainCallParameters, jsAnalysisResult);
|
||||
return translator.translateUnits(reporter, translationUnits, mainCallParameters, jsAnalysisResult, packageMetadata);
|
||||
}
|
||||
|
||||
CollectionsKt.sortBy(allKotlinFiles, ktFile -> VfsUtilCore.virtualToIoFile(ktFile.getVirtualFile()));
|
||||
|
||||
@@ -122,7 +122,7 @@ class K2JSDce : CLITool<K2JSDceArguments>() {
|
||||
|
||||
private fun mapSourcePaths(inputFile: File, targetFile: File): Boolean {
|
||||
val json = try {
|
||||
InputStreamReader(FileInputStream(inputFile), "UTF-8").use { parseJson(it) }
|
||||
parseJson(inputFile)
|
||||
} catch (e: JsonSyntaxException) {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ private fun mergeStdlibParts(outputFile: File, wrapperFile: File, baseDir: File,
|
||||
|
||||
val sourceMapFile = File(file.parent, file.name + ".map")
|
||||
if (sourceMapFile.exists()) {
|
||||
val sourceMapParse = sourceMapFile.reader().use { SourceMapParser.parse(it) }
|
||||
val sourceMapParse = SourceMapParser.parse(sourceMapFile)
|
||||
when (sourceMapParse) {
|
||||
is SourceMapError -> {
|
||||
System.err.println("Error parsing source map file $sourceMapFile: ${sourceMapParse.message}")
|
||||
@@ -82,7 +82,7 @@ private fun mergeStdlibParts(outputFile: File, wrapperFile: File, baseDir: File,
|
||||
|
||||
outputFile.writeText(programText + "\n//# sourceMappingURL=${sourceMapFile.name}\n")
|
||||
|
||||
val sourceMapJson = StringReader(sourceMapContent).use { parseJson(it) }
|
||||
val sourceMapJson = parseJson(sourceMapContent)
|
||||
val sources = (sourceMapJson as JsonObject).properties["sources"] as JsonArray
|
||||
|
||||
sourceMapJson.properties["sourcesContent"] = JsonArray(*sources.elements.map { sourcePath ->
|
||||
|
||||
@@ -134,6 +134,10 @@ open class CompilerCallbackServicesFacadeServer(
|
||||
incrementalResultsConsumer!!.processInlineFunctions(functions)
|
||||
}
|
||||
|
||||
override fun incrementalResultsConsumer_processPackageMetadata(packageName: String, metadata: ByteArray) {
|
||||
incrementalResultsConsumer!!.processPackageMetadata(packageName, metadata)
|
||||
}
|
||||
|
||||
override fun incrementalDataProvider_getHeaderMetadata(): ByteArray = incrementalDataProvider!!.headerMetadata
|
||||
|
||||
override fun incrementalDataProvider_getMetadataVersion(): IntArray = incrementalDataProvider!!.metadataVersion
|
||||
@@ -142,4 +146,9 @@ open class CompilerCallbackServicesFacadeServer(
|
||||
incrementalDataProvider!!.compiledPackageParts.entries.map {
|
||||
CompiledPackagePart(it.key.path, it.value.metadata, it.value.binaryAst, it.value.inlineData)
|
||||
}
|
||||
|
||||
override fun incrementalDataProvider_getPackageMetadata(): Collection<PackageMetadata> =
|
||||
incrementalDataProvider!!.packageMetadata.entries.map { (fqName, metadata) ->
|
||||
PackageMetadata(fqName, metadata)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,6 +112,9 @@ interface CompilerCallbackServicesFacade : Remote {
|
||||
@Throws(RemoteException::class)
|
||||
fun incrementalResultsConsumer_processInlineFunctions(functions: Collection<JsInlineFunctionHash>)
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun incrementalResultsConsumer_processPackageMetadata(packageName: String, metadata: ByteArray)
|
||||
|
||||
// ---------------------------------------------------
|
||||
// IncrementalDataProvider (js)
|
||||
@Throws(RemoteException::class)
|
||||
@@ -122,6 +125,9 @@ interface CompilerCallbackServicesFacade : Remote {
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun incrementalDataProvider_getMetadataVersion(): IntArray
|
||||
|
||||
@Throws(RemoteException::class)
|
||||
fun incrementalDataProvider_getPackageMetadata(): Collection<PackageMetadata>
|
||||
}
|
||||
|
||||
class CompiledPackagePart(
|
||||
@@ -129,6 +135,17 @@ class CompiledPackagePart(
|
||||
val metadata: ByteArray, val binaryAst: ByteArray, val inlineData: ByteArray
|
||||
) : Serializable
|
||||
|
||||
class PackageMetadata(
|
||||
val packageName: String,
|
||||
val metadata: ByteArray
|
||||
) : Serializable {
|
||||
companion object {
|
||||
// just a random number, but should never be changed to avoid deserialization problems
|
||||
private val serialVersionUID: Long = 54021986502349756L
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class RmiFriendlyCompilationCanceledException : Exception(), Serializable {
|
||||
companion object {
|
||||
// just a random number, but should never be changed to avoid deserialization problems
|
||||
|
||||
@@ -32,4 +32,14 @@ class RemoteIncrementalDataProvider(val facade: CompilerCallbackServicesFacade,
|
||||
get() = rpcProfiler.withMeasure(this) {
|
||||
facade.incrementalDataProvider_getMetadataVersion()
|
||||
}
|
||||
|
||||
override val packageMetadata: Map<String, ByteArray>
|
||||
get() = rpcProfiler.withMeasure(this) {
|
||||
val result = mutableMapOf<String, ByteArray>()
|
||||
facade.incrementalDataProvider_getPackageMetadata().forEach {
|
||||
val prev = result.put(it.packageName, it.metadata)
|
||||
check(prev == null) { "packageMetadata: duplicated entry for package `${it.packageName}`" }
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import java.io.File
|
||||
|
||||
class RemoteIncrementalResultsConsumer(val facade: CompilerCallbackServicesFacade, eventManager: EventManager, val rpcProfiler: Profiler) :
|
||||
IncrementalResultsConsumer {
|
||||
|
||||
init {
|
||||
eventManager.onCompilationFinished(this::flush)
|
||||
}
|
||||
@@ -40,6 +41,12 @@ class RemoteIncrementalResultsConsumer(val facade: CompilerCallbackServicesFacad
|
||||
|
||||
override fun processInlineFunctions(functions: Collection<JsInlineFunctionHash>) = error("Should not be called in Daemon Server")
|
||||
|
||||
override fun processPackageMetadata(packageName: String, metadata: ByteArray) {
|
||||
rpcProfiler.withMeasure(this) {
|
||||
facade.incrementalResultsConsumer_processPackageMetadata(packageName, metadata)
|
||||
}
|
||||
}
|
||||
|
||||
fun flush() {
|
||||
rpcProfiler.withMeasure(this) {
|
||||
facade.incrementalResultsConsumer_processInlineFunctions(deferInlineFuncs.map {
|
||||
|
||||
@@ -300,7 +300,7 @@ class Fir2IrDeclarationStorage(
|
||||
startOffset, endOffset, origin, symbol,
|
||||
constructor.name, constructor.visibility,
|
||||
constructor.returnTypeRef.toIrType(session, this),
|
||||
false, false, isPrimary
|
||||
isInline = false, isExternal = false, isPrimary = isPrimary
|
||||
).bindAndDeclareParameters(constructor, descriptor, setParent, shouldLeaveScope)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,18 +167,18 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
||||
callableName,
|
||||
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
|
||||
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
|
||||
Flags.IS_EXPECT_PROPERTY.get(flags),
|
||||
false,
|
||||
false,
|
||||
Flags.IS_CONST.get(flags),
|
||||
Flags.IS_LATEINIT.get(flags),
|
||||
proto.receiverType(c.typeTable)?.toTypeRef(local),
|
||||
returnTypeRef,
|
||||
Flags.IS_VAR.get(flags),
|
||||
null,
|
||||
FirDefaultPropertyGetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))),
|
||||
FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags))),
|
||||
null
|
||||
isExpect = Flags.IS_EXPECT_PROPERTY.get(flags),
|
||||
isActual = false,
|
||||
isOverride = false,
|
||||
isConst = Flags.IS_CONST.get(flags),
|
||||
isLateInit = Flags.IS_LATEINIT.get(flags),
|
||||
receiverTypeRef = proto.receiverType(c.typeTable)?.toTypeRef(local),
|
||||
returnTypeRef = returnTypeRef,
|
||||
isVar = Flags.IS_VAR.get(flags),
|
||||
initializer = null,
|
||||
getter = FirDefaultPropertyGetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(getterFlags))),
|
||||
setter = FirDefaultPropertySetter(c.session, null, returnTypeRef, ProtoEnumFlags.visibility(Flags.VISIBILITY.get(setterFlags))),
|
||||
delegate = null
|
||||
).apply {
|
||||
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.firUnsafe() }
|
||||
annotations += c.annotationDeserializer.loadPropertyAnnotations(proto, local.nameResolver)
|
||||
@@ -209,16 +209,16 @@ class FirMemberDeserializer(private val c: FirDeserializationContext) {
|
||||
ProtoEnumFlags.visibility(Flags.VISIBILITY.get(flags)),
|
||||
ProtoEnumFlags.modality(Flags.MODALITY.get(flags)),
|
||||
Flags.IS_EXPECT_FUNCTION.get(flags),
|
||||
false,
|
||||
false,
|
||||
Flags.IS_OPERATOR.get(flags),
|
||||
Flags.IS_INFIX.get(flags),
|
||||
Flags.IS_INLINE.get(flags),
|
||||
Flags.IS_TAILREC.get(flags),
|
||||
Flags.IS_EXTERNAL_FUNCTION.get(flags),
|
||||
Flags.IS_SUSPEND.get(flags),
|
||||
proto.receiverType(local.typeTable)?.toTypeRef(local),
|
||||
proto.returnType(local.typeTable).toTypeRef(local)
|
||||
isActual = false,
|
||||
isOverride = false,
|
||||
isOperator = Flags.IS_OPERATOR.get(flags),
|
||||
isInfix = Flags.IS_INFIX.get(flags),
|
||||
isInline = Flags.IS_INLINE.get(flags),
|
||||
isTailRec = Flags.IS_TAILREC.get(flags),
|
||||
isExternal = Flags.IS_EXTERNAL_FUNCTION.get(flags),
|
||||
isSuspend = Flags.IS_SUSPEND.get(flags),
|
||||
receiverTypeRef = proto.receiverType(local.typeTable)?.toTypeRef(local),
|
||||
returnTypeRef = proto.returnType(local.typeTable).toTypeRef(local)
|
||||
).apply {
|
||||
typeParameters += local.typeDeserializer.ownTypeParameters.map { it.firUnsafe() }
|
||||
valueParameters += local.memberDeserializer.valueParameters(proto.valueParameterList)
|
||||
|
||||
@@ -40,6 +40,10 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
|
||||
return StandardClassIds.Nothing(symbolProvider).constructType(emptyArray(), false)
|
||||
}
|
||||
|
||||
override fun anyType(): SimpleTypeMarker {
|
||||
return StandardClassIds.Any(symbolProvider).constructType(emptyArray(), false)
|
||||
}
|
||||
|
||||
override fun createFlexibleType(lowerBound: SimpleTypeMarker, upperBound: SimpleTypeMarker): KotlinTypeMarker {
|
||||
require(lowerBound is ConeKotlinType)
|
||||
require(upperBound is ConeKotlinType)
|
||||
@@ -158,9 +162,8 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext,
|
||||
}
|
||||
*/
|
||||
|
||||
val simpleType = this.asSimpleType() ?: return false
|
||||
repeat(simpleType.argumentsCount()) { index ->
|
||||
val argument = simpleType.getArgument(index)
|
||||
repeat(argumentsCount()) { index ->
|
||||
val argument = getArgument(index)
|
||||
if (!argument.isStarProjection() && argument.getType().containsInternal(predicate, visited)) return true
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,11 @@ interface SyntheticSymbol : ConeSymbol
|
||||
|
||||
class SyntheticPropertySymbol(callableId: CallableId) : FirPropertySymbol(callableId), SyntheticSymbol
|
||||
|
||||
class FirSyntheticPropertiesScope(val session: FirSession, val baseScope: FirScope, val typeCalculator: ReturnTypeCalculator) : FirScope {
|
||||
class FirSyntheticPropertiesScope(
|
||||
val session: FirSession,
|
||||
private val baseScope: FirScope,
|
||||
private val typeCalculator: ReturnTypeCalculator
|
||||
) : FirScope {
|
||||
|
||||
val synthetic: MutableMap<ConeCallableSymbol, ConeVariableSymbol> = mutableMapOf()
|
||||
|
||||
@@ -47,18 +51,18 @@ class FirSyntheticPropertiesScope(val session: FirSession, val baseScope: FirSco
|
||||
name,
|
||||
fir.visibility,
|
||||
fir.modality,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
returnTypeRef,
|
||||
true,
|
||||
null,
|
||||
FirDefaultPropertyGetter(session, null, returnTypeRef, fir.visibility),
|
||||
FirDefaultPropertySetter(session, null, returnTypeRef, fir.visibility),
|
||||
null
|
||||
isExpect = false,
|
||||
isActual = false,
|
||||
isOverride = false,
|
||||
isConst = false,
|
||||
isLateInit = false,
|
||||
receiverTypeRef = null,
|
||||
returnTypeRef = returnTypeRef,
|
||||
isVar = true,
|
||||
initializer = null,
|
||||
getter = FirDefaultPropertyGetter(session, null, returnTypeRef, fir.visibility),
|
||||
setter = FirDefaultPropertySetter(session, null, returnTypeRef, fir.visibility),
|
||||
delegate = null
|
||||
)
|
||||
return processor(synthetic)
|
||||
}
|
||||
|
||||
@@ -169,9 +169,9 @@ class FirLibrarySymbolProviderImpl(val session: FirSession) : FirSymbolProvider
|
||||
relativeClassName.shortName(),
|
||||
Visibilities.PUBLIC,
|
||||
Modality.OPEN,
|
||||
false,
|
||||
false,
|
||||
ClassKind.CLASS,
|
||||
isExpect = false,
|
||||
isActual = false,
|
||||
classKind = ClassKind.CLASS,
|
||||
isInner = false,
|
||||
isCompanion = false,
|
||||
isData = false,
|
||||
|
||||
@@ -435,10 +435,10 @@ open class FirBodyResolveTransformer(val session: FirSession, val implicitTypeOn
|
||||
null,
|
||||
Name.identifier("it"),
|
||||
FirResolvedTypeRefImpl(session, null, parameters.single(), emptyList()),
|
||||
null,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
defaultValue = null,
|
||||
isCrossinline = false,
|
||||
isNoinline = false,
|
||||
isVararg = false
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -144,13 +144,13 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext {
|
||||
return typeConstructor
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.argumentsCount(): Int {
|
||||
override fun KotlinTypeMarker.argumentsCount(): Int {
|
||||
require(this is ConeKotlinType)
|
||||
|
||||
return this.typeArguments.size
|
||||
}
|
||||
|
||||
override fun SimpleTypeMarker.getArgument(index: Int): TypeArgumentMarker {
|
||||
override fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker {
|
||||
require(this is ConeKotlinType)
|
||||
|
||||
return this.typeArguments.getOrNull(index)
|
||||
|
||||
@@ -1704,6 +1704,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/parsingPriorityOfGenericArgumentsVsLess.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("rewriteAtSliceOnGetOperator.kt")
|
||||
public void testRewriteAtSliceOnGetOperator() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/rewriteAtSliceOnGetOperator.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("sam.kt")
|
||||
public void testSam() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/callableReference/sam.kt");
|
||||
@@ -8081,6 +8086,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/generics/argumentsForT.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("capturedTypeInInputPosition.kt")
|
||||
public void testCapturedTypeInInputPosition() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/generics/capturedTypeInInputPosition.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("commonSupertypeContravariant.kt")
|
||||
public void testCommonSupertypeContravariant() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/generics/commonSupertypeContravariant.kt");
|
||||
@@ -8920,6 +8930,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssign.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setterProjectedOutAssignFromJava.kt")
|
||||
public void testSetterProjectedOutAssignFromJava() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutAssignFromJava.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("setterProjectedOutNoPlusAssign.kt")
|
||||
public void testSetterProjectedOutNoPlusAssign() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/generics/varProjection/setterProjectedOutNoPlusAssign.kt");
|
||||
@@ -9703,6 +9718,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/inference/possibleCycleOnConstraints.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveTypes.kt")
|
||||
public void testRecursiveTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/recursiveTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("reportAboutUnresolvedReferenceAsUnresolved.kt")
|
||||
public void testReportAboutUnresolvedReferenceAsUnresolved() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/reportAboutUnresolvedReferenceAsUnresolved.kt");
|
||||
@@ -10004,11 +10024,21 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/inference/constraints"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("constraintFromVariantTypeWithNestedProjection.kt")
|
||||
public void testConstraintFromVariantTypeWithNestedProjection() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/constraintFromVariantTypeWithNestedProjection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("constraintOnFunctionLiteral.kt")
|
||||
public void testConstraintOnFunctionLiteral() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/constraintOnFunctionLiteral.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("earlyCompletionForCalls.kt")
|
||||
public void testEarlyCompletionForCalls() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/earlyCompletionForCalls.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("equalityConstraintOnNullableType.kt")
|
||||
public void testEqualityConstraintOnNullableType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/equalityConstraintOnNullableType.kt");
|
||||
@@ -10024,6 +10054,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/ignoreConstraintFromImplicitInNothing.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inferTypeFromCapturedStarProjection.kt")
|
||||
public void testInferTypeFromCapturedStarProjection() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/inferTypeFromCapturedStarProjection.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt6320.kt")
|
||||
public void testKt6320() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/kt6320.kt");
|
||||
@@ -10044,6 +10079,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/kt8879.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("manyConstraintsDueToFlexibleRawTypes.kt")
|
||||
public void testManyConstraintsDueToFlexibleRawTypes() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToFlexibleRawTypes.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt")
|
||||
public void testManyConstraintsDueToRecursiveFlexibleTypesWithWildcards() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/manyConstraintsDueToRecursiveFlexibleTypesWithWildcards.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("notNullConstraintOnNullableType.kt")
|
||||
public void testNotNullConstraintOnNullableType() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/constraints/notNullConstraintOnNullableType.kt");
|
||||
@@ -10189,6 +10234,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
public void testNothingWithCallableReference() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/nothingWithCallableReference.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("platformNothingAsUsefulConstraint.kt")
|
||||
public void testPlatformNothingAsUsefulConstraint() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/inference/nothingType/platformNothingAsUsefulConstraint.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/inference/recursiveCalls")
|
||||
@@ -12358,6 +12408,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/privateCandidatesWithWrongArguments.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("recursiveSamsAndInvoke.kt")
|
||||
public void testRecursiveSamsAndInvoke() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/recursiveSamsAndInvoke.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("samOnTypeParameter.kt")
|
||||
public void testSamOnTypeParameter() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/j+k/sam/samOnTypeParameter.kt");
|
||||
@@ -17323,6 +17378,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/HiddenDeclarations.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitAndExplicitThis.kt")
|
||||
public void testImplicitAndExplicitThis() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/implicitAndExplicitThis.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitReceiverProperty.kt")
|
||||
public void testImplicitReceiverProperty() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/implicitReceiverProperty.kt");
|
||||
@@ -17470,6 +17530,21 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/insideTopLevelExtensionAnnotatedType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt29948.kt")
|
||||
public void testKt29948() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt29948.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt31360.kt")
|
||||
public void testKt31360() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/kt31360.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("markedReceiverWithCapturedTypeArgument.kt")
|
||||
public void testMarkedReceiverWithCapturedTypeArgument() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markedReceiverWithCapturedTypeArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("markersIntersection.kt")
|
||||
public void testMarkersIntersection() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/resolve/dslMarker/markersIntersection.kt");
|
||||
@@ -18025,6 +18100,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/samConversions/GenericSubstitutionKT.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt25290.kt")
|
||||
public void testKt25290() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/samConversions/kt25290.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("OverloadPriority.kt")
|
||||
public void testOverloadPriority() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/samConversions/OverloadPriority.kt");
|
||||
@@ -22203,9 +22283,9 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/typeParameters/implicitNothingAsTypeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("implicitNothingAsTypeParameterNI.kt")
|
||||
public void testImplicitNothingAsTypeParameterNI() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typeParameters/implicitNothingAsTypeParameterNI.kt");
|
||||
@TestMetadata("implicitNothingOnDelegates.kt")
|
||||
public void testImplicitNothingOnDelegates() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typeParameters/implicitNothingOnDelegates.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("misplacedConstraints.kt")
|
||||
@@ -22346,6 +22426,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/importFromTypeAliasObject.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("importMemberFromJavaViaAlias.kt")
|
||||
public void testImportMemberFromJavaViaAlias() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/importMemberFromJavaViaAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inGenerics.kt")
|
||||
public void testInGenerics() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/inGenerics.kt");
|
||||
@@ -22516,6 +22601,11 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/simpleTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("starImportOnTypeAlias.kt")
|
||||
public void testStarImportOnTypeAlias() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/starImportOnTypeAlias.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("starProjection.kt")
|
||||
public void testStarProjection() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/starProjection.kt");
|
||||
@@ -22681,6 +22771,16 @@ public class FirDiagnosticsSmokeTestGenerated extends AbstractFirDiagnosticsSmok
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasShouldExpandToClass.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasesInImportDirectives.kt")
|
||||
public void testTypeAliasesInImportDirectives() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasesInImportDirectives.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeAliasesInQualifiers.kt")
|
||||
public void testTypeAliasesInQualifiers() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/typeAliasesInQualifiers.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typealiasRhsAnnotations.kt")
|
||||
public void testTypealiasRhsAnnotations() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/tests/typealias/typealiasRhsAnnotations.kt");
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
|
||||
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.types.SubstitutingScopeProviderImpl
|
||||
|
||||
private fun StorageComponentContainer.configureJavaTopDownAnalysis(
|
||||
moduleContentScope: GlobalSearchScope,
|
||||
@@ -125,6 +126,7 @@ fun createContainerForLazyResolveWithJava(
|
||||
targetEnvironment.configure(this)
|
||||
|
||||
useImpl<ContractDeserializerImpl>()
|
||||
useImpl<SubstitutingScopeProviderImpl>()
|
||||
useImpl<FilesByFacadeFqNameIndexer>()
|
||||
}.apply {
|
||||
get<AbstractJavaClassFinder>().initialize(bindingTrace, get<KotlinCodeAnalyzer>())
|
||||
|
||||
@@ -1,19 +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.resolve.jvm
|
||||
|
||||
interface GlobalSearchScopeWithModuleSources
|
||||
@@ -44,7 +44,6 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.asJava.KtLightClassMarker;
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinder;
|
||||
import org.jetbrains.kotlin.load.java.JavaClassFinderImpl;
|
||||
import org.jetbrains.kotlin.load.java.structure.JavaClass;
|
||||
import org.jetbrains.kotlin.load.java.structure.impl.JavaClassImpl;
|
||||
import org.jetbrains.kotlin.name.ClassId;
|
||||
@@ -126,30 +125,7 @@ public class KotlinJavaPsiFacade {
|
||||
}
|
||||
else {
|
||||
PsiClass aClass = finder.findClass(qualifiedName, scope);
|
||||
if (aClass != null) {
|
||||
if (scope instanceof JavaClassFinderImpl.FilterOutKotlinSourceFilesScope) {
|
||||
GlobalSearchScope baseScope = ((JavaClassFinderImpl.FilterOutKotlinSourceFilesScope) scope).getBase();
|
||||
boolean isSourcesScope = baseScope instanceof GlobalSearchScopeWithModuleSources;
|
||||
|
||||
if (!isSourcesScope) {
|
||||
Object originalFinder = (finder instanceof KotlinPsiElementFinderWrapperImpl)
|
||||
? ((KotlinPsiElementFinderWrapperImpl) finder).getOriginal()
|
||||
: finder;
|
||||
|
||||
// Temporary fix for #KT-12402
|
||||
boolean isAndroidDataBindingClassWriter = originalFinder.getClass().getName()
|
||||
.equals("com.android.tools.idea.databinding.DataBindingClassFinder");
|
||||
boolean isAndroidDataBindingComponentClassWriter = originalFinder.getClass().getName()
|
||||
.equals("com.android.tools.idea.databinding.DataBindingComponentClassFinder");
|
||||
|
||||
if (isAndroidDataBindingClassWriter || isAndroidDataBindingComponentClassWriter) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return createJavaClass(classId, aClass);
|
||||
}
|
||||
if (aClass != null) return createJavaClass(classId, aClass);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,10 +317,6 @@ public class KotlinJavaPsiFacade {
|
||||
this.finder = finder;
|
||||
}
|
||||
|
||||
public PsiElementFinder getOriginal() {
|
||||
return finder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
|
||||
return finder.findClass(qualifiedName, scope);
|
||||
|
||||
@@ -59,7 +59,8 @@ fun OtherOrigin(element: PsiElement?, descriptor: DeclarationDescriptor? = null)
|
||||
fun OtherOriginFromPure(element: KtPureElement?, descriptor: DeclarationDescriptor? = null) =
|
||||
OtherOrigin(element?.psiOrParent, descriptor)
|
||||
|
||||
fun OtherOrigin(descriptor: DeclarationDescriptor) = JvmDeclarationOrigin(OTHER, null, descriptor)
|
||||
fun OtherOrigin(descriptor: DeclarationDescriptor): JvmDeclarationOrigin =
|
||||
JvmDeclarationOrigin(OTHER, DescriptorToSourceUtils.descriptorToDeclaration(descriptor), descriptor)
|
||||
|
||||
fun Bridge(
|
||||
descriptor: DeclarationDescriptor,
|
||||
|
||||
@@ -60,8 +60,7 @@ class SamAdapterFunctionsScope(
|
||||
private val deprecationResolver: DeprecationResolver,
|
||||
private val lookupTracker: LookupTracker
|
||||
) : SyntheticScope.Default() {
|
||||
private val samViaSyntheticScopeDisabled = languageVersionSettings.supportsFeature(LanguageFeature.NewInference) &&
|
||||
languageVersionSettings.supportsFeature(LanguageFeature.SamConversionForKotlinFunctions)
|
||||
private val samViaSyntheticScopeDisabled = languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
|
||||
|
||||
private val extensionForFunction =
|
||||
storageManager.createMemoizedFunctionWithNullableValues<FunctionDescriptor, FunctionDescriptor> { function ->
|
||||
|
||||
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
|
||||
import org.jetbrains.kotlin.serialization.deserialization.MetadataPackageFragmentProvider
|
||||
import org.jetbrains.kotlin.serialization.deserialization.MetadataPartProvider
|
||||
import org.jetbrains.kotlin.types.SubstitutingScopeProviderImpl
|
||||
|
||||
class CommonAnalysisParameters(
|
||||
val metadataPartProviderFactory: (ModuleContent<*>) -> MetadataPartProvider
|
||||
@@ -166,6 +167,7 @@ object CommonAnalyzerFacade : ResolverForModuleFactory() {
|
||||
useInstance(declarationProviderFactory)
|
||||
useImpl<MetadataPackageFragmentProvider>()
|
||||
useImpl<ContractDeserializerImpl>()
|
||||
useImpl<SubstitutingScopeProviderImpl>()
|
||||
|
||||
val metadataFinderFactory = ServiceManager.getService(moduleContext.project, MetadataFinderFactory::class.java)
|
||||
?: error("No MetadataFinderFactory in project")
|
||||
|
||||
@@ -508,7 +508,7 @@ class ControlFlowInformationProvider private constructor(
|
||||
}
|
||||
}
|
||||
if (descriptor == null) {
|
||||
val descriptors = trace.get(BindingContext.AMBIGUOUS_REFERENCE_TARGET, operationReference) ?: emptyList()
|
||||
val descriptors = trace.get(AMBIGUOUS_REFERENCE_TARGET, operationReference) ?: emptyList<DeclarationDescriptor>()
|
||||
for (referenceDescriptor in descriptors) {
|
||||
if ((referenceDescriptor as? FunctionDescriptor)?.returnType?.let { KotlinBuiltIns.isUnit(it) } == true) {
|
||||
hasReassignMethodReturningUnit = true
|
||||
|
||||
@@ -67,7 +67,7 @@ private fun ESValue.toDataFlowValue(builtIns: KotlinBuiltIns): DataFlowValue? =
|
||||
is ESDataFlowValue -> dataFlowValue
|
||||
is ESConstant -> when (constantReference) {
|
||||
ConstantReference.NULL -> DataFlowValue.nullValue(builtIns)
|
||||
else -> DataFlowValue(IdentifierInfo.NO, type)
|
||||
else -> DataFlowValue(IdentifierInfo.NO, type.toKotlinType(builtIns))
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -20,7 +20,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.contracts.model.Computation
|
||||
import org.jetbrains.kotlin.contracts.model.ESComponents
|
||||
import org.jetbrains.kotlin.contracts.model.ESEffect
|
||||
import org.jetbrains.kotlin.contracts.model.MutableContextInfo
|
||||
import org.jetbrains.kotlin.contracts.model.functors.EqualsFunctor
|
||||
@@ -46,13 +45,6 @@ class EffectSystem(
|
||||
val dataFlowValueFactory: DataFlowValueFactory,
|
||||
val builtIns: KotlinBuiltIns
|
||||
) {
|
||||
// Lazy because this code is executed when the container is set up (before any resolution starts),
|
||||
// so builtins are not fully functional yet at that moment
|
||||
val components: ESComponents by lazy(LazyThreadSafetyMode.NONE) { ESComponents(builtIns) }
|
||||
|
||||
val constants: ESConstants
|
||||
get() = components.constants
|
||||
|
||||
fun getDataFlowInfoForFinishedCall(
|
||||
resolvedCall: ResolvedCall<*>,
|
||||
bindingTrace: BindingTrace,
|
||||
@@ -64,7 +56,7 @@ class EffectSystem(
|
||||
val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return DataFlowInfo.EMPTY
|
||||
if (callExpression is KtDeclaration) return DataFlowInfo.EMPTY
|
||||
|
||||
val resultContextInfo = getContextInfoWhen(ESReturns(constants.wildcard), callExpression, bindingTrace, moduleDescriptor)
|
||||
val resultContextInfo = getContextInfoWhen(ESReturns(ESConstants.wildcard), callExpression, bindingTrace, moduleDescriptor)
|
||||
|
||||
return resultContextInfo.toDataFlowInfo(languageVersionSettings, builtIns)
|
||||
}
|
||||
@@ -83,10 +75,10 @@ class EffectSystem(
|
||||
val rightComputation =
|
||||
getNonTrivialComputation(rightExpression, bindingTrace, moduleDescriptor) ?: return ConditionalDataFlowInfo.EMPTY
|
||||
|
||||
val effects = EqualsFunctor(constants, false).invokeWithArguments(leftComputation, rightComputation)
|
||||
val effects = EqualsFunctor(false).invokeWithArguments(leftComputation, rightComputation)
|
||||
|
||||
val equalsContextInfo = InfoCollector(ESReturns(constants.trueValue), constants).collectFromSchema(effects)
|
||||
val notEqualsContextInfo = InfoCollector(ESReturns(constants.falseValue), constants).collectFromSchema(effects)
|
||||
val equalsContextInfo = InfoCollector(ESReturns(ESConstants.trueValue), builtIns).collectFromSchema(effects)
|
||||
val notEqualsContextInfo = InfoCollector(ESReturns(ESConstants.falseValue), builtIns).collectFromSchema(effects)
|
||||
|
||||
return ConditionalDataFlowInfo(
|
||||
equalsContextInfo.toDataFlowInfo(languageVersionSettings, builtIns),
|
||||
@@ -101,7 +93,7 @@ class EffectSystem(
|
||||
val callExpression = resolvedCall.call.callElement as? KtCallExpression ?: return
|
||||
if (callExpression is KtDeclaration) return
|
||||
|
||||
val resultingContextInfo = getContextInfoWhen(ESReturns(constants.wildcard), callExpression, bindingTrace, moduleDescriptor)
|
||||
val resultingContextInfo = getContextInfoWhen(ESReturns(ESConstants.wildcard), callExpression, bindingTrace, moduleDescriptor)
|
||||
for (effect in resultingContextInfo.firedEffects) {
|
||||
val callsEffect = effect as? ESCalls ?: continue
|
||||
val lambdaExpression = (callsEffect.callable as? ESLambda)?.lambda ?: continue
|
||||
@@ -118,7 +110,7 @@ class EffectSystem(
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.UseReturnsEffect)) return DataFlowInfo.EMPTY
|
||||
if (condition == null) return DataFlowInfo.EMPTY
|
||||
|
||||
return getContextInfoWhen(ESReturns(constants.booleanValue(value)), condition, bindingTrace, moduleDescriptor)
|
||||
return getContextInfoWhen(ESReturns(ESConstants.booleanValue(value)), condition, bindingTrace, moduleDescriptor)
|
||||
.toDataFlowInfo(languageVersionSettings, moduleDescriptor.builtIns)
|
||||
}
|
||||
|
||||
@@ -133,11 +125,11 @@ class EffectSystem(
|
||||
}
|
||||
if (isInContractBlock) return MutableContextInfo.EMPTY
|
||||
val computation = getNonTrivialComputation(expression, bindingTrace, moduleDescriptor) ?: return MutableContextInfo.EMPTY
|
||||
return InfoCollector(observedEffect, constants).collectFromSchema(computation.effects)
|
||||
return InfoCollector(observedEffect, builtIns).collectFromSchema(computation.effects)
|
||||
}
|
||||
|
||||
private fun getNonTrivialComputation(expression: KtExpression, trace: BindingTrace, moduleDescriptor: ModuleDescriptor): Computation? {
|
||||
val visitor = EffectsExtractingVisitor(trace, moduleDescriptor, dataFlowValueFactory, constants, languageVersionSettings)
|
||||
val visitor = EffectsExtractingVisitor(trace, moduleDescriptor, dataFlowValueFactory, languageVersionSettings)
|
||||
return visitor.extractOrGetCached(expression).takeUnless { it == UNKNOWN_COMPUTATION }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,8 @@ import org.jetbrains.kotlin.contracts.model.ConditionalEffect
|
||||
import org.jetbrains.kotlin.contracts.model.ESEffect
|
||||
import org.jetbrains.kotlin.contracts.model.Functor
|
||||
import org.jetbrains.kotlin.contracts.model.functors.*
|
||||
import org.jetbrains.kotlin.contracts.model.structure.CallComputation
|
||||
import org.jetbrains.kotlin.contracts.model.structure.ESConstants
|
||||
import org.jetbrains.kotlin.contracts.model.structure.UNKNOWN_COMPUTATION
|
||||
import org.jetbrains.kotlin.contracts.model.structure.isReturns
|
||||
import org.jetbrains.kotlin.contracts.model.structure.*
|
||||
import org.jetbrains.kotlin.contracts.model.visitors.Reducer
|
||||
import org.jetbrains.kotlin.contracts.parsing.isEqualsDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -58,10 +56,10 @@ class EffectsExtractingVisitor(
|
||||
private val trace: BindingTrace,
|
||||
private val moduleDescriptor: ModuleDescriptor,
|
||||
private val dataFlowValueFactory: DataFlowValueFactory,
|
||||
private val constants: ESConstants,
|
||||
private val languageVersionSettings: LanguageVersionSettings
|
||||
) : KtVisitor<Computation, Unit>() {
|
||||
private val builtIns: KotlinBuiltIns get() = moduleDescriptor.builtIns
|
||||
private val reducer: Reducer = Reducer(builtIns)
|
||||
|
||||
fun extractOrGetCached(element: KtElement): Computation {
|
||||
trace[BindingContext.EXPRESSION_EFFECTS, element]?.let { return it }
|
||||
@@ -77,17 +75,20 @@ class EffectsExtractingVisitor(
|
||||
val descriptor = resolvedCall.resultingDescriptor
|
||||
return when {
|
||||
descriptor.isEqualsDescriptor() -> CallComputation(
|
||||
builtIns.booleanType,
|
||||
EqualsFunctor(constants, false).invokeWithArguments(arguments)
|
||||
ESBooleanType,
|
||||
EqualsFunctor(false).invokeWithArguments(arguments, reducer)
|
||||
)
|
||||
descriptor is ValueDescriptor -> ESVariableWithDataFlowValue(
|
||||
descriptor,
|
||||
(element as KtExpression).createDataFlowValue() ?: return UNKNOWN_COMPUTATION
|
||||
)
|
||||
descriptor is FunctionDescriptor -> CallComputation(
|
||||
descriptor.returnType,
|
||||
descriptor.getFunctor()?.invokeWithArguments(arguments) ?: emptyList()
|
||||
)
|
||||
descriptor is FunctionDescriptor -> {
|
||||
val esType = descriptor.returnType?.toESType()
|
||||
CallComputation(
|
||||
esType,
|
||||
descriptor.getFunctor()?.invokeWithArguments(arguments, reducer) ?: emptyList()
|
||||
)
|
||||
}
|
||||
else -> UNKNOWN_COMPUTATION
|
||||
}
|
||||
}
|
||||
@@ -111,18 +112,18 @@ class EffectsExtractingVisitor(
|
||||
val value: Any? = compileTimeConstant.getValue(type)
|
||||
|
||||
return when (value) {
|
||||
is Boolean -> constants.booleanValue(value)
|
||||
null -> constants.nullValue
|
||||
is Boolean -> ESConstants.booleanValue(value)
|
||||
null -> ESConstants.nullValue
|
||||
else -> UNKNOWN_COMPUTATION
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitIsExpression(expression: KtIsExpression, data: Unit): Computation {
|
||||
val rightType: KotlinType = trace[BindingContext.TYPE, expression.typeReference] ?: return UNKNOWN_COMPUTATION
|
||||
val rightType = trace[BindingContext.TYPE, expression.typeReference]?.toESType() ?: return UNKNOWN_COMPUTATION
|
||||
val arg = extractOrGetCached(expression.leftHandSide)
|
||||
return CallComputation(
|
||||
builtIns.booleanType,
|
||||
IsFunctor(constants, rightType, expression.isNegated).invokeWithArguments(listOf(arg))
|
||||
ESBooleanType,
|
||||
IsFunctor(rightType, expression.isNegated).invokeWithArguments(listOf(arg), reducer)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -134,7 +135,7 @@ class EffectsExtractingVisitor(
|
||||
// null bypassing function's contract, so we have to filter them out
|
||||
|
||||
fun ESEffect.containsReturnsNull(): Boolean =
|
||||
isReturns { value == constants.nullValue } || this is ConditionalEffect && this.simpleEffect.containsReturnsNull()
|
||||
isReturns { value == ESConstants.nullValue } || this is ConditionalEffect && this.simpleEffect.containsReturnsNull()
|
||||
|
||||
val effectsWithoutReturnsNull = computation.effects.filter { !it.containsReturnsNull() }
|
||||
return CallComputation(computation.type, effectsWithoutReturnsNull)
|
||||
@@ -147,10 +148,10 @@ class EffectsExtractingVisitor(
|
||||
val args = listOf(left, right)
|
||||
|
||||
return when (expression.operationToken) {
|
||||
KtTokens.EXCLEQ -> CallComputation(builtIns.booleanType, EqualsFunctor(constants, true).invokeWithArguments(args))
|
||||
KtTokens.EQEQ -> CallComputation(builtIns.booleanType, EqualsFunctor(constants, false).invokeWithArguments(args))
|
||||
KtTokens.ANDAND -> CallComputation(builtIns.booleanType, AndFunctor(constants).invokeWithArguments(args))
|
||||
KtTokens.OROR -> CallComputation(builtIns.booleanType, OrFunctor(constants).invokeWithArguments(args))
|
||||
KtTokens.EXCLEQ -> CallComputation(ESBooleanType, EqualsFunctor(true).invokeWithArguments(args, reducer))
|
||||
KtTokens.EQEQ -> CallComputation(ESBooleanType, EqualsFunctor(false).invokeWithArguments(args, reducer))
|
||||
KtTokens.ANDAND -> CallComputation(ESBooleanType, AndFunctor().invokeWithArguments(args, reducer))
|
||||
KtTokens.OROR -> CallComputation(ESBooleanType, OrFunctor().invokeWithArguments(args, reducer))
|
||||
else -> UNKNOWN_COMPUTATION
|
||||
}
|
||||
}
|
||||
@@ -158,7 +159,7 @@ class EffectsExtractingVisitor(
|
||||
override fun visitUnaryExpression(expression: KtUnaryExpression, data: Unit): Computation {
|
||||
val arg = extractOrGetCached(expression.baseExpression ?: return UNKNOWN_COMPUTATION)
|
||||
return when (expression.operationToken) {
|
||||
KtTokens.EXCL -> CallComputation(builtIns.booleanType, NotFunctor(constants).invokeWithArguments(arg))
|
||||
KtTokens.EXCL -> CallComputation(ESBooleanType, NotFunctor().invokeWithArguments(arg))
|
||||
else -> UNKNOWN_COMPUTATION
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +81,7 @@ public class LocalVariableDescriptor extends VariableDescriptorWithInitializerIm
|
||||
@NotNull
|
||||
@Override
|
||||
public LocalVariableDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
|
||||
if (substitutor.isEmpty()) return this;
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitutio
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.SubstitutingScopeProvider
|
||||
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.isAnyOrNullableAny
|
||||
@@ -77,7 +78,9 @@ fun ResolutionContext<*>.reportTypeMismatchDueToTypeProjection(
|
||||
TypeConstructorSubstitution
|
||||
.create(receiverType)
|
||||
.wrapWithCapturingSubstitution(needApproximation = false)
|
||||
.buildSubstitutor().let { callableDescriptor.substitute(it) } ?: return false
|
||||
.buildSubstitutor().apply {
|
||||
setSubstitutingScopeProvider(SubstitutingScopeProvider.DEFAULT)
|
||||
}.let { callableDescriptor.substitute(it) } ?: return false
|
||||
|
||||
val nonApproximatedExpectedType = correspondingNotApproximatedTypeByDescriptor(substitutedDescriptor) ?: return false
|
||||
if (!TypeUtils.contains(nonApproximatedExpectedType) { it.isCaptured() }) return false
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
||||
import org.jetbrains.kotlin.resolve.lazy.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.types.SubstitutingScopeProviderImpl
|
||||
import org.jetbrains.kotlin.types.expressions.DeclarationScopeProviderForLocalClassifierAnalyzer
|
||||
import org.jetbrains.kotlin.types.expressions.LocalClassDescriptorHolder
|
||||
import org.jetbrains.kotlin.types.expressions.LocalLazyDeclarationResolver
|
||||
@@ -103,6 +104,7 @@ fun createContainerForBodyResolve(
|
||||
useImpl<AnnotationResolverImpl>()
|
||||
|
||||
useImpl<BodyResolver>()
|
||||
useImpl<SubstitutingScopeProviderImpl>()
|
||||
}
|
||||
|
||||
fun createContainerForLazyBodyResolve(
|
||||
@@ -123,6 +125,7 @@ fun createContainerForLazyBodyResolve(
|
||||
useImpl<AnnotationResolverImpl>()
|
||||
useImpl<LazyTopDownAnalyzer>()
|
||||
useImpl<BasicAbsentDescriptorHandler>()
|
||||
useImpl<SubstitutingScopeProviderImpl>()
|
||||
}
|
||||
|
||||
fun createContainerForLazyLocalClassifierAnalyzer(
|
||||
@@ -153,6 +156,7 @@ fun createContainerForLazyLocalClassifierAnalyzer(
|
||||
useImpl<DeclarationScopeProviderForLocalClassifierAnalyzer>()
|
||||
useImpl<LocalLazyDeclarationResolver>()
|
||||
|
||||
useImpl<SubstitutingScopeProviderImpl>()
|
||||
useInstance(languageVersionSettings)
|
||||
useInstance(statementFilter)
|
||||
}
|
||||
@@ -169,6 +173,7 @@ fun createContainerForLazyResolve(
|
||||
configureModule(moduleContext, platform, targetPlatformVersion, bindingTrace)
|
||||
|
||||
useInstance(declarationProviderFactory)
|
||||
useImpl<SubstitutingScopeProviderImpl>()
|
||||
useInstance(languageVersionSettings)
|
||||
|
||||
useImpl<AnnotationResolverImpl>()
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.CallResolver;
|
||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
@@ -303,7 +304,9 @@ public class BodyResolver {
|
||||
if (delegateExpression != null) {
|
||||
LexicalScope scope = scopeForConstructor == null ? scopeForMemberResolution : scopeForConstructor;
|
||||
KotlinType expectedType = supertype != null ? supertype : NO_EXPECTED_TYPE;
|
||||
typeInferrer.getType(scope, delegateExpression, expectedType, outerDataFlowInfo, trace);
|
||||
typeInferrer.getType(
|
||||
scope, delegateExpression, expectedType, outerDataFlowInfo, InferenceSession.Companion.getDefault(), trace
|
||||
);
|
||||
}
|
||||
|
||||
if (descriptor.isExpect()) {
|
||||
@@ -660,7 +663,8 @@ public class BodyResolver {
|
||||
PreliminaryDeclarationVisitor.Companion.createForDeclaration(
|
||||
(KtDeclaration) anonymousInitializer.getParent().getParent(), trace, languageVersionSettings);
|
||||
expressionTypingServices.getTypeInfo(
|
||||
scopeForInitializers, body, NO_EXPECTED_TYPE, outerDataFlowInfo, trace, /*isStatement = */true
|
||||
scopeForInitializers, body, NO_EXPECTED_TYPE, outerDataFlowInfo,
|
||||
InferenceSession.Companion.getDefault(), trace, /*isStatement = */true
|
||||
);
|
||||
}
|
||||
processModifiersOnInitializer(anonymousInitializer, scopeForInitializers);
|
||||
@@ -864,6 +868,7 @@ public class BodyResolver {
|
||||
propertyDescriptor,
|
||||
delegateExpression,
|
||||
propertyHeaderScope,
|
||||
InferenceSession.Companion.getDefault(),
|
||||
trace);
|
||||
}
|
||||
|
||||
@@ -878,7 +883,7 @@ public class BodyResolver {
|
||||
KotlinType expectedTypeForInitializer = property.getTypeReference() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
|
||||
if (propertyDescriptor.getCompileTimeInitializer() == null) {
|
||||
expressionTypingServices.getType(propertyDeclarationInnerScope, initializer, expectedTypeForInitializer,
|
||||
outerDataFlowInfo, trace);
|
||||
outerDataFlowInfo, InferenceSession.Companion.getDefault(), trace);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,14 +53,14 @@ class DelegatedPropertyInferenceSession(
|
||||
?: builtIns.nullableNothingType
|
||||
|
||||
val valueParameterForThis = descriptor.valueParameters.getOrNull(0) ?: return
|
||||
val substitutedType = substitutor.substituteKeepAnnotations(valueParameterForThis.type.unwrap())
|
||||
val substitutedType = substitutor.safeSubstitute(valueParameterForThis.type.unwrap())
|
||||
commonSystem.addSubtypeConstraint(typeOfThis.unwrap(), substitutedType, DelegatedPropertyConstraintPosition(atom))
|
||||
}
|
||||
|
||||
private fun ResolvedCallAtom.addConstraintsForGetValueMethod(commonSystem: ConstraintSystemBuilder) {
|
||||
if (expectedType != null) {
|
||||
val unsubstitutedReturnType = candidateDescriptor.returnType?.unwrap() ?: return
|
||||
val substitutedReturnType = substitutor.substituteKeepAnnotations(unsubstitutedReturnType)
|
||||
val substitutedReturnType = substitutor.safeSubstitute(unsubstitutedReturnType)
|
||||
|
||||
commonSystem.addSubtypeConstraint(substitutedReturnType, expectedType, DelegatedPropertyConstraintPosition(atom))
|
||||
}
|
||||
@@ -71,7 +71,7 @@ class DelegatedPropertyInferenceSession(
|
||||
private fun ResolvedCallAtom.addConstraintsForSetValueMethod(commonSystem: ConstraintSystemBuilder) {
|
||||
if (expectedType != null) {
|
||||
val unsubstitutedParameterType = candidateDescriptor.valueParameters.getOrNull(2)?.type?.unwrap() ?: return
|
||||
val substitutedParameterType = substitutor.substituteKeepAnnotations(unsubstitutedParameterType)
|
||||
val substitutedParameterType = substitutor.safeSubstitute(unsubstitutedParameterType)
|
||||
|
||||
commonSystem.addSubtypeConstraint(expectedType, substitutedParameterType, DelegatedPropertyConstraintPosition(atom))
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@ class DelegatedPropertyResolver(
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
delegateExpression: KtExpression,
|
||||
propertyHeaderScope: LexicalScope,
|
||||
inferenceSession: InferenceSession,
|
||||
trace: BindingTrace
|
||||
) {
|
||||
property.getter?.let { getter ->
|
||||
@@ -86,8 +87,9 @@ class DelegatedPropertyResolver(
|
||||
ScopeUtils.makeScopeForPropertyInitializer(propertyHeaderScope, variableDescriptor)
|
||||
else propertyHeaderScope
|
||||
|
||||
val byExpressionType =
|
||||
resolveDelegateExpression(delegateExpression, property, variableDescriptor, initializerScope, trace, outerDataFlowInfo)
|
||||
val byExpressionType =resolveDelegateExpression(
|
||||
delegateExpression, property, variableDescriptor, initializerScope, trace, outerDataFlowInfo, inferenceSession
|
||||
)
|
||||
|
||||
resolveProvideDelegateMethod(variableDescriptor, delegateExpression, byExpressionType, trace, initializerScope, outerDataFlowInfo)
|
||||
val delegateType = getResolvedDelegateType(variableDescriptor, delegateExpression, byExpressionType, trace)
|
||||
@@ -455,7 +457,8 @@ class DelegatedPropertyResolver(
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
scopeForDelegate: LexicalScope,
|
||||
trace: BindingTrace,
|
||||
dataFlowInfo: DataFlowInfo
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
inferenceSession: InferenceSession
|
||||
): KotlinType {
|
||||
val traceToResolveDelegatedProperty = TemporaryBindingTrace.create(trace, "Trace to resolve delegated property")
|
||||
|
||||
@@ -475,12 +478,13 @@ class DelegatedPropertyResolver(
|
||||
}
|
||||
|
||||
val delegatedPropertyTypeFromNI =
|
||||
resolveWithNewInference(delegateExpression, variableDescriptor, scopeForDelegate, trace, dataFlowInfo)
|
||||
resolveWithNewInference(delegateExpression, variableDescriptor, scopeForDelegate, trace, dataFlowInfo, inferenceSession)
|
||||
val delegateType = expressionTypingServices.safeGetType(
|
||||
scopeForDelegate,
|
||||
delegateExpression,
|
||||
delegatedPropertyTypeFromNI ?: NO_EXPECTED_TYPE,
|
||||
dataFlowInfo,
|
||||
inferenceSession,
|
||||
traceToResolveDelegatedProperty
|
||||
)
|
||||
|
||||
@@ -494,7 +498,8 @@ class DelegatedPropertyResolver(
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
scopeForDelegate: LexicalScope,
|
||||
trace: BindingTrace,
|
||||
dataFlowInfo: DataFlowInfo
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
inferenceSession: InferenceSession
|
||||
): KotlinType? {
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.NewInference)) return null
|
||||
|
||||
@@ -503,7 +508,7 @@ class DelegatedPropertyResolver(
|
||||
val traceToResolveDelegatedProperty = TemporaryBindingTrace.create(trace, "Trace to resolve delegated property")
|
||||
|
||||
val delegateTypeInfo = expressionTypingServices.getTypeInfo(
|
||||
scopeForDelegate, delegateExpression, NO_EXPECTED_TYPE, dataFlowInfo,
|
||||
scopeForDelegate, delegateExpression, NO_EXPECTED_TYPE, dataFlowInfo, inferenceSession,
|
||||
traceToResolveDelegatedProperty, false, delegateExpression, ContextDependency.DEPENDENT
|
||||
)
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.name.Name;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfoFactory;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory;
|
||||
@@ -798,7 +799,8 @@ public class DescriptorResolver {
|
||||
@NotNull LexicalScope scopeForInitializerResolution,
|
||||
@NotNull KtDestructuringDeclarationEntry entry,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull DataFlowInfo dataFlowInfo
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull InferenceSession inferenceSession
|
||||
) {
|
||||
KtDestructuringDeclaration destructuringDeclaration = (KtDestructuringDeclaration) entry.getParent();
|
||||
KtExpression initializer = destructuringDeclaration.getInitializer();
|
||||
@@ -819,6 +821,7 @@ public class DescriptorResolver {
|
||||
entry,
|
||||
trace,
|
||||
dataFlowInfo,
|
||||
inferenceSession,
|
||||
VariableAsPropertyInfo.Companion.createFromDestructuringDeclarationEntry(componentType));
|
||||
}
|
||||
|
||||
@@ -842,7 +845,8 @@ public class DescriptorResolver {
|
||||
@NotNull LexicalScope scopeForInitializerResolution,
|
||||
@NotNull KtProperty property,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull DataFlowInfo dataFlowInfo
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull InferenceSession inferenceSession
|
||||
) {
|
||||
return resolveAsPropertyDescriptor(
|
||||
containingDeclaration,
|
||||
@@ -851,6 +855,7 @@ public class DescriptorResolver {
|
||||
property,
|
||||
trace,
|
||||
dataFlowInfo,
|
||||
inferenceSession,
|
||||
VariableAsPropertyInfo.Companion.createFromProperty(property));
|
||||
}
|
||||
|
||||
@@ -862,6 +867,7 @@ public class DescriptorResolver {
|
||||
@NotNull KtVariableDeclaration variableDeclaration,
|
||||
@NotNull BindingTrace trace,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull InferenceSession inferenceSession,
|
||||
@NotNull VariableAsPropertyInfo propertyInfo
|
||||
) {
|
||||
KtModifierList modifierList = variableDeclaration.getModifierList();
|
||||
@@ -905,7 +911,8 @@ public class DescriptorResolver {
|
||||
container instanceof ClassDescriptor && ((ClassDescriptor) container).isExpect(),
|
||||
modifierList != null && PsiUtilsKt.hasActualModifier(modifierList),
|
||||
modifierList != null && modifierList.hasModifier(KtTokens.EXTERNAL_KEYWORD),
|
||||
propertyInfo.getHasDelegate()
|
||||
propertyInfo.getHasDelegate(),
|
||||
new SubstitutingScopeProviderImpl(languageVersionSettings)
|
||||
);
|
||||
|
||||
List<TypeParameterDescriptorImpl> typeParameterDescriptors;
|
||||
@@ -962,7 +969,8 @@ public class DescriptorResolver {
|
||||
KotlinType propertyType = propertyInfo.getVariableType();
|
||||
KotlinType typeIfKnown = propertyType != null ? propertyType : variableTypeAndInitializerResolver.resolveTypeNullable(
|
||||
propertyDescriptor, scopeForInitializer,
|
||||
variableDeclaration, dataFlowInfo, /* local = */ trace, false
|
||||
variableDeclaration, dataFlowInfo, inferenceSession,
|
||||
trace, /* local = */ false
|
||||
);
|
||||
|
||||
PropertyGetterDescriptorImpl getter = resolvePropertyGetterDescriptor(
|
||||
@@ -980,7 +988,7 @@ public class DescriptorResolver {
|
||||
assert type != null : "At least getter type must be initialized via resolvePropertyGetterDescriptor";
|
||||
|
||||
variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(
|
||||
propertyDescriptor, scopeForInitializer, variableDeclaration, dataFlowInfo, type, trace
|
||||
propertyDescriptor, scopeForInitializer, variableDeclaration, dataFlowInfo, type, inferenceSession, trace
|
||||
);
|
||||
|
||||
propertyDescriptor.setType(type, typeParameterDescriptors, getDispatchReceiverParameterIfNeeded(container), receiverDescriptor);
|
||||
|
||||
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.KtVariableDeclaration
|
||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||
@@ -74,7 +75,8 @@ class LocalVariableResolver(
|
||||
context.trace.report(LOCAL_VARIABLE_WITH_SETTER.on(setter))
|
||||
}
|
||||
|
||||
val propertyDescriptor = resolveLocalVariableDescriptor(scope, property, context.dataFlowInfo, context.trace)
|
||||
val propertyDescriptor =
|
||||
resolveLocalVariableDescriptor(scope, property, context.dataFlowInfo, context.inferenceSession, context.trace)
|
||||
|
||||
val delegateExpression = property.delegateExpression
|
||||
if (delegateExpression != null) {
|
||||
@@ -94,6 +96,7 @@ class LocalVariableResolver(
|
||||
propertyDescriptor,
|
||||
delegateExpression,
|
||||
typingContext.scope,
|
||||
typingContext.inferenceSession,
|
||||
typingContext.trace
|
||||
)
|
||||
propertyDescriptor.getter?.updateAccessorFlagsFromResolvedCallForDelegatedProperty(typingContext.trace)
|
||||
@@ -153,6 +156,7 @@ class LocalVariableResolver(
|
||||
scope: LexicalScope,
|
||||
variable: KtVariableDeclaration,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
inferenceSession: InferenceSession,
|
||||
trace: BindingTrace
|
||||
): VariableDescriptor {
|
||||
val containingDeclaration = scope.ownerDescriptor
|
||||
@@ -176,7 +180,9 @@ class LocalVariableResolver(
|
||||
variable is KtProperty && variable.hasDelegate()
|
||||
)
|
||||
// For a local variable the type must not be deferred
|
||||
type = variableTypeAndInitializerResolver.resolveType(propertyDescriptor, scope, variable, dataFlowInfo, trace, local = true)
|
||||
type = variableTypeAndInitializerResolver.resolveType(
|
||||
propertyDescriptor, scope, variable, dataFlowInfo, inferenceSession, trace, local = true
|
||||
)
|
||||
|
||||
val receiverParameter = (containingDeclaration as ScriptDescriptor).thisAsReceiverParameter
|
||||
propertyDescriptor.setType(type, emptyList<TypeParameterDescriptor>(), receiverParameter, null)
|
||||
@@ -186,11 +192,14 @@ class LocalVariableResolver(
|
||||
} else {
|
||||
val variableDescriptor = resolveLocalVariableDescriptorWithType(scope, variable, null, trace)
|
||||
// For a local variable the type must not be deferred
|
||||
type = variableTypeAndInitializerResolver.resolveType(variableDescriptor, scope, variable, dataFlowInfo, trace, local = true)
|
||||
type = variableTypeAndInitializerResolver.resolveType(
|
||||
variableDescriptor, scope, variable, dataFlowInfo, inferenceSession, trace, local = true
|
||||
)
|
||||
variableDescriptor.setOutType(type)
|
||||
result = variableDescriptor
|
||||
}
|
||||
variableTypeAndInitializerResolver.setConstantForVariableIfNeeded(result, scope, variable, dataFlowInfo, type, trace)
|
||||
variableTypeAndInitializerResolver
|
||||
.setConstantForVariableIfNeeded(result, scope, variable, dataFlowInfo, type, inferenceSession, trace)
|
||||
// Type annotations also should be resolved
|
||||
ForceResolveUtil.forceResolveAllContents(type.annotations)
|
||||
return result
|
||||
|
||||
@@ -231,7 +231,7 @@ class QualifiedExpressionResolver {
|
||||
val packageOrClassDescriptor = resolveToPackageOrClass(
|
||||
path, moduleDescriptor, trace, packageFragmentForCheck,
|
||||
scopeForFirstPart = null, position = QualifierPosition.IMPORT
|
||||
) ?: return null
|
||||
).classDescriptorFromTypeAlias() ?: return null
|
||||
|
||||
if (packageOrClassDescriptor is ClassDescriptor && packageOrClassDescriptor.kind.isSingleton && lastPart.expression != null) {
|
||||
trace.report(
|
||||
@@ -249,6 +249,10 @@ class QualifiedExpressionResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private fun DeclarationDescriptor?.classDescriptorFromTypeAlias(): DeclarationDescriptor? {
|
||||
return if (this is TypeAliasDescriptor) classDescriptor else this
|
||||
}
|
||||
|
||||
private fun computePackageFragmentToCheck(
|
||||
containingFile: KtFile,
|
||||
packageFragmentForVisibilityCheck: PackageFragmentDescriptor?
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.resolve
|
||||
|
||||
import org.jetbrains.kotlin.contracts.description.ContractProviderKey
|
||||
import org.jetbrains.kotlin.contracts.description.LazyContractProvider
|
||||
import org.jetbrains.kotlin.contracts.parsing.isContractCallDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.psi.Call
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isContractDescriptionCallPsiCheck
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isFirstStatement
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
/*
|
||||
* See KT-26386 and KT-30410
|
||||
*/
|
||||
fun disableContractsInsideContractsBlock(call: Call, descriptor: CallableDescriptor?, scope: LexicalScope, trace: BindingTrace) {
|
||||
call.callElement.safeAs<KtExpression>()?.let { callExpression ->
|
||||
if (callExpression.isFirstStatement() && callExpression.isContractDescriptionCallPsiCheck()) {
|
||||
if (descriptor?.isContractCallDescriptor() != true) {
|
||||
scope.ownerDescriptor
|
||||
.safeAs<FunctionDescriptor>()
|
||||
?.getUserData(ContractProviderKey)
|
||||
?.safeAs<LazyContractProvider>()
|
||||
?.setContractDescription(null)
|
||||
} else {
|
||||
trace.record(BindingContext.IS_CONTRACT_DECLARATION_BLOCK, callExpression, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtVariableDeclaration
|
||||
import org.jetbrains.kotlin.resolve.DescriptorResolver.transformAnonymousTypeIfNeeded
|
||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
@@ -44,10 +45,13 @@ class VariableTypeAndInitializerResolver(
|
||||
scopeForInitializer: LexicalScope,
|
||||
variable: KtVariableDeclaration,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
inferenceSession: InferenceSession,
|
||||
trace: BindingTrace,
|
||||
local: Boolean
|
||||
): KotlinType {
|
||||
resolveTypeNullable(variableDescriptor, scopeForInitializer, variable, dataFlowInfo, trace, local)?.let { return it }
|
||||
resolveTypeNullable(
|
||||
variableDescriptor, scopeForInitializer, variable, dataFlowInfo, inferenceSession, trace, local
|
||||
)?.let { return it }
|
||||
|
||||
if (local) {
|
||||
trace.report(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER.on(variable))
|
||||
@@ -61,6 +65,7 @@ class VariableTypeAndInitializerResolver(
|
||||
scopeForInitializer: LexicalScope,
|
||||
variable: KtVariableDeclaration,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
inferenceSession: InferenceSession,
|
||||
trace: BindingTrace,
|
||||
local: Boolean
|
||||
): KotlinType? {
|
||||
@@ -70,7 +75,9 @@ class VariableTypeAndInitializerResolver(
|
||||
|
||||
!variable.hasInitializer() && variable is KtProperty && variableDescriptor is VariableDescriptorWithAccessors &&
|
||||
variable.hasDelegateExpression() ->
|
||||
resolveDelegatedPropertyType(variable, variableDescriptor, scopeForInitializer, dataFlowInfo, trace, local)
|
||||
resolveDelegatedPropertyType(
|
||||
variable, variableDescriptor, scopeForInitializer, dataFlowInfo, inferenceSession, trace, local
|
||||
)
|
||||
|
||||
variable.hasInitializer() -> when {
|
||||
!local ->
|
||||
@@ -81,12 +88,13 @@ class VariableTypeAndInitializerResolver(
|
||||
variable, trace,
|
||||
expressionTypingServices.languageVersionSettings
|
||||
)
|
||||
val initializerType =
|
||||
resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
|
||||
val initializerType = resolveInitializerType(
|
||||
scopeForInitializer, variable.initializer!!, dataFlowInfo, inferenceSession, trace, local
|
||||
)
|
||||
transformAnonymousTypeIfNeeded(variableDescriptor, variable, initializerType, trace, anonymousTypeTransformers)
|
||||
}
|
||||
|
||||
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, trace, local)
|
||||
else -> resolveInitializerType(scopeForInitializer, variable.initializer!!, dataFlowInfo, inferenceSession, trace, local)
|
||||
}
|
||||
|
||||
else -> null
|
||||
@@ -99,6 +107,7 @@ class VariableTypeAndInitializerResolver(
|
||||
variable: KtVariableDeclaration,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
variableType: KotlinType,
|
||||
inferenceSession: InferenceSession,
|
||||
trace: BindingTrace
|
||||
) {
|
||||
if (!variable.hasInitializer() || variable.isVar) return
|
||||
@@ -111,7 +120,8 @@ class VariableTypeAndInitializerResolver(
|
||||
)) return@computeInitializer null
|
||||
|
||||
val initializer = variable.initializer
|
||||
val initializerType = expressionTypingServices.safeGetType(scope, initializer!!, variableType, dataFlowInfo, trace)
|
||||
val initializerType =
|
||||
expressionTypingServices.safeGetType(scope, initializer!!, variableType, dataFlowInfo, inferenceSession, trace)
|
||||
val constant = constantExpressionEvaluator.evaluateExpression(initializer, trace, initializerType)
|
||||
?: return@computeInitializer null
|
||||
|
||||
@@ -131,12 +141,13 @@ class VariableTypeAndInitializerResolver(
|
||||
variableDescriptor: VariableDescriptorWithAccessors,
|
||||
scopeForInitializer: LexicalScope,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
inferenceSession: InferenceSession,
|
||||
trace: BindingTrace,
|
||||
local: Boolean
|
||||
) = wrappedTypeFactory.createRecursionIntolerantDeferredType(trace) {
|
||||
val delegateExpression = property.delegateExpression!!
|
||||
val type = delegatedPropertyResolver.resolveDelegateExpression(
|
||||
delegateExpression, property, variableDescriptor, scopeForInitializer, trace, dataFlowInfo
|
||||
delegateExpression, property, variableDescriptor, scopeForInitializer, trace, dataFlowInfo, inferenceSession
|
||||
)
|
||||
|
||||
val getterReturnType = delegatedPropertyResolver.getGetValueMethodReturnType(
|
||||
@@ -153,10 +164,13 @@ class VariableTypeAndInitializerResolver(
|
||||
scope: LexicalScope,
|
||||
initializer: KtExpression,
|
||||
dataFlowInfo: DataFlowInfo,
|
||||
inferenceSession: InferenceSession,
|
||||
trace: BindingTrace,
|
||||
local: Boolean
|
||||
): KotlinType {
|
||||
val inferredType = expressionTypingServices.safeGetType(scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, trace)
|
||||
val inferredType = expressionTypingServices.safeGetType(
|
||||
scope, initializer, TypeUtils.NO_EXPECTED_TYPE, dataFlowInfo, inferenceSession, trace
|
||||
)
|
||||
val approximatedType = approximateType(inferredType, local)
|
||||
return declarationReturnTypeSanitizer.sanitizeReturnType(approximatedType, wrappedTypeFactory, trace, languageVersionSettings)
|
||||
}
|
||||
|
||||
@@ -135,19 +135,7 @@ class CallCompleter(
|
||||
context: BasicCallResolutionContext,
|
||||
tracing: TracingStrategy
|
||||
) {
|
||||
context.call.callElement.safeAs<KtExpression>()?.let { callExpression ->
|
||||
if (callExpression.isFirstStatement() && callExpression.isContractDescriptionCallPsiCheck()) {
|
||||
if (resolvedCall?.resultingDescriptor?.isContractCallDescriptor() != true) {
|
||||
context.scope.ownerDescriptor
|
||||
.safeAs<FunctionDescriptor>()
|
||||
?.getUserData(ContractProviderKey)
|
||||
?.safeAs<LazyContractProvider>()
|
||||
?.setContractDescription(null)
|
||||
} else {
|
||||
context.trace.record(BindingContext.IS_CONTRACT_DECLARATION_BLOCK, callExpression, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
disableContractsInsideContractsBlock(context.call, resolvedCall?.resultingDescriptor, context.scope, context.trace)
|
||||
|
||||
if (resolvedCall == null || resolvedCall.isCompleted || resolvedCall.constraintSystem == null) {
|
||||
completeArguments(context, results)
|
||||
|
||||
@@ -350,7 +350,7 @@ public class CallResolver {
|
||||
);
|
||||
}
|
||||
KotlinType calleeType = expressionTypingServices.safeGetType(
|
||||
context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.trace);
|
||||
context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.inferenceSession, context.trace);
|
||||
ExpressionReceiver expressionReceiver = ExpressionReceiver.Companion.create(calleeExpression, calleeType, context.trace.getBindingContext());
|
||||
|
||||
Call call = new CallTransformer.CallForImplicitInvoke(context.call.getExplicitReceiver(), expressionReceiver, context.call,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
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
|
||||
@@ -14,6 +15,7 @@ import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.INVOKE_ON
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.BadNamedArgumentsTarget.NON_KOTLIN_FUNCTION
|
||||
import org.jetbrains.kotlin.diagnostics.reportDiagnosticOnce
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isNull
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
@@ -60,6 +62,12 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
val reportOn = (diagnostic as NonApplicableCallForBuilderInferenceDiagnostic).kotlinCall
|
||||
trace.reportDiagnosticOnce(Errors.NON_APPLICABLE_CALL_FOR_BUILDER_INFERENCE.on(reportOn.psiKotlinCall.psiCall.callElement))
|
||||
}
|
||||
OnlyInputTypesDiagnostic::class.java -> {
|
||||
val typeVariable = (diagnostic as OnlyInputTypesDiagnostic).typeVariable as? TypeVariableFromCallableDescriptor ?: return
|
||||
psiKotlinCall.psiCall.calleeExpression?.let {
|
||||
trace.report(TYPE_INFERENCE_ONLY_INPUT_TYPES.on(it, typeVariable.originalTypeParameter))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,6 +136,17 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
trace.report(UNRESOLVED_REFERENCE.on(it.callableReference, it.callableReference))
|
||||
}
|
||||
}
|
||||
|
||||
ArgumentTypeMismatchDiagnostic::class.java -> {
|
||||
require(diagnostic is ArgumentTypeMismatchDiagnostic)
|
||||
reportIfNonNull(callArgument.safeAs<PSIKotlinCallArgument>()?.valueArgument?.getArgumentExpression()) {
|
||||
if (it.isNull()) {
|
||||
trace.reportDiagnosticOnce(NULL_FOR_NONNULL_TYPE.on(it, diagnostic.expectedType))
|
||||
} else {
|
||||
trace.report(TYPE_MISMATCH.on(it, diagnostic.expectedType, diagnostic.actualType))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,7 +238,7 @@ class DiagnosticReporterByTrackingStrategy(
|
||||
argument?.let {
|
||||
it.safeAs<LambdaKotlinCallArgument>()?.let lambda@{ lambda ->
|
||||
val parameterTypes = lambda.parametersTypes?.toList() ?: return@lambda
|
||||
val index = parameterTypes.indexOf(constraintError.upperType)
|
||||
val index = parameterTypes.indexOf(constraintError.upperKotlinType.unwrap())
|
||||
val lambdaExpression = lambda.psiExpression as? KtLambdaExpression ?: return@lambda
|
||||
val parameter = lambdaExpression.valueParameters.getOrNull(index) ?: return@lambda
|
||||
trace.report(Errors.EXPECTED_PARAMETER_TYPE_MISMATCH.on(parameter, constraintError.upperKotlinType.unCapture()))
|
||||
|
||||
@@ -31,7 +31,12 @@ object DslScopeViolationCallChecker : CallChecker {
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.DslMarkersSupport)) return
|
||||
val callImplicitReceivers = resolvedCall.getImplicitReceivers()
|
||||
|
||||
for (callImplicitReceiver in callImplicitReceivers) {
|
||||
val originalReceivers = if (context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference))
|
||||
callImplicitReceivers.map { it.original }
|
||||
else
|
||||
callImplicitReceivers
|
||||
|
||||
for (callImplicitReceiver in originalReceivers) {
|
||||
checkCallImplicitReceiver(callImplicitReceiver, resolvedCall, reportOn, context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,11 @@ import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.types.DeferredType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.expressions.ControlStructureTypingUtils
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
||||
|
||||
object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
|
||||
private val SPECIAL_FUNCTION_NAMES = ControlStructureTypingUtils.ResolveConstruct.values().map { it.specialFunctionName }.toSet()
|
||||
@@ -32,16 +35,21 @@ object ImplicitNothingAsTypeParameterCallChecker : CallChecker {
|
||||
* }
|
||||
*/
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
if (resolvedCall.candidateDescriptor.name !in SPECIAL_FUNCTION_NAMES && resolvedCall.call.typeArguments.isEmpty()) {
|
||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||
val inferredReturnType = resultingDescriptor.returnType
|
||||
if (inferredReturnType is DeferredType)
|
||||
return
|
||||
if (resultingDescriptor.name !in SPECIAL_FUNCTION_NAMES && resolvedCall.call.typeArguments.isEmpty()) {
|
||||
val lambdasFromArgumentsReturnTypes =
|
||||
resolvedCall.candidateDescriptor.valueParameters.filter { it.type.isFunctionType }
|
||||
.map { it.returnType?.arguments?.last()?.type }.toSet()
|
||||
val unsubstitutedReturnType = resultingDescriptor.original.returnType
|
||||
val expectedType = context.resolutionContext.expectedType
|
||||
val hasImplicitNothing = inferredReturnType?.isNothing() == true &&
|
||||
unsubstitutedReturnType?.isTypeParameter() == true &&
|
||||
(TypeUtils.noExpectedType(expectedType) || !expectedType.isNothing())
|
||||
|
||||
val hasImplicitNothingExceptLambdaReturnTypes = resolvedCall.typeArguments.any { (unsubstitutedType, resultingType) ->
|
||||
resultingType.isNothing() && unsubstitutedType.defaultType !in lambdasFromArgumentsReturnTypes
|
||||
}
|
||||
|
||||
if (hasImplicitNothingExceptLambdaReturnTypes) {
|
||||
if (hasImplicitNothing && unsubstitutedReturnType !in lambdasFromArgumentsReturnTypes) {
|
||||
context.trace.report(Errors.IMPLICIT_NOTHING_AS_TYPE_PARAMETER.on(reportOn))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ class KotlinResolutionCallbacksImpl(
|
||||
receiverType: UnwrappedType?,
|
||||
parameters: List<UnwrappedType>,
|
||||
expectedReturnType: UnwrappedType?,
|
||||
annotations: Annotations,
|
||||
stubsForPostponedVariables: Map<NewTypeVariable, StubType>
|
||||
): Pair<List<KotlinCallArgument>, InferenceSession?> {
|
||||
val psiCallArgument = lambdaArgument.psiCallArgument as PSIFunctionKotlinCallArgument
|
||||
@@ -130,7 +131,7 @@ class KotlinResolutionCallbacksImpl(
|
||||
|
||||
val builtIns = outerCallContext.scope.ownerDescriptor.builtIns
|
||||
val expectedType = createFunctionType(
|
||||
builtIns, Annotations.EMPTY, receiverType, parameters, null,
|
||||
builtIns, annotations, receiverType, parameters, null,
|
||||
lambdaInfo.expectedType, isSuspend
|
||||
)
|
||||
|
||||
@@ -264,4 +265,10 @@ class KotlinResolutionCallbacksImpl(
|
||||
trace.record(BindingContext.CAST_TYPE_USED_AS_EXPECTED_TYPE, binaryParent)
|
||||
return resultType
|
||||
}
|
||||
|
||||
override fun disableContractsIfNecessary(resolvedAtom: ResolvedCallAtom) {
|
||||
val atom = resolvedAtom.atom as? PSIKotlinCall ?: return
|
||||
val context = topLevelCallContext ?: return
|
||||
disableContractsInsideContractsBlock(atom.psiCall, resolvedAtom.candidateDescriptor, context.scope, trace)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PropertySetterDescriptorImpl
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
@@ -23,12 +25,13 @@ import org.jetbrains.kotlin.resolve.calls.components.AdditionalDiagnosticReporte
|
||||
import org.jetbrains.kotlin.resolve.calls.components.isVararg
|
||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CallPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.approximateCapturedTypes
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.buildResultingSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateCapturedTypes
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateIntegerLiteralTypes
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.makeNullableTypeIfSafeReceiver
|
||||
import org.jetbrains.kotlin.resolve.calls.results.ResolutionStatus
|
||||
@@ -38,14 +41,13 @@ 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.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.CastImplicitClassReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitClassReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
||||
import org.jetbrains.kotlin.types.expressions.DataFlowAnalyzer
|
||||
import org.jetbrains.kotlin.types.expressions.DoubleColonExpressionResolver
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
||||
@@ -293,15 +295,14 @@ class KotlinToResolvedCallTransformer(
|
||||
// todo external argument
|
||||
|
||||
val argumentExpression = valueArgument.getArgumentExpression() ?: continue
|
||||
updateRecordedType(argumentExpression, parameter, newContext, resolvedCall.isReallySuccess())
|
||||
updateRecordedType(argumentExpression, parameter, newContext)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateRecordedType(
|
||||
expression: KtExpression,
|
||||
parameter: ValueParameterDescriptor?,
|
||||
context: BasicCallResolutionContext,
|
||||
reportErrorForTypeMismatch: Boolean
|
||||
context: BasicCallResolutionContext
|
||||
): KotlinType? {
|
||||
val deparenthesized = expression.let {
|
||||
KtPsiUtil.getLastElementDeparenthesized(it, context.statementFilter)
|
||||
@@ -318,9 +319,6 @@ class KotlinToResolvedCallTransformer(
|
||||
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(context, deparenthesized) ?: updatedType
|
||||
}
|
||||
|
||||
|
||||
var reportErrorDuringTypeCheck = reportErrorForTypeMismatch
|
||||
|
||||
if (parameter != null && ImplicitIntegerCoercion.isEnabledForParameter(parameter)) {
|
||||
val argumentCompileTimeValue = context.trace[BindingContext.COMPILE_TIME_VALUE, deparenthesized]
|
||||
if (argumentCompileTimeValue != null && argumentCompileTimeValue.parameters.isConvertableConstVal) {
|
||||
@@ -329,7 +327,6 @@ class KotlinToResolvedCallTransformer(
|
||||
updatedType = argumentTypeResolver.updateResultArgumentTypeIfNotDenotable(
|
||||
context.trace, context.statementFilter, context.expectedType, generalNumberType, expression
|
||||
)
|
||||
reportErrorDuringTypeCheck = true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -337,7 +334,7 @@ class KotlinToResolvedCallTransformer(
|
||||
|
||||
updatedType = updateRecordedTypeForArgument(updatedType, recordedType, expression, context)
|
||||
|
||||
dataFlowAnalyzer.checkType(updatedType, deparenthesized, context, reportErrorDuringTypeCheck)
|
||||
dataFlowAnalyzer.checkType(updatedType, deparenthesized, context, false)
|
||||
|
||||
return updatedType
|
||||
}
|
||||
@@ -690,32 +687,44 @@ class NewResolvedCallImpl<D : CallableDescriptor>(
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
resultingDescriptor = run {
|
||||
val candidateDescriptor = resolvedCallAtom.candidateDescriptor
|
||||
val containsCapturedTypes = resolvedCallAtom.candidateDescriptor.returnType?.contains { it is NewCapturedType } ?: false
|
||||
val containsIntegerLiteralTypes = resolvedCallAtom.candidateDescriptor.returnType?.contains { it.constructor is IntegerLiteralTypeConstructor } ?: false
|
||||
val containsIntegerLiteralTypes = resolvedCallAtom.candidateDescriptor.returnType?.contains {
|
||||
it.constructor is IntegerLiteralTypeConstructor
|
||||
} ?: false
|
||||
|
||||
when {
|
||||
candidateDescriptor is FunctionDescriptor ||
|
||||
(candidateDescriptor is PropertyDescriptor && (candidateDescriptor.typeParameters.isNotEmpty() || containsCapturedTypes || containsIntegerLiteralTypes)) ->
|
||||
(candidateDescriptor is PropertyDescriptor && candidateDescriptor.typeParameters.isNotEmpty() || containsIntegerLiteralTypes) ->
|
||||
// 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
|
||||
)
|
||||
candidateDescriptor.substituteAndApproximateIntegerLiteralTypes(resolvedCallAtom.substitutor).let {
|
||||
if (substitutor != null) {
|
||||
it.substitute(substitutor)
|
||||
} else {
|
||||
it
|
||||
}
|
||||
}
|
||||
|
||||
else ->
|
||||
candidateDescriptor
|
||||
}
|
||||
} as D
|
||||
|
||||
typeArguments = resolvedCallAtom.substitutor.freshVariables.map {
|
||||
val substituted = (substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
|
||||
TypeApproximator(substituted.constructor.builtIns)
|
||||
.approximateToSuperType(substituted, TypeApproximatorConfiguration.IntegerLiteralsTypesApproximation)
|
||||
?: substituted
|
||||
(substitutor ?: FreshVariableNewTypeSubstitutor.Empty).safeSubstitute(it.defaultType)
|
||||
}
|
||||
|
||||
calculateExpectedTypeForSamConvertedArgumentMap(substitutor)
|
||||
}
|
||||
|
||||
fun approximateCapturedTypesAndHackSetters() {
|
||||
val approximator = TypeApproximator(resultingDescriptor.builtIns)
|
||||
resultingDescriptor = resultingDescriptor.hackSettersAccordingToCapturedOutTypes()
|
||||
resultingDescriptor = resultingDescriptor.approximateCapturedTypes()
|
||||
typeArguments = typeArguments.map {
|
||||
approximator.approximateToSuperType(it, TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation) ?: it
|
||||
}
|
||||
}
|
||||
|
||||
fun getExpectedTypeForSamConvertedArgument(valueArgument: ValueArgument): UnwrappedType? =
|
||||
expedtedTypeForSamConvertedArgumentMap?.get(valueArgument)
|
||||
|
||||
@@ -808,3 +817,41 @@ fun NewResolvedCallImpl<*>.hasInferredReturnType(): Boolean {
|
||||
val returnType = this.resultingDescriptor.returnType ?: return false
|
||||
return !returnType.contains { ErrorUtils.isUninferredParameter(it) }
|
||||
}
|
||||
|
||||
fun ResolvedCall<*>.approximateCapturedTypesAndHackSetters() {
|
||||
when (this) {
|
||||
is NewResolvedCallImpl<*> -> approximateCapturedTypesAndHackSetters()
|
||||
is NewVariableAsFunctionResolvedCallImpl -> {
|
||||
functionCall.approximateCapturedTypesAndHackSetters()
|
||||
variableCall.approximateCapturedTypesAndHackSetters()
|
||||
}
|
||||
else -> throw UnsupportedOperationException("Illegal resolved call: $this")
|
||||
}
|
||||
}
|
||||
|
||||
fun <D : CallableDescriptor> D.hackSettersAccordingToCapturedOutTypes(): D {
|
||||
return when (this) {
|
||||
is PropertyDescriptorImpl -> hackSettersAccordingToCapturedOutTypes() as D
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
private fun PropertyDescriptorImpl.hackSettersAccordingToCapturedOutTypes(): PropertyDescriptor {
|
||||
val setter = setter ?: return this
|
||||
val valueParameter = setter.valueParameters.first()
|
||||
val inputType = valueParameter.type
|
||||
val approximatedType = TypeApproximator(builtIns).approximateToSubType(
|
||||
inputType.unwrap(),
|
||||
TypeApproximatorConfiguration.CapturedAndIntegerLiteralsTypesApproximation
|
||||
) ?: return this
|
||||
|
||||
val newProperty = newCopyBuilder().setOriginal(original).build() as PropertyDescriptorImpl
|
||||
|
||||
val newSetter = with(setter) {
|
||||
PropertySetterDescriptorImpl(newProperty, annotations, modality, visibility, isDefault, isExternal, isInline, kind, original, source)
|
||||
}
|
||||
newSetter.initialize(PropertySetterDescriptorImpl.createSetterParameter(newSetter, approximatedType, setter.annotations))
|
||||
newProperty.initialize(getter, newSetter, backingField, delegateField)
|
||||
newProperty.isSetterProjectedOut = true
|
||||
return newProperty
|
||||
}
|
||||
@@ -382,6 +382,7 @@ class PSICallResolver(
|
||||
|
||||
return cache.getOrPut(implicitReceiver) {
|
||||
context.transformToReceiverWithSmartCastInfo(implicitReceiver.value)
|
||||
.prepareReceiverRegardingCaptureTypes()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +110,7 @@ class ResolvedAtomCompleter(
|
||||
|
||||
kotlinToResolvedCallTransformer.reportDiagnostics(topLevelCallContext, topLevelTrace, resolvedCall, diagnostics)
|
||||
|
||||
resolvedCall.approximateCapturedTypesAndHackSetters()
|
||||
return resolvedCall
|
||||
}
|
||||
|
||||
@@ -155,9 +156,7 @@ class ResolvedAtomCompleter(
|
||||
.replaceBindingTrace(topLevelTrace)
|
||||
|
||||
val argumentExpression = resultValueArgument.valueArgument.getArgumentExpression() ?: continue
|
||||
kotlinToResolvedCallTransformer.updateRecordedType(
|
||||
argumentExpression, parameter = null, context = newContext, reportErrorForTypeMismatch = true
|
||||
)
|
||||
kotlinToResolvedCallTransformer.updateRecordedType(argumentExpression, parameter = null, context = newContext)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,8 +190,8 @@ class ResolvedAtomCompleter(
|
||||
val substitutedFunctionalType = createFunctionType(
|
||||
builtIns,
|
||||
existingLambdaType.annotations,
|
||||
lambda.receiver?.let { resultSubstitutor.substituteKeepAnnotations(it) },
|
||||
lambda.parameters.map { resultSubstitutor.substituteKeepAnnotations(it) },
|
||||
lambda.receiver?.let { resultSubstitutor.safeSubstitute(it) },
|
||||
lambda.parameters.map { resultSubstitutor.safeSubstitute(it) },
|
||||
null, // parameter names transforms to special annotations, so they are already taken from parameter types
|
||||
returnType,
|
||||
lambda.isSuspend
|
||||
@@ -208,7 +207,7 @@ class ResolvedAtomCompleter(
|
||||
}
|
||||
|
||||
val valueType = receiver.value.type.unwrap()
|
||||
val newValueType = resultSubstitutor.substituteKeepAnnotations(valueType)
|
||||
val newValueType = resultSubstitutor.safeSubstitute(valueType)
|
||||
|
||||
if (valueType !== newValueType) {
|
||||
val newReceiverValue = receiver.value.replaceType(newValueType)
|
||||
|
||||
@@ -181,7 +181,9 @@ class InlineAnalyzerExtension(
|
||||
}
|
||||
if (hasInlineArgs) return
|
||||
|
||||
if (functionDescriptor.isInlineOnlyOrReifiable() || functionDescriptor.isExpect || functionDescriptor.isSuspend) return
|
||||
if (functionDescriptor.isInlineWithReified() || functionDescriptor.isInlineOnly() || functionDescriptor.isExpect ||
|
||||
functionDescriptor.isSuspend
|
||||
) return
|
||||
|
||||
if (reasonableInlineRules.any { it.isInlineReasonable(functionDescriptor, function, trace.bindingContext) }) return
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -14,17 +14,30 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
|
||||
private val INLINE_ONLY_ANNOTATION_FQ_NAME = FqName("kotlin.internal.InlineOnly")
|
||||
|
||||
fun MemberDescriptor.isInlineOnlyOrReifiable(): Boolean =
|
||||
this is CallableMemberDescriptor && (isReifiable() || DescriptorUtils.getDirectMember(this).isReifiable() || isInlineOnly())
|
||||
|
||||
/**
|
||||
* @return true if it's impossible to observe a call instruction referencing this member in the bytecode.
|
||||
*/
|
||||
fun MemberDescriptor.isEffectivelyInlineOnly(): Boolean =
|
||||
isInlineOnlyOrReifiable() || (this is FunctionDescriptor && isSuspend && isInline &&
|
||||
(valueParameters.any { it.isCrossinline } || visibility == Visibilities.PRIVATE))
|
||||
isInlineWithReified() || isInlineOnlyPrivateInBytecode()
|
||||
|
||||
/**
|
||||
* @return true if this member should be private in bytecode because it's effectively inline-only.
|
||||
*/
|
||||
fun MemberDescriptor.isInlineOnlyPrivateInBytecode(): Boolean =
|
||||
isInlineOnly() || isPrivateInlineSuspend()
|
||||
|
||||
fun MemberDescriptor.isInlineOnly(): Boolean =
|
||||
this is FunctionDescriptor && isInline &&
|
||||
(hasInlineOnlyAnnotation() || DescriptorUtils.getDirectMember(this).hasInlineOnlyAnnotation())
|
||||
|
||||
private fun CallableMemberDescriptor.isReifiable() = typeParameters.any { it.isReified }
|
||||
private fun MemberDescriptor.isPrivateInlineSuspend(): Boolean =
|
||||
this is FunctionDescriptor && isSuspend && isInline && visibility == Visibilities.PRIVATE
|
||||
|
||||
private fun CallableMemberDescriptor.hasInlineOnlyAnnotation() = annotations.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)
|
||||
fun MemberDescriptor.isInlineWithReified(): Boolean =
|
||||
this is CallableMemberDescriptor && (hasReifiedParameters() || DescriptorUtils.getDirectMember(this).hasReifiedParameters())
|
||||
|
||||
private fun CallableMemberDescriptor.hasReifiedParameters(): Boolean =
|
||||
typeParameters.any { it.isReified }
|
||||
|
||||
private fun CallableMemberDescriptor.hasInlineOnlyAnnotation(): Boolean =
|
||||
annotations.hasAnnotation(INLINE_ONLY_ANNOTATION_FQ_NAME)
|
||||
|
||||
@@ -24,10 +24,12 @@ import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.SubstitutingScopeProvider
|
||||
import org.jetbrains.kotlin.types.WrappedTypeFactory
|
||||
|
||||
interface LazyClassContext {
|
||||
val declarationScopeProvider: DeclarationScopeProvider
|
||||
val substitutingScopeProvider: SubstitutingScopeProvider
|
||||
|
||||
val storageManager: StorageManager
|
||||
val trace: BindingTrace
|
||||
|
||||
@@ -44,6 +44,7 @@ import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyPackageDescriptor;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.storage.*;
|
||||
import org.jetbrains.kotlin.types.SubstitutingScopeProvider;
|
||||
import org.jetbrains.kotlin.types.WrappedTypeFactory;
|
||||
import org.jetbrains.kotlin.utils.SmartList;
|
||||
|
||||
@@ -81,6 +82,7 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
|
||||
private DelegationFilter delegationFilter;
|
||||
private WrappedTypeFactory wrappedTypeFactory;
|
||||
private PlatformDiagnosticSuppressor platformDiagnosticSuppressor;
|
||||
private SubstitutingScopeProvider substitutingScopeProvider;
|
||||
|
||||
private final SyntheticResolveExtension syntheticResolveExtension;
|
||||
|
||||
@@ -146,6 +148,17 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
|
||||
this.platformDiagnosticSuppressor = platformDiagnosticSuppressor;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public SubstitutingScopeProvider getSubstitutingScopeProvider() {
|
||||
return substitutingScopeProvider;
|
||||
}
|
||||
|
||||
@Inject
|
||||
public void setSubstitutingScopeProvider(SubstitutingScopeProvider substitutingScopeProvider) {
|
||||
this.substitutingScopeProvider = substitutingScopeProvider;
|
||||
}
|
||||
|
||||
// Only calls from injectors expected
|
||||
@Deprecated
|
||||
public ResolveSession(
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.LazyClassContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.AbstractPsiBasedDeclarationProvider
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProvider
|
||||
@@ -129,7 +130,8 @@ protected constructor(
|
||||
getScopeForInitializerResolution(propertyDeclaration),
|
||||
propertyDeclaration,
|
||||
trace,
|
||||
c.declarationScopeProvider.getOuterDataFlowInfoForDeclaration(propertyDeclaration)
|
||||
c.declarationScopeProvider.getOuterDataFlowInfoForDeclaration(propertyDeclaration),
|
||||
InferenceSession.default
|
||||
)
|
||||
result.add(propertyDescriptor)
|
||||
}
|
||||
@@ -141,7 +143,8 @@ protected constructor(
|
||||
getScopeForInitializerResolution(entry),
|
||||
entry,
|
||||
trace,
|
||||
c.declarationScopeProvider.getOuterDataFlowInfoForDeclaration(entry)
|
||||
c.declarationScopeProvider.getOuterDataFlowInfoForDeclaration(entry),
|
||||
InferenceSession.default
|
||||
)
|
||||
result.add(propertyDescriptor)
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
) {
|
||||
super(c.getStorageManager(), containingDeclaration, name,
|
||||
KotlinSourceElementKt.toSourceElement(classLikeInfo.getCorrespondingClassOrObject()),
|
||||
isExternal
|
||||
isExternal, c.getSubstitutingScopeProvider()
|
||||
);
|
||||
this.c = c;
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. 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.types
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.OldCapturedTypeCreator
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope
|
||||
import org.jetbrains.kotlin.types.typesApproximation.OldCaptureTypeApproximator
|
||||
|
||||
class SubstitutingScopeProviderImpl(private val languageVersionSettings: LanguageVersionSettings) : SubstitutingScopeProvider {
|
||||
override val isNewInferenceEnabled: Boolean get() = languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
|
||||
|
||||
override fun createSubstitutingScope(workerScope: MemberScope, givenSubstitutor: TypeSubstitutor): SubstitutingScope {
|
||||
return SubstitutingScope(workerScope, givenSubstitutor, this)
|
||||
}
|
||||
|
||||
override fun provideApproximator(): CapturedTypeApproximator {
|
||||
return if (isNewInferenceEnabled) {
|
||||
NoCapturedTypeApproximator
|
||||
} else {
|
||||
OldCaptureTypeApproximator()
|
||||
}
|
||||
}
|
||||
|
||||
override fun provideCapturedTypeCreator(): CapturedTypeCreator {
|
||||
return if (isNewInferenceEnabled) {
|
||||
NoCapturedTypeCreator
|
||||
} else {
|
||||
OldCapturedTypeCreator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object NoCapturedTypeCreator : CapturedTypeCreator {
|
||||
override fun createCapturedType(typeProjection: TypeProjection): TypeProjection {
|
||||
return typeProjection
|
||||
}
|
||||
}
|
||||
|
||||
object NoCapturedTypeApproximator : CapturedTypeApproximator {
|
||||
override fun approximateCapturedTypes(typeProjection: TypeProjection?, approximateContravariant: Boolean): TypeProjection? {
|
||||
return typeProjection
|
||||
}
|
||||
}
|
||||
@@ -958,6 +958,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
|
||||
boolean result = true;
|
||||
KtExpression reportOn = expression != null ? expression : expressionWithParenthesis;
|
||||
KtExpression originalReportOn = reportOn;
|
||||
if (reportOn instanceof KtQualifiedExpression) {
|
||||
KtExpression selector = ((KtQualifiedExpression) reportOn).getSelectorExpression();
|
||||
if (selector != null)
|
||||
@@ -968,14 +969,19 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variable;
|
||||
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
|
||||
if (propertyDescriptor.isSetterProjectedOut()) {
|
||||
trace.report(SETTER_PROJECTED_OUT.on(reportOn, propertyDescriptor));
|
||||
trace.report(SETTER_PROJECTED_OUT.on(originalReportOn, propertyDescriptor));
|
||||
result = false;
|
||||
}
|
||||
else if (setter != null) {
|
||||
ResolvedCall<?> resolvedCall = CallUtilKt.getResolvedCall(expressionWithParenthesis, context.trace.getBindingContext());
|
||||
assert resolvedCall != null
|
||||
: "Call is not resolved for property setter: " + PsiUtilsKt.getElementTextWithContext(expressionWithParenthesis);
|
||||
checkPropertySetterCall(context.replaceBindingTrace(trace), setter, resolvedCall, reportOn);
|
||||
if (((PropertyDescriptor)resolvedCall.getResultingDescriptor()).isSetterProjectedOut()) {
|
||||
trace.report(SETTER_PROJECTED_OUT.on(originalReportOn, propertyDescriptor));
|
||||
result = false;
|
||||
} else {
|
||||
checkPropertySetterCall(context.replaceBindingTrace(trace), setter, resolvedCall, reportOn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1717,15 +1723,9 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
context, call, arrayAccessExpression, isGet ? OperatorNameConventions.GET : OperatorNameConventions.SET);
|
||||
|
||||
List<KtExpression> indices = arrayAccessExpression.getIndexExpressions();
|
||||
// The accumulated data flow info of all index expressions is saved on the last index
|
||||
KotlinTypeInfo resultTypeInfo = arrayTypeInfo;
|
||||
if (!indices.isEmpty()) {
|
||||
resultTypeInfo = facade.getTypeInfo(indices.get(indices.size() - 1), context);
|
||||
}
|
||||
|
||||
if (!isGet) {
|
||||
resultTypeInfo = facade.getTypeInfo(rightHandSide, context);
|
||||
}
|
||||
KotlinTypeInfo resultTypeInfo =
|
||||
computeAccumulatedInfoForArrayAccessExpression(arrayTypeInfo, indices, rightHandSide, isGet, context, facade);
|
||||
|
||||
if ((isImplicit && !functionResults.isSuccess()) || !functionResults.isSingleResult()) {
|
||||
traceForResolveResult.report(isGet ? NO_GET_METHOD.on(arrayAccessExpression) : NO_SET_METHOD.on(arrayAccessExpression));
|
||||
@@ -1735,4 +1735,40 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
functionResults.getResultingCall());
|
||||
return resultTypeInfo.replaceType(functionResults.getResultingDescriptor().getReturnType());
|
||||
}
|
||||
|
||||
private static KotlinTypeInfo computeAccumulatedInfoForArrayAccessExpression(
|
||||
@NotNull KotlinTypeInfo arrayTypeInfo,
|
||||
@NotNull List<KtExpression> indices,
|
||||
@Nullable KtExpression rightHandSide,
|
||||
boolean isGet,
|
||||
@NotNull ExpressionTypingContext context,
|
||||
@NotNull ExpressionTypingInternals facade
|
||||
) {
|
||||
KotlinTypeInfo accumulatedTypeInfo = null;
|
||||
boolean forceResolve = !context.languageVersionSettings.supportsFeature(LanguageFeature.NewInference);
|
||||
|
||||
// The accumulated data flow info of all index expressions is saved on the last index
|
||||
if (!indices.isEmpty()) {
|
||||
accumulatedTypeInfo = getTypeInfo(indices.get(indices.size() - 1), facade, context, forceResolve);
|
||||
}
|
||||
|
||||
if (!isGet && rightHandSide != null) {
|
||||
accumulatedTypeInfo = getTypeInfo(rightHandSide, facade, context, forceResolve);
|
||||
}
|
||||
|
||||
return accumulatedTypeInfo != null ? accumulatedTypeInfo : arrayTypeInfo;
|
||||
}
|
||||
|
||||
private static KotlinTypeInfo getTypeInfo(
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull ExpressionTypingInternals facade,
|
||||
@NotNull ExpressionTypingContext context,
|
||||
boolean forceExpressionResolve
|
||||
) {
|
||||
if (forceExpressionResolve) {
|
||||
return facade.getTypeInfo(expression, context);
|
||||
} else {
|
||||
return BindingContextUtils.getRecordedTypeInfo(expression, context.trace.getBindingContext());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.psi.psiUtil.PsiUtilsKt;
|
||||
import org.jetbrains.kotlin.resolve.*;
|
||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency;
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
|
||||
@@ -71,9 +72,10 @@ public class ExpressionTypingServices {
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull KotlinType expectedType,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull InferenceSession inferenceSession,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
KotlinType type = getType(scope, expression, expectedType, dataFlowInfo, trace);
|
||||
KotlinType type = getType(scope, expression, expectedType, dataFlowInfo, inferenceSession, trace);
|
||||
|
||||
return type != null ? type : ErrorUtils.createErrorType("Type for " + expression.getText());
|
||||
}
|
||||
@@ -84,10 +86,14 @@ public class ExpressionTypingServices {
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull KotlinType expectedType,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull InferenceSession inferenceSession,
|
||||
@NotNull BindingTrace trace,
|
||||
boolean isStatement
|
||||
) {
|
||||
return getTypeInfo(scope, expression, expectedType, dataFlowInfo, trace, isStatement, expression, ContextDependency.INDEPENDENT);
|
||||
return getTypeInfo(
|
||||
scope, expression, expectedType, dataFlowInfo, inferenceSession,
|
||||
trace, isStatement, expression, ContextDependency.INDEPENDENT
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -96,6 +102,7 @@ public class ExpressionTypingServices {
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull KotlinType expectedType,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull InferenceSession inferenceSession,
|
||||
@NotNull BindingTrace trace,
|
||||
boolean isStatement,
|
||||
@NotNull KtExpression contextExpression,
|
||||
@@ -103,7 +110,7 @@ public class ExpressionTypingServices {
|
||||
) {
|
||||
ExpressionTypingContext context = ExpressionTypingContext.newContext(
|
||||
trace, scope, dataFlowInfo, expectedType, contextDependency, statementFilter, getLanguageVersionSettings(),
|
||||
expressionTypingComponents.dataFlowValueFactory
|
||||
expressionTypingComponents.dataFlowValueFactory, inferenceSession
|
||||
);
|
||||
if (contextExpression != expression) {
|
||||
context = context.replaceExpressionContextProvider(arg -> arg == expression ? contextExpression : null);
|
||||
@@ -122,9 +129,10 @@ public class ExpressionTypingServices {
|
||||
@NotNull KtExpression expression,
|
||||
@NotNull KotlinType expectedType,
|
||||
@NotNull DataFlowInfo dataFlowInfo,
|
||||
@NotNull InferenceSession inferenceSession,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
return getTypeInfo(scope, expression, expectedType, dataFlowInfo, trace, false).getType();
|
||||
return getTypeInfo(scope, expression, expectedType, dataFlowInfo, inferenceSession, trace, false).getType();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.jetbrains.kotlin.resolve.lazy.descriptors.LazyClassDescriptor
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.types.SubstitutingScopeProvider
|
||||
import org.jetbrains.kotlin.types.WrappedTypeFactory
|
||||
|
||||
class LocalClassifierAnalyzer(
|
||||
@@ -65,7 +66,8 @@ class LocalClassifierAnalyzer(
|
||||
private val targetPlatformVersion: TargetPlatformVersion,
|
||||
private val languageVersionSettings: LanguageVersionSettings,
|
||||
private val delegationFilter: DelegationFilter,
|
||||
private val wrappedTypeFactory: WrappedTypeFactory
|
||||
private val wrappedTypeFactory: WrappedTypeFactory,
|
||||
private val substitutingScopeProvider: SubstitutingScopeProvider
|
||||
) {
|
||||
fun processClassOrObject(
|
||||
scope: LexicalWritableScope?,
|
||||
@@ -99,7 +101,8 @@ class LocalClassifierAnalyzer(
|
||||
languageVersionSettings,
|
||||
SyntheticResolveExtension.getInstance(project),
|
||||
delegationFilter,
|
||||
wrappedTypeFactory
|
||||
wrappedTypeFactory,
|
||||
substitutingScopeProvider
|
||||
)
|
||||
)
|
||||
|
||||
@@ -126,7 +129,8 @@ class LocalClassDescriptorHolder(
|
||||
val languageVersionSettings: LanguageVersionSettings,
|
||||
val syntheticResolveExtension: SyntheticResolveExtension,
|
||||
val delegationFilter: DelegationFilter,
|
||||
val wrappedTypeFactory: WrappedTypeFactory
|
||||
val wrappedTypeFactory: WrappedTypeFactory,
|
||||
val substitutingScopeProvider: SubstitutingScopeProvider
|
||||
) {
|
||||
// We do not need to synchronize here, because this code is used strictly from one thread
|
||||
private var classDescriptor: ClassDescriptor? = null
|
||||
@@ -166,6 +170,7 @@ class LocalClassDescriptorHolder(
|
||||
override val syntheticResolveExtension = this@LocalClassDescriptorHolder.syntheticResolveExtension
|
||||
override val delegationFilter: DelegationFilter = this@LocalClassDescriptorHolder.delegationFilter
|
||||
override val wrappedTypeFactory: WrappedTypeFactory = this@LocalClassDescriptorHolder.wrappedTypeFactory
|
||||
override val substitutingScopeProvider: SubstitutingScopeProvider = this@LocalClassDescriptorHolder.substitutingScopeProvider
|
||||
},
|
||||
containingDeclaration,
|
||||
classOrObject.nameAsSafeName,
|
||||
|
||||
@@ -2014,6 +2014,11 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
||||
runTest("jps-plugin/testData/incremental/withJava/other/multifilePackagePartMethodAdded/");
|
||||
}
|
||||
|
||||
@TestMetadata("multifilePartsWithProperties")
|
||||
public void testMultifilePartsWithProperties() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/withJava/other/multifilePartsWithProperties/");
|
||||
}
|
||||
|
||||
@TestMetadata("optionalParameter")
|
||||
public void testOptionalParameter() throws Exception {
|
||||
runTest("jps-plugin/testData/incremental/withJava/other/optionalParameter/");
|
||||
@@ -2322,6 +2327,19 @@ public class IncrementalJvmCompilerRunnerTestGenerated extends AbstractIncrement
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/other/multifilePartsWithProperties")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class MultifilePartsWithProperties extends AbstractIncrementalJvmCompilerRunnerTest {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.ANY, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInMultifilePartsWithProperties() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/withJava/other/multifilePartsWithProperties"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("jps-plugin/testData/incremental/withJava/other/optionalParameter")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -33,7 +33,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
|
||||
protected abstract val stateMachineMethodName: Name
|
||||
protected abstract fun getCoroutineBaseClass(function: IrFunction): IrClassSymbol
|
||||
|
||||
protected abstract fun nameForCoroutineClass(function: IrFunction): Name
|
||||
|
||||
protected abstract fun buildStateMachine(
|
||||
originalBody: IrBody, stateMachineFunction: IrFunction,
|
||||
@@ -258,8 +258,6 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
val stateMachineFunction: IrFunction
|
||||
)
|
||||
|
||||
private var coroutineId = 0
|
||||
|
||||
private inner class CoroutineBuilder(val irFunction: IrFunction, val functionReference: IrFunctionReference?) {
|
||||
|
||||
private val startOffset = irFunction.startOffset
|
||||
@@ -273,7 +271,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
startOffset, endOffset,
|
||||
DECLARATION_ORIGIN_COROUTINE_IMPL,
|
||||
IrClassSymbolImpl(d),
|
||||
"${irFunction.name}COROUTINE\$${coroutineId++}".synthesizedName,
|
||||
nameForCoroutineClass(irFunction),
|
||||
ClassKind.CLASS,
|
||||
irFunction.visibility,
|
||||
Modality.FINAL,
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower.coroutines
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.backend.common.ir.isSuspend
|
||||
import org.jetbrains.kotlin.backend.common.lower.AbstractSuspendFunctionsLowering
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -34,10 +35,13 @@ class JsSuspendFunctionsLowering(ctx: JsIrBackendContext) : AbstractSuspendFunct
|
||||
private val coroutineImplResultSymbolSetter = ctx.coroutineImplResultSymbolSetter
|
||||
|
||||
private var exceptionTrapId = -1
|
||||
private var coroutineId = 0
|
||||
|
||||
override val stateMachineMethodName = Name.identifier("doResume")
|
||||
override fun getCoroutineBaseClass(function: IrFunction) = context.ir.symbols.coroutineImpl
|
||||
|
||||
override fun nameForCoroutineClass(function: IrFunction) = "${function.name}COROUTINE\$${coroutineId++}".synthesizedName
|
||||
|
||||
override fun buildStateMachine(
|
||||
originalBody: IrBody,
|
||||
stateMachineFunction: IrFunction,
|
||||
|
||||
@@ -444,7 +444,7 @@ class StateMachineBuilder(
|
||||
|
||||
private fun transformArguments(arguments: Array<IrExpression?>): Array<IrExpression?> {
|
||||
|
||||
var suspendableCount = arguments.fold(0) { r, n -> if (n in suspendableNodes) r + 1 else r }
|
||||
var suspendableCount = arguments.fold(0) { r, n -> if (n != null && n in suspendableNodes) r + 1 else r }
|
||||
|
||||
val newArguments = arrayOfNulls<IrExpression>(arguments.size)
|
||||
|
||||
|
||||
@@ -359,11 +359,8 @@ private val Modality.flags: Int
|
||||
private val Visibility.flags: Int
|
||||
get() = AsmUtil.getVisibilityAccessFlag(this) ?: throw AssertionError("Unsupported visibility $this")
|
||||
|
||||
private val IrField.OtherOrigin: JvmDeclarationOrigin
|
||||
get() = OtherOrigin(descriptor.psiElement, this.descriptor)
|
||||
|
||||
internal val IrFunction.OtherOrigin: JvmDeclarationOrigin
|
||||
get() = OtherOrigin(descriptor.psiElement, this.descriptor)
|
||||
internal val IrDeclaration.OtherOrigin: JvmDeclarationOrigin
|
||||
get() = OtherOrigin(descriptor)
|
||||
|
||||
private fun IrClass.getSuperClassInfo(typeMapper: IrTypeMapper): IrSuperClassInfo {
|
||||
if (isInterface) {
|
||||
@@ -378,4 +375,4 @@ private fun IrClass.getSuperClassInfo(typeMapper: IrTypeMapper): IrSuperClassInf
|
||||
}
|
||||
|
||||
return IrSuperClassInfo(AsmTypes.OBJECT_TYPE, null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
/*
|
||||
* 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.
|
||||
* 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.backend.jvm.codegen
|
||||
@@ -66,7 +55,7 @@ class IrSourceCompilerForInline(
|
||||
get() = OwnerKind.getMemberOwnerKind(callElement.descriptor.containingDeclaration)
|
||||
|
||||
override val inlineCallSiteInfo: InlineCallSiteInfo
|
||||
get() = InlineCallSiteInfo("TODO", null, null, false)
|
||||
get() = InlineCallSiteInfo("TODO", null, null, false, false)
|
||||
|
||||
override val lazySourceMapper: DefaultSourceMapper
|
||||
get() = codegen.classCodegen.getOrCreateSourceMapper()
|
||||
|
||||
@@ -157,7 +157,11 @@ private class AdditionalClassAnnotationLowering(private val context: JvmBackendC
|
||||
private fun generateRetentionAnnotation(irClass: IrClass) {
|
||||
if (irClass.hasAnnotation(FqName("java.lang.annotation.Retention"))) return
|
||||
val kotlinRetentionPolicy = irClass.getAnnotation(FqName("kotlin.annotation.Retention"))
|
||||
val javaRetentionPolicy = annotationRetentionMap[kotlinRetentionPolicy] ?: rpRuntime
|
||||
val javaRetentionPolicy = if (kotlinRetentionPolicy is KotlinRetention) {
|
||||
annotationRetentionMap[kotlinRetentionPolicy] ?: rpRuntime
|
||||
} else {
|
||||
rpRuntime
|
||||
}
|
||||
|
||||
irClass.annotations.add(
|
||||
IrConstructorCallImpl.fromSymbolOwner(
|
||||
|
||||
@@ -61,7 +61,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
|
||||
get() = context.state.typeMapper.mapSignatureSkipGeneric(collectRealOverrides().first().descriptor).toString()
|
||||
|
||||
private val IrMemberAccessExpression.signature: String
|
||||
get() = localPropertyIndices[getter]?.let { "<v#$it>" }
|
||||
get() = getter?.let { getter -> localPropertyIndices[getter]?.let { "<v#$it>" } }
|
||||
?: (getter?.owner as? IrSimpleFunction)?.signature
|
||||
// Plain Java fields do not have a getter, but can be referenced nonetheless. The signature should be
|
||||
// the one that a getter would have, if it existed.
|
||||
|
||||
@@ -66,11 +66,10 @@ internal open class KtUltraLightField(
|
||||
private val kotlinType: KotlinType? by lazyPub {
|
||||
when {
|
||||
declaration is KtProperty && declaration.hasDelegate() ->
|
||||
propertyDescriptor
|
||||
?.let {
|
||||
val context = LightClassGenerationSupport.getInstance(project).analyze(declaration)
|
||||
PropertyCodegen.getDelegateTypeForProperty(declaration, it, context)
|
||||
}
|
||||
propertyDescriptor?.let {
|
||||
val context = LightClassGenerationSupport.getInstance(project).analyze(declaration)
|
||||
PropertyCodegen.getDelegateTypeForProperty(it, context)
|
||||
}
|
||||
declaration is KtObjectDeclaration ->
|
||||
(declaration.resolve() as? ClassDescriptor)?.defaultType
|
||||
declaration is KtEnumEntry -> {
|
||||
|
||||
@@ -417,7 +417,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
|
||||
override fun getOwnMethods(): List<KtLightMethod> = if (tooComplex) super.getOwnMethods() else _ownMethods
|
||||
|
||||
private fun asJavaMethods(ktFunction: KtFunction, forceStatic: Boolean, forcePrivate: Boolean = false): Collection<KtLightMethod> {
|
||||
if (ktFunction.hasAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME)) return emptyList()
|
||||
if (ktFunction.hasAnnotation(JVM_SYNTHETIC_ANNOTATION_FQ_NAME) || ktFunction.hasReifiedParameters()) return emptyList()
|
||||
|
||||
val basicMethod = asJavaMethod(ktFunction, forceStatic, forcePrivate)
|
||||
|
||||
@@ -540,7 +540,6 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
|
||||
|
||||
private fun KtDeclaration.isInlineOnly(): Boolean {
|
||||
if (this !is KtCallableDeclaration || !hasModifier(INLINE_KEYWORD)) return false
|
||||
if (typeParameters.any { it.hasModifier(REIFIED_KEYWORD) }) return true
|
||||
if (annotationEntries.isEmpty()) return false
|
||||
|
||||
val descriptor = resolve() as? CallableMemberDescriptor ?: return false
|
||||
@@ -588,7 +587,7 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
|
||||
|
||||
private fun propertyAccessors(declaration: KtCallableDeclaration, mutable: Boolean, onlyJvmStatic: Boolean): List<KtLightMethod> {
|
||||
val propertyName = declaration.name ?: return emptyList()
|
||||
if (declaration.isConstOrJvmField()) return emptyList()
|
||||
if (declaration.isConstOrJvmField() || declaration.hasReifiedParameters()) return emptyList()
|
||||
|
||||
val ktGetter = (declaration as? KtProperty)?.getter
|
||||
val ktSetter = (declaration as? KtProperty)?.setter
|
||||
@@ -654,6 +653,9 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor
|
||||
!declaration.hasModifier(ABSTRACT_KEYWORD)
|
||||
}
|
||||
|
||||
private fun KtCallableDeclaration.hasReifiedParameters(): Boolean =
|
||||
typeParameters.any { it.hasModifier(REIFIED_KEYWORD) }
|
||||
|
||||
override fun getInitializers(): Array<PsiClassInitializer> = emptyArray()
|
||||
|
||||
override fun getContainingClass(): PsiClass? =
|
||||
|
||||
@@ -137,6 +137,8 @@ open class KtLightMethodImpl protected constructor(
|
||||
override fun getTypeParameters(): Array<PsiTypeParameter> =
|
||||
typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
|
||||
|
||||
override fun hasTypeParameters() = typeParameters.isNotEmpty()
|
||||
|
||||
override fun getSignature(substitutor: PsiSubstitutor): MethodSignature {
|
||||
if (substitutor == PsiSubstitutor.EMPTY) {
|
||||
return clsDelegate.getSignature(substitutor)
|
||||
@@ -218,8 +220,6 @@ open class KtLightMethodImpl protected constructor(
|
||||
|
||||
override fun getThrowsList() = clsDelegate.throwsList
|
||||
|
||||
override fun hasTypeParameters() = clsDelegate.hasTypeParameters()
|
||||
|
||||
override fun isVarArgs() = (dummyDelegate ?: clsDelegate).isVarArgs
|
||||
|
||||
override fun isConstructor() = dummyDelegate?.isConstructor ?: clsDelegate.isConstructor
|
||||
|
||||
@@ -18,10 +18,7 @@ package org.jetbrains.kotlin.kdoc.psi.impl
|
||||
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.PsiReference
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
|
||||
import org.jetbrains.kotlin.psi.KtElementImpl
|
||||
import org.jetbrains.kotlin.kdoc.psi.api.KDoc
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
|
||||
class KDocLink(node: ASTNode) : KtElementImpl(node) {
|
||||
@@ -42,7 +39,4 @@ class KDocLink(node: ASTNode) : KtElementImpl(node) {
|
||||
val tag = getStrictParentOfType<KDocTag>()
|
||||
return if (tag != null && tag.getSubjectLink() == this) tag else null
|
||||
}
|
||||
|
||||
override fun getReferences(): Array<out PsiReference> =
|
||||
ReferenceProvidersRegistry.getReferencesFromProviders(this)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2010-2019 JetBrains s.r.o. 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.psi
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiReference
|
||||
|
||||
open class KotlinReferenceProvidersService {
|
||||
open fun getReferences(psiElement: PsiElement): Array<PsiReference> = PsiReference.EMPTY_ARRAY
|
||||
|
||||
companion object {
|
||||
private val NO_REFERENCES_SERVICE = KotlinReferenceProvidersService()
|
||||
|
||||
@JvmStatic
|
||||
fun getInstance(): KotlinReferenceProvidersService {
|
||||
return ServiceManager.getService(KotlinReferenceProvidersService::class.java) ?: NO_REFERENCES_SERVICE
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun getReferencesFromProviders(psiElement: PsiElement): Array<PsiReference> {
|
||||
return getInstance().getReferences(psiElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,8 +18,9 @@ package org.jetbrains.kotlin.psi;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiModifiableCodeBlock;
|
||||
import com.intellij.psi.impl.source.tree.CompositeElement;
|
||||
import com.intellij.psi.impl.source.tree.LazyParseablePsiElement;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
@@ -94,14 +95,6 @@ public class KtBlockExpression extends LazyParseablePsiElement implements KtElem
|
||||
super.delete();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public PsiReference getReference() {
|
||||
PsiReference[] references = getReferences();
|
||||
if (references.length == 1) return references[0];
|
||||
else return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PsiElement[] getChildren() {
|
||||
@@ -118,12 +111,6 @@ public class KtBlockExpression extends LazyParseablePsiElement implements KtElem
|
||||
return result == null ? PsiElement.EMPTY_ARRAY : PsiUtilCore.toPsiElementArray(result);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferences() {
|
||||
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public KtElement getPsiOrParent() {
|
||||
|
||||
@@ -19,8 +19,10 @@ package org.jetbrains.kotlin.psi;
|
||||
import com.intellij.extapi.psi.ASTWrapperPsiElement;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.idea.KotlinLanguage;
|
||||
@@ -92,7 +94,7 @@ public class KtElementImpl extends ASTWrapperPsiElement implements KtElement {
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferences() {
|
||||
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
|
||||
return KotlinReferenceProvidersService.getReferencesFromProviders(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.intellij.extapi.psi.StubBasedPsiElementBase;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
|
||||
import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
@@ -109,7 +108,7 @@ public class KtElementImplStub<T extends StubElement<?>> extends StubBasedPsiEle
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiReference[] getReferences() {
|
||||
return ReferenceProvidersRegistry.getReferencesFromProviders(this, PsiReferenceService.Hints.NO_HINTS);
|
||||
return KotlinReferenceProvidersService.getReferencesFromProviders(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -17,10 +17,7 @@
|
||||
package org.jetbrains.kotlin.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.ElementManipulators;
|
||||
import com.intellij.psi.LiteralTextEscaper;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiLanguageInjectionHost;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -28,7 +25,8 @@ import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub;
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes;
|
||||
|
||||
public class KtStringTemplateExpression extends KtElementImplStub<KotlinPlaceHolderStub<KtStringTemplateExpression>> implements KtExpression, PsiLanguageInjectionHost {
|
||||
public class KtStringTemplateExpression extends KtElementImplStub<KotlinPlaceHolderStub<KtStringTemplateExpression>>
|
||||
implements KtExpression, PsiLanguageInjectionHost, ContributedReferenceHost {
|
||||
private static final TokenSet CLOSE_QUOTE_TOKEN_SET = TokenSet.create(KtTokens.CLOSING_QUOTE);
|
||||
|
||||
public KtStringTemplateExpression(@NotNull ASTNode node) {
|
||||
|
||||
@@ -25,10 +25,13 @@ import com.intellij.psi.impl.source.tree.TreeUtil
|
||||
import com.intellij.psi.search.PsiSearchScopeUtil
|
||||
import com.intellij.psi.search.SearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import java.util.*
|
||||
import kotlin.contracts.ExperimentalContracts
|
||||
import kotlin.contracts.contract
|
||||
|
||||
// NOTE: in this file we collect only LANGUAGE INDEPENDENT methods working with PSI and not modifying it
|
||||
|
||||
@@ -477,3 +480,11 @@ fun LazyParseablePsiElement.getContainingKtFile(): KtFile {
|
||||
val fileString = if (file != null && file.isValid) file.text else ""
|
||||
throw IllegalStateException("KtElement not inside KtFile: $file with text \"$fileString\" for element $this of type ${this::class.java} node = ${this.node}")
|
||||
}
|
||||
|
||||
@UseExperimental(ExperimentalContracts::class)
|
||||
fun KtExpression.isNull(): Boolean {
|
||||
contract {
|
||||
returns(true) implies (this@isNull is KtConstantExpression)
|
||||
}
|
||||
return this is KtConstantExpression && this.node.elementType == KtNodeTypes.NULL
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.contracts.description
|
||||
|
||||
import org.jetbrains.kotlin.contracts.interpretation.ContractInterpretationDispatcher
|
||||
import org.jetbrains.kotlin.contracts.model.ESComponents
|
||||
import org.jetbrains.kotlin.contracts.model.Functor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -40,12 +39,11 @@ open class ContractDescription(
|
||||
val ownerFunction: FunctionDescriptor,
|
||||
storageManager: StorageManager
|
||||
) {
|
||||
private val computeFunctor = storageManager.createMemoizedFunctionWithNullableValues<ModuleDescriptor, Functor> { module ->
|
||||
val components = ESComponents(module.builtIns)
|
||||
ContractInterpretationDispatcher(components).convertContractDescriptorToFunctor(this)
|
||||
private val computeFunctor = storageManager.createNullableLazyValue {
|
||||
ContractInterpretationDispatcher().convertContractDescriptorToFunctor(this)
|
||||
}
|
||||
|
||||
fun getFunctor(usageModule: ModuleDescriptor): Functor? = computeFunctor(usageModule)
|
||||
fun getFunctor(usageModule: ModuleDescriptor): Functor? = computeFunctor.invoke()
|
||||
}
|
||||
|
||||
interface ContractDescriptionElement {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user