Merge commits from both masters and update to 1.5.0-dev-500 compiler
Kotlin/Native base commit: ed1035eb82d63dde60823852276901aaeacb644b
This commit is contained in:
@@ -1,7 +1,4 @@
|
|||||||
201
|
|
||||||
202
|
202
|
||||||
203_202
|
201
|
||||||
193
|
as41_201
|
||||||
as40_193
|
as42
|
||||||
as41
|
|
||||||
as42_202
|
|
||||||
Generated
+1
@@ -10,6 +10,7 @@
|
|||||||
<w>commonizers</w>
|
<w>commonizers</w>
|
||||||
<w>commonizes</w>
|
<w>commonizes</w>
|
||||||
<w>commonizing</w>
|
<w>commonizing</w>
|
||||||
|
<w>interop</w>
|
||||||
<w>jetbrains</w>
|
<w>jetbrains</w>
|
||||||
<w>konan</w>
|
<w>konan</w>
|
||||||
<w>kotlinx</w>
|
<w>kotlinx</w>
|
||||||
|
|||||||
+1304
File diff suppressed because it is too large
Load Diff
+2697
File diff suppressed because it is too large
Load Diff
+2042
File diff suppressed because it is too large
Load Diff
+3879
File diff suppressed because it is too large
Load Diff
+143
-10045
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,10 @@
|
|||||||
|
|
||||||
# Kotlin Programming Language
|
# Kotlin Programming Language
|
||||||
|
|
||||||
Welcome to [Kotlin](https://kotlinlang.org/)! Some handy links:
|
Welcome to [Kotlin](https://kotlinlang.org/)!
|
||||||
|
It is an open-source, statically typed programming language supported and developed by [JetBrains](https://www.jetbrains.com/) and open-source contributors.
|
||||||
|
|
||||||
|
Some handy links:
|
||||||
|
|
||||||
* [Kotlin Site](https://kotlinlang.org/)
|
* [Kotlin Site](https://kotlinlang.org/)
|
||||||
* [Getting Started Guide](https://kotlinlang.org/docs/tutorials/getting-started.html)
|
* [Getting Started Guide](https://kotlinlang.org/docs/tutorials/getting-started.html)
|
||||||
|
|||||||
+4
-2
@@ -188,7 +188,7 @@ extra["versions.kotlinx-collections-immutable-jvm"] = immutablesVersion
|
|||||||
extra["versions.ktor-network"] = "1.0.1"
|
extra["versions.ktor-network"] = "1.0.1"
|
||||||
|
|
||||||
if (!project.hasProperty("versions.kotlin-native")) {
|
if (!project.hasProperty("versions.kotlin-native")) {
|
||||||
extra["versions.kotlin-native"] = "1.4.30-dev-17200"
|
extra["versions.kotlin-native"] = "1.4.30-dev-17395"
|
||||||
}
|
}
|
||||||
|
|
||||||
val intellijUltimateEnabled by extra(project.kotlinBuildProperties.intellijUltimateEnabled)
|
val intellijUltimateEnabled by extra(project.kotlinBuildProperties.intellijUltimateEnabled)
|
||||||
@@ -467,7 +467,7 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<Test> {
|
tasks.withType<Test> {
|
||||||
outputs.doNotCacheIf("https://youtrack.jetbrains.com/issue/KT-37089") { true }
|
outputs.doNotCacheIf("https://youtrack.jetbrains.com/issue/KTI-112") { !isTestDistributionEnabled() }
|
||||||
}
|
}
|
||||||
|
|
||||||
normalization {
|
normalization {
|
||||||
@@ -854,6 +854,8 @@ tasks {
|
|||||||
|
|
||||||
register("kaptIdeTest") {
|
register("kaptIdeTest") {
|
||||||
dependsOn(":kotlin-annotation-processing:test")
|
dependsOn(":kotlin-annotation-processing:test")
|
||||||
|
dependsOn(":kotlin-annotation-processing-base:test")
|
||||||
|
dependsOn(":kotlin-annotation-processing-cli:test")
|
||||||
}
|
}
|
||||||
|
|
||||||
register("gradleIdeTest") {
|
register("gradleIdeTest") {
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ dependencies {
|
|||||||
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.5")
|
implementation("gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext:0.5")
|
||||||
|
|
||||||
implementation("org.gradle:test-retry-gradle-plugin:1.1.9")
|
implementation("org.gradle:test-retry-gradle-plugin:1.1.9")
|
||||||
|
implementation("com.gradle.enterprise:test-distribution-gradle-plugin:1.2.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
samWithReceiver {
|
samWithReceiver {
|
||||||
|
|||||||
@@ -54,11 +54,12 @@ var Project.javaHome: String?
|
|||||||
extra["javaHome"] = v
|
extra["javaHome"] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Project.generator(fqName: String, sourceSet: SourceSet? = null) = smartJavaExec {
|
fun Project.generator(fqName: String, sourceSet: SourceSet? = null, configure: JavaExec.() -> Unit = {}) = smartJavaExec {
|
||||||
classpath = (sourceSet ?: testSourceSet).runtimeClasspath
|
classpath = (sourceSet ?: testSourceSet).runtimeClasspath
|
||||||
mainClass.set(fqName)
|
mainClass.set(fqName)
|
||||||
workingDir = rootDir
|
workingDir = rootDir
|
||||||
systemProperty("line.separator", "\n")
|
systemProperty("line.separator", "\n")
|
||||||
|
configure()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Project.getBooleanProperty(name: String): Boolean? = this.findProperty(name)?.let {
|
fun Project.getBooleanProperty(name: String): Boolean? = this.findProperty(name)?.let {
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.gradle.enterprise.gradleplugin.testdistribution.TestDistributionExtension
|
||||||
|
import org.gradle.api.tasks.testing.Test
|
||||||
|
import org.gradle.internal.os.OperatingSystem
|
||||||
|
|
||||||
|
|
||||||
|
fun Test.configureTestDistribution(configure: TestDistributionExtension.() -> Unit = {}) {
|
||||||
|
val isTeamcityBuild = project.kotlinBuildProperties.isTeamcityBuild
|
||||||
|
val testDistributionEnabled = project.findProperty("kotlin.build.test.distribution.enabled")?.toString()?.toBoolean()
|
||||||
|
?: isTeamcityBuild
|
||||||
|
|
||||||
|
useJUnitPlatform()
|
||||||
|
extensions.configure(TestDistributionExtension::class.java) {
|
||||||
|
enabled.set(testDistributionEnabled)
|
||||||
|
maxRemoteExecutors.set(20)
|
||||||
|
if (isTeamcityBuild) {
|
||||||
|
requirements.set(setOf("os=${OperatingSystem.current().familyName}"))
|
||||||
|
} else {
|
||||||
|
maxLocalExecutors.set(0)
|
||||||
|
}
|
||||||
|
configure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Test.isTestDistributionEnabled(): Boolean =
|
||||||
|
extensions.findByType(TestDistributionExtension::class.java)?.enabled?.orNull ?: false
|
||||||
+2
-3
@@ -269,8 +269,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val fullFileText =
|
val fullFileText = FileUtil.loadFile(file, true)
|
||||||
FileUtil.loadFile(file, true).replace("COROUTINES_PACKAGE", "kotlin.coroutines")
|
|
||||||
|
|
||||||
if (fullFileText.contains("// WITH_COROUTINES")) {
|
if (fullFileText.contains("// WITH_COROUTINES")) {
|
||||||
if (fullFileText.contains("kotlin.coroutines.experimental")) continue
|
if (fullFileText.contains("kotlin.coroutines.experimental")) continue
|
||||||
@@ -317,7 +316,7 @@ class CodegenTestsOnAndroidGenerator private constructor(private val pathManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun createTestFiles(file: File, expectedText: String): List<KotlinBaseTest.TestFile> =
|
private fun createTestFiles(file: File, expectedText: String): List<KotlinBaseTest.TestFile> =
|
||||||
CodegenTestCase.createTestFilesFromFile(file, expectedText, "kotlin.coroutines", false, TargetBackend.JVM)
|
CodegenTestCase.createTestFilesFromFile(file, expectedText, false, TargetBackend.JVM)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val GRADLE_VERSION = "5.6.4" // update GRADLE_SHA_256 on change
|
const val GRADLE_VERSION = "5.6.4" // update GRADLE_SHA_256 on change
|
||||||
|
|||||||
@@ -26,13 +26,13 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
import org.jetbrains.org.objectweb.asm.*;
|
import org.jetbrains.org.objectweb.asm.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
|
||||||
|
|
||||||
public abstract class AbstractClassBuilder implements ClassBuilder {
|
public abstract class AbstractClassBuilder implements ClassBuilder {
|
||||||
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.API_VERSION) {};
|
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.API_VERSION) {};
|
||||||
|
public static final RecordComponentVisitor EMPTY_RECORD_VISITOR = new RecordComponentVisitor(Opcodes.API_VERSION) {};
|
||||||
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.API_VERSION) {};
|
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.API_VERSION) {};
|
||||||
|
|
||||||
private String thisName;
|
private String thisName;
|
||||||
@@ -91,6 +91,16 @@ public abstract class AbstractClassBuilder implements ClassBuilder {
|
|||||||
return visitor;
|
return visitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public RecordComponentVisitor newRecordComponent(@NotNull String name, @NotNull String desc, @Nullable String signature) {
|
||||||
|
RecordComponentVisitor visitor = getVisitor().visitRecordComponent(name, desc, signature);
|
||||||
|
if (visitor == null) {
|
||||||
|
return EMPTY_RECORD_VISITOR;
|
||||||
|
}
|
||||||
|
return visitor;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public JvmSerializationBindings getSerializationBindings() {
|
public JvmSerializationBindings getSerializationBindings() {
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.FileMapping;
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.SMAPBuilder;
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
||||||
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
|
import org.jetbrains.org.objectweb.asm.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.inline.InlineCodegenUtilsKt.GENERATE_SMAP;
|
||||||
|
|
||||||
|
public abstract class AbstractClassBuilder implements ClassBuilder {
|
||||||
|
protected static final MethodVisitor EMPTY_METHOD_VISITOR = new MethodVisitor(Opcodes.API_VERSION) {};
|
||||||
|
protected static final FieldVisitor EMPTY_FIELD_VISITOR = new FieldVisitor(Opcodes.API_VERSION) {};
|
||||||
|
|
||||||
|
private String thisName;
|
||||||
|
|
||||||
|
private final JvmSerializationBindings serializationBindings = new JvmSerializationBindings();
|
||||||
|
|
||||||
|
private String sourceName;
|
||||||
|
|
||||||
|
private String debugInfo;
|
||||||
|
|
||||||
|
public static class Concrete extends AbstractClassBuilder {
|
||||||
|
private final ClassVisitor v;
|
||||||
|
|
||||||
|
public Concrete(@NotNull ClassVisitor v) {
|
||||||
|
this.v = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public ClassVisitor getVisitor() {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public FieldVisitor newField(
|
||||||
|
@NotNull JvmDeclarationOrigin origin,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String desc,
|
||||||
|
@Nullable String signature,
|
||||||
|
@Nullable Object value
|
||||||
|
) {
|
||||||
|
FieldVisitor visitor = getVisitor().visitField(access, name, desc, signature, value);
|
||||||
|
if (visitor == null) {
|
||||||
|
return EMPTY_FIELD_VISITOR;
|
||||||
|
}
|
||||||
|
return visitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public MethodVisitor newMethod(
|
||||||
|
@NotNull JvmDeclarationOrigin origin,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String desc,
|
||||||
|
@Nullable String signature,
|
||||||
|
@Nullable String[] exceptions
|
||||||
|
) {
|
||||||
|
MethodVisitor visitor = getVisitor().visitMethod(access, name, desc, signature, exceptions);
|
||||||
|
if (visitor == null) {
|
||||||
|
return EMPTY_METHOD_VISITOR;
|
||||||
|
}
|
||||||
|
return visitor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public JvmSerializationBindings getSerializationBindings() {
|
||||||
|
return serializationBindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
|
||||||
|
return getVisitor().visitAnnotation(desc, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void done() {
|
||||||
|
getVisitor().visitSource(sourceName, debugInfo);
|
||||||
|
getVisitor().visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void defineClass(
|
||||||
|
@Nullable PsiElement origin,
|
||||||
|
int version,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@Nullable String signature,
|
||||||
|
@NotNull String superName,
|
||||||
|
@NotNull String[] interfaces
|
||||||
|
) {
|
||||||
|
thisName = name;
|
||||||
|
getVisitor().visit(version, access, name, signature, superName, interfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSource(@NotNull String name, @Nullable String debug) {
|
||||||
|
assert sourceName == null || sourceName.equals(name) : "inconsistent file name: " + sourceName + " vs " + name;
|
||||||
|
sourceName = name;
|
||||||
|
debugInfo = debug;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax) {
|
||||||
|
if (!GENERATE_SMAP) return;
|
||||||
|
|
||||||
|
List<FileMapping> fileMappings = smap.getResultMappings();
|
||||||
|
if (fileMappings.isEmpty()) return;
|
||||||
|
|
||||||
|
visitSource(fileMappings.get(0).getName(), SMAPBuilder.INSTANCE.build(fileMappings, backwardsCompatibleSyntax));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
|
||||||
|
getVisitor().visitOuterClass(owner, name, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
|
||||||
|
getVisitor().visitInnerClass(name, outerName, innerName, access);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NotNull
|
||||||
|
public String getThisName() {
|
||||||
|
assert thisName != null : "This name isn't set";
|
||||||
|
return thisName;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,7 +29,8 @@ class CallableMethod(
|
|||||||
override val generateCalleeType: Type?,
|
override val generateCalleeType: Type?,
|
||||||
override val returnKotlinType: KotlinType?,
|
override val returnKotlinType: KotlinType?,
|
||||||
val isInterfaceMethod: Boolean,
|
val isInterfaceMethod: Boolean,
|
||||||
private val isDefaultMethodInInterface: Boolean
|
private val isDefaultMethodInInterface: Boolean,
|
||||||
|
private val boxInlineClassBeforeInvoke: Boolean
|
||||||
) : Callable {
|
) : Callable {
|
||||||
private val defaultImplMethod: Method by lazy(LazyThreadSafetyMode.PUBLICATION, computeDefaultMethod)
|
private val defaultImplMethod: Method by lazy(LazyThreadSafetyMode.PUBLICATION, computeDefaultMethod)
|
||||||
|
|
||||||
@@ -49,6 +50,9 @@ class CallableMethod(
|
|||||||
get() = getAsmMethod().argumentTypes
|
get() = getAsmMethod().argumentTypes
|
||||||
|
|
||||||
override fun genInvokeInstruction(v: InstructionAdapter) {
|
override fun genInvokeInstruction(v: InstructionAdapter) {
|
||||||
|
if (boxInlineClassBeforeInvoke) {
|
||||||
|
StackValue.boxInlineClass(dispatchReceiverKotlinType!!, v)
|
||||||
|
}
|
||||||
v.visitMethodInsn(
|
v.visitMethodInsn(
|
||||||
invokeOpcode,
|
invokeOpcode,
|
||||||
owner.internalName,
|
owner.internalName,
|
||||||
|
|||||||
@@ -19,14 +19,10 @@ package org.jetbrains.kotlin.codegen;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.inline.FileMapping;
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
import org.jetbrains.org.objectweb.asm.*;
|
||||||
import org.jetbrains.org.objectweb.asm.ClassVisitor;
|
|
||||||
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
|
||||||
|
|
||||||
public interface ClassBuilder {
|
public interface ClassBuilder {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -49,6 +45,12 @@ public interface ClassBuilder {
|
|||||||
@Nullable String[] exceptions
|
@Nullable String[] exceptions
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@NotNull RecordComponentVisitor newRecordComponent(
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String desc,
|
||||||
|
@Nullable String signature
|
||||||
|
);
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
JvmSerializationBindings getSerializationBindings();
|
JvmSerializationBindings getSerializationBindings();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
||||||
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
|
import org.jetbrains.org.objectweb.asm.*;
|
||||||
|
|
||||||
|
public interface ClassBuilder {
|
||||||
|
@NotNull
|
||||||
|
FieldVisitor newField(
|
||||||
|
@NotNull JvmDeclarationOrigin origin,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String desc,
|
||||||
|
@Nullable String signature,
|
||||||
|
@Nullable Object value
|
||||||
|
);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
MethodVisitor newMethod(
|
||||||
|
@NotNull JvmDeclarationOrigin origin,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String desc,
|
||||||
|
@Nullable String signature,
|
||||||
|
@Nullable String[] exceptions
|
||||||
|
);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
JvmSerializationBindings getSerializationBindings();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible);
|
||||||
|
|
||||||
|
void done();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
ClassVisitor getVisitor();
|
||||||
|
|
||||||
|
void defineClass(
|
||||||
|
@Nullable PsiElement origin,
|
||||||
|
int version,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@Nullable String signature,
|
||||||
|
@NotNull String superName,
|
||||||
|
@NotNull String[] interfaces
|
||||||
|
);
|
||||||
|
|
||||||
|
void visitSource(@NotNull String name, @Nullable String debug);
|
||||||
|
|
||||||
|
void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax);
|
||||||
|
|
||||||
|
void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc);
|
||||||
|
|
||||||
|
void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access);
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String getThisName();
|
||||||
|
}
|
||||||
+1
-1
@@ -267,7 +267,7 @@ class DefaultParameterValueSubstitutor(val state: GenerationState) {
|
|||||||
if (classDescriptor.kind != ClassKind.CLASS) return false
|
if (classDescriptor.kind != ClassKind.CLASS) return false
|
||||||
|
|
||||||
if (classOrObject.isLocal) return false
|
if (classOrObject.isLocal) return false
|
||||||
if (classDescriptor.isInline) return false
|
if (classDescriptor.isInlineClass()) return false
|
||||||
if (shouldHideConstructorDueToInlineClassTypeValueParameters(constructorDescriptor)) return false
|
if (shouldHideConstructorDueToInlineClassTypeValueParameters(constructorDescriptor)) return false
|
||||||
|
|
||||||
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
|
if (CodegenBinding.canHaveOuter(state.bindingContext, classDescriptor)) return false
|
||||||
|
|||||||
@@ -19,14 +19,10 @@ package org.jetbrains.kotlin.codegen;
|
|||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.kotlin.codegen.inline.FileMapping;
|
|
||||||
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
||||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
import org.jetbrains.org.objectweb.asm.AnnotationVisitor;
|
import org.jetbrains.org.objectweb.asm.*;
|
||||||
import org.jetbrains.org.objectweb.asm.ClassVisitor;
|
|
||||||
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
|
||||||
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
|
||||||
|
|
||||||
public abstract class DelegatingClassBuilder implements ClassBuilder {
|
public abstract class DelegatingClassBuilder implements ClassBuilder {
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -58,6 +54,14 @@ public abstract class DelegatingClassBuilder implements ClassBuilder {
|
|||||||
return getDelegate().newMethod(origin, access, name, desc, signature, exceptions);
|
return getDelegate().newMethod(origin, access, name, desc, signature, exceptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public RecordComponentVisitor newRecordComponent(
|
||||||
|
@NotNull String name, @NotNull String desc, @Nullable String signature
|
||||||
|
) {
|
||||||
|
return getDelegate().newRecordComponent(name, desc, signature);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public JvmSerializationBindings getSerializationBindings() {
|
public JvmSerializationBindings getSerializationBindings() {
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.codegen;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.codegen.inline.SourceMapper;
|
||||||
|
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
|
import org.jetbrains.org.objectweb.asm.*;
|
||||||
|
|
||||||
|
public abstract class DelegatingClassBuilder implements ClassBuilder {
|
||||||
|
@NotNull
|
||||||
|
protected abstract ClassBuilder getDelegate();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public FieldVisitor newField(
|
||||||
|
@NotNull JvmDeclarationOrigin origin,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String desc,
|
||||||
|
@Nullable String signature,
|
||||||
|
@Nullable Object value
|
||||||
|
) {
|
||||||
|
return getDelegate().newField(origin, access, name, desc, signature, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public MethodVisitor newMethod(
|
||||||
|
@NotNull JvmDeclarationOrigin origin,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@NotNull String desc,
|
||||||
|
@Nullable String signature,
|
||||||
|
@Nullable String[] exceptions
|
||||||
|
) {
|
||||||
|
return getDelegate().newMethod(origin, access, name, desc, signature, exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public JvmSerializationBindings getSerializationBindings() {
|
||||||
|
return getDelegate().getSerializationBindings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public AnnotationVisitor newAnnotation(@NotNull String desc, boolean visible) {
|
||||||
|
return getDelegate().newAnnotation(desc, visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void done() {
|
||||||
|
getDelegate().done();
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public ClassVisitor getVisitor() {
|
||||||
|
return getDelegate().getVisitor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void defineClass(
|
||||||
|
@Nullable PsiElement origin,
|
||||||
|
int version,
|
||||||
|
int access,
|
||||||
|
@NotNull String name,
|
||||||
|
@Nullable String signature,
|
||||||
|
@NotNull String superName,
|
||||||
|
@NotNull String[] interfaces
|
||||||
|
) {
|
||||||
|
getDelegate().defineClass(origin, version, access, name, signature, superName, interfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSource(@NotNull String name, @Nullable String debug) {
|
||||||
|
getDelegate().visitSource(name, debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitSMAP(@NotNull SourceMapper smap, boolean backwardsCompatibleSyntax) {
|
||||||
|
getDelegate().visitSMAP(smap, backwardsCompatibleSyntax);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitOuterClass(@NotNull String owner, @Nullable String name, @Nullable String desc) {
|
||||||
|
getDelegate().visitOuterClass(owner, name, desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitInnerClass(@NotNull String name, @Nullable String outerName, @Nullable String innerName, int access) {
|
||||||
|
getDelegate().visitInnerClass(name, outerName, innerName, access);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getThisName() {
|
||||||
|
return getDelegate().getThisName();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -216,7 +216,7 @@ public class DescriptorAsmUtil {
|
|||||||
private static boolean isInlineClassWrapperConstructor(@NotNull FunctionDescriptor functionDescriptor, @Nullable OwnerKind kind) {
|
private static boolean isInlineClassWrapperConstructor(@NotNull FunctionDescriptor functionDescriptor, @Nullable OwnerKind kind) {
|
||||||
if (!(functionDescriptor instanceof ConstructorDescriptor)) return false;
|
if (!(functionDescriptor instanceof ConstructorDescriptor)) return false;
|
||||||
ClassDescriptor classDescriptor = ((ConstructorDescriptor) functionDescriptor).getConstructedClass();
|
ClassDescriptor classDescriptor = ((ConstructorDescriptor) functionDescriptor).getConstructedClass();
|
||||||
return classDescriptor.isInline() && kind == OwnerKind.IMPLEMENTATION;
|
return InlineClassesUtilsKt.isInlineClass(classDescriptor) && kind == OwnerKind.IMPLEMENTATION;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getCommonCallableFlags(FunctionDescriptor functionDescriptor, @NotNull GenerationState state) {
|
public static int getCommonCallableFlags(FunctionDescriptor functionDescriptor, @NotNull GenerationState state) {
|
||||||
@@ -559,7 +559,7 @@ public class DescriptorAsmUtil {
|
|||||||
if (receiverKotlinType.isMarkedNullable()) return null;
|
if (receiverKotlinType.isMarkedNullable()) return null;
|
||||||
|
|
||||||
DeclarationDescriptor receiverTypeDescriptor = receiverKotlinType.getConstructor().getDeclarationDescriptor();
|
DeclarationDescriptor receiverTypeDescriptor = receiverKotlinType.getConstructor().getDeclarationDescriptor();
|
||||||
assert receiverTypeDescriptor instanceof ClassDescriptor && ((ClassDescriptor) receiverTypeDescriptor).isInline() :
|
assert receiverTypeDescriptor != null && InlineClassesUtilsKt.isInlineClass(receiverTypeDescriptor) :
|
||||||
"Inline class type expected: " + receiverKotlinType;
|
"Inline class type expected: " + receiverKotlinType;
|
||||||
ClassDescriptor receiverClassDescriptor = (ClassDescriptor) receiverTypeDescriptor;
|
ClassDescriptor receiverClassDescriptor = (ClassDescriptor) receiverTypeDescriptor;
|
||||||
FunctionDescriptor toStringDescriptor = receiverClassDescriptor.getUnsubstitutedMemberScope()
|
FunctionDescriptor toStringDescriptor = receiverClassDescriptor.getUnsubstitutedMemberScope()
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.JVM_INLINE_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
|
import org.jetbrains.kotlin.resolve.descriptorUtil.secondaryConstructors
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.Synthetic
|
||||||
@@ -55,6 +56,13 @@ class ErasedInlineClassBodyCodegen(
|
|||||||
generateUnboxMethod()
|
generateUnboxMethod()
|
||||||
generateFunctionsFromAny()
|
generateFunctionsFromAny()
|
||||||
generateSpecializedEqualsStub()
|
generateSpecializedEqualsStub()
|
||||||
|
generateJvmInlineAnnotation()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun generateJvmInlineAnnotation() {
|
||||||
|
if (descriptor.isInline) {
|
||||||
|
v.newAnnotation(JVM_INLINE_ANNOTATION_FQ_NAME.topLevelClassAsmType().descriptor, true).visitEnd()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateFunctionsFromAny() {
|
private fun generateFunctionsFromAny() {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor;
|
|||||||
import org.jetbrains.kotlin.diagnostics.Errors;
|
import org.jetbrains.kotlin.diagnostics.Errors;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil;
|
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil;
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor;
|
||||||
import org.jetbrains.kotlin.load.kotlin.DescriptorBasedTypeSignatureMappingKt;
|
import org.jetbrains.kotlin.load.kotlin.DescriptorBasedTypeSignatureMappingKt;
|
||||||
import org.jetbrains.kotlin.load.kotlin.MethodSignatureMappingKt;
|
import org.jetbrains.kotlin.load.kotlin.MethodSignatureMappingKt;
|
||||||
import org.jetbrains.kotlin.name.Name;
|
import org.jetbrains.kotlin.name.Name;
|
||||||
@@ -375,22 +376,17 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
|
||||||
if (!functionDescriptor.isSuspend()) return stackValue;
|
if (!functionDescriptor.isSuspend()) return stackValue;
|
||||||
|
|
||||||
|
// When we call suspend operator fun invoke using parens, we cannot box receiver as return type inline class
|
||||||
|
if (resolvedCall instanceof VariableAsFunctionResolvedCall &&
|
||||||
|
functionDescriptor.isOperator() && functionDescriptor.getName().getIdentifier().equals("invoke")
|
||||||
|
) return stackValue;
|
||||||
|
|
||||||
KotlinType unboxedInlineClass = CoroutineCodegenUtilKt
|
KotlinType unboxedInlineClass = CoroutineCodegenUtilKt
|
||||||
.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(functionDescriptor, typeMapper);
|
.originalReturnTypeOfSuspendFunctionReturningUnboxedInlineClass(functionDescriptor, typeMapper);
|
||||||
|
|
||||||
StackValue stackValueToWrap = stackValue;
|
StackValue stackValueToWrap = stackValue;
|
||||||
KotlinType originalKotlinType;
|
KotlinType originalKotlinType = unboxedInlineClass != null ? unboxedInlineClass : stackValueToWrap.kotlinType;
|
||||||
if (unboxedInlineClass != null) {
|
Type originalType = unboxedInlineClass != null ? typeMapper.mapType(unboxedInlineClass) : stackValueToWrap.type;
|
||||||
originalKotlinType = unboxedInlineClass;
|
|
||||||
} else {
|
|
||||||
originalKotlinType = stackValueToWrap.kotlinType;
|
|
||||||
}
|
|
||||||
Type originalType;
|
|
||||||
if (unboxedInlineClass != null) {
|
|
||||||
originalType = typeMapper.mapType(unboxedInlineClass);
|
|
||||||
} else {
|
|
||||||
originalType = stackValueToWrap.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
stackValue = new StackValue(originalType, originalKotlinType) {
|
stackValue = new StackValue(originalType, originalKotlinType) {
|
||||||
@Override
|
@Override
|
||||||
@@ -1195,7 +1191,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
ClassDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
ClassDescriptor captureThis = closure.getCapturedOuterClassDescriptor();
|
||||||
if (captureThis != null) {
|
if (captureThis != null) {
|
||||||
StackValue thisOrOuter = generateThisOrOuter(captureThis, false);
|
StackValue thisOrOuter = generateThisOrOuter(captureThis, false);
|
||||||
assert !isPrimitive(thisOrOuter.type) || captureThis.isInline() :
|
assert !isPrimitive(thisOrOuter.type) || InlineClassesUtilsKt.isInlineClass(captureThis) :
|
||||||
"This or outer for " + captureThis + " should be non-primitive: " + thisOrOuter.type;
|
"This or outer for " + captureThis + " should be non-primitive: " + thisOrOuter.type;
|
||||||
callGenerator.putCapturedValueOnStack(thisOrOuter, thisOrOuter.type, paramIndex++);
|
callGenerator.putCapturedValueOnStack(thisOrOuter, thisOrOuter.type, paramIndex++);
|
||||||
}
|
}
|
||||||
@@ -2409,9 +2405,14 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
fieldName = KotlinTypeMapper.mapDefaultFieldName(propertyDescriptor, isDelegatedProperty);
|
fieldName = KotlinTypeMapper.mapDefaultFieldName(propertyDescriptor, isDelegatedProperty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KotlinType propertyType = propertyDescriptor.getOriginal().getType();
|
||||||
|
if (propertyDescriptor instanceof JavaPropertyDescriptor && InlineClassesUtilsKt.isInlineClassType(propertyType)) {
|
||||||
|
propertyType = TypeUtils.makeNullable(propertyType);
|
||||||
|
}
|
||||||
|
|
||||||
return StackValue.property(
|
return StackValue.property(
|
||||||
propertyDescriptor, backingFieldOwner,
|
propertyDescriptor, backingFieldOwner,
|
||||||
typeMapper.mapType(isDelegatedProperty && forceField ? delegateType : propertyDescriptor.getOriginal().getType()),
|
typeMapper.mapType(isDelegatedProperty && forceField ? delegateType : propertyType),
|
||||||
isStaticBackingField, fieldName, callableGetter, callableSetter, receiver, this, resolvedCall, skipLateinitAssertion,
|
isStaticBackingField, fieldName, callableGetter, callableSetter, receiver, this, resolvedCall, skipLateinitAssertion,
|
||||||
isDelegatedProperty && forceField ? delegateType : null
|
isDelegatedProperty && forceField ? delegateType : null
|
||||||
);
|
);
|
||||||
@@ -4380,6 +4381,10 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
|
|
||||||
Type exprType = expressionType(expr);
|
Type exprType = expressionType(expr);
|
||||||
KotlinType exprKotlinType = kotlinType(expr);
|
KotlinType exprKotlinType = kotlinType(expr);
|
||||||
|
if (exprKotlinType != null && InlineClassesUtilsKt.isInlineClassType(exprKotlinType) &&
|
||||||
|
FlexibleTypesKt.isNullabilityFlexible(exprKotlinType)) {
|
||||||
|
exprKotlinType = TypeUtils.makeNullable(exprKotlinType);
|
||||||
|
}
|
||||||
StackValue value;
|
StackValue value;
|
||||||
if (compileTimeConstant != null) {
|
if (compileTimeConstant != null) {
|
||||||
value = StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType);
|
value = StackValue.constant(compileTimeConstant.getValue(), exprType, exprKotlinType);
|
||||||
@@ -4835,7 +4840,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
|
|||||||
ReceiverParameterDescriptor dispatchReceiver = constructor.getDispatchReceiverParameter();
|
ReceiverParameterDescriptor dispatchReceiver = constructor.getDispatchReceiverParameter();
|
||||||
ClassDescriptor containingDeclaration = constructor.getContainingDeclaration();
|
ClassDescriptor containingDeclaration = constructor.getContainingDeclaration();
|
||||||
|
|
||||||
if (!containingDeclaration.isInline()) {
|
if (!InlineClassesUtilsKt.isInlineClass(containingDeclaration)) {
|
||||||
v.anew(objectType);
|
v.anew(objectType);
|
||||||
v.dup();
|
v.dup();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1221,7 +1221,12 @@ public class FunctionCodegen {
|
|||||||
|
|
||||||
// 'null' because the "could not find expected declaration" error has been already reported in isDefaultNeeded earlier
|
// 'null' because the "could not find expected declaration" error has been already reported in isDefaultNeeded earlier
|
||||||
List<ValueParameterDescriptor> valueParameters =
|
List<ValueParameterDescriptor> valueParameters =
|
||||||
CodegenUtil.getFunctionParametersForDefaultValueGeneration(functionDescriptor, null);
|
functionDescriptor.isSuspend()
|
||||||
|
? CollectionsKt.plus(
|
||||||
|
CodegenUtil.getFunctionParametersForDefaultValueGeneration(
|
||||||
|
CoroutineCodegenUtilKt.unwrapInitialDescriptorForSuspendFunction(functionDescriptor), null),
|
||||||
|
CollectionsKt.last(functionDescriptor.getValueParameters()))
|
||||||
|
: CodegenUtil.getFunctionParametersForDefaultValueGeneration(functionDescriptor, null);
|
||||||
|
|
||||||
boolean isStatic = isStaticMethod(methodContext.getContextKind(), functionDescriptor);
|
boolean isStatic = isStaticMethod(methodContext.getContextKind(), functionDescriptor);
|
||||||
FrameMap frameMap = createFrameMap(state, signature, functionDescriptor.getExtensionReceiverParameter(), valueParameters, isStatic);
|
FrameMap frameMap = createFrameMap(state, signature, functionDescriptor.getExtensionReceiverParameter(), valueParameters, isStatic);
|
||||||
@@ -1589,7 +1594,7 @@ public class FunctionCodegen {
|
|||||||
|
|
||||||
// When delegating to inline class, we invoke static implementation method
|
// When delegating to inline class, we invoke static implementation method
|
||||||
// that takes inline class underlying value as 1st argument.
|
// that takes inline class underlying value as 1st argument.
|
||||||
int toArgsShift = toClass.isInline() ? 1 : 0;
|
int toArgsShift = InlineClassesUtilsKt.isInlineClass(toClass) ? 1 : 0;
|
||||||
|
|
||||||
int reg = 1;
|
int reg = 1;
|
||||||
for (int i = 0; i < argTypes.length; ++i) {
|
for (int i = 0; i < argTypes.length; ++i) {
|
||||||
@@ -1609,7 +1614,7 @@ public class FunctionCodegen {
|
|||||||
if (toClass.getKind() == ClassKind.INTERFACE) {
|
if (toClass.getKind() == ClassKind.INTERFACE) {
|
||||||
iv.invokeinterface(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor());
|
iv.invokeinterface(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor());
|
||||||
}
|
}
|
||||||
else if (toClass.isInline()) {
|
else if (InlineClassesUtilsKt.isInlineClass(toClass)) {
|
||||||
iv.invokestatic(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor(), false);
|
iv.invokestatic(internalName, delegateToMethod.getName(), delegateToMethod.getDescriptor(), false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|||||||
+3
-3
@@ -84,7 +84,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
|||||||
String toStringMethodDesc = getToStringDesc();
|
String toStringMethodDesc = getToStringDesc();
|
||||||
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), toStringMethodName, toStringMethodDesc, null, null);
|
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), toStringMethodName, toStringMethodDesc, null, null);
|
||||||
|
|
||||||
if (!isInErasedInlineClass && classDescriptor.isInline()) {
|
if (!isInErasedInlineClass && InlineClassesUtilsKt.isInlineClass(classDescriptor)) {
|
||||||
FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper);
|
FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
|||||||
String hashCodeMethodDesc = getHashCodeDesc();
|
String hashCodeMethodDesc = getHashCodeDesc();
|
||||||
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), hashCodeMethodName, hashCodeMethodDesc, null, null);
|
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), hashCodeMethodName, hashCodeMethodDesc, null, null);
|
||||||
|
|
||||||
if (!isInErasedInlineClass && classDescriptor.isInline()) {
|
if (!isInErasedInlineClass && InlineClassesUtilsKt.isInlineClass(classDescriptor)) {
|
||||||
FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper);
|
FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -233,7 +233,7 @@ public class FunctionsFromAnyGeneratorImpl extends FunctionsFromAnyGenerator {
|
|||||||
String equalsMethodDesc = getEqualsDesc();
|
String equalsMethodDesc = getEqualsDesc();
|
||||||
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), equalsMethodName, equalsMethodDesc, null, null);
|
MethodVisitor mv = v.newMethod(methodOrigin, getAccess(), equalsMethodName, equalsMethodDesc, null, null);
|
||||||
|
|
||||||
if (!isInErasedInlineClass && classDescriptor.isInline()) {
|
if (!isInErasedInlineClass && InlineClassesUtilsKt.isInlineClass(classDescriptor)) {
|
||||||
FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper);
|
FunctionCodegen.generateMethodInsideInlineClassWrapper(methodOrigin, function, classDescriptor, mv, typeMapper);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmClassSignature;
|
||||||
@@ -221,6 +222,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
access |= ACC_ENUM;
|
access |= ACC_ENUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (JvmAnnotationUtilKt.isJvmRecord(descriptor)) {
|
||||||
|
access |= ACC_RECORD;
|
||||||
|
}
|
||||||
|
|
||||||
v.defineClass(
|
v.defineClass(
|
||||||
myClass.getPsiOrParent(),
|
myClass.getPsiOrParent(),
|
||||||
state.getClassFileVersion(),
|
state.getClassFileVersion(),
|
||||||
@@ -260,7 +265,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
@Override
|
@Override
|
||||||
protected void generateErasedInlineClassIfNeeded() {
|
protected void generateErasedInlineClassIfNeeded() {
|
||||||
if (!(myClass instanceof KtClass)) return;
|
if (!(myClass instanceof KtClass)) return;
|
||||||
if (!descriptor.isInline()) return;
|
if (!InlineClassesUtilsKt.isInlineClass(descriptor)) return;
|
||||||
|
|
||||||
ClassContext erasedInlineClassContext = context.intoWrapperForErasedInlineClass(descriptor, state);
|
ClassContext erasedInlineClassContext = context.intoWrapperForErasedInlineClass(descriptor, state);
|
||||||
new ErasedInlineClassBodyCodegen((KtClass) myClass, erasedInlineClassContext, v, state, this).generate();
|
new ErasedInlineClassBodyCodegen((KtClass) myClass, erasedInlineClassContext, v, state, this).generate();
|
||||||
@@ -269,7 +274,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
@Override
|
@Override
|
||||||
protected void generateUnboxMethodForInlineClass() {
|
protected void generateUnboxMethodForInlineClass() {
|
||||||
if (!(myClass instanceof KtClass)) return;
|
if (!(myClass instanceof KtClass)) return;
|
||||||
if (!descriptor.isInline()) return;
|
if (!InlineClassesUtilsKt.isInlineClass(descriptor)) return;
|
||||||
|
|
||||||
Type ownerType = typeMapper.mapClass(descriptor);
|
Type ownerType = typeMapper.mapClass(descriptor);
|
||||||
ValueParameterDescriptor inlinedValue = InlineClassesUtilsKt.underlyingRepresentation(this.descriptor);
|
ValueParameterDescriptor inlinedValue = InlineClassesUtilsKt.underlyingRepresentation(this.descriptor);
|
||||||
@@ -450,7 +455,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
try {
|
try {
|
||||||
lookupConstructorExpressionsInClosureIfPresent();
|
lookupConstructorExpressionsInClosureIfPresent();
|
||||||
constructorCodegen.generatePrimaryConstructor(delegationFieldsInfo, superClassAsmType);
|
constructorCodegen.generatePrimaryConstructor(delegationFieldsInfo, superClassAsmType);
|
||||||
if (!descriptor.isInline() && !(descriptor instanceof SyntheticClassOrObjectDescriptor)) {
|
if (!InlineClassesUtilsKt.isInlineClass(descriptor) && !(descriptor instanceof SyntheticClassOrObjectDescriptor)) {
|
||||||
// Synthetic classes does not have declarations for secondary constructors
|
// Synthetic classes does not have declarations for secondary constructors
|
||||||
for (ClassConstructorDescriptor secondaryConstructor : DescriptorUtilsKt.getSecondaryConstructors(descriptor)) {
|
for (ClassConstructorDescriptor secondaryConstructor : DescriptorUtilsKt.getSecondaryConstructors(descriptor)) {
|
||||||
constructorCodegen.generateSecondaryConstructor(secondaryConstructor, superClassAsmType);
|
constructorCodegen.generateSecondaryConstructor(secondaryConstructor, superClassAsmType);
|
||||||
@@ -552,7 +557,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateFunctionsFromAnyForInlineClasses() {
|
private void generateFunctionsFromAnyForInlineClasses() {
|
||||||
if (!descriptor.isInline()) return;
|
if (!InlineClassesUtilsKt.isInlineClass(descriptor)) return;
|
||||||
if (!(myClass instanceof KtClassOrObject)) return;
|
if (!(myClass instanceof KtClassOrObject)) return;
|
||||||
new FunctionsFromAnyGeneratorImpl(
|
new FunctionsFromAnyGeneratorImpl(
|
||||||
(KtClassOrObject) myClass, bindingContext, descriptor, classAsmType, context, v, state
|
(KtClassOrObject) myClass, bindingContext, descriptor, classAsmType, context, v, state
|
||||||
|
|||||||
+1248
File diff suppressed because it is too large
Load Diff
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
|||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
|
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
@@ -435,9 +436,10 @@ public class PropertyCodegen {
|
|||||||
v.getSerializationBindings().put(FIELD_FOR_PROPERTY, propertyDescriptor, new Pair<>(type, name));
|
v.getSerializationBindings().put(FIELD_FOR_PROPERTY, propertyDescriptor, new Pair<>(type, name));
|
||||||
|
|
||||||
if (isBackingFieldOwner) {
|
if (isBackingFieldOwner) {
|
||||||
|
String signature = isDelegate ? null : typeMapper.mapFieldSignature(kotlinType, propertyDescriptor);
|
||||||
FieldVisitor fv = builder.newField(
|
FieldVisitor fv = builder.newField(
|
||||||
JvmDeclarationOriginKt.OtherOrigin(propertyDescriptor), modifiers, name, type.getDescriptor(),
|
JvmDeclarationOriginKt.OtherOrigin(propertyDescriptor), modifiers, name, type.getDescriptor(),
|
||||||
isDelegate ? null : typeMapper.mapFieldSignature(kotlinType, propertyDescriptor), defaultValue
|
signature, defaultValue
|
||||||
);
|
);
|
||||||
|
|
||||||
if (annotatedField != null) {
|
if (annotatedField != null) {
|
||||||
@@ -450,6 +452,10 @@ public class PropertyCodegen {
|
|||||||
AnnotationCodegen.forField(fv, memberCodegen, state, skipNullabilityAnnotations)
|
AnnotationCodegen.forField(fv, memberCodegen, state, skipNullabilityAnnotations)
|
||||||
.genAnnotations(annotatedField, type, propertyDescriptor.getType(), null, additionalVisibleAnnotations);
|
.genAnnotations(annotatedField, type, propertyDescriptor.getType(), null, additionalVisibleAnnotations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor && JvmAnnotationUtilKt.isJvmRecord((ClassDescriptor) propertyDescriptor.getContainingDeclaration())) {
|
||||||
|
builder.newRecordComponent(name, type.getDescriptor(), signature);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,680 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2018 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;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import kotlin.Pair;
|
||||||
|
import kotlin.collections.CollectionsKt;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.jetbrains.kotlin.codegen.context.CodegenContextUtil;
|
||||||
|
import org.jetbrains.kotlin.codegen.context.FieldOwnerContext;
|
||||||
|
import org.jetbrains.kotlin.codegen.context.MultifileClassFacadeContext;
|
||||||
|
import org.jetbrains.kotlin.codegen.context.MultifileClassPartContext;
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState;
|
||||||
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature;
|
||||||
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
|
import org.jetbrains.kotlin.load.java.DescriptorsJvmAbiUtil;
|
||||||
|
import org.jetbrains.kotlin.load.java.JvmAbi;
|
||||||
|
import org.jetbrains.kotlin.psi.*;
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorFactory;
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils;
|
||||||
|
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.util.UnderscoreUtilKt;
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKt;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature;
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature;
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor;
|
||||||
|
import org.jetbrains.kotlin.types.ErrorUtils;
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType;
|
||||||
|
import org.jetbrains.org.objectweb.asm.FieldVisitor;
|
||||||
|
import org.jetbrains.org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.jetbrains.org.objectweb.asm.Opcodes;
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
import org.jetbrains.org.objectweb.asm.commons.Method;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getDeprecatedAccessFlag;
|
||||||
|
import static org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getVisibilityForBackingField;
|
||||||
|
import static org.jetbrains.kotlin.codegen.FunctionCodegen.processInterfaceMethod;
|
||||||
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isConstOrHasJvmFieldAnnotation;
|
||||||
|
import static org.jetbrains.kotlin.codegen.JvmCodegenUtil.isJvmInterface;
|
||||||
|
import static org.jetbrains.kotlin.codegen.binding.CodegenBinding.*;
|
||||||
|
import static org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings.*;
|
||||||
|
import static org.jetbrains.kotlin.diagnostics.Errors.EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND;
|
||||||
|
import static org.jetbrains.kotlin.fileClasses.JvmFileClassUtilKt.isTopLevelInJvmMultifileClass;
|
||||||
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isCompanionObject;
|
||||||
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface;
|
||||||
|
import static org.jetbrains.kotlin.resolve.jvm.AsmTypes.K_PROPERTY_TYPE;
|
||||||
|
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmFieldAnnotation;
|
||||||
|
import static org.jetbrains.kotlin.resolve.jvm.annotations.JvmAnnotationUtilKt.hasJvmSyntheticAnnotation;
|
||||||
|
import static org.jetbrains.org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
|
public class PropertyCodegen {
|
||||||
|
private final GenerationState state;
|
||||||
|
private final ClassBuilder v;
|
||||||
|
private final FunctionCodegen functionCodegen;
|
||||||
|
private final KotlinTypeMapper typeMapper;
|
||||||
|
private final BindingContext bindingContext;
|
||||||
|
private final FieldOwnerContext context;
|
||||||
|
private final MemberCodegen<?> memberCodegen;
|
||||||
|
private final OwnerKind kind;
|
||||||
|
|
||||||
|
public PropertyCodegen(
|
||||||
|
@NotNull FieldOwnerContext context,
|
||||||
|
@NotNull ClassBuilder v,
|
||||||
|
@NotNull FunctionCodegen functionCodegen,
|
||||||
|
@NotNull MemberCodegen<?> memberCodegen
|
||||||
|
) {
|
||||||
|
this.state = functionCodegen.state;
|
||||||
|
this.v = v;
|
||||||
|
this.functionCodegen = functionCodegen;
|
||||||
|
this.typeMapper = state.getTypeMapper();
|
||||||
|
this.bindingContext = state.getBindingContext();
|
||||||
|
this.context = context;
|
||||||
|
this.memberCodegen = memberCodegen;
|
||||||
|
this.kind = context.getContextKind();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void gen(@NotNull KtProperty property) {
|
||||||
|
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, property);
|
||||||
|
if (!(variableDescriptor instanceof PropertyDescriptor)) {
|
||||||
|
throw ExceptionLogger.logDescriptorNotFound(
|
||||||
|
"Property " + property.getName() + " should have a property descriptor: " + variableDescriptor, property
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyDescriptor propertyDescriptor = (PropertyDescriptor) variableDescriptor;
|
||||||
|
gen(property, propertyDescriptor, property.getGetter(), property.getSetter());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void genDestructuringDeclaration(@NotNull KtDestructuringDeclarationEntry entry) {
|
||||||
|
VariableDescriptor variableDescriptor = bindingContext.get(BindingContext.VARIABLE, entry);
|
||||||
|
if (!(variableDescriptor instanceof PropertyDescriptor)) {
|
||||||
|
throw ExceptionLogger.logDescriptorNotFound(
|
||||||
|
"Destructuring declaration entry" + entry.getName() + " should have a property descriptor: " + variableDescriptor, entry
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
genBackingFieldAndAnnotations(deserializedProperty);
|
||||||
|
|
||||||
|
if (!isConstOrHasJvmFieldAnnotation(deserializedProperty)) {
|
||||||
|
generateGetter(deserializedProperty, null);
|
||||||
|
generateSetter(deserializedProperty, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void gen(
|
||||||
|
@NotNull KtProperty declaration,
|
||||||
|
@NotNull PropertyDescriptor descriptor,
|
||||||
|
@Nullable KtPropertyAccessor getter,
|
||||||
|
@Nullable KtPropertyAccessor setter
|
||||||
|
) {
|
||||||
|
assert kind == OwnerKind.PACKAGE || kind == OwnerKind.IMPLEMENTATION ||
|
||||||
|
kind == OwnerKind.DEFAULT_IMPLS || kind == OwnerKind.ERASED_INLINE_CLASS
|
||||||
|
: "Generating property with a wrong kind (" + kind + "): " + descriptor;
|
||||||
|
|
||||||
|
genBackingFieldAndAnnotations(descriptor);
|
||||||
|
|
||||||
|
boolean isDefaultGetterAndSetter = isDefaultAccessor(getter) && isDefaultAccessor(setter);
|
||||||
|
|
||||||
|
if (isAccessorNeeded(descriptor, getter, isDefaultGetterAndSetter)) {
|
||||||
|
generateGetter(descriptor, getter);
|
||||||
|
}
|
||||||
|
if (isAccessorNeeded(descriptor, setter, isDefaultGetterAndSetter)) {
|
||||||
|
generateSetter(descriptor, setter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isDefaultAccessor(@Nullable KtPropertyAccessor accessor) {
|
||||||
|
return accessor == null || !accessor.hasBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
genBackingFieldAndAnnotations(descriptor);
|
||||||
|
|
||||||
|
generateGetter(descriptor, null);
|
||||||
|
generateSetter(descriptor, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
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() && !DescriptorVisibilities.isPrivate(descriptor.getVisibility())
|
||||||
|
? !(context instanceof MultifileClassPartContext)
|
||||||
|
: CodegenContextUtil.isImplementationOwner(context, descriptor);
|
||||||
|
|
||||||
|
generateBackingField(descriptor, isBackingFieldOwner);
|
||||||
|
generateSyntheticMethodIfNeeded(descriptor, isBackingFieldOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isAccessorNeeded(
|
||||||
|
@NotNull PropertyDescriptor descriptor,
|
||||||
|
@Nullable KtPropertyAccessor accessor,
|
||||||
|
boolean isDefaultGetterAndSetter
|
||||||
|
) {
|
||||||
|
return isAccessorNeeded(descriptor, accessor, isDefaultGetterAndSetter, kind);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isReferenceablePropertyWithGetter(@NotNull PropertyDescriptor descriptor) {
|
||||||
|
PsiElement psiElement = DescriptorToSourceUtils.descriptorToDeclaration(descriptor);
|
||||||
|
KtDeclaration ktDeclaration = psiElement instanceof KtDeclaration ? (KtDeclaration) psiElement : null;
|
||||||
|
if (ktDeclaration instanceof KtProperty) {
|
||||||
|
KtProperty ktProperty = (KtProperty) ktDeclaration;
|
||||||
|
boolean isDefaultGetterAndSetter =
|
||||||
|
isDefaultAccessor(ktProperty.getGetter()) && isDefaultAccessor(ktProperty.getSetter());
|
||||||
|
return isAccessorNeeded(descriptor, ktProperty.getGetter(), isDefaultGetterAndSetter, OwnerKind.IMPLEMENTATION);
|
||||||
|
} else if (ktDeclaration instanceof KtParameter) {
|
||||||
|
return isAccessorNeeded(descriptor, null, true, OwnerKind.IMPLEMENTATION);
|
||||||
|
} else {
|
||||||
|
return isAccessorNeeded(descriptor, null, false, OwnerKind.IMPLEMENTATION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if it's necessary to generate an accessor to the property, i.e. if this property can be referenced via getter/setter
|
||||||
|
* for any reason
|
||||||
|
*
|
||||||
|
* @see JvmCodegenUtil#couldUseDirectAccessToProperty
|
||||||
|
*/
|
||||||
|
private static boolean isAccessorNeeded(
|
||||||
|
@NotNull PropertyDescriptor descriptor,
|
||||||
|
@Nullable KtPropertyAccessor accessor,
|
||||||
|
boolean isDefaultGetterAndSetter,
|
||||||
|
OwnerKind kind
|
||||||
|
) {
|
||||||
|
if (isConstOrHasJvmFieldAnnotation(descriptor)) return false;
|
||||||
|
|
||||||
|
boolean isDefaultAccessor = isDefaultAccessor(accessor);
|
||||||
|
|
||||||
|
// Don't generate accessors for interface properties with default accessors in DefaultImpls
|
||||||
|
if (kind == OwnerKind.DEFAULT_IMPLS && isDefaultAccessor) return false;
|
||||||
|
|
||||||
|
// Delegated or extension properties can only be referenced via accessors
|
||||||
|
if (descriptor.isDelegated() || descriptor.getExtensionReceiverParameter() != null) return true;
|
||||||
|
|
||||||
|
// Companion object properties should have accessors for non-private properties because these properties can be referenced
|
||||||
|
// via getter/setter. But these accessors getter/setter are not required for private properties that have a default getter
|
||||||
|
// and setter, in this case, the property can always be accessed through the accessor 'access<property name>$cp' and avoid some
|
||||||
|
// useless indirection by using others accessors.
|
||||||
|
if (isCompanionObject(descriptor.getContainingDeclaration())) {
|
||||||
|
if (DescriptorVisibilities.isPrivate(descriptor.getVisibility()) && isDefaultGetterAndSetter) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-const properties from multifile classes have accessors regardless of visibility
|
||||||
|
if (isTopLevelInJvmMultifileClass(descriptor)) return true;
|
||||||
|
|
||||||
|
// Private class properties have accessors only in cases when those accessors are non-trivial
|
||||||
|
if (DescriptorVisibilities.isPrivate(descriptor.getVisibility())) {
|
||||||
|
return !isDefaultAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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() && DescriptorVisibilities.isPrivate(descriptor.getSetter().getVisibility())) {
|
||||||
|
return !isDefaultAccessor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-public API (private and internal) primary vals of inline classes don't have getter
|
||||||
|
if (InlineClassesUtilsKt.isUnderlyingPropertyOfInlineClass(descriptor) && !descriptor.getVisibility().isPublicAPI()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean areAccessorsNeededForPrimaryConstructorProperty(
|
||||||
|
@NotNull PropertyDescriptor descriptor,
|
||||||
|
@NotNull OwnerKind kind
|
||||||
|
) {
|
||||||
|
if (hasJvmFieldAnnotation(descriptor)) return false;
|
||||||
|
if (kind == OwnerKind.ERASED_INLINE_CLASS) return false;
|
||||||
|
|
||||||
|
DescriptorVisibility visibility = descriptor.getVisibility();
|
||||||
|
if (InlineClassesUtilsKt.isInlineClass(descriptor.getContainingDeclaration())) {
|
||||||
|
return visibility.isPublicAPI();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return !DescriptorVisibilities.isPrivate(visibility);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generatePrimaryConstructorProperty(@NotNull PropertyDescriptor descriptor) {
|
||||||
|
genBackingFieldAndAnnotations(descriptor);
|
||||||
|
|
||||||
|
if (areAccessorsNeededForPrimaryConstructorProperty(descriptor, context.getContextKind())) {
|
||||||
|
generateGetter(descriptor, null);
|
||||||
|
generateSetter(descriptor, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void generateConstructorPropertyAsMethodForAnnotationClass(
|
||||||
|
@NotNull KtParameter parameter,
|
||||||
|
@NotNull PropertyDescriptor descriptor,
|
||||||
|
@Nullable FunctionDescriptor expectedAnnotationConstructor
|
||||||
|
) {
|
||||||
|
JvmMethodGenericSignature signature = typeMapper.mapAnnotationParameterSignature(descriptor);
|
||||||
|
Method asmMethod = signature.getAsmMethod();
|
||||||
|
MethodVisitor mv = v.newMethod(
|
||||||
|
JvmDeclarationOriginKt.OtherOrigin(parameter, descriptor),
|
||||||
|
ACC_PUBLIC | ACC_ABSTRACT,
|
||||||
|
asmMethod.getName(),
|
||||||
|
asmMethod.getDescriptor(),
|
||||||
|
signature.getGenericsSignature(),
|
||||||
|
null
|
||||||
|
);
|
||||||
|
|
||||||
|
PropertyGetterDescriptor getter = descriptor.getGetter();
|
||||||
|
assert getter != null : "Annotation property should have a getter: " + descriptor;
|
||||||
|
v.getSerializationBindings().put(METHOD_FOR_FUNCTION, getter, asmMethod);
|
||||||
|
AnnotationCodegen.forMethod(mv, memberCodegen, state).genAnnotations(getter, asmMethod.getReturnType(), null);
|
||||||
|
|
||||||
|
KtExpression defaultValue = loadAnnotationArgumentDefaultValue(parameter, descriptor, expectedAnnotationConstructor);
|
||||||
|
if (defaultValue != null) {
|
||||||
|
ConstantValue<?> constant = ExpressionCodegen.getCompileTimeConstant(
|
||||||
|
defaultValue, bindingContext, true, state.getShouldInlineConstVals());
|
||||||
|
assert !state.getClassBuilderMode().generateBodies || constant != null
|
||||||
|
: "Default value for annotation parameter should be compile time value: " + defaultValue.getText();
|
||||||
|
if (constant != null) {
|
||||||
|
AnnotationCodegen annotationCodegen = AnnotationCodegen.forAnnotationDefaultValue(mv, memberCodegen, state);
|
||||||
|
annotationCodegen.generateAnnotationDefaultValue(constant, descriptor.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mv.visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
private KtExpression loadAnnotationArgumentDefaultValue(
|
||||||
|
@NotNull KtParameter ktParameter,
|
||||||
|
@NotNull PropertyDescriptor descriptor,
|
||||||
|
@Nullable FunctionDescriptor expectedAnnotationConstructor
|
||||||
|
) {
|
||||||
|
KtExpression value = ktParameter.getDefaultValue();
|
||||||
|
if (value != null) return value;
|
||||||
|
|
||||||
|
if (expectedAnnotationConstructor != null) {
|
||||||
|
ValueParameterDescriptor expectedParameter = CollectionsKt.single(
|
||||||
|
expectedAnnotationConstructor.getValueParameters(), parameter -> parameter.getName().equals(descriptor.getName())
|
||||||
|
);
|
||||||
|
PsiElement element = DescriptorToSourceUtils.descriptorToDeclaration(expectedParameter);
|
||||||
|
if (!(element instanceof KtParameter)) {
|
||||||
|
state.getDiagnostics().report(EXPECTED_FUNCTION_SOURCE_WITH_DEFAULT_ARGUMENTS_NOT_FOUND.on(ktParameter));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return ((KtParameter) element).getDefaultValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateBackingField(@NotNull PropertyDescriptor descriptor, boolean isBackingFieldOwner) {
|
||||||
|
if (isJvmInterface(descriptor.getContainingDeclaration()) || kind == OwnerKind.DEFAULT_IMPLS ||
|
||||||
|
kind == OwnerKind.ERASED_INLINE_CLASS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object defaultValue;
|
||||||
|
if (descriptor.isDelegated()) {
|
||||||
|
defaultValue = null;
|
||||||
|
}
|
||||||
|
else if (Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, descriptor))) {
|
||||||
|
if (shouldWriteFieldInitializer(descriptor)) {
|
||||||
|
ConstantValue<?> initializer = descriptor.getCompileTimeInitializer();
|
||||||
|
defaultValue = initializer == null ? null : initializer.getValue();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
defaultValue = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
generateBackingField(descriptor, descriptor.isDelegated(), defaultValue, isBackingFieldOwner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Annotations on properties are stored in bytecode on an empty synthetic method. This way they're still
|
||||||
|
// accessible via reflection, and 'deprecated' and 'synthetic' flags prevent this method from being called accidentally
|
||||||
|
private void generateSyntheticMethodIfNeeded(@NotNull PropertyDescriptor descriptor, boolean isBackingFieldOwner) {
|
||||||
|
Annotations annotations = descriptor.getAnnotations();
|
||||||
|
if (annotations.isEmpty()) return;
|
||||||
|
|
||||||
|
Method signature = typeMapper.mapSyntheticMethodForPropertyAnnotations(descriptor);
|
||||||
|
if (kind != OwnerKind.DEFAULT_IMPLS && CodegenContextUtil.isImplementationOwner(context, descriptor)) {
|
||||||
|
v.getSerializationBindings().put(SYNTHETIC_METHOD_FOR_PROPERTY, descriptor, signature);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBackingFieldOwner) {
|
||||||
|
if (!isInterface(context.getContextDescriptor()) ||
|
||||||
|
processInterfaceMethod(descriptor, kind, false, true, state.getJvmDefaultMode())) {
|
||||||
|
memberCodegen.generateSyntheticAnnotationsMethod(descriptor, signature, annotations);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateBackingField(
|
||||||
|
@NotNull PropertyDescriptor propertyDescriptor,
|
||||||
|
boolean isDelegate,
|
||||||
|
@Nullable Object defaultValue,
|
||||||
|
boolean isBackingFieldOwner
|
||||||
|
) {
|
||||||
|
FieldDescriptor annotatedField = isDelegate ? propertyDescriptor.getDelegateField() : propertyDescriptor.getBackingField();
|
||||||
|
|
||||||
|
int modifiers = getDeprecatedAccessFlag(propertyDescriptor);
|
||||||
|
|
||||||
|
for (AnnotationCodegen.JvmFlagAnnotation flagAnnotation : AnnotationCodegen.FIELD_FLAGS) {
|
||||||
|
modifiers |= flagAnnotation.getJvmFlag(annotatedField);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kind == OwnerKind.PACKAGE) {
|
||||||
|
modifiers |= ACC_STATIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!propertyDescriptor.isLateInit() && (!propertyDescriptor.isVar() || isDelegate)) {
|
||||||
|
modifiers |= ACC_FINAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasJvmSyntheticAnnotation(propertyDescriptor)) {
|
||||||
|
modifiers |= ACC_SYNTHETIC;
|
||||||
|
}
|
||||||
|
|
||||||
|
KotlinType kotlinType = isDelegate ? getDelegateTypeForProperty(propertyDescriptor, bindingContext) : propertyDescriptor.getType();
|
||||||
|
Type type = typeMapper.mapType(kotlinType);
|
||||||
|
|
||||||
|
ClassBuilder builder = v;
|
||||||
|
|
||||||
|
FieldOwnerContext backingFieldContext = context;
|
||||||
|
List<String> additionalVisibleAnnotations = Collections.emptyList();
|
||||||
|
if (DescriptorAsmUtil.isInstancePropertyWithStaticBackingField(propertyDescriptor) ) {
|
||||||
|
modifiers |= ACC_STATIC;
|
||||||
|
|
||||||
|
if (DescriptorsJvmAbiUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) {
|
||||||
|
ImplementationBodyCodegen codegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||||
|
builder = codegen.v;
|
||||||
|
backingFieldContext = codegen.context;
|
||||||
|
if (DescriptorVisibilities.isPrivate(((ClassDescriptor) propertyDescriptor.getContainingDeclaration()).getVisibility())) {
|
||||||
|
modifiers |= ACC_DEPRECATED;
|
||||||
|
additionalVisibleAnnotations = Collections.singletonList(CodegenUtilKt.JAVA_LANG_DEPRECATED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modifiers |= getVisibilityForBackingField(propertyDescriptor, isDelegate);
|
||||||
|
|
||||||
|
if (DescriptorAsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) {
|
||||||
|
ImplementationBodyCodegen parentBodyCodegen = (ImplementationBodyCodegen) memberCodegen.getParentCodegen();
|
||||||
|
parentBodyCodegen.addCompanionObjectPropertyToCopy(propertyDescriptor, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = backingFieldContext.getFieldName(propertyDescriptor, isDelegate);
|
||||||
|
|
||||||
|
v.getSerializationBindings().put(FIELD_FOR_PROPERTY, propertyDescriptor, new Pair<>(type, name));
|
||||||
|
|
||||||
|
if (isBackingFieldOwner) {
|
||||||
|
String signature = isDelegate ? null : typeMapper.mapFieldSignature(kotlinType, propertyDescriptor);
|
||||||
|
FieldVisitor fv = builder.newField(
|
||||||
|
JvmDeclarationOriginKt.OtherOrigin(propertyDescriptor), modifiers, name, type.getDescriptor(),
|
||||||
|
signature, defaultValue
|
||||||
|
);
|
||||||
|
|
||||||
|
if (annotatedField != null) {
|
||||||
|
// Don't emit nullability annotations for backing field if:
|
||||||
|
// - backing field is synthetic;
|
||||||
|
// - property is lateinit (since corresponding field is actually nullable).
|
||||||
|
boolean skipNullabilityAnnotations =
|
||||||
|
(modifiers & ACC_SYNTHETIC) != 0 ||
|
||||||
|
propertyDescriptor.isLateInit();
|
||||||
|
AnnotationCodegen.forField(fv, memberCodegen, state, skipNullabilityAnnotations)
|
||||||
|
.genAnnotations(annotatedField, type, propertyDescriptor.getType(), null, additionalVisibleAnnotations);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propertyDescriptor.getContainingDeclaration() instanceof ClassDescriptor && JvmAnnotationUtilKt.isJvmRecord((ClassDescriptor) propertyDescriptor.getContainingDeclaration())) {
|
||||||
|
// builder.newRecordComponent(name, type.getDescriptor(), signature);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static KotlinType getDelegateTypeForProperty(
|
||||||
|
@NotNull PropertyDescriptor propertyDescriptor,
|
||||||
|
@NotNull BindingContext bindingContext
|
||||||
|
) {
|
||||||
|
ResolvedCall<FunctionDescriptor> provideDelegateResolvedCall =
|
||||||
|
bindingContext.get(BindingContext.PROVIDE_DELEGATE_RESOLVED_CALL, propertyDescriptor);
|
||||||
|
|
||||||
|
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
|
||||||
|
delegateType = ErrorUtils.createErrorType("Delegate type");
|
||||||
|
}
|
||||||
|
return delegateType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean shouldWriteFieldInitializer(@NotNull PropertyDescriptor descriptor) {
|
||||||
|
if (!descriptor.isConst() &&
|
||||||
|
state.getLanguageVersionSettings().supportsFeature(LanguageFeature.NoConstantValueAttributeForNonConstVals)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//final field of primitive or String type
|
||||||
|
if (!descriptor.isVar()) {
|
||||||
|
Type type = typeMapper.mapType(descriptor);
|
||||||
|
return AsmUtil.isPrimitive(type) || "java.lang.String".equals(type.getClassName());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(@NotNull PropertyDescriptor descriptor, @Nullable KtPropertyAccessor setter) {
|
||||||
|
if (!descriptor.isVar()) return;
|
||||||
|
|
||||||
|
generateAccessor(
|
||||||
|
setter,
|
||||||
|
descriptor.getSetter() != null ? descriptor.getSetter() : DescriptorFactory.createDefaultSetter(
|
||||||
|
descriptor, Annotations.Companion.getEMPTY(), Annotations.Companion.getEMPTY()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateAccessor(@Nullable KtPropertyAccessor accessor, @NotNull PropertyAccessorDescriptor descriptor) {
|
||||||
|
if (context instanceof MultifileClassFacadeContext &&
|
||||||
|
(DescriptorVisibilities.isPrivate(descriptor.getVisibility()) ||
|
||||||
|
DescriptorAsmUtil.getVisibilityAccessFlag(descriptor) == Opcodes.ACC_PRIVATE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FunctionGenerationStrategy strategy;
|
||||||
|
if (accessor == null || !accessor.hasBody()) {
|
||||||
|
if (descriptor.getCorrespondingProperty().isDelegated()) {
|
||||||
|
strategy = new DelegatedPropertyAccessorStrategy(state, descriptor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strategy = new DefaultPropertyAccessorStrategy(state, descriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strategy = new FunctionGenerationStrategy.FunctionDefault(state, accessor);
|
||||||
|
}
|
||||||
|
|
||||||
|
functionCodegen.generateMethod(JvmDeclarationOriginKt.OtherOrigin(descriptor), descriptor, strategy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DefaultPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased {
|
||||||
|
private final PropertyAccessorDescriptor propertyAccessorDescriptor;
|
||||||
|
|
||||||
|
public DefaultPropertyAccessorStrategy(@NotNull GenerationState state, @NotNull PropertyAccessorDescriptor descriptor) {
|
||||||
|
super(state);
|
||||||
|
propertyAccessorDescriptor = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||||
|
InstructionAdapter v = codegen.v;
|
||||||
|
PropertyDescriptor propertyDescriptor = propertyAccessorDescriptor.getCorrespondingProperty();
|
||||||
|
StackValue property = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
|
||||||
|
|
||||||
|
PsiElement jetProperty = DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor);
|
||||||
|
if (jetProperty instanceof KtProperty || jetProperty instanceof KtParameter) {
|
||||||
|
codegen.markLineNumber((KtElement) jetProperty, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propertyAccessorDescriptor instanceof PropertyGetterDescriptor) {
|
||||||
|
Type type = signature.getReturnType();
|
||||||
|
property.put(type, v);
|
||||||
|
v.areturn(type);
|
||||||
|
}
|
||||||
|
else if (propertyAccessorDescriptor instanceof PropertySetterDescriptor) {
|
||||||
|
List<ValueParameterDescriptor> valueParameters = propertyAccessorDescriptor.getValueParameters();
|
||||||
|
assert valueParameters.size() == 1 : "Property setter should have only one value parameter but has " + propertyAccessorDescriptor;
|
||||||
|
int parameterIndex = codegen.lookupLocalIndex(valueParameters.get(0));
|
||||||
|
assert parameterIndex >= 0 : "Local index for setter parameter should be positive or zero: " + propertyAccessorDescriptor;
|
||||||
|
Type type = codegen.typeMapper.mapType(propertyDescriptor);
|
||||||
|
property.store(StackValue.local(parameterIndex, type), codegen.v);
|
||||||
|
v.visitInsn(RETURN);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalStateException("Unknown property accessor: " + propertyAccessorDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static StackValue invokeDelegatedPropertyConventionMethod(
|
||||||
|
@NotNull ExpressionCodegen codegen,
|
||||||
|
@NotNull ResolvedCall<FunctionDescriptor> resolvedCall,
|
||||||
|
@NotNull StackValue receiver,
|
||||||
|
@NotNull PropertyDescriptor propertyDescriptor
|
||||||
|
) {
|
||||||
|
codegen.tempVariables.put(
|
||||||
|
resolvedCall.getCall().getValueArguments().get(1).asElement(),
|
||||||
|
getDelegatedPropertyMetadata(propertyDescriptor, codegen.getBindingContext())
|
||||||
|
);
|
||||||
|
|
||||||
|
return codegen.invokeFunction(resolvedCall, receiver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isDelegatedPropertyWithOptimizedMetadata(
|
||||||
|
@NotNull VariableDescriptorWithAccessors descriptor,
|
||||||
|
@NotNull BindingContext bindingContext
|
||||||
|
) {
|
||||||
|
return Boolean.TRUE == bindingContext.get(DELEGATED_PROPERTY_WITH_OPTIMIZED_METADATA, descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static @NotNull StackValue getOptimizedDelegatedPropertyMetadataValue() {
|
||||||
|
return StackValue.constant(null, K_PROPERTY_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static StackValue getDelegatedPropertyMetadata(
|
||||||
|
@NotNull VariableDescriptorWithAccessors descriptor,
|
||||||
|
@NotNull BindingContext bindingContext
|
||||||
|
) {
|
||||||
|
if (isDelegatedPropertyWithOptimizedMetadata(descriptor, bindingContext)) {
|
||||||
|
return getOptimizedDelegatedPropertyMetadataValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
Type owner = bindingContext.get(DELEGATED_PROPERTY_METADATA_OWNER, descriptor);
|
||||||
|
assert owner != null : "Delegated property owner not found: " + descriptor;
|
||||||
|
|
||||||
|
List<VariableDescriptorWithAccessors> allDelegatedProperties = bindingContext.get(DELEGATED_PROPERTIES_WITH_METADATA, owner);
|
||||||
|
int index = allDelegatedProperties == null ? -1 : allDelegatedProperties.indexOf(descriptor);
|
||||||
|
if (index < 0) {
|
||||||
|
throw new AssertionError("Delegated property not found in " + owner + ": " + descriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
StackValue.Field array = StackValue.field(
|
||||||
|
Type.getType("[" + K_PROPERTY_TYPE), owner, JvmAbi.DELEGATED_PROPERTIES_ARRAY_NAME, true, StackValue.none()
|
||||||
|
);
|
||||||
|
return StackValue.arrayElement(K_PROPERTY_TYPE, null, array, StackValue.constant(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DelegatedPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased {
|
||||||
|
private final PropertyAccessorDescriptor propertyAccessorDescriptor;
|
||||||
|
|
||||||
|
public DelegatedPropertyAccessorStrategy(@NotNull GenerationState state, @NotNull PropertyAccessorDescriptor descriptor) {
|
||||||
|
super(state);
|
||||||
|
this.propertyAccessorDescriptor = descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void doGenerateBody(@NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature) {
|
||||||
|
InstructionAdapter v = codegen.v;
|
||||||
|
|
||||||
|
BindingContext bindingContext = state.getBindingContext();
|
||||||
|
ResolvedCall<FunctionDescriptor> resolvedCall =
|
||||||
|
bindingContext.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, propertyAccessorDescriptor);
|
||||||
|
assert resolvedCall != null : "Resolve call should be recorded for delegate call " + signature.toString();
|
||||||
|
|
||||||
|
PropertyDescriptor propertyDescriptor = propertyAccessorDescriptor.getCorrespondingProperty();
|
||||||
|
StackValue.Property property = codegen.intermediateValueForProperty(propertyDescriptor, true, null, StackValue.LOCAL_0);
|
||||||
|
StackValue.Property delegate = property.getDelegateOrNull();
|
||||||
|
assert delegate != null : "No delegate for delegated property: " + propertyDescriptor;
|
||||||
|
StackValue lastValue = invokeDelegatedPropertyConventionMethod(codegen, resolvedCall, delegate, propertyDescriptor);
|
||||||
|
Type asmType = signature.getReturnType();
|
||||||
|
KotlinType kotlinReturnType = propertyAccessorDescriptor.getOriginal().getReturnType();
|
||||||
|
lastValue.put(asmType, kotlinReturnType, v);
|
||||||
|
v.areturn(asmType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void genDelegate(@NotNull PropertyDescriptor delegate, @NotNull PropertyDescriptor delegateTo, @NotNull StackValue field) {
|
||||||
|
ClassDescriptor toClass = (ClassDescriptor) delegateTo.getContainingDeclaration();
|
||||||
|
|
||||||
|
PropertyGetterDescriptor getter = delegate.getGetter();
|
||||||
|
if (getter != null) {
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
functionCodegen.genDelegate(getter, delegateTo.getGetter().getOriginal(), toClass, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertySetterDescriptor setter = delegate.getSetter();
|
||||||
|
if (setter != null) {
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
functionCodegen.genDelegate(setter, delegateTo.getSetter().getOriginal(), toClass, field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -775,7 +775,8 @@ public abstract class StackValue {
|
|||||||
) {
|
) {
|
||||||
// Coerce 'this' for the case when it is smart cast.
|
// Coerce 'this' for the case when it is smart cast.
|
||||||
// Do not coerce for other cases due to the 'protected' access issues (JVMS 7, 4.9.2 Structural Constraints).
|
// Do not coerce for other cases due to the 'protected' access issues (JVMS 7, 4.9.2 Structural Constraints).
|
||||||
boolean coerceType = descriptor.getKind() == ClassKind.INTERFACE || descriptor.isInline() || (castReceiver && !isSuper);
|
boolean coerceType = descriptor.getKind() == ClassKind.INTERFACE || InlineClassesUtilsKt.isInlineClass(descriptor) ||
|
||||||
|
(castReceiver && !isSuper);
|
||||||
return new ThisOuter(codegen, descriptor, isSuper, coerceType);
|
return new ThisOuter(codegen, descriptor, isSuper, coerceType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.codegen.binding.MutableClosure;
|
|||||||
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper;
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
|
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
|
||||||
|
import org.jetbrains.kotlin.resolve.InlineClassesUtilsKt;
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes;
|
||||||
import org.jetbrains.kotlin.types.SimpleType;
|
import org.jetbrains.kotlin.types.SimpleType;
|
||||||
import org.jetbrains.org.objectweb.asm.Type;
|
import org.jetbrains.org.objectweb.asm.Type;
|
||||||
@@ -48,7 +49,7 @@ public class ConstructorContext extends MethodContext {
|
|||||||
ClassDescriptor capturedOuterClassDescriptor = closure != null ? closure.getCapturedOuterClassDescriptor() : null;
|
ClassDescriptor capturedOuterClassDescriptor = closure != null ? closure.getCapturedOuterClassDescriptor() : null;
|
||||||
StackValue stackValue;
|
StackValue stackValue;
|
||||||
if (capturedOuterClassDescriptor != null) {
|
if (capturedOuterClassDescriptor != null) {
|
||||||
if (capturedOuterClassDescriptor.isInline()) {
|
if (InlineClassesUtilsKt.isInlineClass(capturedOuterClassDescriptor)) {
|
||||||
SimpleType outerClassKotlinType = capturedOuterClassDescriptor.getDefaultType();
|
SimpleType outerClassKotlinType = capturedOuterClassDescriptor.getDefaultType();
|
||||||
Type outerClassType = kotlinTypeMapper.mapType(capturedOuterClassDescriptor);
|
Type outerClassType = kotlinTypeMapper.mapType(capturedOuterClassDescriptor);
|
||||||
stackValue = StackValue.local(1, outerClassType, outerClassKotlinType);
|
stackValue = StackValue.local(1, outerClassType, outerClassKotlinType);
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClassType
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
@@ -294,7 +295,7 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, funDescriptor,
|
functionCodegen.generateMethod(JvmDeclarationOrigin.NO_ORIGIN, funDescriptor,
|
||||||
object : FunctionGenerationStrategy.CodegenBased(state) {
|
object : FunctionGenerationStrategy.CodegenBased(state) {
|
||||||
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
override fun doGenerateBody(codegen: ExpressionCodegen, signature: JvmMethodSignature) {
|
||||||
codegen.v.generateInvokeMethod(signature)
|
codegen.v.generateInvokeMethod(signature, funDescriptor)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -316,13 +317,13 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
)
|
)
|
||||||
mv.visitCode()
|
mv.visitCode()
|
||||||
with(InstructionAdapter(mv)) {
|
with(InstructionAdapter(mv)) {
|
||||||
generateInvokeMethod(jvmMethodSignature)
|
generateInvokeMethod(jvmMethodSignature, untypedDescriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCodegen.endVisit(mv, "invoke", element)
|
FunctionCodegen.endVisit(mv, "invoke", element)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun InstructionAdapter.generateInvokeMethod(signature: JvmMethodSignature) {
|
private fun InstructionAdapter.generateInvokeMethod(signature: JvmMethodSignature, descriptor: FunctionDescriptor) {
|
||||||
// this
|
// this
|
||||||
load(0, AsmTypes.OBJECT_TYPE)
|
load(0, AsmTypes.OBJECT_TYPE)
|
||||||
val parameterTypes = signature.valueParameters.map { it.asmType }
|
val parameterTypes = signature.valueParameters.map { it.asmType }
|
||||||
@@ -348,16 +349,23 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
load(arraySlot, AsmTypes.OBJECT_TYPE)
|
load(arraySlot, AsmTypes.OBJECT_TYPE)
|
||||||
} else {
|
} else {
|
||||||
var index = 0
|
var index = 0
|
||||||
|
val fromKotlinTypes =
|
||||||
|
if (!generateErasedCreate && doNotGenerateInvokeBridge) funDescriptor.allValueParameterTypes()
|
||||||
|
else funDescriptor.allValueParameterTypes().map { funDescriptor.module.builtIns.nullableAnyType }
|
||||||
|
val toKotlinTypes =
|
||||||
|
if (!generateErasedCreate && doNotGenerateInvokeBridge) createCoroutineDescriptor.allValueParameterTypes()
|
||||||
|
else descriptor.allValueParameterTypes()
|
||||||
parameterTypes.withVariableIndices().forEach { (varIndex, type) ->
|
parameterTypes.withVariableIndices().forEach { (varIndex, type) ->
|
||||||
load(varIndex + 1, type)
|
load(varIndex + 1, type)
|
||||||
StackValue.coerce(type, createArgumentTypes[index++], this)
|
StackValue.coerce(type, fromKotlinTypes[index], createArgumentTypes[index], toKotlinTypes[index], this)
|
||||||
|
index++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this.create(..)
|
// this.create(..)
|
||||||
invokevirtual(
|
invokevirtual(
|
||||||
v.thisName,
|
v.thisName,
|
||||||
createCoroutineDescriptor.name.identifier,
|
typeMapper.mapFunctionName(createCoroutineDescriptor, null),
|
||||||
Type.getMethodDescriptor(
|
Type.getMethodDescriptor(
|
||||||
languageVersionSettings.continuationAsmType(),
|
languageVersionSettings.continuationAsmType(),
|
||||||
*createArgumentTypes.toTypedArray()
|
*createArgumentTypes.toTypedArray()
|
||||||
@@ -439,12 +447,24 @@ class CoroutineCodegenForLambda private constructor(
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
if (generateErasedCreate) {
|
if (generateErasedCreate) {
|
||||||
load(index, AsmTypes.OBJECT_TYPE)
|
if (parameter.type.isInlineClassType()) {
|
||||||
StackValue.coerce(
|
load(cloneIndex, fieldInfoForCoroutineLambdaParameter.ownerType)
|
||||||
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
load(index, AsmTypes.OBJECT_TYPE)
|
||||||
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
StackValue.unboxInlineClass(AsmTypes.OBJECT_TYPE, parameter.type, this)
|
||||||
this
|
putfield(
|
||||||
)
|
fieldInfoForCoroutineLambdaParameter.ownerInternalName,
|
||||||
|
fieldInfoForCoroutineLambdaParameter.fieldName,
|
||||||
|
fieldInfoForCoroutineLambdaParameter.fieldType.descriptor
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
load(index, AsmTypes.OBJECT_TYPE)
|
||||||
|
StackValue.coerce(
|
||||||
|
AsmTypes.OBJECT_TYPE, builtIns.nullableAnyType,
|
||||||
|
fieldInfoForCoroutineLambdaParameter.fieldType, fieldInfoForCoroutineLambdaParameter.fieldKotlinType,
|
||||||
|
this
|
||||||
|
)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
load(index, fieldInfoForCoroutineLambdaParameter.fieldType)
|
load(index, fieldInfoForCoroutineLambdaParameter.fieldType)
|
||||||
}
|
}
|
||||||
@@ -831,3 +851,6 @@ private object FailingFunctionGenerationStrategy : FunctionGenerationStrategy()
|
|||||||
fun reportSuspensionPointInsideMonitor(element: KtElement, state: GenerationState, stackTraceElement: String) {
|
fun reportSuspensionPointInsideMonitor(element: KtElement, state: GenerationState, stackTraceElement: String) {
|
||||||
state.diagnostics.report(ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR.on(element, stackTraceElement))
|
state.diagnostics.report(ErrorsJvm.SUSPENSION_POINT_INSIDE_MONITOR.on(element, stackTraceElement))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun FunctionDescriptor.allValueParameterTypes(): List<KotlinType> =
|
||||||
|
(listOfNotNull(extensionReceiverParameter?.type)) + valueParameters.map { it.type }
|
||||||
+9
-18
@@ -1222,8 +1222,9 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
|||||||
oldLvt += record
|
oldLvt += record
|
||||||
}
|
}
|
||||||
method.localVariables.clear()
|
method.localVariables.clear()
|
||||||
// Skip `this` for suspend lamdba
|
// Skip `this` for suspend lambda
|
||||||
val start = if (isForNamedFunction) 0 else 1
|
val start = if (isForNamedFunction) 0 else 1
|
||||||
|
val oldLvtNodeToLatestNewLvtNode = mutableMapOf<LocalVariableNode, LocalVariableNode>()
|
||||||
for (variableIndex in start until method.maxLocals) {
|
for (variableIndex in start until method.maxLocals) {
|
||||||
if (oldLvt.none { it.index == variableIndex }) continue
|
if (oldLvt.none { it.index == variableIndex }) continue
|
||||||
var startLabel: LabelNode? = null
|
var startLabel: LabelNode? = null
|
||||||
@@ -1239,25 +1240,15 @@ private fun updateLvtAccordingToLiveness(method: MethodNode, isForNamedFunction:
|
|||||||
val endLabel = insn as? LabelNode ?: insn.findNextOrNull { it is LabelNode } as? LabelNode ?: continue
|
val endLabel = insn as? LabelNode ?: insn.findNextOrNull { it is LabelNode } as? LabelNode ?: continue
|
||||||
// startLabel can be null in case of parameters
|
// startLabel can be null in case of parameters
|
||||||
@Suppress("NAME_SHADOWING") val startLabel = startLabel ?: lvtRecord.start
|
@Suppress("NAME_SHADOWING") val startLabel = startLabel ?: lvtRecord.start
|
||||||
var recordToExtend: LocalVariableNode? = null
|
// Attempt to extend existing local variable node corresponding to the record in
|
||||||
for (record in method.localVariables) {
|
// the original local variable table.
|
||||||
if (record.name == lvtRecord.name &&
|
var recordToExtend: LocalVariableNode? = oldLvtNodeToLatestNewLvtNode[lvtRecord]
|
||||||
record.desc == lvtRecord.desc &&
|
if (recordToExtend != null && InsnSequence(recordToExtend.end, startLabel).none { isBeforeSuspendMarker(it) }) {
|
||||||
record.signature == lvtRecord.signature &&
|
|
||||||
record.index == lvtRecord.index
|
|
||||||
) {
|
|
||||||
if (InsnSequence(record.end, startLabel).none { isBeforeSuspendMarker(it) }) {
|
|
||||||
recordToExtend = record
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (recordToExtend != null) {
|
|
||||||
recordToExtend.end = endLabel
|
recordToExtend.end = endLabel
|
||||||
} else {
|
} else {
|
||||||
method.localVariables.add(
|
val node = LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
|
||||||
LocalVariableNode(lvtRecord.name, lvtRecord.desc, lvtRecord.signature, startLabel, endLabel, lvtRecord.index)
|
method.localVariables.add(node)
|
||||||
)
|
oldLvtNodeToLatestNewLvtNode[lvtRecord] = node
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.psi.KtFunction
|
import org.jetbrains.kotlin.psi.KtFunction
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
import org.jetbrains.kotlin.psi.psiUtil.getElementTextWithContext
|
||||||
import org.jetbrains.kotlin.resolve.inline.isEffectivelyInlineOnly
|
import org.jetbrains.kotlin.resolve.inline.isEffectivelyInlineOnly
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
import org.jetbrains.kotlin.resolve.jvm.diagnostics.OtherOrigin
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
@@ -92,7 +93,9 @@ class SuspendFunctionGenerationStrategy(
|
|||||||
sourceFile = declaration.containingKtFile.name,
|
sourceFile = declaration.containingKtFile.name,
|
||||||
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
shouldPreserveClassInitialization = constructorCallNormalizationMode.shouldPreserveClassInitialization,
|
||||||
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
|
needDispatchReceiver = originalSuspendDescriptor.dispatchReceiverParameter != null,
|
||||||
internalNameForDispatchReceiver = containingClassInternalNameOrNull(),
|
internalNameForDispatchReceiver = (originalSuspendDescriptor.containingDeclaration as? ClassDescriptor)?.let {
|
||||||
|
if (it.isInlineClass()) state.typeMapper.mapType(it).internalName else null
|
||||||
|
} ?: containingClassInternalNameOrNull(),
|
||||||
languageVersionSettings = languageVersionSettings,
|
languageVersionSettings = languageVersionSettings,
|
||||||
disableTailCallOptimizationForFunctionReturningUnit = originalSuspendDescriptor.returnType?.isUnit() == true &&
|
disableTailCallOptimizationForFunctionReturningUnit = originalSuspendDescriptor.returnType?.isUnit() == true &&
|
||||||
originalSuspendDescriptor.overriddenDescriptors.isNotEmpty() &&
|
originalSuspendDescriptor.overriddenDescriptors.isNotEmpty() &&
|
||||||
|
|||||||
@@ -136,9 +136,7 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
) {
|
) {
|
||||||
var nodeAndSmap: SMAPAndMethodNode? = null
|
var nodeAndSmap: SMAPAndMethodNode? = null
|
||||||
try {
|
try {
|
||||||
nodeAndSmap = createInlineMethodNode(
|
nodeAndSmap = createInlineMethodNode(mapDefaultSignature, typeArguments, typeSystem)
|
||||||
functionDescriptor, methodOwner, jvmSignature, mapDefaultSignature, typeArguments, typeSystem, state, sourceCompiler
|
|
||||||
)
|
|
||||||
endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas), registerLineNumberAfterwards)
|
endCall(inlineCall(nodeAndSmap, inlineDefaultLambdas), registerLineNumberAfterwards)
|
||||||
} catch (e: CompilationException) {
|
} catch (e: CompilationException) {
|
||||||
throw e
|
throw e
|
||||||
@@ -274,6 +272,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
|
|
||||||
abstract fun extractDefaultLambdas(node: MethodNode): List<DefaultLambda>
|
abstract fun extractDefaultLambdas(node: MethodNode): List<DefaultLambda>
|
||||||
|
|
||||||
|
abstract fun descriptorIsDeserialized(memberDescriptor: CallableMemberDescriptor): Boolean
|
||||||
|
|
||||||
fun generateAndInsertFinallyBlocks(
|
fun generateAndInsertFinallyBlocks(
|
||||||
intoNode: MethodNode,
|
intoNode: MethodNode,
|
||||||
insertPoints: List<MethodInliner.PointForExternalFinallyBlocks>,
|
insertPoints: List<MethodInliner.PointForExternalFinallyBlocks>,
|
||||||
@@ -512,38 +512,33 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
internal fun createInlineMethodNode(
|
||||||
|
callDefault: Boolean,
|
||||||
internal fun createInlineMethodNode(
|
typeArguments: List<TypeParameterMarker>?,
|
||||||
functionDescriptor: FunctionDescriptor,
|
typeSystem: TypeSystemCommonBackendContext
|
||||||
methodOwner: Type,
|
): SMAPAndMethodNode {
|
||||||
jvmSignature: JvmMethodSignature,
|
val intrinsic = generateInlineIntrinsic(state, functionDescriptor, typeArguments, typeSystem)
|
||||||
callDefault: Boolean,
|
if (intrinsic != null) {
|
||||||
typeArguments: List<TypeParameterMarker>?,
|
return SMAPAndMethodNode(intrinsic, createDefaultFakeSMAP())
|
||||||
typeSystem: TypeSystemCommonBackendContext,
|
|
||||||
state: GenerationState,
|
|
||||||
sourceCompilerForInline: SourceCompilerForInline
|
|
||||||
): SMAPAndMethodNode {
|
|
||||||
val intrinsic = generateInlineIntrinsic(state, functionDescriptor, typeArguments, typeSystem)
|
|
||||||
if (intrinsic != null) {
|
|
||||||
return SMAPAndMethodNode(intrinsic, createDefaultFakeSMAP())
|
|
||||||
}
|
|
||||||
|
|
||||||
val asmMethod = if (callDefault)
|
|
||||||
state.typeMapper.mapDefaultMethod(functionDescriptor, sourceCompilerForInline.contextKind)
|
|
||||||
else
|
|
||||||
mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod)
|
|
||||||
|
|
||||||
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
|
|
||||||
if (!isBuiltInArrayIntrinsic(functionDescriptor) && directMember !is DescriptorWithContainerSource) {
|
|
||||||
val node = sourceCompilerForInline.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
|
|
||||||
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val asmMethod = if (callDefault)
|
||||||
|
state.typeMapper.mapDefaultMethod(functionDescriptor, sourceCompiler.contextKind)
|
||||||
|
else
|
||||||
|
mangleSuspendInlineFunctionAsmMethodIfNeeded(functionDescriptor, jvmSignature.asmMethod)
|
||||||
|
|
||||||
|
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
|
||||||
|
if (!isBuiltInArrayIntrinsic(functionDescriptor) && !descriptorIsDeserialized(directMember)) {
|
||||||
|
val node = sourceCompiler.doCreateMethodNodeFromSource(functionDescriptor, jvmSignature, callDefault, asmMethod)
|
||||||
|
node.node.preprocessSuspendMarkers(forInline = true, keepFakeContinuation = false)
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
return getCompiledMethodNodeInner(functionDescriptor, directMember, asmMethod, methodOwner, state, jvmSignature)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
internal fun createSpecialInlineMethodNodeFromBinaries(functionDescriptor: FunctionDescriptor, state: GenerationState): MethodNode {
|
internal fun createSpecialInlineMethodNodeFromBinaries(functionDescriptor: FunctionDescriptor, state: GenerationState): MethodNode {
|
||||||
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
|
val directMember = getDirectMemberAndCallableFromObject(functionDescriptor)
|
||||||
assert(directMember is DescriptorWithContainerSource) {
|
assert(directMember is DescriptorWithContainerSource) {
|
||||||
@@ -577,7 +572,8 @@ abstract class InlineCodegen<out T : BaseExpressionCodegen>(
|
|||||||
doCreateMethodNodeFromCompiled(directMember, state, jvmSignature.asmMethod)
|
doCreateMethodNodeFromCompiled(directMember, state, jvmSignature.asmMethod)
|
||||||
else
|
else
|
||||||
null
|
null
|
||||||
result ?: throw IllegalStateException("Couldn't obtain compiled function body for $functionDescriptor")
|
result ?:
|
||||||
|
throw IllegalStateException("Couldn't obtain compiled function body for $functionDescriptor")
|
||||||
}
|
}
|
||||||
|
|
||||||
return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP)
|
return SMAPAndMethodNode(cloneMethodNode(resultInCache.node), resultInCache.classSMAP)
|
||||||
|
|||||||
+4
-4
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.codegen.inline
|
package org.jetbrains.kotlin.codegen.inline
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.linkWithLabel
|
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
@@ -16,7 +15,6 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.org.objectweb.asm.Label
|
import org.jetbrains.org.objectweb.asm.Label
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.tree.LabelNode
|
|
||||||
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
import org.jetbrains.org.objectweb.asm.tree.MethodNode
|
||||||
|
|
||||||
class InlineCodegenForDefaultBody(
|
class InlineCodegenForDefaultBody(
|
||||||
@@ -41,8 +39,10 @@ class InlineCodegenForDefaultBody(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
|
override fun genCallInner(callableMethod: Callable, resolvedCall: ResolvedCall<*>?, callDefault: Boolean, codegen: ExpressionCodegen) {
|
||||||
val nodeAndSmap = InlineCodegen.createInlineMethodNode(
|
val nodeAndSmap = PsiInlineCodegen(
|
||||||
function, methodOwner, jvmSignature, callDefault, null, codegen.typeSystem, state, sourceCompilerForInline
|
codegen, state, function, methodOwner, jvmSignature, TypeParameterMappings(), sourceCompilerForInline
|
||||||
|
).createInlineMethodNode(
|
||||||
|
callDefault, null, codegen.typeSystem
|
||||||
)
|
)
|
||||||
val childSourceMapper = SourceMapCopier(sourceMapper, nodeAndSmap.classSMAP)
|
val childSourceMapper = SourceMapCopier(sourceMapper, nodeAndSmap.classSMAP)
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.codegen.*
|
|||||||
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getMethodAsmFlags
|
import org.jetbrains.kotlin.codegen.DescriptorAsmUtil.getMethodAsmFlags
|
||||||
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
import org.jetbrains.kotlin.codegen.binding.CodegenBinding
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||||
@@ -25,6 +26,7 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil.isInlinableParameterExpres
|
|||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodParameterKind
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DescriptorWithContainerSource
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -208,4 +210,7 @@ class PsiInlineCodegen(
|
|||||||
::PsiDefaultLambda
|
::PsiDefaultLambda
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun descriptorIsDeserialized(memberDescriptor: CallableMemberDescriptor): Boolean =
|
||||||
|
memberDescriptor is DescriptorWithContainerSource
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,7 +130,9 @@ fun <T, R : DefaultLambda> expandMaskConditionsAndUpdateVariableNodes(
|
|||||||
node.instructions.insert(position, newInsn)
|
node.instructions.insert(position, newInsn)
|
||||||
}
|
}
|
||||||
|
|
||||||
node.localVariables.removeIf { it.start in toDelete && it.end in toDelete }
|
node.localVariables.removeIf {
|
||||||
|
(it.start in toDelete && it.end in toDelete) || defaultLambdas.contains(it.index)
|
||||||
|
}
|
||||||
|
|
||||||
node.remove(toDelete)
|
node.remove(toDelete)
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.codegen
|
package org.jetbrains.kotlin.codegen
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
import org.jetbrains.kotlin.load.kotlin.JvmPackagePartSource
|
||||||
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinder
|
||||||
@@ -44,6 +41,10 @@ fun CallableDescriptor.isGenericParameter(): Boolean {
|
|||||||
fun classFileContainsMethod(descriptor: FunctionDescriptor, state: GenerationState, method: Method): Boolean? {
|
fun classFileContainsMethod(descriptor: FunctionDescriptor, state: GenerationState, method: Method): Boolean? {
|
||||||
if (descriptor !is DeserializedSimpleFunctionDescriptor) return null
|
if (descriptor !is DeserializedSimpleFunctionDescriptor) return null
|
||||||
|
|
||||||
|
if (descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||||
|
return descriptor.overriddenDescriptors.any { classFileContainsMethod(it, state, method) == true }
|
||||||
|
}
|
||||||
|
|
||||||
val classId: ClassId = when {
|
val classId: ClassId = when {
|
||||||
descriptor.containingDeclaration is DeserializedClassDescriptor -> {
|
descriptor.containingDeclaration is DeserializedClassDescriptor -> {
|
||||||
(descriptor.containingDeclaration as DeserializedClassDescriptor).classId ?: return null
|
(descriptor.containingDeclaration as DeserializedClassDescriptor).classId ?: return null
|
||||||
@@ -56,6 +57,10 @@ fun classFileContainsMethod(descriptor: FunctionDescriptor, state: GenerationSta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return classFileContainsMethod(classId, state, method)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun classFileContainsMethod(classId: ClassId, state: GenerationState, method: Method): Boolean? {
|
||||||
val bytes = VirtualFileFinder.getInstance(state.project, state.module).findVirtualFileWithHeader(classId)
|
val bytes = VirtualFileFinder.getInstance(state.project, state.module).findVirtualFileWithHeader(classId)
|
||||||
?.contentsToByteArray() ?: return null
|
?.contentsToByteArray() ?: return null
|
||||||
var found = false
|
var found = false
|
||||||
|
|||||||
+2
-1
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Pair
|
|||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
|
import org.jetbrains.kotlin.codegen.optimization.common.StrictBasicValue
|
||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
import org.jetbrains.org.objectweb.asm.tree.AbstractInsnNode
|
||||||
@@ -119,7 +120,7 @@ fun getUnboxedType(boxedType: Type, state: GenerationState): Type {
|
|||||||
|
|
||||||
fun unboxedTypeOfInlineClass(boxedType: Type, state: GenerationState): Type? {
|
fun unboxedTypeOfInlineClass(boxedType: Type, state: GenerationState): Type? {
|
||||||
val descriptor =
|
val descriptor =
|
||||||
state.jvmBackendClassResolver.resolveToClassDescriptors(boxedType).singleOrNull()?.takeIf { it.isInline } ?: return null
|
state.jvmBackendClassResolver.resolveToClassDescriptors(boxedType).singleOrNull()?.takeIf { it.isInlineClass() } ?: return null
|
||||||
return state.mapInlineClass(descriptor)
|
return state.mapInlineClass(descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.optimization.common
|
|||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||||
|
|
||||||
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>
|
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>>
|
||||||
+1
-1
@@ -8,4 +8,4 @@ package org.jetbrains.kotlin.codegen.optimization.common
|
|||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
import org.jetbrains.org.objectweb.asm.tree.analysis.BasicValue
|
||||||
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
import org.jetbrains.org.objectweb.asm.tree.analysis.Frame
|
||||||
|
|
||||||
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>>
|
typealias TypeAnnotatedFrames = Array<Frame<BasicValue>?>
|
||||||
@@ -201,7 +201,7 @@ class GenerationState private constructor(
|
|||||||
|
|
||||||
val target = configuration.get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
|
val target = configuration.get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
|
||||||
val runtimeStringConcat =
|
val runtimeStringConcat =
|
||||||
if (target.bytecodeVersion >= JvmTarget.JVM_9.bytecodeVersion)
|
if (target.majorVersion >= JvmTarget.JVM_9.majorVersion)
|
||||||
configuration.get(JVMConfigurationKeys.STRING_CONCAT) ?: JvmStringConcat.INLINE
|
configuration.get(JVMConfigurationKeys.STRING_CONCAT) ?: JvmStringConcat.INLINE
|
||||||
else JvmStringConcat.INLINE
|
else JvmStringConcat.INLINE
|
||||||
|
|
||||||
@@ -272,7 +272,10 @@ class GenerationState private constructor(
|
|||||||
|
|
||||||
val rootContext: CodegenContext<*> = RootContext(this)
|
val rootContext: CodegenContext<*> = RootContext(this)
|
||||||
|
|
||||||
val classFileVersion: Int = target.bytecodeVersion
|
val classFileVersion: Int = run {
|
||||||
|
val minorVersion = if (configuration.getBoolean(JVMConfigurationKeys.ENABLE_JVM_PREVIEW)) 0xffff else 0
|
||||||
|
(minorVersion shl 16) + target.majorVersion
|
||||||
|
}
|
||||||
|
|
||||||
val generateParametersMetadata: Boolean = configuration.getBoolean(JVMConfigurationKeys.PARAMETERS_METADATA)
|
val generateParametersMetadata: Boolean = configuration.getBoolean(JVMConfigurationKeys.PARAMETERS_METADATA)
|
||||||
|
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.state
|
package org.jetbrains.kotlin.codegen.state
|
||||||
|
|
||||||
typealias JvmMethodExceptionTypes = Array<out String>?
|
typealias JvmMethodExceptionTypes = Array<out String?>?
|
||||||
+1
-1
@@ -5,4 +5,4 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.codegen.state
|
package org.jetbrains.kotlin.codegen.state
|
||||||
|
|
||||||
typealias JvmMethodExceptionTypes = Array<out String?>?
|
typealias JvmMethodExceptionTypes = Array<out String>?
|
||||||
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized
|
import org.jetbrains.kotlin.load.java.descriptors.getImplClassNameForDeserialized
|
||||||
import org.jetbrains.kotlin.load.java.getJvmMethodNameIfSpecial
|
import org.jetbrains.kotlin.load.java.getJvmMethodNameIfSpecial
|
||||||
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinReflectingJvmDescriptor
|
import org.jetbrains.kotlin.load.java.getOverriddenBuiltinReflectingJvmDescriptor
|
||||||
@@ -50,6 +51,7 @@ import org.jetbrains.kotlin.resolve.*
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall
|
import org.jetbrains.kotlin.resolve.BindingContextUtils.getDelegationConstructorCall
|
||||||
import org.jetbrains.kotlin.resolve.BindingContextUtils.isBoxedLocalCapturedInClosure
|
import org.jetbrains.kotlin.resolve.BindingContextUtils.isBoxedLocalCapturedInClosure
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils.*
|
import org.jetbrains.kotlin.resolve.DescriptorUtils.*
|
||||||
|
import org.jetbrains.kotlin.resolve.annotations.hasJvmStaticAnnotation
|
||||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
@@ -60,6 +62,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isPublishedApi
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.DEFAULT_CONSTRUCTOR_MARKER
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.JAVA_LANG_RECORD_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.isCompiledToJvmDefault
|
import org.jetbrains.kotlin.resolve.jvm.annotations.isCompiledToJvmDefault
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodGenericSignature
|
||||||
@@ -379,7 +382,8 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
val originalDescriptor = descriptor.original
|
val originalDescriptor = descriptor.original
|
||||||
return CallableMethod(
|
return CallableMethod(
|
||||||
owner, owner, { mapDefaultMethod(originalDescriptor, OwnerKind.IMPLEMENTATION) }, method, INVOKESPECIAL,
|
owner, owner, { mapDefaultMethod(originalDescriptor, OwnerKind.IMPLEMENTATION) }, method, INVOKESPECIAL,
|
||||||
null, null, null, null, null, originalDescriptor.returnType, isInterfaceMethod = false, isDefaultMethodInInterface = false
|
null, null, null, null, null, originalDescriptor.returnType, isInterfaceMethod = false, isDefaultMethodInInterface = false,
|
||||||
|
boxInlineClassBeforeInvoke = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,6 +406,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
val dispatchReceiverKotlinType: KotlinType?
|
val dispatchReceiverKotlinType: KotlinType?
|
||||||
var isInterfaceMember = false
|
var isInterfaceMember = false
|
||||||
var isDefaultMethodInInterface = false
|
var isDefaultMethodInInterface = false
|
||||||
|
var boxInlineClassBeforeInvoke = false
|
||||||
|
|
||||||
if (functionParent is ClassDescriptor) {
|
if (functionParent is ClassDescriptor) {
|
||||||
val declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor)
|
val declarationFunctionDescriptor = findAnyDeclaration(functionDescriptor)
|
||||||
@@ -445,18 +450,22 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val toInlinedErasedClass = functionParent.isInline &&
|
val toInlinedErasedClass = functionParent.isInlineClass() &&
|
||||||
(!isAccessor(functionDescriptor) || isInlineClassConstructorAccessor(functionDescriptor))
|
(!isAccessor(functionDescriptor) || isInlineClassConstructorAccessor(functionDescriptor))
|
||||||
|
|
||||||
if (toInlinedErasedClass) {
|
if (toInlinedErasedClass) {
|
||||||
functionDescriptor = descriptor
|
functionDescriptor = descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
val isStaticInvocation =
|
val isFakeOverrideOfJvmDefault = toInlinedErasedClass &&
|
||||||
isStaticDeclaration(functionDescriptor) && functionDescriptor !is ImportedFromObjectCallableDescriptor<*> ||
|
functionDescriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE &&
|
||||||
isStaticAccessor(functionDescriptor) ||
|
functionDescriptor.overridesJvmDefault()
|
||||||
functionDescriptor.isJvmStaticInObjectOrClassOrInterface() ||
|
|
||||||
toInlinedErasedClass
|
val isStaticInvocation = !isFakeOverrideOfJvmDefault &&
|
||||||
|
(isStaticDeclaration(functionDescriptor) && functionDescriptor !is ImportedFromObjectCallableDescriptor<*> ||
|
||||||
|
isStaticAccessor(functionDescriptor) ||
|
||||||
|
functionDescriptor.isJvmStaticInObjectOrClassOrInterface() ||
|
||||||
|
toInlinedErasedClass)
|
||||||
when {
|
when {
|
||||||
isStaticInvocation -> {
|
isStaticInvocation -> {
|
||||||
invokeOpcode = INVOKESTATIC
|
invokeOpcode = INVOKESTATIC
|
||||||
@@ -466,8 +475,13 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
invokeOpcode = INVOKEINTERFACE
|
invokeOpcode = INVOKEINTERFACE
|
||||||
isInterfaceMember = true
|
isInterfaceMember = true
|
||||||
}
|
}
|
||||||
|
isFakeOverrideOfJvmDefault -> {
|
||||||
|
invokeOpcode = INVOKEVIRTUAL
|
||||||
|
boxInlineClassBeforeInvoke = true
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val isPrivateFunInvocation = DescriptorVisibilities.isPrivate(functionDescriptor.visibility) && !functionDescriptor.isSuspend
|
val isPrivateFunInvocation =
|
||||||
|
DescriptorVisibilities.isPrivate(functionDescriptor.visibility) && !functionDescriptor.isSuspend
|
||||||
invokeOpcode = if (superCall || isPrivateFunInvocation) INVOKESPECIAL else INVOKEVIRTUAL
|
invokeOpcode = if (superCall || isPrivateFunInvocation) INVOKESPECIAL else INVOKEVIRTUAL
|
||||||
isInterfaceMember = false
|
isInterfaceMember = false
|
||||||
}
|
}
|
||||||
@@ -479,7 +493,7 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
else
|
else
|
||||||
functionDescriptor.original
|
functionDescriptor.original
|
||||||
|
|
||||||
signature = if (toInlinedErasedClass)
|
signature = if (toInlinedErasedClass && !isFakeOverrideOfJvmDefault)
|
||||||
mapSignatureForInlineErasedClassSkipGeneric(functionToCall)
|
mapSignatureForInlineErasedClassSkipGeneric(functionToCall)
|
||||||
else
|
else
|
||||||
mapSignature(
|
mapSignature(
|
||||||
@@ -547,10 +561,18 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
signature, invokeOpcode, thisClass, dispatchReceiverKotlinType, receiverParameterType, extensionReceiverKotlinType,
|
signature, invokeOpcode, thisClass, dispatchReceiverKotlinType, receiverParameterType, extensionReceiverKotlinType,
|
||||||
calleeType, returnKotlinType,
|
calleeType, returnKotlinType,
|
||||||
if (jvmTarget >= JvmTarget.JVM_1_8) isInterfaceMember else invokeOpcode == INVOKEINTERFACE,
|
if (jvmTarget >= JvmTarget.JVM_1_8) isInterfaceMember else invokeOpcode == INVOKEINTERFACE,
|
||||||
isDefaultMethodInInterface
|
isDefaultMethodInInterface, boxInlineClassBeforeInvoke
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun CallableMemberDescriptor.overridesJvmDefault(): Boolean {
|
||||||
|
if (kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) {
|
||||||
|
return overriddenDescriptors.any { it.overridesJvmDefault() }
|
||||||
|
}
|
||||||
|
if (isCompiledToJvmDefault(jvmDefaultMode)) return true
|
||||||
|
return (containingDeclaration as? JavaClassDescriptor)?.kind == ClassKind.INTERFACE && modality != Modality.ABSTRACT
|
||||||
|
}
|
||||||
|
|
||||||
fun mapFunctionName(descriptor: FunctionDescriptor, kind: OwnerKind?): String {
|
fun mapFunctionName(descriptor: FunctionDescriptor, kind: OwnerKind?): String {
|
||||||
if (descriptor !is JavaCallableMemberDescriptor) {
|
if (descriptor !is JavaCallableMemberDescriptor) {
|
||||||
val platformName = getJvmName(descriptor)
|
val platformName = getJvmName(descriptor)
|
||||||
@@ -563,10 +585,16 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
return when {
|
return when {
|
||||||
descriptor is PropertyAccessorDescriptor -> {
|
descriptor is PropertyAccessorDescriptor -> {
|
||||||
val property = descriptor.correspondingProperty
|
val property = descriptor.correspondingProperty
|
||||||
if (isAnnotationClass(property.containingDeclaration)) {
|
val containingDeclaration = property.containingDeclaration
|
||||||
|
|
||||||
|
if (isAnnotationClass(containingDeclaration) &&
|
||||||
|
(!property.hasJvmStaticAnnotation() && !descriptor.hasJvmStaticAnnotation())
|
||||||
|
) {
|
||||||
return property.name.asString()
|
return property.name.asString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((containingDeclaration as? ClassDescriptor)?.hasJavaLangRecordSupertype() == true) return property.name.asString()
|
||||||
|
|
||||||
val isAccessor = property is AccessorForPropertyDescriptor
|
val isAccessor = property is AccessorForPropertyDescriptor
|
||||||
val propertyName = if (isAccessor)
|
val propertyName = if (isAccessor)
|
||||||
(property as AccessorForPropertyDescriptor).accessorSuffix
|
(property as AccessorForPropertyDescriptor).accessorSuffix
|
||||||
@@ -601,6 +629,9 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ClassDescriptor.hasJavaLangRecordSupertype() =
|
||||||
|
typeConstructor.supertypes.any { KotlinBuiltIns.isConstructedFromGivenClass(it, JAVA_LANG_RECORD_FQ_NAME) }
|
||||||
|
|
||||||
private val shouldMangleByReturnType =
|
private val shouldMangleByReturnType =
|
||||||
languageVersionSettings.supportsFeature(LanguageFeature.MangleClassMembersReturningInlineClasses)
|
languageVersionSettings.supportsFeature(LanguageFeature.MangleClassMembersReturningInlineClasses)
|
||||||
|
|
||||||
@@ -965,7 +996,8 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
if ((isFunctionExpression(descriptor) || isFunctionLiteral(descriptor)) && returnType.isInlineClassType()) return true
|
if ((isFunctionExpression(descriptor) || isFunctionLiteral(descriptor)) && returnType.isInlineClassType()) return true
|
||||||
|
|
||||||
return isJvmPrimitive(returnType) &&
|
return isJvmPrimitive(returnType) &&
|
||||||
getAllOverriddenDescriptors(descriptor).any { !isJvmPrimitive(it.returnType!!) }
|
getAllOverriddenDescriptors(descriptor).any { !isJvmPrimitive(it.returnType!!) } ||
|
||||||
|
returnType.isInlineClassType() && descriptor is JavaMethodDescriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isJvmPrimitive(kotlinType: KotlinType) =
|
private fun isJvmPrimitive(kotlinType: KotlinType) =
|
||||||
@@ -1031,7 +1063,11 @@ class KotlinTypeMapper @JvmOverloads constructor(
|
|||||||
|
|
||||||
fun writeParameterType(sw: JvmSignatureWriter, type: KotlinType, callableDescriptor: CallableDescriptor?) {
|
fun writeParameterType(sw: JvmSignatureWriter, type: KotlinType, callableDescriptor: CallableDescriptor?) {
|
||||||
if (sw.skipGenericSignature()) {
|
if (sw.skipGenericSignature()) {
|
||||||
mapType(type, sw, TypeMappingMode.DEFAULT)
|
if (type.isInlineClassType() && callableDescriptor is JavaMethodDescriptor) {
|
||||||
|
mapType(type, sw, TypeMappingMode.GENERIC_ARGUMENT)
|
||||||
|
} else {
|
||||||
|
mapType(type, sw, TypeMappingMode.DEFAULT)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,12 @@ package org.jetbrains.kotlin.codegen.state
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspendFunction
|
import org.jetbrains.kotlin.codegen.coroutines.unwrapInitialDescriptorForSuspendFunction
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
|
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||||
import org.jetbrains.kotlin.name.Name
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
import org.jetbrains.kotlin.resolve.InlineClassDescriptorResolver
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||||
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForParameterTypes
|
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForParameterTypes
|
||||||
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
import org.jetbrains.kotlin.resolve.jvm.requiresFunctionNameManglingForReturnType
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
@@ -85,6 +85,7 @@ fun getManglingSuffixBasedOnKotlinSignature(
|
|||||||
): String? {
|
): String? {
|
||||||
if (descriptor !is FunctionDescriptor) return null
|
if (descriptor !is FunctionDescriptor) return null
|
||||||
if (descriptor is ConstructorDescriptor) return null
|
if (descriptor is ConstructorDescriptor) return null
|
||||||
|
if (descriptor is JavaMethodDescriptor) return null
|
||||||
if (InlineClassDescriptorResolver.isSynthesizedBoxOrUnboxMethod(descriptor)) return null
|
if (InlineClassDescriptorResolver.isSynthesizedBoxOrUnboxMethod(descriptor)) return null
|
||||||
|
|
||||||
// Don't mangle functions with '@JvmName' annotation.
|
// Don't mangle functions with '@JvmName' annotation.
|
||||||
@@ -111,7 +112,7 @@ fun getManglingSuffixBasedOnKotlinSignature(
|
|||||||
private fun getInfoForMangling(type: KotlinType): InfoForMangling? {
|
private fun getInfoForMangling(type: KotlinType): InfoForMangling? {
|
||||||
val descriptor = type.constructor.declarationDescriptor ?: return null
|
val descriptor = type.constructor.declarationDescriptor ?: return null
|
||||||
return when (descriptor) {
|
return when (descriptor) {
|
||||||
is ClassDescriptor -> InfoForMangling(descriptor.fqNameUnsafe, descriptor.isInline, type.isMarkedNullable)
|
is ClassDescriptor -> InfoForMangling(descriptor.fqNameUnsafe, descriptor.isInlineClass(), type.isMarkedNullable)
|
||||||
|
|
||||||
is TypeParameterDescriptor -> {
|
is TypeParameterDescriptor -> {
|
||||||
getInfoForMangling(descriptor.representativeUpperBound)
|
getInfoForMangling(descriptor.representativeUpperBound)
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.resolve.isInlineClass
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||||
|
|
||||||
@@ -93,4 +94,4 @@ fun KotlinType.removeExternalProjections(): KotlinType {
|
|||||||
|
|
||||||
fun isInlineClassConstructorAccessor(descriptor: FunctionDescriptor): Boolean =
|
fun isInlineClassConstructorAccessor(descriptor: FunctionDescriptor): Boolean =
|
||||||
descriptor is AccessorForConstructorDescriptor &&
|
descriptor is AccessorForConstructorDescriptor &&
|
||||||
descriptor.calleeDescriptor.constructedClass.isInline
|
descriptor.calleeDescriptor.constructedClass.isInlineClass()
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
|
||||||
|
import org.jetbrains.kotlin.ideaExt.idea
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
@@ -69,10 +70,20 @@ dependencies {
|
|||||||
antLauncherJar(toolsJar())
|
antLauncherJar(toolsJar())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val generationRoot = projectDir.resolve("tests-gen")
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
"main" {}
|
"main" {}
|
||||||
"test" {
|
"test" {
|
||||||
projectDefault()
|
projectDefault()
|
||||||
|
this.java.srcDir(generationRoot.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kotlinBuildProperties.isInJpsBuildIdeaSync) {
|
||||||
|
apply(plugin = "idea")
|
||||||
|
idea {
|
||||||
|
this.module.generatedSourceDirs.add(generationRoot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +98,9 @@ projectTest(parallel = true) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val generateTests by generator("org.jetbrains.kotlin.generators.tests.GenerateCompilerTestsKt")
|
val generateTestData by generator("org.jetbrains.kotlin.generators.tests.GenerateCompilerTestDataKt")
|
||||||
|
val generateTests by generator("org.jetbrains.kotlin.generators.tests.GenerateCompilerTestsKt") {
|
||||||
|
dependsOn(generateTestData)
|
||||||
|
}
|
||||||
|
|
||||||
testsJar()
|
testsJar()
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ if "%_KOTLIN_RUNNER%"=="1" (
|
|||||||
"%_JAVACMD%" %JAVA_OPTS% "-Dkotlin.home=%_KOTLIN_HOME%" -cp "%_KOTLIN_HOME%\lib\kotlin-runner.jar" ^
|
"%_JAVACMD%" %JAVA_OPTS% "-Dkotlin.home=%_KOTLIN_HOME%" -cp "%_KOTLIN_HOME%\lib\kotlin-runner.jar" ^
|
||||||
org.jetbrains.kotlin.runner.Main %KOTLIN_OPTS%
|
org.jetbrains.kotlin.runner.Main %KOTLIN_OPTS%
|
||||||
) else (
|
) else (
|
||||||
|
setlocal EnableDelayedExpansion
|
||||||
SET _ADDITIONAL_CLASSPATH=
|
SET _ADDITIONAL_CLASSPATH=
|
||||||
|
|
||||||
if not "%_KOTLIN_TOOL%"=="" (
|
if not "%_KOTLIN_TOOL%"=="" (
|
||||||
@@ -56,7 +57,7 @@ if "%_KOTLIN_RUNNER%"=="1" (
|
|||||||
)
|
)
|
||||||
|
|
||||||
"%_JAVACMD%" %JAVA_OPTS% -noverify -cp "%_KOTLIN_HOME%\lib\kotlin-preloader.jar" ^
|
"%_JAVACMD%" %JAVA_OPTS% -noverify -cp "%_KOTLIN_HOME%\lib\kotlin-preloader.jar" ^
|
||||||
org.jetbrains.kotlin.preloading.Preloader -cp "%_KOTLIN_HOME%\lib\kotlin-compiler.jar%_ADDITIONAL_CLASSPATH%" ^
|
org.jetbrains.kotlin.preloading.Preloader -cp "%_KOTLIN_HOME%\lib\kotlin-compiler.jar!_ADDITIONAL_CLASSPATH!" ^
|
||||||
%_KOTLIN_COMPILER% %KOTLIN_OPTS%
|
%_KOTLIN_COMPILER% %KOTLIN_OPTS%
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
<idea-plugin>
|
||||||
|
<id>org.jetbrains.kotlin</id>
|
||||||
|
<version>1.2</version>
|
||||||
|
|
||||||
|
<!-- Don't add more extension points here! Logic in KotlinCoreEnvironment assumes that there is only one EP. -->
|
||||||
|
<!-- And this file should be removed once 202 is no longer supported -->
|
||||||
|
<extensionPoints>
|
||||||
|
<extensionPoint qualifiedName="com.intellij.psi.classFileDecompiler"
|
||||||
|
interface="com.intellij.psi.compiled.ClassFileDecompilers$Decompiler"
|
||||||
|
dynamic="true"/>
|
||||||
|
</extensionPoints>
|
||||||
|
</idea-plugin>
|
||||||
+3
@@ -125,6 +125,9 @@ class K2JSCompilerArguments : CommonCompilerArguments() {
|
|||||||
@Argument(value = "-Xir-dce-print-reachability-info", description = "Print declarations' reachability info to stdout during performing DCE")
|
@Argument(value = "-Xir-dce-print-reachability-info", description = "Print declarations' reachability info to stdout during performing DCE")
|
||||||
var irDcePrintReachabilityInfo: Boolean by FreezableVar(false)
|
var irDcePrintReachabilityInfo: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
|
@Argument(value = "-Xir-property-lazy-initialization", description = "Perform lazy initialization for properties")
|
||||||
|
var irPropertyLazyInitialization: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
@Argument(value = "-Xir-only", description = "Disables pre-IR backend")
|
@Argument(value = "-Xir-only", description = "Disables pre-IR backend")
|
||||||
var irOnly: Boolean by FreezableVar(false)
|
var irOnly: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
|
|||||||
+8
@@ -418,6 +418,13 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
|||||||
)
|
)
|
||||||
var useOldInlineClassesManglingScheme: Boolean by FreezableVar(false)
|
var useOldInlineClassesManglingScheme: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
|
@Argument(
|
||||||
|
value = "-Xjvm-enable-preview",
|
||||||
|
description = "Allow using features from Java language that are in preview phase.\n" +
|
||||||
|
"Works as `--enable-preview` in Java. All class files are marked as preview-generated thus it won't be possible to use them in release environment"
|
||||||
|
)
|
||||||
|
var enableJvmPreview: Boolean by FreezableVar(false)
|
||||||
|
|
||||||
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
|
||||||
val result = super.configureAnalysisFlags(collector)
|
val result = super.configureAnalysisFlags(collector)
|
||||||
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
result[JvmAnalysisFlags.strictMetadataVersionSemantics] = strictMetadataVersionSemantics
|
||||||
@@ -438,6 +445,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
|||||||
result[JvmAnalysisFlags.sanitizeParentheses] = sanitizeParentheses
|
result[JvmAnalysisFlags.sanitizeParentheses] = sanitizeParentheses
|
||||||
result[JvmAnalysisFlags.suppressMissingBuiltinsError] = suppressMissingBuiltinsError
|
result[JvmAnalysisFlags.suppressMissingBuiltinsError] = suppressMissingBuiltinsError
|
||||||
result[JvmAnalysisFlags.irCheckLocalNames] = irCheckLocalNames
|
result[JvmAnalysisFlags.irCheckLocalNames] = irCheckLocalNames
|
||||||
|
result[JvmAnalysisFlags.enableJvmPreview] = enableJvmPreview
|
||||||
result[AnalysisFlags.reportErrorsOnIrDependencies] = !useIR && !useFir && !allowJvmIrDependencies
|
result[AnalysisFlags.reportErrorsOnIrDependencies] = !useIR && !useFir && !allowJvmIrDependencies
|
||||||
result[JvmAnalysisFlags.disableUltraLightClasses] = disableUltraLightClasses
|
result[JvmAnalysisFlags.disableUltraLightClasses] = disableUltraLightClasses
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -27,7 +27,10 @@ import org.jetbrains.kotlin.cli.common.messages.MessageUtil
|
|||||||
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
|
||||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||||
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
|
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
|
||||||
import org.jetbrains.kotlin.config.*
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
|
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||||
|
import org.jetbrains.kotlin.config.Services
|
||||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||||
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
|
import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider
|
||||||
@@ -261,7 +264,8 @@ class K2JsIrCompiler : CLICompiler<K2JSCompilerArguments>() {
|
|||||||
generateDceJs = arguments.irDce,
|
generateDceJs = arguments.irDce,
|
||||||
dceDriven = arguments.irDceDriven,
|
dceDriven = arguments.irDceDriven,
|
||||||
multiModule = arguments.irPerModule,
|
multiModule = arguments.irPerModule,
|
||||||
relativeRequirePath = true
|
relativeRequirePath = true,
|
||||||
|
propertyLazyInitialization = arguments.irPropertyLazyInitialization,
|
||||||
)
|
)
|
||||||
} catch (e: JsIrCompilationError) {
|
} catch (e: JsIrCompilationError) {
|
||||||
return COMPILATION_ERROR
|
return COMPILATION_ERROR
|
||||||
|
|||||||
+4
-5
@@ -39,7 +39,6 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
|
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmBindingContextSlices
|
import org.jetbrains.kotlin.resolve.jvm.JvmBindingContextSlices
|
||||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||||
@@ -128,7 +127,7 @@ class AnalyzerWithCompilerReport(
|
|||||||
psiElement: E, factory: DiagnosticFactory0<E>, val message: String
|
psiElement: E, factory: DiagnosticFactory0<E>, val message: String
|
||||||
) : SimpleDiagnostic<E>(psiElement, factory, Severity.ERROR) {
|
) : SimpleDiagnostic<E>(psiElement, factory, Severity.ERROR) {
|
||||||
|
|
||||||
override fun isValid(): Boolean = true
|
override val isValid: Boolean = true
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -154,16 +153,16 @@ class AnalyzerWithCompilerReport(
|
|||||||
return diagnostic.severity == Severity.ERROR
|
return diagnostic.severity == Severity.ERROR
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportDiagnostics(unsortedDiagnostics: Diagnostics, reporter: DiagnosticMessageReporter): Boolean {
|
fun reportDiagnostics(unsortedDiagnostics: GenericDiagnostics<*>, reporter: DiagnosticMessageReporter): Boolean {
|
||||||
var hasErrors = false
|
var hasErrors = false
|
||||||
val diagnostics = sortedDiagnostics(unsortedDiagnostics.all())
|
val diagnostics = sortedDiagnostics(unsortedDiagnostics.all().filterIsInstance<Diagnostic>())
|
||||||
for (diagnostic in diagnostics) {
|
for (diagnostic in diagnostics) {
|
||||||
hasErrors = hasErrors or reportDiagnostic(diagnostic, reporter)
|
hasErrors = hasErrors or reportDiagnostic(diagnostic, reporter)
|
||||||
}
|
}
|
||||||
return hasErrors
|
return hasErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reportDiagnostics(diagnostics: Diagnostics, messageCollector: MessageCollector): Boolean {
|
fun reportDiagnostics(diagnostics: GenericDiagnostics<*>, messageCollector: MessageCollector): Boolean {
|
||||||
val hasErrors = reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector))
|
val hasErrors = reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector))
|
||||||
|
|
||||||
if (diagnostics.any { it.factory == Errors.INCOMPATIBLE_CLASS }) {
|
if (diagnostics.any { it.factory == Errors.INCOMPATIBLE_CLASS }) {
|
||||||
|
|||||||
-36
@@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.cli.common.messages
|
|
||||||
|
|
||||||
import com.intellij.psi.PsiFile
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class behaviour is the same as [MessageCollector.report] in [AnalyzerWithCompilerReport.reportDiagnostic].
|
|
||||||
*/
|
|
||||||
class DefaultDiagnosticReporter(override val messageCollector: MessageCollector) : MessageCollectorBasedReporter
|
|
||||||
|
|
||||||
interface MessageCollectorBasedReporter : DiagnosticMessageReporter {
|
|
||||||
val messageCollector: MessageCollector
|
|
||||||
|
|
||||||
override fun report(diagnostic: Diagnostic, file: PsiFile, render: String) = messageCollector.report(
|
|
||||||
AnalyzerWithCompilerReport.convertSeverity(diagnostic.severity),
|
|
||||||
render,
|
|
||||||
MessageUtil.psiFileToMessageLocation(file, file.name, DiagnosticUtils.getLineAndColumn(diagnostic))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -17,8 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.cli.common.messages;
|
package org.jetbrains.kotlin.cli.common.messages;
|
||||||
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.openapi.vfs.impl.jar.CoreJarVirtualFile;
|
|
||||||
import com.intellij.openapi.vfs.local.CoreLocalVirtualFile;
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -53,10 +51,6 @@ public class MessageUtil {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static String virtualFileToPath(@NotNull VirtualFile virtualFile) {
|
public static String virtualFileToPath(@NotNull VirtualFile virtualFile) {
|
||||||
// Convert path to platform-dependent format when virtualFile is local file.
|
return toSystemDependentName(virtualFile.getPath());
|
||||||
if (virtualFile instanceof CoreLocalVirtualFile || virtualFile instanceof CoreJarVirtualFile) {
|
|
||||||
return toSystemDependentName(virtualFile.getPath());
|
|
||||||
}
|
|
||||||
return virtualFile.getPath();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.cli.common.messages;
|
|
||||||
|
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import com.intellij.psi.PsiFile;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
|
|
||||||
import org.jetbrains.kotlin.diagnostics.PsiDiagnosticUtils;
|
|
||||||
|
|
||||||
import static com.intellij.openapi.util.io.FileUtil.toSystemDependentName;
|
|
||||||
|
|
||||||
public class MessageUtil {
|
|
||||||
private MessageUtil() {}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static CompilerMessageLocation psiElementToMessageLocation(@Nullable PsiElement element) {
|
|
||||||
if (element == null) return null;
|
|
||||||
PsiFile file = element.getContainingFile();
|
|
||||||
return psiFileToMessageLocation(file, "<no path>", DiagnosticUtils.getLineAndColumnInPsiFile(file, element.getTextRange()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static CompilerMessageLocation psiFileToMessageLocation(
|
|
||||||
@NotNull PsiFile file,
|
|
||||||
@Nullable String defaultValue,
|
|
||||||
@NotNull PsiDiagnosticUtils.LineAndColumn lineAndColumn
|
|
||||||
) {
|
|
||||||
VirtualFile virtualFile = file.getVirtualFile();
|
|
||||||
String path = virtualFile != null ? virtualFileToPath(virtualFile) : defaultValue;
|
|
||||||
return CompilerMessageLocation.create(path, lineAndColumn.getLine(), lineAndColumn.getColumn(), lineAndColumn.getLineContent());
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static String virtualFileToPath(@NotNull VirtualFile virtualFile) {
|
|
||||||
return toSystemDependentName(virtualFile.getPath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -77,15 +77,23 @@ open class CliBindingTrace @TestOnly constructor() : BindingTraceContext() {
|
|||||||
this.kotlinCodeAnalyzer = kotlinCodeAnalyzer
|
this.kotlinCodeAnalyzer = kotlinCodeAnalyzer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun <K, V> get(slice: ReadOnlySlice<K, V>, key: K): V? {
|
override fun <K, V> get(slice: ReadOnlySlice<K, V>, key: K): V? {
|
||||||
val value = super.get(slice, key)
|
val value = super.get(slice, key)
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
if (BindingContext.FUNCTION === slice || BindingContext.VARIABLE === slice) {
|
if (key is KtDeclaration) {
|
||||||
if (key is KtDeclaration) {
|
// NB: intentional code duplication, see https://youtrack.jetbrains.com/issue/KT-43296
|
||||||
|
if (BindingContext.FUNCTION === slice) {
|
||||||
if (!KtPsiUtil.isLocal(key)) {
|
if (!KtPsiUtil.isLocal(key)) {
|
||||||
kotlinCodeAnalyzer!!.resolveToDescriptor(key)
|
kotlinCodeAnalyzer!!.resolveToDescriptor(key)
|
||||||
return super.get(slice, key)
|
return super.get(slice, key) as V?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (BindingContext.VARIABLE === slice) {
|
||||||
|
if (!KtPsiUtil.isLocal(key)) {
|
||||||
|
kotlinCodeAnalyzer!!.resolveToDescriptor(key)
|
||||||
|
return super.get(slice, key) as V?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -40,7 +40,6 @@ public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnviron
|
|||||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
||||||
|
|
||||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
||||||
registerApplicationExtensionPoint(ClassFileDecompilers.EP_NAME, ClassFileDecompilers.Decompiler.class);
|
|
||||||
|
|
||||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
||||||
|
|
||||||
@@ -52,4 +51,4 @@ public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnviron
|
|||||||
protected VirtualFileSystem createJrtFileSystem() {
|
protected VirtualFileSystem createJrtFileSystem() {
|
||||||
return new CoreJrtFileSystem();
|
return new CoreJrtFileSystem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-55
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 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.cli.jvm.compiler;
|
|
||||||
|
|
||||||
import com.intellij.DynamicBundle;
|
|
||||||
import com.intellij.codeInsight.ContainerProvider;
|
|
||||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
|
||||||
import com.intellij.core.JavaCoreApplicationEnvironment;
|
|
||||||
import com.intellij.lang.MetaLanguage;
|
|
||||||
import com.intellij.openapi.Disposable;
|
|
||||||
import com.intellij.openapi.extensions.Extensions;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
|
||||||
import com.intellij.psi.FileContextProvider;
|
|
||||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
|
||||||
import com.intellij.psi.compiled.ClassFileDecompilers;
|
|
||||||
import com.intellij.psi.meta.MetaDataContributor;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
|
||||||
|
|
||||||
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
|
|
||||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
|
||||||
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
|
||||||
registerExtensionPoints();
|
|
||||||
return environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
|
||||||
super(parentDisposable, unitTestMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void registerExtensionPoints() {
|
|
||||||
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
|
|
||||||
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
|
|
||||||
|
|
||||||
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
|
||||||
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
|
||||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
|
||||||
|
|
||||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
|
||||||
registerApplicationExtensionPoint(ClassFileDecompilers.getInstance().EP_NAME, ClassFileDecompilers.Decompiler.class);
|
|
||||||
|
|
||||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
|
||||||
|
|
||||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
protected VirtualFileSystem createJrtFileSystem() {
|
|
||||||
return new CoreJrtFileSystem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-53
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.cli.jvm.compiler;
|
|
||||||
|
|
||||||
import com.intellij.DynamicBundle;
|
|
||||||
import com.intellij.codeInsight.ContainerProvider;
|
|
||||||
import com.intellij.codeInsight.runner.JavaMainMethodProvider;
|
|
||||||
import com.intellij.core.JavaCoreApplicationEnvironment;
|
|
||||||
import com.intellij.lang.MetaLanguage;
|
|
||||||
import com.intellij.openapi.Disposable;
|
|
||||||
import com.intellij.openapi.extensions.Extensions;
|
|
||||||
import com.intellij.openapi.vfs.VirtualFileSystem;
|
|
||||||
import com.intellij.psi.FileContextProvider;
|
|
||||||
import com.intellij.psi.augment.PsiAugmentProvider;
|
|
||||||
import com.intellij.psi.meta.MetaDataContributor;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem;
|
|
||||||
|
|
||||||
public class KotlinCoreApplicationEnvironment extends JavaCoreApplicationEnvironment {
|
|
||||||
public static KotlinCoreApplicationEnvironment create(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
|
||||||
KotlinCoreApplicationEnvironment environment = new KotlinCoreApplicationEnvironment(parentDisposable, unitTestMode);
|
|
||||||
registerExtensionPoints();
|
|
||||||
return environment;
|
|
||||||
}
|
|
||||||
|
|
||||||
private KotlinCoreApplicationEnvironment(@NotNull Disposable parentDisposable, boolean unitTestMode) {
|
|
||||||
super(parentDisposable, unitTestMode);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void registerExtensionPoints() {
|
|
||||||
registerApplicationExtensionPoint(DynamicBundle.LanguageBundleEP.EP_NAME, DynamicBundle.LanguageBundleEP.class);
|
|
||||||
registerApplicationExtensionPoint(FileContextProvider.EP_NAME, FileContextProvider.class);
|
|
||||||
|
|
||||||
registerApplicationExtensionPoint(MetaDataContributor.EP_NAME, MetaDataContributor.class);
|
|
||||||
registerApplicationExtensionPoint(PsiAugmentProvider.EP_NAME, PsiAugmentProvider.class);
|
|
||||||
registerApplicationExtensionPoint(JavaMainMethodProvider.EP_NAME, JavaMainMethodProvider.class);
|
|
||||||
|
|
||||||
registerApplicationExtensionPoint(ContainerProvider.EP_NAME, ContainerProvider.class);
|
|
||||||
|
|
||||||
registerApplicationExtensionPoint(MetaLanguage.EP_NAME, MetaLanguage.class);
|
|
||||||
|
|
||||||
IdeaExtensionPoints.INSTANCE.registerVersionSpecificAppExtensionPoints(Extensions.getRootArea());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
protected VirtualFileSystem createJrtFileSystem() {
|
|
||||||
return new CoreJrtFileSystem();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -33,13 +33,16 @@ import com.intellij.openapi.extensions.Extensions
|
|||||||
import com.intellij.openapi.extensions.ExtensionsArea
|
import com.intellij.openapi.extensions.ExtensionsArea
|
||||||
import com.intellij.openapi.fileTypes.PlainTextFileType
|
import com.intellij.openapi.fileTypes.PlainTextFileType
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.roots.LanguageLevelProjectExtension
|
||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
import com.intellij.openapi.util.io.FileUtilRt
|
import com.intellij.openapi.util.io.FileUtilRt
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.openapi.vfs.*
|
import com.intellij.openapi.vfs.*
|
||||||
import com.intellij.openapi.vfs.impl.ZipHandler
|
import com.intellij.openapi.vfs.impl.ZipHandler
|
||||||
|
import com.intellij.pom.java.LanguageLevel
|
||||||
import com.intellij.psi.PsiElementFinder
|
import com.intellij.psi.PsiElementFinder
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
|
import com.intellij.psi.compiled.ClassFileDecompilers
|
||||||
import com.intellij.psi.impl.JavaClassSupersImpl
|
import com.intellij.psi.impl.JavaClassSupersImpl
|
||||||
import com.intellij.psi.impl.PsiElementFinderImpl
|
import com.intellij.psi.impl.PsiElementFinderImpl
|
||||||
import com.intellij.psi.impl.PsiTreeChangePreprocessor
|
import com.intellij.psi.impl.PsiTreeChangePreprocessor
|
||||||
@@ -249,6 +252,8 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
project.putUserData(APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY, fun(roots: List<File>) {
|
project.putUserData(APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY, fun(roots: List<File>) {
|
||||||
updateClasspath(roots.map { JavaSourceRoot(it, null) })
|
updateClasspath(roots.map { JavaSourceRoot(it, null) })
|
||||||
})
|
})
|
||||||
|
|
||||||
|
LanguageLevelProjectExtension.getInstance(project).languageLevel = LanguageLevel.JDK_15_PREVIEW
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun collectAdditionalSources(project: MockProject) {
|
private fun collectAdditionalSources(project: MockProject) {
|
||||||
@@ -509,6 +514,11 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
val applicationEnvironment = KotlinCoreApplicationEnvironment.create(parentDisposable, unitTestMode)
|
val applicationEnvironment = KotlinCoreApplicationEnvironment.create(parentDisposable, unitTestMode)
|
||||||
|
|
||||||
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml")
|
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml")
|
||||||
|
// FIX ME WHEN BUNCH 202 REMOVED: this code is required to support compiler bundled to both 202 and 203.
|
||||||
|
// Please, remove "com.intellij.psi.classFileDecompiler" EP registration once 202 is no longer supported by the compiler
|
||||||
|
if (!Extensions.getRootArea().hasExtensionPoint("com.intellij.psi.classFileDecompiler")) {
|
||||||
|
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/core.xml")
|
||||||
|
}
|
||||||
|
|
||||||
registerApplicationServicesForCLI(applicationEnvironment)
|
registerApplicationServicesForCLI(applicationEnvironment)
|
||||||
registerApplicationServices(applicationEnvironment)
|
registerApplicationServices(applicationEnvironment)
|
||||||
@@ -692,4 +702,4 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,703 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.cli.jvm.compiler
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.ExternalAnnotationsManager
|
||||||
|
import com.intellij.codeInsight.InferredAnnotationsManager
|
||||||
|
import com.intellij.core.CoreApplicationEnvironment
|
||||||
|
import com.intellij.core.CoreJavaFileManager
|
||||||
|
import com.intellij.core.JavaCoreProjectEnvironment
|
||||||
|
import com.intellij.ide.highlighter.JavaFileType
|
||||||
|
import com.intellij.lang.java.JavaParserDefinition
|
||||||
|
import com.intellij.mock.MockProject
|
||||||
|
import com.intellij.openapi.Disposable
|
||||||
|
import com.intellij.openapi.application.TransactionGuard
|
||||||
|
import com.intellij.openapi.application.TransactionGuardImpl
|
||||||
|
import com.intellij.openapi.components.ServiceManager
|
||||||
|
import com.intellij.openapi.diagnostic.Logger
|
||||||
|
import com.intellij.openapi.extensions.Extensions
|
||||||
|
import com.intellij.openapi.extensions.ExtensionsArea
|
||||||
|
import com.intellij.openapi.fileTypes.PlainTextFileType
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.roots.LanguageLevelProjectExtension
|
||||||
|
import com.intellij.openapi.util.Disposer
|
||||||
|
import com.intellij.openapi.util.io.FileUtilRt
|
||||||
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
|
import com.intellij.openapi.vfs.*
|
||||||
|
import com.intellij.openapi.vfs.impl.ZipHandler
|
||||||
|
import com.intellij.pom.java.LanguageLevel
|
||||||
|
import com.intellij.psi.PsiElementFinder
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
|
import com.intellij.psi.compiled.ClassFileDecompilers
|
||||||
|
import com.intellij.psi.impl.JavaClassSupersImpl
|
||||||
|
import com.intellij.psi.impl.PsiElementFinderImpl
|
||||||
|
import com.intellij.psi.impl.PsiTreeChangePreprocessor
|
||||||
|
import com.intellij.psi.impl.file.impl.JavaFileManager
|
||||||
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
|
import com.intellij.psi.util.JavaClassSupers
|
||||||
|
import com.intellij.util.io.URLUtil
|
||||||
|
import com.intellij.util.lang.UrlClassLoader
|
||||||
|
import org.jetbrains.annotations.TestOnly
|
||||||
|
import org.jetbrains.kotlin.asJava.KotlinAsJavaSupport
|
||||||
|
import org.jetbrains.kotlin.asJava.LightClassGenerationSupport
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.FacadeCache
|
||||||
|
import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
||||||
|
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||||
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
|
import org.jetbrains.kotlin.cli.common.CliModuleVisibilityManagerImpl
|
||||||
|
import org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY
|
||||||
|
import org.jetbrains.kotlin.cli.common.config.ContentRoot
|
||||||
|
import org.jetbrains.kotlin.cli.common.config.KotlinSourceRoot
|
||||||
|
import org.jetbrains.kotlin.cli.common.config.kotlinSourceRoots
|
||||||
|
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
|
||||||
|
import org.jetbrains.kotlin.cli.common.extensions.ShellExtension
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.ERROR
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.STRONG_WARNING
|
||||||
|
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||||
|
import org.jetbrains.kotlin.cli.common.toBooleanLenient
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.JvmRuntimeVersionsConsistencyChecker
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.config.*
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.index.*
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.javac.JavacWrapperRegistrar
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleFinder
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.modules.CliJavaModuleResolver
|
||||||
|
import org.jetbrains.kotlin.cli.jvm.modules.CoreJrtFileSystem
|
||||||
|
import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension
|
||||||
|
import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension
|
||||||
|
import org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
|
||||||
|
import org.jetbrains.kotlin.config.*
|
||||||
|
import org.jetbrains.kotlin.extensions.*
|
||||||
|
import org.jetbrains.kotlin.extensions.internal.CandidateInterceptor
|
||||||
|
import org.jetbrains.kotlin.extensions.internal.TypeResolutionInterceptor
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinFileType
|
||||||
|
import org.jetbrains.kotlin.js.translate.extensions.JsSyntheticTranslateExtension
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.KotlinBinaryClassCache
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.ModuleVisibilityManager
|
||||||
|
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
|
||||||
|
import org.jetbrains.kotlin.parsing.KotlinParserDefinition
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
|
||||||
|
import org.jetbrains.kotlin.resolve.ModuleAnnotationsResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.extensions.ExtraImportsProviderExtension
|
||||||
|
import org.jetbrains.kotlin.resolve.extensions.SyntheticResolveExtension
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.extensions.AnalysisHandlerExtension
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.modules.JavaModuleResolver
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.declarations.CliDeclarationProviderFactoryService
|
||||||
|
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
|
||||||
|
import org.jetbrains.kotlin.serialization.DescriptorSerializerPlugin
|
||||||
|
import org.jetbrains.kotlin.utils.PathUtil
|
||||||
|
import java.io.File
|
||||||
|
import java.nio.file.FileSystems
|
||||||
|
import java.util.zip.ZipFile
|
||||||
|
|
||||||
|
class KotlinCoreEnvironment private constructor(
|
||||||
|
val projectEnvironment: JavaCoreProjectEnvironment,
|
||||||
|
private val initialConfiguration: CompilerConfiguration,
|
||||||
|
configFiles: EnvironmentConfigFiles
|
||||||
|
) {
|
||||||
|
|
||||||
|
class ProjectEnvironment(
|
||||||
|
disposable: Disposable,
|
||||||
|
applicationEnvironment: KotlinCoreApplicationEnvironment
|
||||||
|
) :
|
||||||
|
KotlinCoreProjectEnvironment(disposable, applicationEnvironment) {
|
||||||
|
|
||||||
|
private var extensionRegistered = false
|
||||||
|
|
||||||
|
override fun preregisterServices() {
|
||||||
|
registerProjectExtensionPoints(project.extensionArea)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun registerExtensionsFromPlugins(configuration: CompilerConfiguration) {
|
||||||
|
if (!extensionRegistered) {
|
||||||
|
registerPluginExtensionPoints(project)
|
||||||
|
registerExtensionsFromPlugins(project, configuration)
|
||||||
|
extensionRegistered = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun registerJavaPsiFacade() {
|
||||||
|
with(project) {
|
||||||
|
registerService(
|
||||||
|
CoreJavaFileManager::class.java,
|
||||||
|
ServiceManager.getService(this, JavaFileManager::class.java) as CoreJavaFileManager
|
||||||
|
)
|
||||||
|
|
||||||
|
registerKotlinLightClassSupport(project)
|
||||||
|
|
||||||
|
registerService(ExternalAnnotationsManager::class.java, MockExternalAnnotationsManager())
|
||||||
|
registerService(InferredAnnotationsManager::class.java, MockInferredAnnotationsManager())
|
||||||
|
}
|
||||||
|
|
||||||
|
super.registerJavaPsiFacade()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val sourceFiles = mutableListOf<KtFile>()
|
||||||
|
private val rootsIndex: JvmDependenciesDynamicCompoundIndex
|
||||||
|
private val packagePartProviders = mutableListOf<JvmPackagePartProvider>()
|
||||||
|
|
||||||
|
private val classpathRootsResolver: ClasspathRootsResolver
|
||||||
|
private val initialRoots = ArrayList<JavaRoot>()
|
||||||
|
|
||||||
|
val configuration: CompilerConfiguration = initialConfiguration.apply { setupJdkClasspathRoots(configFiles) }.copy()
|
||||||
|
|
||||||
|
init {
|
||||||
|
PersistentFSConstants::class.java.getDeclaredField("ourMaxIntellisenseFileSize")
|
||||||
|
.apply { isAccessible = true }
|
||||||
|
.setInt(null, FileUtilRt.LARGE_FOR_CONTENT_LOADING)
|
||||||
|
|
||||||
|
val project = projectEnvironment.project
|
||||||
|
|
||||||
|
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
|
||||||
|
(projectEnvironment as? ProjectEnvironment)?.registerExtensionsFromPlugins(configuration)
|
||||||
|
// otherwise consider that project environment is properly configured before passing to the environment
|
||||||
|
// TODO: consider some asserts to check important extension points
|
||||||
|
|
||||||
|
project.registerService(DeclarationProviderFactoryService::class.java, CliDeclarationProviderFactoryService(sourceFiles))
|
||||||
|
|
||||||
|
val isJvm = configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||||
|
project.registerService(ModuleVisibilityManager::class.java, CliModuleVisibilityManagerImpl(isJvm))
|
||||||
|
|
||||||
|
registerProjectServicesForCLI(projectEnvironment)
|
||||||
|
|
||||||
|
registerProjectServices(projectEnvironment.project)
|
||||||
|
|
||||||
|
for (extension in CompilerConfigurationExtension.getInstances(project)) {
|
||||||
|
extension.updateConfiguration(configuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceFiles += createKtFiles(project)
|
||||||
|
|
||||||
|
collectAdditionalSources(project)
|
||||||
|
|
||||||
|
sourceFiles.sortBy { it.virtualFile.path }
|
||||||
|
|
||||||
|
val jdkHome = configuration.get(JVMConfigurationKeys.JDK_HOME)
|
||||||
|
val jrtFileSystem = VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.JRT_PROTOCOL)
|
||||||
|
val javaModuleFinder = CliJavaModuleFinder(jdkHome?.path?.let { path ->
|
||||||
|
jrtFileSystem?.findFileByPath(path + URLUtil.JAR_SEPARATOR)
|
||||||
|
})
|
||||||
|
|
||||||
|
val outputDirectory =
|
||||||
|
configuration.get(JVMConfigurationKeys.MODULES)?.singleOrNull()?.getOutputDirectory()
|
||||||
|
?: configuration.get(JVMConfigurationKeys.OUTPUT_DIRECTORY)?.absolutePath
|
||||||
|
|
||||||
|
classpathRootsResolver = ClasspathRootsResolver(
|
||||||
|
PsiManager.getInstance(project),
|
||||||
|
messageCollector,
|
||||||
|
configuration.getList(JVMConfigurationKeys.ADDITIONAL_JAVA_MODULES),
|
||||||
|
this::contentRootToVirtualFile,
|
||||||
|
javaModuleFinder,
|
||||||
|
!configuration.getBoolean(CLIConfigurationKeys.ALLOW_KOTLIN_PACKAGE),
|
||||||
|
outputDirectory?.let(this::findLocalFile)
|
||||||
|
)
|
||||||
|
|
||||||
|
val (initialRoots, javaModules) =
|
||||||
|
classpathRootsResolver.convertClasspathRoots(configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS))
|
||||||
|
this.initialRoots.addAll(initialRoots)
|
||||||
|
|
||||||
|
if (!configuration.getBoolean(JVMConfigurationKeys.SKIP_RUNTIME_VERSION_CHECK) && messageCollector != null) {
|
||||||
|
JvmRuntimeVersionsConsistencyChecker.checkCompilerClasspathConsistency(
|
||||||
|
messageCollector,
|
||||||
|
configuration,
|
||||||
|
initialRoots.mapNotNull { (file, type) -> if (type == JavaRoot.RootType.BINARY) file else null }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val (roots, singleJavaFileRoots) =
|
||||||
|
initialRoots.partition { (file) -> file.isDirectory || file.extension != JavaFileType.DEFAULT_EXTENSION }
|
||||||
|
|
||||||
|
// REPL and kapt2 update classpath dynamically
|
||||||
|
rootsIndex = JvmDependenciesDynamicCompoundIndex().apply {
|
||||||
|
addIndex(JvmDependenciesIndexImpl(roots))
|
||||||
|
updateClasspathFromRootsIndex(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
(ServiceManager.getService(project, CoreJavaFileManager::class.java) as KotlinCliJavaFileManagerImpl).initialize(
|
||||||
|
rootsIndex,
|
||||||
|
packagePartProviders,
|
||||||
|
SingleJavaFileRootsIndex(singleJavaFileRoots),
|
||||||
|
configuration.getBoolean(JVMConfigurationKeys.USE_PSI_CLASS_FILES_READING)
|
||||||
|
)
|
||||||
|
|
||||||
|
project.registerService(
|
||||||
|
JavaModuleResolver::class.java,
|
||||||
|
CliJavaModuleResolver(classpathRootsResolver.javaModuleGraph, javaModules, javaModuleFinder.systemModules.toList())
|
||||||
|
)
|
||||||
|
|
||||||
|
val finderFactory = CliVirtualFileFinderFactory(rootsIndex)
|
||||||
|
project.registerService(MetadataFinderFactory::class.java, finderFactory)
|
||||||
|
project.registerService(VirtualFileFinderFactory::class.java, finderFactory)
|
||||||
|
|
||||||
|
project.putUserData(APPEND_JAVA_SOURCE_ROOTS_HANDLER_KEY, fun(roots: List<File>) {
|
||||||
|
updateClasspath(roots.map { JavaSourceRoot(it, null) })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun collectAdditionalSources(project: MockProject) {
|
||||||
|
var unprocessedSources: Collection<KtFile> = sourceFiles
|
||||||
|
val processedSources = HashSet<KtFile>()
|
||||||
|
val processedSourcesByExtension = HashMap<CollectAdditionalSourcesExtension, Collection<KtFile>>()
|
||||||
|
// repeat feeding extensions with sources while new sources a being added
|
||||||
|
var sourceCollectionIterations = 0
|
||||||
|
while (unprocessedSources.isNotEmpty()) {
|
||||||
|
if (sourceCollectionIterations++ > 10) { // TODO: consider using some appropriate global constant
|
||||||
|
throw IllegalStateException("Unable to collect additional sources in reasonable number of iterations")
|
||||||
|
}
|
||||||
|
processedSources.addAll(unprocessedSources)
|
||||||
|
val allNewSources = ArrayList<KtFile>()
|
||||||
|
for (extension in CollectAdditionalSourcesExtension.getInstances(project)) {
|
||||||
|
// do not feed the extension with the sources it returned on the previous iteration
|
||||||
|
val sourcesToProcess = unprocessedSources - (processedSourcesByExtension[extension] ?: emptyList())
|
||||||
|
val newSources = extension.collectAdditionalSourcesAndUpdateConfiguration(sourcesToProcess, configuration, project)
|
||||||
|
if (newSources.isNotEmpty()) {
|
||||||
|
allNewSources.addAll(newSources)
|
||||||
|
processedSourcesByExtension[extension] = newSources
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unprocessedSources = allNewSources.filterNot { processedSources.contains(it) }.distinct()
|
||||||
|
sourceFiles += unprocessedSources
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addKotlinSourceRoots(rootDirs: List<File>) {
|
||||||
|
val roots = rootDirs.map { KotlinSourceRoot(it.absolutePath, isCommon = false) }
|
||||||
|
sourceFiles += createSourceFilesFromSourceRoots(configuration, project, roots)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createPackagePartProvider(scope: GlobalSearchScope): JvmPackagePartProvider {
|
||||||
|
return JvmPackagePartProvider(configuration.languageVersionSettings, scope).apply {
|
||||||
|
addRoots(initialRoots, configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY))
|
||||||
|
packagePartProviders += this
|
||||||
|
(ModuleAnnotationsResolver.getInstance(project) as CliModuleAnnotationsResolver).addPackagePartProvider(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val VirtualFile.javaFiles: List<VirtualFile>
|
||||||
|
get() = mutableListOf<VirtualFile>().apply {
|
||||||
|
VfsUtilCore.processFilesRecursively(this@javaFiles) { file ->
|
||||||
|
if (file.fileType == JavaFileType.INSTANCE) {
|
||||||
|
add(file)
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val allJavaFiles: List<File>
|
||||||
|
get() = configuration.javaSourceRoots
|
||||||
|
.mapNotNull(this::findLocalFile)
|
||||||
|
.flatMap { it.javaFiles }
|
||||||
|
.map { File(it.canonicalPath) }
|
||||||
|
|
||||||
|
fun registerJavac(
|
||||||
|
javaFiles: List<File> = allJavaFiles,
|
||||||
|
kotlinFiles: List<KtFile> = sourceFiles,
|
||||||
|
arguments: Array<String>? = null,
|
||||||
|
bootClasspath: List<File>? = null,
|
||||||
|
sourcePath: List<File>? = null
|
||||||
|
): Boolean {
|
||||||
|
return JavacWrapperRegistrar.registerJavac(
|
||||||
|
projectEnvironment.project, configuration, javaFiles, kotlinFiles, arguments, bootClasspath, sourcePath,
|
||||||
|
LightClassGenerationSupport.getInstance(project), packagePartProviders
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val applicationEnvironment: CoreApplicationEnvironment
|
||||||
|
get() = projectEnvironment.environment
|
||||||
|
|
||||||
|
val project: Project
|
||||||
|
get() = projectEnvironment.project
|
||||||
|
|
||||||
|
internal fun countLinesOfCode(sourceFiles: List<KtFile>): Int =
|
||||||
|
sourceFiles.sumBy { sourceFile ->
|
||||||
|
val text = sourceFile.text
|
||||||
|
StringUtil.getLineBreakCount(text) + (if (StringUtil.endsWithLineBreak(text)) 0 else 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateClasspathFromRootsIndex(index: JvmDependenciesIndex) {
|
||||||
|
index.indexedRoots.forEach {
|
||||||
|
projectEnvironment.addSourcesToClasspath(it.file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun updateClasspath(contentRoots: List<ContentRoot>): List<File>? {
|
||||||
|
// TODO: add new Java modules to CliJavaModuleResolver
|
||||||
|
val newRoots = classpathRootsResolver.convertClasspathRoots(contentRoots).roots
|
||||||
|
|
||||||
|
if (packagePartProviders.isEmpty()) {
|
||||||
|
initialRoots.addAll(newRoots)
|
||||||
|
} else {
|
||||||
|
for (packagePartProvider in packagePartProviders) {
|
||||||
|
packagePartProvider.addRoots(newRoots, configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rootsIndex.addNewIndexForRoots(newRoots)?.let { newIndex ->
|
||||||
|
updateClasspathFromRootsIndex(newIndex)
|
||||||
|
newIndex.indexedRoots.mapNotNull { (file) ->
|
||||||
|
VfsUtilCore.virtualToIoFile(VfsUtilCore.getVirtualFileForJar(file) ?: file)
|
||||||
|
}.toList()
|
||||||
|
}.orEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun contentRootToVirtualFile(root: JvmContentRoot): VirtualFile? =
|
||||||
|
when (root) {
|
||||||
|
is JvmClasspathRoot ->
|
||||||
|
if (root.file.isFile) findJarRoot(root.file) else findExistingRoot(root, "Classpath entry")
|
||||||
|
is JvmModulePathRoot ->
|
||||||
|
if (root.file.isFile) findJarRoot(root.file) else findExistingRoot(root, "Java module root")
|
||||||
|
is JavaSourceRoot ->
|
||||||
|
findExistingRoot(root, "Java source root")
|
||||||
|
else ->
|
||||||
|
throw IllegalStateException("Unexpected root: $root")
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun findLocalFile(path: String): VirtualFile? =
|
||||||
|
applicationEnvironment.localFileSystem.findFileByPath(path)
|
||||||
|
|
||||||
|
private fun findExistingRoot(root: JvmContentRoot, rootDescription: String): VirtualFile? {
|
||||||
|
return findLocalFile(root.file.absolutePath).also {
|
||||||
|
if (it == null) {
|
||||||
|
report(STRONG_WARNING, "$rootDescription points to a non-existent location: ${root.file}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun findJarRoot(file: File): VirtualFile? =
|
||||||
|
applicationEnvironment.jarFileSystem.findFileByPath("$file${URLUtil.JAR_SEPARATOR}")
|
||||||
|
|
||||||
|
private fun getSourceRootsCheckingForDuplicates(): List<KotlinSourceRoot> {
|
||||||
|
val uniqueSourceRoots = hashSetOf<String>()
|
||||||
|
val result = mutableListOf<KotlinSourceRoot>()
|
||||||
|
|
||||||
|
for (root in configuration.kotlinSourceRoots) {
|
||||||
|
if (!uniqueSourceRoots.add(root.path)) {
|
||||||
|
report(STRONG_WARNING, "Duplicate source root: ${root.path}")
|
||||||
|
}
|
||||||
|
result.add(root)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSourceFiles(): List<KtFile> = sourceFiles
|
||||||
|
|
||||||
|
private fun createKtFiles(project: Project): List<KtFile> =
|
||||||
|
createSourceFilesFromSourceRoots(configuration, project, getSourceRootsCheckingForDuplicates())
|
||||||
|
|
||||||
|
internal fun report(severity: CompilerMessageSeverity, message: String) = configuration.report(severity, message)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOG = Logger.getInstance(KotlinCoreEnvironment::class.java)
|
||||||
|
|
||||||
|
private val APPLICATION_LOCK = Object()
|
||||||
|
private var ourApplicationEnvironment: KotlinCoreApplicationEnvironment? = null
|
||||||
|
private var ourProjectCount = 0
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun createForProduction(
|
||||||
|
parentDisposable: Disposable, configuration: CompilerConfiguration, configFiles: EnvironmentConfigFiles
|
||||||
|
): KotlinCoreEnvironment {
|
||||||
|
setupIdeaStandaloneExecution()
|
||||||
|
val appEnv = getOrCreateApplicationEnvironmentForProduction(parentDisposable, configuration)
|
||||||
|
val projectEnv = ProjectEnvironment(parentDisposable, appEnv)
|
||||||
|
val environment = KotlinCoreEnvironment(projectEnv, configuration, configFiles)
|
||||||
|
|
||||||
|
synchronized(APPLICATION_LOCK) {
|
||||||
|
ourProjectCount++
|
||||||
|
}
|
||||||
|
return environment
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun createForProduction(
|
||||||
|
projectEnvironment: JavaCoreProjectEnvironment, configuration: CompilerConfiguration, configFiles: EnvironmentConfigFiles
|
||||||
|
): KotlinCoreEnvironment {
|
||||||
|
val environment = KotlinCoreEnvironment(projectEnvironment, configuration, configFiles)
|
||||||
|
|
||||||
|
if (projectEnvironment.environment == applicationEnvironment) {
|
||||||
|
// accounting for core environment disposing
|
||||||
|
synchronized(APPLICATION_LOCK) {
|
||||||
|
ourProjectCount++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return environment
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestOnly
|
||||||
|
@JvmStatic
|
||||||
|
fun createForTests(
|
||||||
|
parentDisposable: Disposable, initialConfiguration: CompilerConfiguration, extensionConfigs: EnvironmentConfigFiles
|
||||||
|
): KotlinCoreEnvironment {
|
||||||
|
val configuration = initialConfiguration.copy()
|
||||||
|
// Tests are supposed to create a single project and dispose it right after use
|
||||||
|
val appEnv = createApplicationEnvironment(parentDisposable, configuration, unitTestMode = true)
|
||||||
|
val projectEnv = ProjectEnvironment(parentDisposable, appEnv)
|
||||||
|
return KotlinCoreEnvironment(projectEnv, configuration, extensionConfigs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// used in the daemon for jar cache cleanup
|
||||||
|
val applicationEnvironment: KotlinCoreApplicationEnvironment? get() = ourApplicationEnvironment
|
||||||
|
|
||||||
|
fun getOrCreateApplicationEnvironmentForProduction(
|
||||||
|
parentDisposable: Disposable, configuration: CompilerConfiguration
|
||||||
|
): KotlinCoreApplicationEnvironment {
|
||||||
|
synchronized(APPLICATION_LOCK) {
|
||||||
|
if (ourApplicationEnvironment == null) {
|
||||||
|
val disposable = Disposer.newDisposable()
|
||||||
|
ourApplicationEnvironment = createApplicationEnvironment(disposable, configuration, unitTestMode = false)
|
||||||
|
ourProjectCount = 0
|
||||||
|
Disposer.register(disposable, Disposable {
|
||||||
|
synchronized(APPLICATION_LOCK) {
|
||||||
|
ourApplicationEnvironment = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// Disposing of the environment is unsafe in production then parallel builds are enabled, but turning it off universally
|
||||||
|
// breaks a lot of tests, therefore it is disabled for production and enabled for tests
|
||||||
|
if (System.getProperty(KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY).toBooleanLenient() != true) {
|
||||||
|
// JPS may run many instances of the compiler in parallel (there's an option for compiling independent modules in parallel in IntelliJ)
|
||||||
|
// All projects share the same ApplicationEnvironment, and when the last project is disposed, the ApplicationEnvironment is disposed as well
|
||||||
|
@Suppress("ObjectLiteralToLambda") // Disposer tree depends on identity of disposables.
|
||||||
|
Disposer.register(parentDisposable, object : Disposable {
|
||||||
|
override fun dispose() {
|
||||||
|
synchronized(APPLICATION_LOCK) {
|
||||||
|
if (--ourProjectCount <= 0) {
|
||||||
|
disposeApplicationEnvironment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return ourApplicationEnvironment!!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is also used in Gradle after configuration phase finished.
|
||||||
|
*/
|
||||||
|
fun disposeApplicationEnvironment() {
|
||||||
|
synchronized(APPLICATION_LOCK) {
|
||||||
|
val environment = ourApplicationEnvironment ?: return
|
||||||
|
ourApplicationEnvironment = null
|
||||||
|
Disposer.dispose(environment.parentDisposable)
|
||||||
|
ZipHandler.clearFileAccessorCache()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createApplicationEnvironment(
|
||||||
|
parentDisposable: Disposable, configuration: CompilerConfiguration, unitTestMode: Boolean
|
||||||
|
): KotlinCoreApplicationEnvironment {
|
||||||
|
val applicationEnvironment = KotlinCoreApplicationEnvironment.create(parentDisposable, unitTestMode)
|
||||||
|
|
||||||
|
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/compiler.xml")
|
||||||
|
// FIX ME WHEN BUNCH 202 REMOVED: this code is required to support compiler bundled to both 202 and 203.
|
||||||
|
// Please, remove "com.intellij.psi.classFileDecompiler" EP registration once 202 is no longer supported by the compiler
|
||||||
|
if (!Extensions.getRootArea().hasExtensionPoint("com.intellij.psi.classFileDecompiler")) {
|
||||||
|
registerApplicationExtensionPointsAndExtensionsFrom(configuration, "extensions/core.xml")
|
||||||
|
}
|
||||||
|
|
||||||
|
registerApplicationServicesForCLI(applicationEnvironment)
|
||||||
|
registerApplicationServices(applicationEnvironment)
|
||||||
|
|
||||||
|
return applicationEnvironment
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerApplicationExtensionPointsAndExtensionsFrom(configuration: CompilerConfiguration, configFilePath: String) {
|
||||||
|
fun File.hasConfigFile(configFile: String): Boolean =
|
||||||
|
if (isDirectory) File(this, "META-INF" + File.separator + configFile).exists()
|
||||||
|
else try {
|
||||||
|
ZipFile(this).use {
|
||||||
|
it.getEntry("META-INF/$configFile") != null
|
||||||
|
}
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
val pluginRoot: File =
|
||||||
|
configuration.get(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT)?.let(::File)
|
||||||
|
?: PathUtil.getResourcePathForClass(this::class.java).takeIf { it.hasConfigFile(configFilePath) }
|
||||||
|
// hack for load extensions when compiler run directly from project directory (e.g. in tests)
|
||||||
|
?: File("compiler/cli/cli-common/resources").takeIf { it.hasConfigFile(configFilePath) }
|
||||||
|
?: throw IllegalStateException(
|
||||||
|
"Unable to find extension point configuration $configFilePath " +
|
||||||
|
"(cp:\n ${(Thread.currentThread().contextClassLoader as? UrlClassLoader)?.urls?.joinToString("\n ") { it.file }})"
|
||||||
|
)
|
||||||
|
|
||||||
|
CoreApplicationEnvironment.registerExtensionPointAndExtensions(
|
||||||
|
FileSystems.getDefault().getPath(pluginRoot.path),
|
||||||
|
configFilePath,
|
||||||
|
Extensions.getRootArea()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
@Suppress("MemberVisibilityCanPrivate") // made public for CLI Android Lint
|
||||||
|
fun registerPluginExtensionPoints(project: MockProject) {
|
||||||
|
ExpressionCodegenExtension.registerExtensionPoint(project)
|
||||||
|
SyntheticResolveExtension.registerExtensionPoint(project)
|
||||||
|
ClassBuilderInterceptorExtension.registerExtensionPoint(project)
|
||||||
|
AnalysisHandlerExtension.registerExtensionPoint(project)
|
||||||
|
PackageFragmentProviderExtension.registerExtensionPoint(project)
|
||||||
|
StorageComponentContainerContributor.registerExtensionPoint(project)
|
||||||
|
DeclarationAttributeAltererExtension.registerExtensionPoint(project)
|
||||||
|
PreprocessedVirtualFileFactoryExtension.registerExtensionPoint(project)
|
||||||
|
JsSyntheticTranslateExtension.registerExtensionPoint(project)
|
||||||
|
CompilerConfigurationExtension.registerExtensionPoint(project)
|
||||||
|
CollectAdditionalSourcesExtension.registerExtensionPoint(project)
|
||||||
|
ExtraImportsProviderExtension.registerExtensionPoint(project)
|
||||||
|
IrGenerationExtension.registerExtensionPoint(project)
|
||||||
|
ScriptEvaluationExtension.registerExtensionPoint(project)
|
||||||
|
ShellExtension.registerExtensionPoint(project)
|
||||||
|
TypeResolutionInterceptor.registerExtensionPoint(project)
|
||||||
|
CandidateInterceptor.registerExtensionPoint(project)
|
||||||
|
DescriptorSerializerPlugin.registerExtensionPoint(project)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun registerExtensionsFromPlugins(project: MockProject, configuration: CompilerConfiguration) {
|
||||||
|
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
for (registrar in configuration.getList(ComponentRegistrar.PLUGIN_COMPONENT_REGISTRARS)) {
|
||||||
|
try {
|
||||||
|
registrar.registerProjectComponents(project, configuration)
|
||||||
|
} catch (e: AbstractMethodError) {
|
||||||
|
val message = "The provided plugin ${registrar.javaClass.name} is not compatible with this version of compiler"
|
||||||
|
// Since the scripting plugin is often discovered in the compiler environment, it is often taken from the incompatible
|
||||||
|
// location, and in many cases this is not a fatal error, therefore strong warning is generated instead of exception
|
||||||
|
if (registrar.javaClass.simpleName == "ScriptingCompilerConfigurationComponentRegistrar") {
|
||||||
|
messageCollector?.report(STRONG_WARNING, "Default scripting plugin is disabled: $message")
|
||||||
|
} else {
|
||||||
|
throw IllegalStateException(message, e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun registerApplicationServicesForCLI(applicationEnvironment: KotlinCoreApplicationEnvironment) {
|
||||||
|
// ability to get text from annotations xml files
|
||||||
|
applicationEnvironment.registerFileType(PlainTextFileType.INSTANCE, "xml")
|
||||||
|
applicationEnvironment.registerParserDefinition(JavaParserDefinition())
|
||||||
|
}
|
||||||
|
|
||||||
|
// made public for Upsource
|
||||||
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
|
@JvmStatic
|
||||||
|
fun registerApplicationServices(applicationEnvironment: KotlinCoreApplicationEnvironment) {
|
||||||
|
with(applicationEnvironment) {
|
||||||
|
registerFileType(KotlinFileType.INSTANCE, "kt")
|
||||||
|
registerFileType(KotlinFileType.INSTANCE, KotlinParserDefinition.STD_SCRIPT_SUFFIX)
|
||||||
|
registerParserDefinition(KotlinParserDefinition())
|
||||||
|
application.registerService(KotlinBinaryClassCache::class.java, KotlinBinaryClassCache())
|
||||||
|
application.registerService(JavaClassSupers::class.java, JavaClassSupersImpl::class.java)
|
||||||
|
application.registerService(TransactionGuard::class.java, TransactionGuardImpl::class.java)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun registerProjectExtensionPoints(area: ExtensionsArea) {
|
||||||
|
CoreApplicationEnvironment.registerExtensionPoint(
|
||||||
|
area, PsiTreeChangePreprocessor.EP.name, PsiTreeChangePreprocessor::class.java
|
||||||
|
)
|
||||||
|
CoreApplicationEnvironment.registerExtensionPoint(area, PsiElementFinder.EP.name, PsiElementFinder::class.java)
|
||||||
|
|
||||||
|
IdeaExtensionPoints.registerVersionSpecificProjectExtensionPoints(area)
|
||||||
|
}
|
||||||
|
|
||||||
|
// made public for Upsource
|
||||||
|
@JvmStatic
|
||||||
|
@Deprecated("Use registerProjectServices(project) instead.", ReplaceWith("registerProjectServices(projectEnvironment.project)"))
|
||||||
|
fun registerProjectServices(
|
||||||
|
projectEnvironment: JavaCoreProjectEnvironment,
|
||||||
|
@Suppress("UNUSED_PARAMETER") messageCollector: MessageCollector?
|
||||||
|
) {
|
||||||
|
registerProjectServices(projectEnvironment.project)
|
||||||
|
}
|
||||||
|
|
||||||
|
// made public for Android Lint
|
||||||
|
@JvmStatic
|
||||||
|
fun registerProjectServices(project: MockProject) {
|
||||||
|
with(project) {
|
||||||
|
registerService(KotlinJavaPsiFacade::class.java, KotlinJavaPsiFacade(this))
|
||||||
|
registerService(FacadeCache::class.java, FacadeCache(this))
|
||||||
|
registerService(ModuleAnnotationsResolver::class.java, CliModuleAnnotationsResolver())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun registerProjectServicesForCLI(@Suppress("UNUSED_PARAMETER") projectEnvironment: JavaCoreProjectEnvironment) {
|
||||||
|
/**
|
||||||
|
* Note that Kapt may restart code analysis process, and CLI services should be aware of that.
|
||||||
|
* Use PsiManager.getModificationTracker() to ensure that all the data you cached is still valid.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// made public for Android Lint
|
||||||
|
@JvmStatic
|
||||||
|
fun registerKotlinLightClassSupport(project: MockProject) {
|
||||||
|
with(project) {
|
||||||
|
val traceHolder = CliTraceHolder()
|
||||||
|
val cliLightClassGenerationSupport = CliLightClassGenerationSupport(traceHolder, project)
|
||||||
|
val kotlinAsJavaSupport = CliKotlinAsJavaSupport(this, traceHolder)
|
||||||
|
registerService(LightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||||
|
registerService(CliLightClassGenerationSupport::class.java, cliLightClassGenerationSupport)
|
||||||
|
registerService(KotlinAsJavaSupport::class.java, kotlinAsJavaSupport)
|
||||||
|
registerService(CodeAnalyzerInitializer::class.java, traceHolder)
|
||||||
|
|
||||||
|
// We don't pass Disposable because in some tests, we manually unregister these extensions, and that leads to LOG.error
|
||||||
|
// exception from `ExtensionPointImpl.doRegisterExtension`, because the registered extension can no longer be found
|
||||||
|
// when the project is being disposed.
|
||||||
|
// For example, see the `unregisterExtension` call in `GenerationUtils.compileFilesUsingFrontendIR`.
|
||||||
|
// TODO: refactor this to avoid registering unneeded extensions in the first place, and avoid using deprecated API.
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
PsiElementFinder.EP.getPoint(project).registerExtension(JavaElementFinder(this, kotlinAsJavaSupport))
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
PsiElementFinder.EP.getPoint(project).registerExtension(PsiElementFinderImpl(this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun CompilerConfiguration.setupJdkClasspathRoots(configFiles: EnvironmentConfigFiles) {
|
||||||
|
if (getBoolean(JVMConfigurationKeys.NO_JDK)) return
|
||||||
|
|
||||||
|
val jvmTarget = configFiles == EnvironmentConfigFiles.JVM_CONFIG_FILES
|
||||||
|
if (!jvmTarget) return
|
||||||
|
|
||||||
|
val jdkHome = get(JVMConfigurationKeys.JDK_HOME)
|
||||||
|
val (javaRoot, classesRoots) = if (jdkHome == null) {
|
||||||
|
val javaHome = File(System.getProperty("java.home"))
|
||||||
|
put(JVMConfigurationKeys.JDK_HOME, javaHome)
|
||||||
|
|
||||||
|
javaHome to PathUtil.getJdkClassesRootsFromCurrentJre()
|
||||||
|
} else {
|
||||||
|
jdkHome to PathUtil.getJdkClassesRoots(jdkHome)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!CoreJrtFileSystem.isModularJdk(javaRoot)) {
|
||||||
|
if (classesRoots.isEmpty()) {
|
||||||
|
report(ERROR, "No class roots are found in the JDK path: $javaRoot")
|
||||||
|
} else {
|
||||||
|
addJvmSdkRoots(classesRoots)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -686,4 +686,4 @@ class KotlinCoreEnvironment private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-36
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.cli.jvm.compiler
|
|||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.vfs.*
|
import com.intellij.openapi.vfs.*
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.PsiElementFinder
|
import com.intellij.psi.PsiElementFinder
|
||||||
import com.intellij.psi.PsiJavaModule
|
import com.intellij.psi.PsiJavaModule
|
||||||
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
import com.intellij.psi.search.DelegatingGlobalSearchScope
|
||||||
@@ -30,6 +29,7 @@ import org.jetbrains.kotlin.asJava.finder.JavaElementFinder
|
|||||||
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
|
import org.jetbrains.kotlin.backend.common.output.OutputFileCollection
|
||||||
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
|
import org.jetbrains.kotlin.backend.common.output.SimpleOutputFileCollection
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.JvmGeneratorExtensions
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
import org.jetbrains.kotlin.backend.jvm.JvmIrCodegenFactory
|
||||||
import org.jetbrains.kotlin.backend.jvm.jvmPhases
|
import org.jetbrains.kotlin.backend.jvm.jvmPhases
|
||||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||||
@@ -53,9 +53,7 @@ import org.jetbrains.kotlin.config.*
|
|||||||
import org.jetbrains.kotlin.container.get
|
import org.jetbrains.kotlin.container.get
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.*
|
import org.jetbrains.kotlin.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.FirPsiSourceElement
|
|
||||||
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
import org.jetbrains.kotlin.fir.analysis.FirAnalyzerFacade
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.*
|
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
import org.jetbrains.kotlin.fir.backend.jvm.FirJvmBackendClassResolver
|
||||||
import org.jetbrains.kotlin.fir.backend.jvm.FirMetadataSerializer
|
import org.jetbrains.kotlin.fir.backend.jvm.FirMetadataSerializer
|
||||||
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
import org.jetbrains.kotlin.fir.checkers.registerExtendedCommonCheckers
|
||||||
@@ -71,7 +69,7 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
import org.jetbrains.kotlin.resolve.CompilerEnvironment
|
||||||
import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics
|
import org.jetbrains.kotlin.resolve.diagnostics.SimpleGenericDiagnostics
|
||||||
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
import org.jetbrains.kotlin.resolve.jvm.KotlinJavaPsiFacade
|
||||||
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory
|
||||||
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
import org.jetbrains.kotlin.utils.newLinkedHashMapWithExpectedSize
|
||||||
@@ -342,9 +340,7 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
firAnalyzerFacade.runResolution()
|
firAnalyzerFacade.runResolution()
|
||||||
val firDiagnostics = firAnalyzerFacade.runCheckers().values.flatten()
|
val firDiagnostics = firAnalyzerFacade.runCheckers().values.flatten()
|
||||||
AnalyzerWithCompilerReport.reportDiagnostics(
|
AnalyzerWithCompilerReport.reportDiagnostics(
|
||||||
SimpleDiagnostics(
|
SimpleGenericDiagnostics(firDiagnostics),
|
||||||
firDiagnostics.map { it.toRegularDiagnostic() }
|
|
||||||
),
|
|
||||||
environment.messageCollector
|
environment.messageCollector
|
||||||
)
|
)
|
||||||
performanceManager?.notifyAnalysisFinished()
|
performanceManager?.notifyAnalysisFinished()
|
||||||
@@ -356,7 +352,8 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
performanceManager?.notifyGenerationStarted()
|
performanceManager?.notifyGenerationStarted()
|
||||||
|
|
||||||
performanceManager?.notifyIRTranslationStarted()
|
performanceManager?.notifyIRTranslationStarted()
|
||||||
val (moduleFragment, symbolTable, sourceManager, components) = firAnalyzerFacade.convertToIr()
|
val extensions = JvmGeneratorExtensions()
|
||||||
|
val (moduleFragment, symbolTable, sourceManager, components) = firAnalyzerFacade.convertToIr(extensions)
|
||||||
|
|
||||||
performanceManager?.notifyIRTranslationFinished()
|
performanceManager?.notifyIRTranslationFinished()
|
||||||
|
|
||||||
@@ -392,9 +389,9 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
performanceManager?.notifyIRGenerationStarted()
|
performanceManager?.notifyIRGenerationStarted()
|
||||||
generationState.beforeCompile()
|
generationState.beforeCompile()
|
||||||
codegenFactory.generateModuleInFrontendIRMode(
|
codegenFactory.generateModuleInFrontendIRMode(
|
||||||
generationState, moduleFragment, symbolTable, sourceManager
|
generationState, moduleFragment, symbolTable, sourceManager, extensions
|
||||||
) { context, irClass, _, serializationBindings, parent ->
|
) { context, irClass, _, serializationBindings, parent ->
|
||||||
FirMetadataSerializer(session, context, irClass, serializationBindings, parent)
|
FirMetadataSerializer(session, context, irClass, serializationBindings, components, parent)
|
||||||
}
|
}
|
||||||
CodegenFactory.doCheckCancelled(generationState)
|
CodegenFactory.doCheckCancelled(generationState)
|
||||||
generationState.factory.done()
|
generationState.factory.done()
|
||||||
@@ -427,30 +424,6 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
|
return writeOutputs(environment, projectConfiguration, chunk, outputs, mainClassFqName)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun FirDiagnostic<*>.toRegularDiagnostic(): Diagnostic {
|
|
||||||
val psiSource = element as FirPsiSourceElement<*>
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
when (this) {
|
|
||||||
is FirSimpleDiagnostic ->
|
|
||||||
return SimpleDiagnostic(
|
|
||||||
psiSource.psi, factory.psiDiagnosticFactory as DiagnosticFactory0<PsiElement>, severity
|
|
||||||
)
|
|
||||||
is FirDiagnosticWithParameters1<*, *> ->
|
|
||||||
return DiagnosticWithParameters1(
|
|
||||||
psiSource.psi, this.a, factory.psiDiagnosticFactory as DiagnosticFactory1<PsiElement, Any>, severity
|
|
||||||
)
|
|
||||||
is FirDiagnosticWithParameters2<*, *, *> ->
|
|
||||||
return DiagnosticWithParameters2(
|
|
||||||
psiSource.psi, this.a, this.b, factory.psiDiagnosticFactory as DiagnosticFactory2<PsiElement, Any, Any>, severity
|
|
||||||
)
|
|
||||||
is FirDiagnosticWithParameters3<*, *, *, *> ->
|
|
||||||
return DiagnosticWithParameters3(
|
|
||||||
psiSource.psi, this.a, this.b, this.c,
|
|
||||||
factory.psiDiagnosticFactory as DiagnosticFactory3<PsiElement, Any, Any, Any>, severity
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getBuildFilePaths(buildFile: File?, sourceFilePaths: List<String>): List<String> =
|
private fun getBuildFilePaths(buildFile: File?, sourceFilePaths: List<String>): List<String> =
|
||||||
if (buildFile == null) sourceFilePaths
|
if (buildFile == null) sourceFilePaths
|
||||||
else sourceFilePaths.map { path ->
|
else sourceFilePaths.map { path ->
|
||||||
@@ -490,6 +463,10 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
environment.updateClasspath(result.additionalJavaRoots.map { JavaSourceRoot(it, null) })
|
environment.updateClasspath(result.additionalJavaRoots.map { JavaSourceRoot(it, null) })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.additionalClassPathRoots.isNotEmpty()) {
|
||||||
|
environment.updateClasspath(result.additionalClassPathRoots.map { JvmClasspathRoot(it, false) })
|
||||||
|
}
|
||||||
|
|
||||||
if (result.additionalKotlinRoots.isNotEmpty()) {
|
if (result.additionalKotlinRoots.isNotEmpty()) {
|
||||||
environment.addKotlinSourceRoots(result.additionalKotlinRoots)
|
environment.addKotlinSourceRoots(result.additionalKotlinRoots)
|
||||||
}
|
}
|
||||||
@@ -499,8 +476,8 @@ object KotlinToJVMBytecodeCompiler {
|
|||||||
// Clear all diagnostic messages
|
// Clear all diagnostic messages
|
||||||
configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]?.clear()
|
configuration[CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY]?.clear()
|
||||||
|
|
||||||
// Repeat analysis with additional Java roots (kapt generated sources)
|
// Repeat analysis with additional source roots generated by compiler plugins.
|
||||||
return analyze(environment)
|
return repeatAnalysisIfNeeded(analyze(environment), environment)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -12,4 +12,6 @@ fun setupIdeaStandaloneExecution() {
|
|||||||
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
||||||
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
||||||
System.getProperties().setProperty("ast.loading.filter", "false")
|
System.getProperties().setProperty("ast.loading.filter", "false")
|
||||||
|
System.getProperties().setProperty("idea.ignore.disabled.plugins", "true")
|
||||||
|
System.getProperties().setProperty("idea.home.path", System.getProperty("java.io.tmpdir"))
|
||||||
}
|
}
|
||||||
-2
@@ -12,6 +12,4 @@ fun setupIdeaStandaloneExecution() {
|
|||||||
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
System.getProperties().setProperty("psi.incremental.reparse.depth.limit", "1000")
|
||||||
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
System.getProperties().setProperty("ide.hide.excluded.files", "false")
|
||||||
System.getProperties().setProperty("ast.loading.filter", "false")
|
System.getProperties().setProperty("ast.loading.filter", "false")
|
||||||
System.getProperties().setProperty("idea.ignore.disabled.plugins", "true")
|
|
||||||
System.getProperties().setProperty("idea.home.path", System.getProperty("java.io.tmpdir"))
|
|
||||||
}
|
}
|
||||||
@@ -39,7 +39,7 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu
|
|||||||
}
|
}
|
||||||
|
|
||||||
val jvmTarget = get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
|
val jvmTarget = get(JVMConfigurationKeys.JVM_TARGET) ?: JvmTarget.DEFAULT
|
||||||
if (jvmTarget.bytecodeVersion < JvmTarget.JVM_1_8.bytecodeVersion) {
|
if (jvmTarget.majorVersion < JvmTarget.JVM_1_8.majorVersion) {
|
||||||
val jvmDefaultMode = languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)
|
val jvmDefaultMode = languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode)
|
||||||
if (jvmDefaultMode.forAllMethodsWithBody) {
|
if (jvmDefaultMode.forAllMethodsWithBody) {
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
@@ -53,7 +53,7 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu
|
|||||||
val runtimeStringConcat = JvmStringConcat.fromString(arguments.stringConcat!!)
|
val runtimeStringConcat = JvmStringConcat.fromString(arguments.stringConcat!!)
|
||||||
if (runtimeStringConcat != null) {
|
if (runtimeStringConcat != null) {
|
||||||
put(JVMConfigurationKeys.STRING_CONCAT, runtimeStringConcat)
|
put(JVMConfigurationKeys.STRING_CONCAT, runtimeStringConcat)
|
||||||
if (jvmTarget.bytecodeVersion < JvmTarget.JVM_9.bytecodeVersion && runtimeStringConcat != JvmStringConcat.INLINE) {
|
if (jvmTarget.majorVersion < JvmTarget.JVM_9.majorVersion && runtimeStringConcat != JvmStringConcat.INLINE) {
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
WARNING,
|
WARNING,
|
||||||
"`-Xstring-concat=${arguments.stringConcat}` does nothing with JVM target `${jvmTarget.description}`."
|
"`-Xstring-concat=${arguments.stringConcat}` does nothing with JVM target `${jvmTarget.description}`."
|
||||||
@@ -61,8 +61,8 @@ fun CompilerConfiguration.setupJvmSpecificArguments(arguments: K2JVMCompilerArgu
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
messageCollector.report(
|
messageCollector.report(
|
||||||
ERROR, "Unknown `string-concat` mode: ${arguments.jvmTarget}\n" +
|
ERROR, "Unknown -Xstring-concat mode: ${arguments.jvmTarget}\n" +
|
||||||
"Supported versions: ${JvmStringConcat.values().joinToString { it.name.toLowerCase() }}"
|
"Supported versions: ${JvmStringConcat.values().joinToString { it.description }}"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -232,6 +232,12 @@ fun CompilerConfiguration.configureAdvancedJvmOptions(arguments: K2JVMCompilerAr
|
|||||||
put(JVMConfigurationKeys.USE_SINGLE_MODULE, arguments.singleModule)
|
put(JVMConfigurationKeys.USE_SINGLE_MODULE, arguments.singleModule)
|
||||||
put(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS, arguments.useOldSpilledVarTypeAnalysis)
|
put(JVMConfigurationKeys.USE_OLD_SPILLED_VAR_TYPE_ANALYSIS, arguments.useOldSpilledVarTypeAnalysis)
|
||||||
put(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME, arguments.useOldInlineClassesManglingScheme)
|
put(JVMConfigurationKeys.USE_OLD_INLINE_CLASSES_MANGLING_SCHEME, arguments.useOldInlineClassesManglingScheme)
|
||||||
|
put(JVMConfigurationKeys.ENABLE_JVM_PREVIEW, arguments.enableJvmPreview)
|
||||||
|
|
||||||
|
if (arguments.enableJvmPreview) {
|
||||||
|
getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||||
|
.report(INFO, "Using preview Java language features")
|
||||||
|
}
|
||||||
|
|
||||||
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
arguments.declarationsOutputPath?.let { put(JVMConfigurationKeys.DECLARATIONS_JSON_PATH, it) }
|
||||||
}
|
}
|
||||||
@@ -242,4 +248,4 @@ fun CompilerConfiguration.configureKlibPaths(arguments: K2JVMCompilerArguments)
|
|||||||
?.toTypedArray()
|
?.toTypedArray()
|
||||||
?.filterNot { it.isEmpty() }
|
?.filterNot { it.isEmpty() }
|
||||||
?.let { put(JVMConfigurationKeys.KLIB_PATHS, it) }
|
?.let { put(JVMConfigurationKeys.KLIB_PATHS, it) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,4 +140,7 @@ public class JVMConfigurationKeys {
|
|||||||
|
|
||||||
public static final CompilerConfigurationKey<Boolean> USE_OLD_INLINE_CLASSES_MANGLING_SCHEME =
|
public static final CompilerConfigurationKey<Boolean> USE_OLD_INLINE_CLASSES_MANGLING_SCHEME =
|
||||||
CompilerConfigurationKey.create("Use old, 1.4 version of inline classes mangling scheme");
|
CompilerConfigurationKey.create("Use old, 1.4 version of inline classes mangling scheme");
|
||||||
|
|
||||||
|
public static final CompilerConfigurationKey<Boolean> ENABLE_JVM_PREVIEW =
|
||||||
|
CompilerConfigurationKey.create("Enable Java language preview features");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,9 @@ object JvmAnalysisFlags {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
val disableUltraLightClasses by AnalysisFlag.Delegates.Boolean
|
val disableUltraLightClasses by AnalysisFlag.Delegates.Boolean
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
val enableJvmPreview by AnalysisFlag.Delegates.Boolean
|
||||||
|
|
||||||
private object Delegates {
|
private object Delegates {
|
||||||
object JavaTypeEnhancementStateWarnByDefault {
|
object JavaTypeEnhancementStateWarnByDefault {
|
||||||
operator fun provideDelegate(instance: Any?, property: KProperty<*>): AnalysisFlag.Delegate<JavaTypeEnhancementState> =
|
operator fun provideDelegate(instance: Any?, property: KProperty<*>): AnalysisFlag.Delegate<JavaTypeEnhancementState> =
|
||||||
|
|||||||
@@ -19,32 +19,21 @@ package org.jetbrains.kotlin.config
|
|||||||
import org.jetbrains.kotlin.platform.TargetPlatformVersion
|
import org.jetbrains.kotlin.platform.TargetPlatformVersion
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
|
||||||
enum class JvmTarget(override val description: String) : TargetPlatformVersion {
|
enum class JvmTarget(
|
||||||
JVM_1_6("1.6"),
|
override val description: String,
|
||||||
JVM_1_8("1.8"),
|
val majorVersion: Int,
|
||||||
JVM_9("9"),
|
) : TargetPlatformVersion {
|
||||||
JVM_10("10"),
|
JVM_1_6("1.6", Opcodes.V1_6),
|
||||||
JVM_11("11"),
|
JVM_1_8("1.8", Opcodes.V1_8),
|
||||||
JVM_12("12"),
|
JVM_9("9", Opcodes.V9),
|
||||||
JVM_13("13"),
|
JVM_10("10", Opcodes.V10),
|
||||||
JVM_14("14"),
|
JVM_11("11", Opcodes.V11),
|
||||||
JVM_15("15"),
|
JVM_12("12", Opcodes.V12),
|
||||||
|
JVM_13("13", Opcodes.V12 + 1),
|
||||||
|
JVM_14("14", Opcodes.V12 + 2),
|
||||||
|
JVM_15("15", Opcodes.V12 + 3),
|
||||||
;
|
;
|
||||||
|
|
||||||
val bytecodeVersion: Int by lazy {
|
|
||||||
when (this) {
|
|
||||||
JVM_1_6 -> Opcodes.V1_6
|
|
||||||
JVM_1_8 -> Opcodes.V1_8
|
|
||||||
JVM_9 -> Opcodes.V9
|
|
||||||
JVM_10 -> Opcodes.V10
|
|
||||||
JVM_11 -> Opcodes.V11
|
|
||||||
JVM_12 -> Opcodes.V12
|
|
||||||
JVM_13 -> Opcodes.V12 + 1
|
|
||||||
JVM_14 -> Opcodes.V12 + 2
|
|
||||||
JVM_15 -> Opcodes.V12 + 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val DEFAULT = JVM_1_6
|
val DEFAULT = JVM_1_6
|
||||||
@@ -52,14 +41,14 @@ enum class JvmTarget(override val description: String) : TargetPlatformVersion {
|
|||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun fromString(string: String) = values().find { it.description == string }
|
fun fromString(string: String) = values().find { it.description == string }
|
||||||
|
|
||||||
fun getDescription(bytecodeVersion: Int): String {
|
fun getDescription(majorVersion: Int): String {
|
||||||
val platformDescription = values().find { it.bytecodeVersion == bytecodeVersion }?.description ?: when (bytecodeVersion) {
|
val platformDescription = values().find { it.majorVersion == majorVersion }?.description ?: when (majorVersion) {
|
||||||
Opcodes.V1_7 -> "1.7"
|
Opcodes.V1_7 -> "1.7"
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (platformDescription != null) "JVM target $platformDescription"
|
return if (platformDescription != null) "JVM target $platformDescription"
|
||||||
else "JVM bytecode version $bytecodeVersion"
|
else "JVM bytecode version $majorVersion"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import org.jetbrains.kotlin.ideaExt.idea
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2000-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2000-2018 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.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
@@ -29,9 +31,21 @@ dependencies {
|
|||||||
testRuntimeOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
testRuntimeOnly(intellijCoreDep()) { includeJars("intellij-core") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val generationRoot = projectDir.resolve("tests-gen")
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
"main" { none() }
|
"main" { none() }
|
||||||
"test" { projectDefault() }
|
"test" {
|
||||||
|
projectDefault()
|
||||||
|
this.java.srcDir(generationRoot.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kotlinBuildProperties.isInJpsBuildIdeaSync) {
|
||||||
|
apply(plugin = "idea")
|
||||||
|
idea {
|
||||||
|
this.module.generatedSourceDirs.add(generationRoot)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
projectTest(parallel = true) {
|
projectTest(parallel = true) {
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
@R|java/lang/annotation/Documented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) public abstract annotation class MyNullable : R|kotlin/Annotation| {
|
@R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.NEVER|()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) public abstract annotation class MyNullable : R|kotlin/Annotation| {
|
||||||
public constructor(): R|MyNullable|
|
public constructor(): R|MyNullable|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
public constructor(): R|A|
|
public constructor(): R|A|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
|
||||||
public constructor(): R|FieldsAreNullable|
|
public constructor(): R|FieldsAreNullable|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -6,19 +6,19 @@
|
|||||||
public constructor(): R|A|
|
public constructor(): R|A|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class ForceFlexibility : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class ForceFlexibility : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/ForceFlexibility|
|
public constructor(): R|spr/ForceFlexibility|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/NonNullApi|
|
public constructor(): R|spr/NonNullApi|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Target|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/Nullable|
|
public constructor(): R|spr/Nullable|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Documented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) public abstract annotation class UnknownNullability : R|kotlin/Annotation| {
|
@R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) public abstract annotation class UnknownNullability : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/UnknownNullability|
|
public constructor(): R|spr/UnknownNullability|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -20,15 +20,15 @@ public abstract interface B : R|kotlin/Any| {
|
|||||||
public abstract fun foobar(@R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|): R|kotlin/Unit|
|
public abstract fun foobar(@R|javax/annotation/Nonnull|() x: R|@EnhancedNullability kotlin/String|): R|kotlin/Unit|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class ForceFlexibility : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|spr/UnknownNullability|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class ForceFlexibility : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/ForceFlexibility|
|
public constructor(): R|spr/ForceFlexibility|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/NonNullApi|
|
public constructor(): R|spr/NonNullApi|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Documented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) public abstract annotation class UnknownNullability : R|kotlin/Annotation| {
|
@R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/meta/TypeQualifierNickname|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.UNKNOWN|()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) public abstract annotation class UnknownNullability : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/UnknownNullability|
|
public constructor(): R|spr/UnknownNullability|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -54,11 +54,11 @@
|
|||||||
public constructor(): R|C|
|
public constructor(): R|C|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
||||||
public constructor(): R|NonNullApi|
|
public constructor(): R|NonNullApi|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NullableApi : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NullableApi : R|kotlin/Annotation| {
|
||||||
public constructor(): R|NullableApi|
|
public constructor(): R|NullableApi|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -12,15 +12,15 @@
|
|||||||
public constructor(): R|A|
|
public constructor(): R|A|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class FieldsAreNullable : R|kotlin/Annotation| {
|
||||||
public constructor(): R|FieldsAreNullable|
|
public constructor(): R|FieldsAreNullable|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
||||||
public constructor(): R|NonNullApi|
|
public constructor(): R|NonNullApi|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NullableApi : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/CheckForNull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|(), R|java/lang/annotation/ElementType.FIELD|())) public abstract annotation class NullableApi : R|kotlin/Annotation| {
|
||||||
public constructor(): R|NullableApi|
|
public constructor(): R|NullableApi|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+2
-2
@@ -10,11 +10,11 @@
|
|||||||
public constructor(): R|A|
|
public constructor(): R|A|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.TYPE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.CLASS|(), R|kotlin/annotation/AnnotationTarget.FILE|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/NonNullApi|
|
public constructor(): R|spr/NonNullApi|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Target|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/Nullable|
|
public constructor(): R|spr/Nullable|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -10,11 +10,11 @@ public open class A : R|kotlin/Any| {
|
|||||||
public constructor(): R|test/A|
|
public constructor(): R|test/A|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Target|(R|java/lang/annotation/ElementType.PACKAGE|()) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(<implicitArrayOf>()) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|() @R|javax/annotation/meta/TypeQualifierDefault|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) public abstract annotation class NonNullApi : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/NonNullApi|
|
public constructor(): R|spr/NonNullApi|
|
||||||
|
|
||||||
}
|
}
|
||||||
@R|java/lang/annotation/Target|(<implicitArrayOf>(R|java/lang/annotation/ElementType.METHOD|(), R|java/lang/annotation/ElementType.PARAMETER|())) @R|java/lang/annotation/Retention|(R|java/lang/annotation/RetentionPolicy.RUNTIME|()) @R|java/lang/annotation/Documented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
|
@R|kotlin/annotation/Target|(<implicitArrayOf>(R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|(), R|kotlin/annotation/AnnotationTarget.FUNCTION|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_GETTER|(), R|kotlin/annotation/AnnotationTarget.PROPERTY_SETTER|())) @R|kotlin/annotation/Retention|(R|kotlin/annotation/AnnotationRetention.RUNTIME|()) @R|kotlin/annotation/MustBeDocumented|() @R|javax/annotation/Nonnull|(R|javax/annotation/meta/When.MAYBE|()) @R|javax/annotation/meta/TypeQualifierNickname|() public abstract annotation class Nullable : R|kotlin/Annotation| {
|
||||||
public constructor(): R|spr/Nullable|
|
public constructor(): R|spr/Nullable|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
FILE: RedundantSingleExpressionStringTemplateChecker.kt
|
FILE: RedundantSingleExpressionStringTemplateChecker.kt
|
||||||
public final val x: R|kotlin/String| = String(Hello)
|
public final val x: R|kotlin/String| = String(Hello)
|
||||||
public get(): R|kotlin/String|
|
public get(): R|kotlin/String|
|
||||||
public final val y: R|kotlin/String| = R|/x|.R|kotlin/Any.toString|()
|
public final val y: R|kotlin/String| = <strcat>(R|/x|.R|kotlin/Any.toString|())
|
||||||
public get(): R|kotlin/String|
|
public get(): R|kotlin/String|
|
||||||
public final val z: R|kotlin/String| = R|/y|.R|kotlin/Any.hashCode|().R|kotlin/Any.toString|()
|
public final val z: R|kotlin/String| = <strcat>(R|/y|.R|kotlin/Any.hashCode|().R|kotlin/Any.toString|())
|
||||||
public get(): R|kotlin/String|
|
public get(): R|kotlin/String|
|
||||||
public final fun toString(x: R|kotlin/String|): R|kotlin/String| {
|
public final fun toString(x: R|kotlin/String|): R|kotlin/String| {
|
||||||
^toString <strcat>(String(IC), R|<local>/x|.R|kotlin/Any.toString|())
|
^toString <strcat>(String(IC), R|<local>/x|.R|kotlin/Any.toString|())
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@ FILE: NotNullTypeChain.kt
|
|||||||
public final val list1: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(1))
|
public final val list1: R|kotlin/collections/List<kotlin/Int>| = R|kotlin/collections/listOf|<R|kotlin/Int|>(Int(1))
|
||||||
public get(): R|kotlin/collections/List<kotlin/Int>|
|
public get(): R|kotlin/collections/List<kotlin/Int>|
|
||||||
public final val list: R|kotlin/collections/List<kotlin/String>| = R|/list1|.R|kotlin/collections/orEmpty|<R|kotlin/Int|>().R|kotlin/collections/map|<R|kotlin/Int|, R|kotlin/String|>(<L> = map@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/String| <kind=UNKNOWN> {
|
public final val list: R|kotlin/collections/List<kotlin/String>| = R|/list1|.R|kotlin/collections/orEmpty|<R|kotlin/Int|>().R|kotlin/collections/map|<R|kotlin/Int|, R|kotlin/String|>(<L> = map@fun <anonymous>(it: R|kotlin/Int|): R|kotlin/String| <kind=UNKNOWN> {
|
||||||
^ R|<local>/it|.R|kotlin/Any.toString|()
|
^ <strcat>(R|<local>/it|.R|kotlin/Any.toString|())
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
public get(): R|kotlin/collections/List<kotlin/String>|
|
public get(): R|kotlin/collections/List<kotlin/String>|
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
annotation class Ann(val value: Int)
|
||||||
|
|
||||||
|
fun foo(): Int {
|
||||||
|
val x = 3
|
||||||
|
@Ann(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>x<!>) val y = 5
|
||||||
|
return y
|
||||||
|
}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
FILE: usedInAnnotationArguments.kt
|
||||||
|
public final annotation class Ann : R|kotlin/Annotation| {
|
||||||
|
public constructor(value: R|kotlin/Int|): R|Ann| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
public final val value: R|kotlin/Int| = R|<local>/value|
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun foo(): R|kotlin/Int| {
|
||||||
|
lval x: R|kotlin/Int| = Int(3)
|
||||||
|
@R|Ann|(R|<local>/x|) lval y: R|kotlin/Int| = Int(5)
|
||||||
|
^foo R|<local>/y|
|
||||||
|
}
|
||||||
+2
-1
@@ -28,7 +28,7 @@ public final class Test : R|kotlin/Any| {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final inline class Z : R|kotlin/Any| {
|
@R|kotlin/jvm/JvmInline|() public final inline class Z : R|kotlin/Any| {
|
||||||
public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
|
public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
|
||||||
|
|
||||||
public open fun hashCode(): R|kotlin/Int|
|
public open fun hashCode(): R|kotlin/Int|
|
||||||
@@ -41,3 +41,4 @@ public final inline class Z : R|kotlin/Any| {
|
|||||||
public constructor(x: R|kotlin/Int|): R|test/Z|
|
public constructor(x: R|kotlin/Int|): R|test/Z|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -1,4 +1,4 @@
|
|||||||
public final inline class Z : R|kotlin/Any| {
|
@R|kotlin/jvm/JvmInline|() public final inline class Z : R|kotlin/Any| {
|
||||||
public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
|
public open operator fun equals(other: R|kotlin/Any?|): R|kotlin/Boolean|
|
||||||
|
|
||||||
public open fun hashCode(): R|kotlin/Int|
|
public open fun hashCode(): R|kotlin/Int|
|
||||||
@@ -11,3 +11,4 @@ public final inline class Z : R|kotlin/Any| {
|
|||||||
@R|kotlin/PublishedApi|() internal constructor(value: R|kotlin/Int|): R|test/Z|
|
@R|kotlin/PublishedApi|() internal constructor(value: R|kotlin/Int|): R|test/Z|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,6 @@ public final const val s: R|kotlin/Short| = Short(20000)
|
|||||||
public final const val s1: R|kotlin/Short| = Short(1)
|
public final const val s1: R|kotlin/Short| = Short(1)
|
||||||
public get(): R|kotlin/Short|
|
public get(): R|kotlin/Short|
|
||||||
|
|
||||||
public final const val str: R|kotlin/String|
|
public final const val str: R|kotlin/String| = String(:))
|
||||||
public get(): R|kotlin/String|
|
public get(): R|kotlin/String|
|
||||||
|
|
||||||
|
|||||||
@@ -8,5 +8,5 @@ FILE: stringTemplates.kt
|
|||||||
public final fun foo(s: R|kotlin/String|): R|kotlin/Unit| {
|
public final fun foo(s: R|kotlin/String|): R|kotlin/Unit| {
|
||||||
}
|
}
|
||||||
public final fun test(a: R|A|): R|kotlin/Unit| {
|
public final fun test(a: R|A|): R|kotlin/Unit| {
|
||||||
R|/foo|(R|<local>/a|.R|kotlin/Any.toString|())
|
R|/foo|(<strcat>(R|<local>/a|.R|kotlin/Any.toString|()))
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -5,4 +5,4 @@ interface B : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>A
|
|||||||
interface C
|
interface C
|
||||||
class D
|
class D
|
||||||
|
|
||||||
interface E : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>A<!>(), C, D()
|
interface E : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>A<!>(), C, <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>D<!>()
|
||||||
Vendored
+1
-1
@@ -8,6 +8,6 @@ interface D : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>C
|
|||||||
|
|
||||||
interface E : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>Any<!>()
|
interface E : <!INTERFACE_WITH_SUPERCLASS, SUPERTYPE_INITIALIZED_IN_INTERFACE!>Any<!>()
|
||||||
|
|
||||||
interface F : A, <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>B<!>(), <!INTERFACE_WITH_SUPERCLASS!>C<!>, D(), Any() {
|
interface F : A, <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>B<!>(), <!INTERFACE_WITH_SUPERCLASS!>C<!>, <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>D<!>(), <!SUPERTYPE_INITIALIZED_IN_INTERFACE!>Any<!>() {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -3,11 +3,11 @@ interface Some {
|
|||||||
open fun bar() {}
|
open fun bar() {}
|
||||||
|
|
||||||
open val x: Int
|
open val x: Int
|
||||||
open val y = 1
|
open val y = <!PROPERTY_INITIALIZER_IN_INTERFACE!>1<!>
|
||||||
open val z get() = 1
|
open val z get() = 1
|
||||||
|
|
||||||
open var xx: Int
|
open var xx: Int
|
||||||
open var yy = 1
|
open var yy = <!PROPERTY_INITIALIZER_IN_INTERFACE!>1<!>
|
||||||
open var zz: Int
|
open var zz: Int
|
||||||
set(value) {
|
set(value) {
|
||||||
field = value
|
field = value
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
interface CommonBackendContext
|
||||||
|
|
||||||
|
interface PhaserState<Data> {
|
||||||
|
var depth: Int
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PhaseConfig {
|
||||||
|
val needProfiling: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun <R, D> PhaserState<D>.downlevel(nlevels: Int, block: () -> R): R {
|
||||||
|
depth += nlevels
|
||||||
|
val result = block()
|
||||||
|
depth -= nlevels
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
interface CompilerPhase<in Context : CommonBackendContext, Input, Output> {
|
||||||
|
fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Input>, context: Context, input: Input): Output
|
||||||
|
}
|
||||||
|
|
||||||
|
class NamedCompilerPhase<in Context : CommonBackendContext, Data>(
|
||||||
|
private val lower: CompilerPhase<Context, Data, Data>
|
||||||
|
) : CompilerPhase<Context, Data, Data> {
|
||||||
|
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, input: Data): Data {
|
||||||
|
// Expected: output: Data, Actual: output: Data?
|
||||||
|
val output = if (phaseConfig.needProfiling) {
|
||||||
|
runAndProfile(phaseConfig, phaserState, context, input)
|
||||||
|
} else {
|
||||||
|
phaserState.downlevel(1) {
|
||||||
|
lower.invoke(phaseConfig, phaserState, context, input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
runAfter(phaseConfig, phaserState, context, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runAfter(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, output: Data) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runAndProfile(phaseConfig: PhaseConfig, phaserState: PhaserState<Data>, context: Context, source: Data): Data {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
FILE: compilerPhase.kt
|
||||||
|
public abstract interface CommonBackendContext : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface PhaserState<Data> : R|kotlin/Any| {
|
||||||
|
public abstract var depth: R|kotlin/Int|
|
||||||
|
public get(): R|kotlin/Int|
|
||||||
|
public set(value: R|kotlin/Int|): R|kotlin/Unit|
|
||||||
|
|
||||||
|
}
|
||||||
|
public abstract interface PhaseConfig : R|kotlin/Any| {
|
||||||
|
public abstract val needProfiling: R|kotlin/Boolean|
|
||||||
|
public get(): R|kotlin/Boolean|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final inline fun <R, D> R|PhaserState<D>|.downlevel(nlevels: R|kotlin/Int|, block: R|() -> R|): R|R| {
|
||||||
|
this@R|/downlevel|.R|/PhaserState.depth| = this@R|/downlevel|.R|/PhaserState.depth|.R|kotlin/Int.plus|(R|<local>/nlevels|)
|
||||||
|
lval result: R|R| = R|<local>/block|.R|SubstitutionOverride<kotlin/Function0.invoke: R|R|>|()
|
||||||
|
this@R|/downlevel|.R|/PhaserState.depth| = this@R|/downlevel|.R|/PhaserState.depth|.R|kotlin/Int.minus|(R|<local>/nlevels|)
|
||||||
|
^downlevel R|<local>/result|
|
||||||
|
}
|
||||||
|
public abstract interface CompilerPhase<in Context : R|CommonBackendContext|, Input, Output> : R|kotlin/Any| {
|
||||||
|
public abstract fun invoke(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Input>|, context: R|Context|, input: R|Input|): R|Output|
|
||||||
|
|
||||||
|
}
|
||||||
|
public final class NamedCompilerPhase<in Context : R|CommonBackendContext|, Data> : R|CompilerPhase<Context, Data, Data>| {
|
||||||
|
public constructor<in Context : R|CommonBackendContext|, Data>(lower: R|CompilerPhase<Context, Data, Data>|): R|NamedCompilerPhase<Context, Data>| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
private final val lower: R|CompilerPhase<Context, Data, Data>| = R|<local>/lower|
|
||||||
|
private get(): R|CompilerPhase<Context, Data, Data>|
|
||||||
|
|
||||||
|
public final override fun invoke(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Data>|, context: R|Context|, input: R|Data|): R|Data| {
|
||||||
|
lval output: R|Data| = when () {
|
||||||
|
R|<local>/phaseConfig|.R|/PhaseConfig.needProfiling| -> {
|
||||||
|
this@R|/NamedCompilerPhase|.R|/NamedCompilerPhase.runAndProfile|(R|<local>/phaseConfig|, R|<local>/phaserState|, R|<local>/context|, R|<local>/input|)
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
R|<local>/phaserState|.R|/downlevel|<R|Data|, R|Data|>(Int(1), <L> = downlevel@fun <anonymous>(): R|Data| <kind=UNKNOWN> {
|
||||||
|
^ this@R|/NamedCompilerPhase|.R|/NamedCompilerPhase.lower|.R|SubstitutionOverride</CompilerPhase.invoke: R|Data|>|(R|<local>/phaseConfig|, R|<local>/phaserState|, R|<local>/context|, R|<local>/input|)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this@R|/NamedCompilerPhase|.R|/NamedCompilerPhase.runAfter|(R|<local>/phaseConfig|, R|<local>/phaserState|, R|<local>/context|, R|<local>/output|)
|
||||||
|
}
|
||||||
|
|
||||||
|
private final fun runAfter(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Data>|, context: R|Context|, output: R|Data|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
|
||||||
|
private final fun runAndProfile(phaseConfig: R|PhaseConfig|, phaserState: R|PhaserState<Data>|, context: R|Context|, source: R|Data|): R|Data| {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
interface A
|
||||||
|
interface B
|
||||||
|
|
||||||
|
fun foo(x: A) {}
|
||||||
|
fun foo(x: B) {}
|
||||||
|
|
||||||
|
open class C : A, B
|
||||||
|
|
||||||
|
fun main(a: A) {
|
||||||
|
foo(a)
|
||||||
|
|
||||||
|
val anonymousA: A = object : C() {}
|
||||||
|
foo(anonymousA)
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
FILE: questionableSmartCast.kt
|
||||||
|
public abstract interface A : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public abstract interface B : R|kotlin/Any| {
|
||||||
|
}
|
||||||
|
public final fun foo(x: R|A|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public final fun foo(x: R|B|): R|kotlin/Unit| {
|
||||||
|
}
|
||||||
|
public open class C : R|A|, R|B| {
|
||||||
|
public constructor(): R|C| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
public final fun main(a: R|A|): R|kotlin/Unit| {
|
||||||
|
R|/foo|(R|<local>/a|)
|
||||||
|
lval anonymousA: R|A| = object : R|C| {
|
||||||
|
private constructor(): R|<anonymous>| {
|
||||||
|
super<R|C|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
R|/foo|(R|<local>/anonymousA|)
|
||||||
|
}
|
||||||
+20
@@ -0,0 +1,20 @@
|
|||||||
|
// FILE: AliasFor.java
|
||||||
|
|
||||||
|
public @interface AliasFor {
|
||||||
|
@AliasFor(value = "attribute")
|
||||||
|
String value() default "";
|
||||||
|
|
||||||
|
@AliasFor(value = "value")
|
||||||
|
String attribute() default "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Service.java
|
||||||
|
public @interface Service {
|
||||||
|
@AliasFor(value = "component")
|
||||||
|
String value() default "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: Annotated.kt
|
||||||
|
|
||||||
|
@Service(value = "Your")
|
||||||
|
class My
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
FILE: Annotated.kt
|
||||||
|
@R|Service|(value = String(Your)) public final class My : R|kotlin/Any| {
|
||||||
|
public constructor(): R|My| {
|
||||||
|
super<R|kotlin/Any|>()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user