[FIR] Allow annotation instantiation.
This commit disables the frontend error reporting for supported cases.
This commit is contained in:
committed by
TeamCityServer
parent
56d472451c
commit
b79ca7d7df
+8
-1
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
|
||||||
@@ -37,7 +38,13 @@ object FirConstructorCallChecker : FirFunctionCallChecker() {
|
|||||||
klass !is FirRegularClass || klass.classKind != ClassKind.ANNOTATION_CLASS
|
klass !is FirRegularClass || klass.classKind != ClassKind.ANNOTATION_CLASS
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
reporter.reportOn(expression.source, FirErrors.ANNOTATION_CLASS_CONSTRUCTOR_CALL, context)
|
if (!context.languageVersionSettings.supportsFeature(LanguageFeature.InstantiationOfAnnotationClasses) ||
|
||||||
|
declarationClass.typeParameterSymbols.isNotEmpty()
|
||||||
|
) reporter.reportOn(
|
||||||
|
expression.source,
|
||||||
|
FirErrors.ANNOTATION_CLASS_CONSTRUCTOR_CALL,
|
||||||
|
context
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
@@ -50,4 +49,4 @@ fun box(): String {
|
|||||||
test(G().insideClassAgain(), "test.E", "test_A1")
|
test(G().insideClassAgain(), "test.E", "test_A1")
|
||||||
test(outsideClass(), "test.TestKt", "test_A2")
|
test(outsideClass(), "test.TestKt", "test_A2")
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// DONT_TARGET_EXACT_BACKEND: JS
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
@@ -29,4 +28,4 @@ fun box(): String {
|
|||||||
if (barlike != foo1.bar.hashCode()) return "Failed HC1"
|
if (barlike != foo1.bar.hashCode()) return "Failed HC1"
|
||||||
if (barlike != foo2.bar.hashCode()) return "Failed HC2"
|
if (barlike != foo2.bar.hashCode()) return "Failed HC2"
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// DONT_TARGET_EXACT_BACKEND: JS
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
@@ -14,4 +13,4 @@ fun box(): String {
|
|||||||
val actualToString = ann1.toString()
|
val actualToString = ann1.toString()
|
||||||
if (actualToString != expectedToString) return "Expected ann1.toString() equals to $expectedToString, but it's $actualToString"
|
if (actualToString != expectedToString) return "Expected ann1.toString() equals to $expectedToString, but it's $actualToString"
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// DONT_TARGET_EXACT_BACKEND: JS
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
@@ -46,4 +45,4 @@ fun box(): String {
|
|||||||
assertEquals("bar", p.s)
|
assertEquals("bar", p.s)
|
||||||
assertEquals(E.B, p.e)
|
assertEquals(E.B, p.e)
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// DONT_TARGET_EXACT_BACKEND: JS
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
@@ -52,4 +51,4 @@ fun box(): String {
|
|||||||
.replace(" (Kotlin reflection is not available)", "")
|
.replace(" (Kotlin reflection is not available)", "")
|
||||||
.replace("interface", "class")
|
.replace("interface", "class")
|
||||||
return if (s == targetJS || s == targetJVM || s == targetNative) "OK" else "FAILED, got string $s"
|
return if (s == targetJS || s == targetJVM || s == targetNative) "OK" else "FAILED, got string $s"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
@@ -15,4 +14,4 @@ fun box(): String {
|
|||||||
if (kClass != Foo::class) return "FAIL $kClass"
|
if (kClass != Foo::class) return "FAIL $kClass"
|
||||||
if (jClass != Foo::class.java) return "FAIL $jClass"
|
if (jClass != Foo::class.java) return "FAIL $jClass"
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// DONT_TARGET_EXACT_BACKEND: JS
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
@@ -28,4 +27,4 @@ fun box(): String {
|
|||||||
assertEquals(A(1), one)
|
assertEquals(A(1), one)
|
||||||
assertEquals(A(2), two)
|
assertEquals(A(2), two)
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// Fir2IrLazyClass does not handle methods from java dependencies in declarations.
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
|
||||||
@@ -41,4 +42,4 @@ fun box(): String {
|
|||||||
// val d = D()
|
// val d = D()
|
||||||
val d = D("OK").value
|
val d = D("OK").value
|
||||||
return d
|
return d
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
@@ -20,4 +19,4 @@ fun box(): String {
|
|||||||
if (m.toString() == """@kotlin.Metadata(bytecodeVersion=[1, 0, 3], data1=[], data2=[], extraInt=0, extraString=, kind=0, metadataVersion=[], packageName=foo)""")
|
if (m.toString() == """@kotlin.Metadata(bytecodeVersion=[1, 0, 3], data1=[], data2=[], extraInt=0, extraString=, kind=0, metadataVersion=[], packageName=foo)""")
|
||||||
return "OK"
|
return "OK"
|
||||||
return m.toString()
|
return m.toString()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// DONT_TARGET_EXACT_BACKEND: JS
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
@@ -27,4 +26,4 @@ fun box(): String {
|
|||||||
if (here().hashCode() != createInOtherFile().hashCode()) return "Fail hashCode"
|
if (here().hashCode() != createInOtherFile().hashCode()) return "Fail hashCode"
|
||||||
if (here().toString() != createInOtherFile().toString()) return "Fail toString"
|
if (here().toString() != createInOtherFile().toString()) return "Fail toString"
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
|
// With FIR the annotation implementation class is not regenerated as it
|
||||||
|
// is seen as coming from the same module.
|
||||||
|
// See IrSourceCompilerForInline.kt:isCallInsideSameModuleAsCallee.
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// TARGET_BACKEND: JVM_IR
|
// TARGET_BACKEND: JVM_IR
|
||||||
// IGNORE_DEXING
|
// IGNORE_DEXING
|
||||||
|
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||||
|
|
||||||
@@ -39,4 +41,4 @@ fun box(): String {
|
|||||||
assert(one.javaClass.getEnclosingClass().getName() == "test.C")
|
assert(one.javaClass.getEnclosingClass().getName() == "test.C")
|
||||||
assert(two.javaClass.getEnclosingClass().getName() == "test.C")
|
assert(two.javaClass.getEnclosingClass().getName() == "test.C")
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-1
@@ -1,3 +1,4 @@
|
|||||||
|
// Multi-platform not supported with FIR yet.
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
@@ -30,4 +31,4 @@ fun box(): String {
|
|||||||
if (createCommon().value != "OK") return "FAIL common"
|
if (createCommon().value != "OK") return "FAIL common"
|
||||||
if (createPlatform().value != "OK") return "FAIL platform"
|
if (createPlatform().value != "OK") return "FAIL platform"
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// DONT_TARGET_EXACT_BACKEND: JS
|
// DONT_TARGET_EXACT_BACKEND: JS
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
||||||
@@ -39,4 +38,4 @@ fun box(): String {
|
|||||||
val two = two()
|
val two = two()
|
||||||
assert(two.i == 2)
|
assert(two.i == 2)
|
||||||
return "OK"
|
return "OK"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
// IGNORE_BACKEND: WASM
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
||||||
@@ -34,4 +33,4 @@ class C() {
|
|||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
return C().one().i
|
return C().one().i
|
||||||
}
|
}
|
||||||
|
|||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
// WITH_RUNTIME
|
|
||||||
// SKIP_TXT
|
|
||||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
|
||||||
|
|
||||||
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)<!>
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// SKIP_TXT
|
// SKIP_TXT
|
||||||
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
// !LANGUAGE: +InstantiationOfAnnotationClasses
|
||||||
|
|||||||
+2
-2
@@ -7,8 +7,8 @@ val test1a = <!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>AbstractClass()<!>
|
|||||||
|
|
||||||
annotation class AnnotationClass
|
annotation class AnnotationClass
|
||||||
typealias Test2 = AnnotationClass
|
typealias Test2 = AnnotationClass
|
||||||
val test2 = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>Test2()<!>
|
val test2 = Test2()
|
||||||
val test2a = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>AnnotationClass()<!>
|
val test2a = AnnotationClass()
|
||||||
|
|
||||||
enum class EnumClass { VALUE1, VALUE2 }
|
enum class EnumClass { VALUE1, VALUE2 }
|
||||||
typealias Test3 = EnumClass
|
typealias Test3 = EnumClass
|
||||||
|
|||||||
+1
-1
@@ -21,4 +21,4 @@ annotation class AnnAnn(val i: Array<Ann>)
|
|||||||
@AnnAnn(arrayOf(Ann(intArrayOf(1))))
|
@AnnAnn(arrayOf(Ann(intArrayOf(1))))
|
||||||
@AnnAnn(<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>iAnn<!>)<!>)
|
@AnnAnn(<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>iAnn<!>)<!>)
|
||||||
class TestAnn
|
class TestAnn
|
||||||
val iAnn = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>Ann(intArrayOf(1))<!>
|
val iAnn = Ann(intArrayOf(1))
|
||||||
|
|||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
@Repeatable
|
|
||||||
annotation class Ann(vararg val i: Int)
|
|
||||||
|
|
||||||
@Ann(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i<!>)
|
|
||||||
@Ann(i2)
|
|
||||||
@Ann(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i3<!>)
|
|
||||||
@Ann(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i<!>, i2, <!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i3<!>)
|
|
||||||
@Ann(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>intArrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i<!>)<!>)
|
|
||||||
@Ann(*intArrayOf(i2))
|
|
||||||
@Ann(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>intArrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i3<!>)<!>)
|
|
||||||
@Ann(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>intArrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i<!>, i2, <!ANNOTATION_ARGUMENT_MUST_BE_CONST!>i3<!>)<!>)
|
|
||||||
class Test
|
|
||||||
|
|
||||||
var i = 1
|
|
||||||
const val i2 = 1
|
|
||||||
val i3 = foo()
|
|
||||||
|
|
||||||
fun foo(): Int = 1
|
|
||||||
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
@Repeatable
|
|
||||||
annotation class AnnAnn(vararg val i: Ann)
|
|
||||||
@AnnAnn(*arrayOf(Ann(1)))
|
|
||||||
@AnnAnn(*<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>iAnn<!>)<!>)
|
|
||||||
class TestAnn
|
|
||||||
val iAnn = <!ANNOTATION_CLASS_CONSTRUCTOR_CALL!>Ann(1)<!>
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
@Retention(AnnotationRetention.SOURCE)
|
||||||
@Repeatable
|
@Repeatable
|
||||||
annotation class Ann(vararg val i: Int)
|
annotation class Ann(vararg val i: Int)
|
||||||
|
|||||||
Reference in New Issue
Block a user