[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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user