[FIR] Support several annotation argument diagnostics

This commit is contained in:
Лихолетов Михаил
2020-09-13 15:44:09 +03:00
committed by Mikhail Glukhikh
parent 0c13d3197c
commit cfc1ebb4be
50 changed files with 580 additions and 219 deletions
@@ -0,0 +1,12 @@
import kotlin.reflect.KClass
annotation class Ann(val a: Array<KClass<*>>)
inline val <reified T> T.test
get() = @Ann(
<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(
<!ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR!>T::class<!>,
<!ANNOTATION_ARGUMENT_KCLASS_LITERAL_OF_TYPE_PARAMETER_ERROR!>Array<Array<Array<Array<T>>>>::class<!>
)<!>
) object {}
@@ -0,0 +1,20 @@
FILE: annotationArgumentKClassLiteralTypeError.kt
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(a: R|kotlin/Array<kotlin/reflect/KClass<*>>|): R|Ann| {
super<R|kotlin/Any|>()
}
public final val a: R|kotlin/Array<kotlin/reflect/KClass<*>>| = R|<local>/a|
public get(): R|kotlin/Array<kotlin/reflect/KClass<*>>|
}
public final val <reified T> R|T|.test: R|<anonymous><T>|
public get(): R|<anonymous><T>| {
^ @R|Ann|(<implicitArrayOf>(<getClass>(R|T|), <getClass>(Q|kotlin/Array|))) object : R|kotlin/Any| {
private constructor(): R|<anonymous><T>| {
super<R|kotlin/Any|>()
}
}
}
@@ -0,0 +1,31 @@
annotation class Ann1(vararg val a: String)
annotation class Ann2(val a: IntArray)
annotation class Ann3(val a: Array<String>)
var foo = "a"
var bar = 1
fun baz() = 2
val arr = arrayOf("a", "b")
val two = 2
const val cnst = 3
class Class {
val a = 1
}
@Ann1(
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>foo<!>,
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>foo + bar<!>,
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>"$foo $bar"<!>,
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>"${baz()} "<!>
)
@Ann2(
<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>intArrayOf(
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>bar<!>,
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>baz()<!>,
<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>bar + cnst<!>
)<!>
)
@Ann3(<!ANNOTATION_ARGUMENT_MUST_BE_CONST!>arr<!>)
fun test() {}
@@ -0,0 +1,54 @@
FILE: annotationArgumentMustBeConst.kt
public final annotation class Ann1 : R|kotlin/Annotation| {
public constructor(vararg a: R|kotlin/Array<out kotlin/String>|): R|Ann1| {
super<R|kotlin/Any|>()
}
public final val a: R|kotlin/Array<out kotlin/String>| = R|<local>/a|
public get(): R|kotlin/Array<out kotlin/String>|
}
public final annotation class Ann2 : R|kotlin/Annotation| {
public constructor(a: R|kotlin/IntArray|): R|Ann2| {
super<R|kotlin/Any|>()
}
public final val a: R|kotlin/IntArray| = R|<local>/a|
public get(): R|kotlin/IntArray|
}
public final annotation class Ann3 : R|kotlin/Annotation| {
public constructor(a: R|kotlin/Array<kotlin/String>|): R|Ann3| {
super<R|kotlin/Any|>()
}
public final val a: R|kotlin/Array<kotlin/String>| = R|<local>/a|
public get(): R|kotlin/Array<kotlin/String>|
}
public final var foo: R|kotlin/String| = String(a)
public get(): R|kotlin/String|
public set(value: R|kotlin/String|): R|kotlin/Unit|
public final var bar: R|kotlin/Int| = Int(1)
public get(): R|kotlin/Int|
public set(value: R|kotlin/Int|): R|kotlin/Unit|
public final fun baz(): R|kotlin/Int| {
^baz Int(2)
}
public final val arr: R|kotlin/Array<kotlin/String>| = R|kotlin/arrayOf|<R|kotlin/String|>(vararg(String(a), String(b)))
public get(): R|kotlin/Array<kotlin/String>|
public final val two: R|kotlin/Int| = Int(2)
public get(): R|kotlin/Int|
public final const val cnst: R|kotlin/Int| = Int(3)
public get(): R|kotlin/Int|
public final class Class : R|kotlin/Any| {
public constructor(): R|Class| {
super<R|kotlin/Any|>()
}
public final val a: R|kotlin/Int| = Int(1)
public get(): R|kotlin/Int|
}
@R|Ann1|(vararg(R|/foo|, R|/foo|.R|kotlin/String.plus|(R|/bar|), <strcat>(R|/foo|.R|kotlin/Any.toString|(), String( ), R|/bar|.R|kotlin/Any.toString|()), <strcat>(R|/baz|().R|kotlin/Any.toString|(), String( )))) @R|Ann2|(<implicitArrayOf>(R|/bar|, R|/baz|(), R|/bar|.R|kotlin/Int.plus|(R|/cnst|))) @R|Ann3|(R|/arr|) public final fun test(): R|kotlin/Unit| {
}
@@ -0,0 +1,11 @@
enum class TestEnum {
Foo
}
annotation class Ann(vararg val a: TestEnum)
val foo = TestEnum.Foo
var bar = TestEnum.Foo
@Ann(<!ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST!>foo<!>, <!ANNOTATION_ARGUMENT_MUST_BE_ENUM_CONST!>bar<!>)
fun test() {}
@@ -0,0 +1,30 @@
FILE: annotationArgumentMustBeEnumConst.kt
public final enum class TestEnum : R|kotlin/Enum<TestEnum>| {
private constructor(): R|TestEnum| {
super<R|kotlin/Enum<TestEnum>|>()
}
public final static enum entry Foo: R|TestEnum|
public final static fun values(): R|kotlin/Array<TestEnum>| {
}
public final static fun valueOf(value: R|kotlin/String|): R|TestEnum| {
}
}
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(vararg a: R|kotlin/Array<out TestEnum>|): R|Ann| {
super<R|kotlin/Any|>()
}
public final val a: R|kotlin/Array<out TestEnum>| = R|<local>/a|
public get(): R|kotlin/Array<out TestEnum>|
}
public final val foo: R|TestEnum| = Q|TestEnum|.R|/TestEnum.Foo|
public get(): R|TestEnum|
public final var bar: R|TestEnum| = Q|TestEnum|.R|/TestEnum.Foo|
public get(): R|TestEnum|
public set(value: R|TestEnum|): R|kotlin/Unit|
@R|Ann|(vararg(R|/foo|, R|/bar|)) public final fun test(): R|kotlin/Unit| {
}
@@ -0,0 +1,24 @@
import kotlin.reflect.KClass
@Repeatable
annotation class Ann(val a: Array<KClass<*>>)
class Foo
val foo = Foo::class
fun bar() = Foo::class
@Ann(
[
<!ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL!>""::class<!>,
<!ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL!>true::class<!>,
<!ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL!>1::class<!>
]
)
@Ann(
[
<!ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL!>foo<!>,
<!ANNOTATION_ARGUMENT_MUST_BE_KCLASS_LITERAL!>bar()<!>
]
)
fun test1() {}
@@ -0,0 +1,23 @@
FILE: annotationArgumentMustBeKClassLiteral.kt
@R|kotlin/annotation/Repeatable|() public final annotation class Ann : R|kotlin/Annotation| {
public constructor(a: R|kotlin/Array<kotlin/reflect/KClass<*>>|): R|Ann| {
super<R|kotlin/Any|>()
}
public final val a: R|kotlin/Array<kotlin/reflect/KClass<*>>| = R|<local>/a|
public get(): R|kotlin/Array<kotlin/reflect/KClass<*>>|
}
public final class Foo : R|kotlin/Any| {
public constructor(): R|Foo| {
super<R|kotlin/Any|>()
}
}
public final val foo: R|kotlin/reflect/KClass<Foo>| = <getClass>(Q|Foo|)
public get(): R|kotlin/reflect/KClass<Foo>|
public final fun bar(): R|kotlin/reflect/KClass<Foo>| {
^bar <getClass>(Q|Foo|)
}
@R|Ann|(<implicitArrayOf>(<getClass>(String()), <getClass>(Boolean(true)), <getClass>(Int(1)))) @R|Ann|(<implicitArrayOf>(R|/foo|, R|/bar|())) public final fun test1(): R|kotlin/Unit| {
}
@@ -0,0 +1,13 @@
annotation class Ann(val a: Array<String>)
val foo = ""
var bar = 1
const val cnst = 2
@Ann(
<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>arrayOf(
<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>foo<!>,
<!NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION!>foo + cnst.toString()<!>
)<!>
)
fun test() {}
@@ -0,0 +1,19 @@
FILE: nonConstValInAnnotationArgument.kt
public final annotation class Ann : R|kotlin/Annotation| {
public constructor(a: R|kotlin/Array<kotlin/String>|): R|Ann| {
super<R|kotlin/Any|>()
}
public final val a: R|kotlin/Array<kotlin/String>| = R|<local>/a|
public get(): R|kotlin/Array<kotlin/String>|
}
public final val foo: R|kotlin/String| = String()
public get(): R|kotlin/String|
public final var bar: R|kotlin/Int| = Int(1)
public get(): R|kotlin/Int|
public set(value: R|kotlin/Int|): R|kotlin/Unit|
public final const val cnst: R|kotlin/Int| = Int(2)
public get(): R|kotlin/Int|
@R|Ann|(<implicitArrayOf>(R|/foo|, R|/foo|.R|kotlin/String.plus|(R|/cnst|.R|kotlin/Any.toString|()))) public final fun test(): R|kotlin/Unit| {
}