[K/N] Implement instantiating of annotation class
This commit is contained in:
+12
@@ -407,6 +407,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationFromStdlib.kt")
|
||||
public void testAnnotationFromStdlib() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationFromStdlib.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationInstances.kt")
|
||||
public void testAnnotationInstances() throws Exception {
|
||||
@@ -437,6 +443,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inInlineFunction.kt")
|
||||
public void testInInlineFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/inInlineFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaAnnotation.kt")
|
||||
public void testJavaAnnotation() throws Exception {
|
||||
|
||||
-40
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.CallExpressionResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
|
||||
/**
|
||||
* Additional checker that prohibits usage of LanguageFeature.InstantiationOfAnnotationClasses on backends
|
||||
* that do not support this feature yet
|
||||
*/
|
||||
object InstantiationOfAnnotationClassesCallChecker : CallChecker {
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.InstantiationOfAnnotationClasses)) return
|
||||
val calledDescriptor = resolvedCall.resultingDescriptor as? ConstructorDescriptor ?: return
|
||||
val constructedClass = calledDescriptor.constructedClass
|
||||
val expression = resolvedCall.call.callElement as? KtCallExpression ?: return
|
||||
if (DescriptorUtils.isAnnotationClass(constructedClass) && !CallExpressionResolver.canInstantiateAnnotationClass(
|
||||
expression,
|
||||
context.trace
|
||||
)
|
||||
) {
|
||||
val supported = constructedClass.declaredTypeParameters.isEmpty()
|
||||
if (supported) {
|
||||
context.trace.report(Errors.ANNOTATION_CLASS_CONSTRUCTOR_CALL.on(expression))
|
||||
} else {
|
||||
// already reported in CallExpressionResolver.getCallExpressionTypeInfoWithoutFinalTypeCheck
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: WASM
|
||||
// DONT_TARGET_EXACT_BACKEND: JS
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: WASM
|
||||
// DONT_TARGET_EXACT_BACKEND: JS
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
fun box(): String {
|
||||
val ann1 = kotlin.SinceKotlin("1.6.0")
|
||||
val expectedToString = "@kotlin.SinceKotlin(version=1.6.0)"
|
||||
val actualToString = ann1.toString()
|
||||
if (actualToString != expectedToString) return "Expected ann1.toString() equals to $expectedToString, but it's $actualToString"
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: WASM
|
||||
|
||||
// (supported: JVM_IR, JS_IR(_E6))
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: WASM
|
||||
// DONT_TARGET_EXACT_BACKEND: JS
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: WASM
|
||||
// DONT_TARGET_EXACT_BACKEND: JS
|
||||
|
||||
@@ -49,5 +48,8 @@ fun box(): String {
|
||||
val targetJVM = "@test.Anno(s=OK, i=42, f=2.718281828, u=43, e=E0, a=@test.A(b=1, s=1, i=1, f=1.0, d=1.0, l=1, c=c, bool=true), " +
|
||||
"k=interface test.A (Kotlin reflection is not available), arr=[], intArr=[1, 2], arrOfE=[E0], arrOfA=[@test.Empty()])"
|
||||
val targetJS = "@test.Anno(s=OK, i=42, f=2.718281828, u=43, e=E0, a=@test.A(b=1, s=1, i=1, f=1, d=1, l=1, c=c, bool=true), k=class A, arr=[...], intArr=[...], arrOfE=[...], arrOfA=[...])"
|
||||
return if (s == targetJS || s == targetJVM) "OK" else "FAILED, got string $s"
|
||||
val targetNative = targetJVM
|
||||
.replace(" (Kotlin reflection is not available)", "")
|
||||
.replace("interface", "class")
|
||||
return if (s == targetJS || s == targetJVM || s == targetNative) "OK" else "FAILED, got string $s"
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: WASM
|
||||
// DONT_TARGET_EXACT_BACKEND: JS
|
||||
// IGNORE_DEXING
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
import kotlin.test.*
|
||||
|
||||
annotation class A(val i: Int)
|
||||
|
||||
inline fun foo(i: Int): A = A(i)
|
||||
|
||||
inline fun bar(f: () -> Int): A = A(f())
|
||||
|
||||
class C {
|
||||
fun one(): A = foo(1)
|
||||
fun two(): A = bar { 2 }
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
val one = C().one()
|
||||
val two = C().two()
|
||||
assertEquals(1, one.i)
|
||||
assertEquals(2, two.i)
|
||||
assertEquals(A(1), one)
|
||||
assertEquals(A(2), two)
|
||||
return "OK"
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: WASM
|
||||
// DONT_TARGET_EXACT_BACKEND: JS
|
||||
|
||||
|
||||
-1
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: WASM
|
||||
|
||||
// (supported: JVM_IR, JS_IR(_E6))
|
||||
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: WASM
|
||||
// DONT_TARGET_EXACT_BACKEND: JS
|
||||
|
||||
// WITH_RUNTIME
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: WASM
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: NATIVE
|
||||
// IGNORE_BACKEND: WASM
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// WITH_RUNTIME
|
||||
// SKIP_TXT
|
||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
annotation class A
|
||||
annotation class B(val int: Int)
|
||||
annotation class C(val int: Int = 42)
|
||||
|
||||
annotation class G<T: Any>(val int: KClass<T>)
|
||||
|
||||
fun box() {
|
||||
val a = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>A()<!>
|
||||
val b = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>B(4)<!>
|
||||
val c = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>C()<!>
|
||||
val foo = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>G(Int::class)<!>
|
||||
}
|
||||
-6
@@ -24,12 +24,6 @@ public class DiagnosticsNativeTestGenerated extends AbstractDiagnosticsNativeTes
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/nativeTests"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationConstructorCallNative.kt")
|
||||
public void testAnnotationConstructorCallNative() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/nativeTests/annotationConstructorCallNative.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("identifiers.kt")
|
||||
public void testIdentifiers() throws Exception {
|
||||
|
||||
+18
@@ -395,6 +395,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationFromStdlib.kt")
|
||||
public void testAnnotationFromStdlib() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationFromStdlib.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationInstances.kt")
|
||||
public void testAnnotationInstances() throws Exception {
|
||||
@@ -413,6 +419,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inInlineFunction.kt")
|
||||
public void testInInlineFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/inInlineFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("multifileEqHc.kt")
|
||||
public void testMultifileEqHc() throws Exception {
|
||||
@@ -424,6 +436,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
public void testMultiplatformInstantiation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("nestedAnnotationInstances.kt")
|
||||
public void testNestedAnnotationInstances() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/nestedAnnotationInstances.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
|
||||
+12
@@ -407,6 +407,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationFromStdlib.kt")
|
||||
public void testAnnotationFromStdlib() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationFromStdlib.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("annotationInstances.kt")
|
||||
public void testAnnotationInstances() throws Exception {
|
||||
@@ -437,6 +443,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("inInlineFunction.kt")
|
||||
public void testInInlineFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/inInlineFunction.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("javaAnnotation.kt")
|
||||
public void testJavaAnnotation() throws Exception {
|
||||
|
||||
+15
@@ -344,6 +344,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationFromStdlib.kt")
|
||||
public void ignoreAnnotationFromStdlib() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationFromStdlib.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationInstances.kt")
|
||||
public void ignoreAnnotationInstances() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
|
||||
@@ -359,6 +364,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inInlineFunction.kt")
|
||||
public void ignoreInInlineFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/inInlineFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multifileEqHc.kt")
|
||||
public void ignoreMultifileEqHc() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
|
||||
@@ -369,6 +379,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedAnnotationInstances.kt")
|
||||
public void ignoreNestedAnnotationInstances() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/nestedAnnotationInstances.kt");
|
||||
}
|
||||
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.js.analyze.JsNativeDiagnosticSuppressor
|
||||
import org.jetbrains.kotlin.js.naming.NameSuggestion
|
||||
import org.jetbrains.kotlin.js.resolve.diagnostics.*
|
||||
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.InstantiationOfAnnotationClassesCallChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.types.DynamicTypesAllowed
|
||||
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/es6/semantics/IrJsCodegenBoxES6TestGenerated.java
Generated
+15
@@ -97,6 +97,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationFromStdlib.kt")
|
||||
public void testAnnotationFromStdlib() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationFromStdlib.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationInstances.kt")
|
||||
public void testAnnotationInstances() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
|
||||
@@ -112,6 +117,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inInlineFunction.kt")
|
||||
public void testInInlineFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/inInlineFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multifileEqHc.kt")
|
||||
public void testMultifileEqHc() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
|
||||
@@ -121,6 +131,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
public void testMultiplatformInstantiation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedAnnotationInstances.kt")
|
||||
public void testNestedAnnotationInstances() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/nestedAnnotationInstances.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
|
||||
Generated
+15
@@ -97,6 +97,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationFromStdlib.kt")
|
||||
public void testAnnotationFromStdlib() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationFromStdlib.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationInstances.kt")
|
||||
public void testAnnotationInstances() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
|
||||
@@ -112,6 +117,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inInlineFunction.kt")
|
||||
public void testInInlineFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/inInlineFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multifileEqHc.kt")
|
||||
public void testMultifileEqHc() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
|
||||
@@ -121,6 +131,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
public void testMultiplatformInstantiation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedAnnotationInstances.kt")
|
||||
public void testNestedAnnotationInstances() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/nestedAnnotationInstances.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
|
||||
js/js.tests/tests-gen/org/jetbrains/kotlin/js/test/wasm/semantics/IrCodegenBoxWasmTestGenerated.java
Generated
+15
@@ -92,6 +92,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationEqHc.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationFromStdlib.kt")
|
||||
public void testAnnotationFromStdlib() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationFromStdlib.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("annotationInstances.kt")
|
||||
public void testAnnotationInstances() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationInstances.kt");
|
||||
@@ -107,6 +112,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/annotationToString.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("inInlineFunction.kt")
|
||||
public void testInInlineFunction() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/inInlineFunction.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("multifileEqHc.kt")
|
||||
public void testMultifileEqHc() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multifileEqHc.kt");
|
||||
@@ -116,6 +126,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
||||
public void testMultiplatformInstantiation() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/multiplatformInstantiation.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("nestedAnnotationInstances.kt")
|
||||
public void testNestedAnnotationInstances() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/annotations/instances/nestedAnnotationInstances.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/annotations/kClassMapping")
|
||||
|
||||
-11
@@ -5,18 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
internal fun IrClass.isNonGeneratedAnnotation(): Boolean =
|
||||
this.kind == ClassKind.ANNOTATION_CLASS &&
|
||||
!this.annotations.hasAnnotation(serialInfoAnnotationFqName) &&
|
||||
!this.annotations.hasAnnotation(inheritableSerialInfoFqName)
|
||||
|
||||
private val serialInfoAnnotationFqName = FqName("kotlinx.serialization.SerialInfo")
|
||||
private val inheritableSerialInfoFqName = FqName("kotlinx.serialization.InheritableSerialInfo")
|
||||
|
||||
/**
|
||||
* We don't need to generate RTTI in some cases, e.g. Objective-C external classes.
|
||||
|
||||
+6
@@ -87,6 +87,12 @@ internal val stripTypeAliasDeclarationsPhase = makeKonanModuleLoweringPhase(
|
||||
description = "Strip typealias declarations"
|
||||
)
|
||||
|
||||
internal val annotationImplementationPhase = makeKonanFileLoweringPhase(
|
||||
{ context -> AnnotationImplementationLowering { NativeAnnotationImplementationTransformer(context, it) } },
|
||||
name = "AnnotationImplementation",
|
||||
description = "Create synthetic annotations implementations and use them in annotations constructor calls"
|
||||
)
|
||||
|
||||
internal val lowerBeforeInlinePhase = makeKonanModuleLoweringPhase(
|
||||
::PreInlineLowering,
|
||||
name = "LowerBeforeInline",
|
||||
|
||||
+1
-1
@@ -7,7 +7,6 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
|
||||
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer
|
||||
import org.jetbrains.kotlin.backend.konan.MemoryModel
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier
|
||||
import org.jetbrains.kotlin.backend.konan.lower.SamSuperTypesChecker
|
||||
@@ -224,6 +223,7 @@ internal val allLoweringsPhase = NamedCompilerPhase(
|
||||
name = "IrLowerByFile",
|
||||
description = "IR Lowering by file",
|
||||
lower = listOf(
|
||||
annotationImplementationPhase,
|
||||
rangeContainsLoweringPhase,
|
||||
forLoopsPhase,
|
||||
flattenStringConcatenationPhase,
|
||||
|
||||
+20
-14
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.backend.konan.lower.TestProcessor
|
||||
import org.jetbrains.kotlin.builtins.StandardNames
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.findClassAcrossModuleDependencies
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.kotlin.ir.symbols.IrEnumEntrySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.typeWith
|
||||
import org.jetbrains.kotlin.ir.util.ReferenceSymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
@@ -292,18 +294,29 @@ internal class KonanSymbols(
|
||||
val getProgressionLast = context.getKonanInternalFunctions("getProgressionLast")
|
||||
.map { Pair(it.returnType, symbolTable.referenceSimpleFunction(it)) }.toMap()
|
||||
|
||||
val arrayContentToString = arrays.associateBy({ it }, { findArrayExtension(it, "contentToString") })
|
||||
private fun arrayToExtensionSymbolMap(name: String, filter: (FunctionDescriptor) -> Boolean = { true }) = arrays.associateWith {
|
||||
findArrayExtension(it, name, filter)
|
||||
}
|
||||
|
||||
val arrayContentHashCode = arrays.associateBy({ it }, { findArrayExtension(it, "contentHashCode") })
|
||||
val arrayContentToString = arrayToExtensionSymbolMap("contentToString") {
|
||||
it.extensionReceiverParameter?.type?.isMarkedNullable == false
|
||||
}
|
||||
val arrayContentHashCode = arrayToExtensionSymbolMap("contentHashCode") {
|
||||
it.extensionReceiverParameter?.type?.isMarkedNullable == false
|
||||
}
|
||||
val arrayContentEquals = arrayToExtensionSymbolMap("contentEquals") {
|
||||
it.extensionReceiverParameter?.type?.isMarkedNullable == false
|
||||
}
|
||||
|
||||
private fun findArrayExtension(classSymbol: IrClassSymbol, name: String): IrSimpleFunctionSymbol =
|
||||
override val arraysContentEquals by lazy { arrayContentEquals.mapKeys { it.key.defaultType } }
|
||||
|
||||
private fun findArrayExtension(classSymbol: IrClassSymbol, name: String, filter: (FunctionDescriptor) -> Boolean): IrSimpleFunctionSymbol =
|
||||
irBuiltIns.findFunctions(Name.identifier(name), "kotlin", "collections")
|
||||
.singleOrNull {
|
||||
it.descriptor.let {
|
||||
it.valueParameters.isEmpty()
|
||||
&& it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == classSymbol.descriptor
|
||||
&& it.extensionReceiverParameter?.type?.isMarkedNullable == false
|
||||
it.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == classSymbol.descriptor
|
||||
&& !it.isExpect
|
||||
&& filter(it)
|
||||
}
|
||||
} ?: error(classSymbol.toString())
|
||||
|
||||
@@ -314,14 +327,7 @@ internal class KonanSymbols(
|
||||
return symbolTable.referenceFunction(descriptor)
|
||||
}
|
||||
|
||||
val copyInto = arrays.map { symbol ->
|
||||
val funSymbol = irBuiltIns.findFunctions(Name.identifier("copyInto"), StandardNames.COLLECTIONS_PACKAGE_FQ_NAME)
|
||||
.single {
|
||||
!it.descriptor.isExpect &&
|
||||
it.descriptor.extensionReceiverParameter?.type?.constructor?.declarationDescriptor == symbol.descriptor
|
||||
}
|
||||
symbol to funSymbol
|
||||
}.toMap()
|
||||
val copyInto = arrayToExtensionSymbolMap("copyInto")
|
||||
|
||||
val arrayGet = arrays.associateWith { it.descriptor.unsubstitutedMemberScope
|
||||
.getContributedFunctions(Name.identifier("get"), NoLookupLocation.FROM_BACKEND)
|
||||
|
||||
+1
-1
@@ -877,7 +877,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
context.log{"visitClass : ${ir2string(declaration)}"}
|
||||
|
||||
if (declaration.isNonGeneratedAnnotation() || !declaration.requiresCodeGeneration()) {
|
||||
if (!declaration.requiresCodeGeneration()) {
|
||||
// For non-generated annotation classes generate only nested classes.
|
||||
declaration.declarations
|
||||
.filterIsInstance<IrClass>()
|
||||
|
||||
+9
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.propertyIfAccessor
|
||||
import org.jetbrains.kotlin.backend.konan.ir.ModuleIndex
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
@@ -34,7 +35,14 @@ import org.jetbrains.kotlin.resolve.multiplatform.OptionalAnnotationUtil
|
||||
internal class ExpectDeclarationsRemoving(val context: Context) : FileLoweringPass {
|
||||
override fun lower(irFile: IrFile) {
|
||||
// All declarations with `isExpect == true` are nested into a top-level declaration with `isExpect == true`.
|
||||
irFile.declarations.removeAll { it.descriptor.isExpectMember }
|
||||
irFile.declarations.removeAll {
|
||||
when (it) {
|
||||
is IrClass -> it.isExpect
|
||||
is IrFunction -> it.isExpect
|
||||
is IrProperty -> it.isExpect
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
-11
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.ir.createDispatchReceiverParameter
|
||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlockBody
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.backend.konan.isNonGeneratedAnnotation
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.irDelegatingConstructorCall
|
||||
@@ -154,16 +153,6 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo
|
||||
}
|
||||
|
||||
private fun lowerConstructors(initializeMethodSymbol: IrSimpleFunctionSymbol?) {
|
||||
if (irClass.kind == ClassKind.ANNOTATION_CLASS) {
|
||||
if (irClass.isNonGeneratedAnnotation()) return
|
||||
|
||||
val irConstructor = irClass.declarations.filterIsInstance<IrConstructor>().single()
|
||||
assert(irConstructor.body == null)
|
||||
irConstructor.body = context.createIrBuilder(irConstructor.symbol).irBlockBody(irConstructor) {
|
||||
+irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
|
||||
+IrInstanceInitializerCallImpl(startOffset, endOffset, irClass.symbol, context.irBuiltIns.unitType)
|
||||
}
|
||||
}
|
||||
irClass.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.deepCopyWithVariables
|
||||
import org.jetbrains.kotlin.backend.common.lower.AnnotationImplementationTransformer
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
|
||||
|
||||
internal class NativeAnnotationImplementationTransformer(context: Context, irFile: IrFile) :
|
||||
AnnotationImplementationTransformer(context, irFile) {
|
||||
|
||||
private val arrayContentEqualsMap = context.ir.symbols.arraysContentEquals
|
||||
|
||||
override fun getArrayContentEqualsSymbol(type: IrType) =
|
||||
when {
|
||||
type.isPrimitiveArray() -> arrayContentEqualsMap[type]
|
||||
else -> arrayContentEqualsMap.entries.singleOrNull { (k, _) -> k.isArray() }?.value
|
||||
} ?: error("Can't find an Arrays.contentEquals method for array type ${type.render()}")
|
||||
|
||||
override fun IrClass.platformSetup() {
|
||||
visibility = DescriptorVisibilities.PRIVATE
|
||||
parent = irFile!!
|
||||
}
|
||||
|
||||
override fun implementAnnotationPropertiesAndConstructor(implClass: IrClass, annotationClass: IrClass, generatedConstructor: IrConstructor) {
|
||||
val properties = annotationClass.getAnnotationProperties()
|
||||
properties.forEach { property ->
|
||||
val propType = property.getter!!.returnType
|
||||
val propName = property.name
|
||||
val parameter = generatedConstructor.addValueParameter(propName.asString(), propType)
|
||||
// VALUE_FROM_PARAMETER
|
||||
val originalParameter = ((property.backingField?.initializer?.expression as? IrGetValue)?.symbol?.owner as? IrValueParameter)
|
||||
if (originalParameter?.defaultValue != null) {
|
||||
parameter.defaultValue = originalParameter.defaultValue!!.deepCopyWithVariables().also { it.transformChildrenVoid() }
|
||||
}
|
||||
}
|
||||
|
||||
generatedConstructor.body = context.irFactory.createBlockBody(
|
||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, listOf(
|
||||
IrDelegatingConstructorCallImpl(
|
||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, context.irBuiltIns.unitType, annotationClass.constructors.single().symbol,
|
||||
typeArgumentsCount = 0, valueArgumentsCount = generatedConstructor.valueParameters.size
|
||||
).apply {
|
||||
generatedConstructor.valueParameters.forEach {
|
||||
putValueArgument(it.index, IrGetValueImpl(SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, it.symbol))
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
override val forbidDirectFieldAccessInMethods = true
|
||||
}
|
||||
+2
-3
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.backend.konan.ir.actualCallee
|
||||
import org.jetbrains.kotlin.backend.konan.ir.isAny
|
||||
import org.jetbrains.kotlin.backend.konan.ir.isObjCObjectType
|
||||
import org.jetbrains.kotlin.backend.konan.ir.isVirtualCall
|
||||
import org.jetbrains.kotlin.backend.konan.isNonGeneratedAnnotation
|
||||
import org.jetbrains.kotlin.backend.konan.logMultiple
|
||||
import org.jetbrains.kotlin.backend.konan.lower.erasedUpperBound
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -201,8 +200,8 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
||||
|
||||
override fun visitConstructor(declaration: IrConstructor) {
|
||||
val body = declaration.body
|
||||
assert (body != null || declaration.constructedClass.isNonGeneratedAnnotation()) {
|
||||
"Non-annotation class constructor has empty body"
|
||||
assert (body != null) {
|
||||
"Class constructor has empty body"
|
||||
}
|
||||
context.logMultiple {
|
||||
+"Analysing function ${declaration.descriptor}"
|
||||
|
||||
-1
@@ -615,7 +615,6 @@ internal object DataFlowIR {
|
||||
}
|
||||
val bridgeTargetSymbol = if (isSpecialBridge || bridgeTarget == null) null else mapFunction(bridgeTarget)
|
||||
val placeToFunctionsTable = !isAbstract && it !is IrConstructor && irClass != null
|
||||
&& !irClass.isNonGeneratedAnnotation()
|
||||
&& (it.isOverridableOrOverrides || bridgeTarget != null || function.isSpecial || !irClass.isFinal())
|
||||
val symbolTableIndex = if (placeToFunctionsTable) module.numberOfFunctions++ else -1
|
||||
val frozen = it is IrConstructor && irClass!!.annotations.findAnnotation(KonanFqNames.frozen) != null
|
||||
|
||||
-2
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtCallableDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.PlatformConfiguratorBase
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.InstantiationOfAnnotationClassesCallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.TypeOfChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.inline.ReasonableInlineRule
|
||||
@@ -23,7 +22,6 @@ import org.jetbrains.kotlin.resolve.konan.diagnostics.*
|
||||
object NativePlatformConfigurator : PlatformConfiguratorBase(
|
||||
additionalCallCheckers = listOf(
|
||||
SuperCallWithDefaultArgumentsChecker(),
|
||||
InstantiationOfAnnotationClassesCallChecker
|
||||
),
|
||||
additionalDeclarationCheckers = listOf(
|
||||
NativeThrowsChecker, NativeSharedImmutableChecker,
|
||||
|
||||
Reference in New Issue
Block a user