diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/evaluate/IrConstTransformer.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/evaluate/IrConstTransformer.kt index 03411984be8..3d9bfa41112 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/evaluate/IrConstTransformer.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/evaluate/IrConstTransformer.kt @@ -61,12 +61,16 @@ class IrConstTransformer(irBuiltIns: IrBuiltIns) : IrElementTransformerVoid() { private fun transformAnnotations(annotationContainer: IrAnnotationContainer) { annotationContainer.annotations.forEach { annotation -> - for (i in 0 until annotation.valueArgumentsCount) { - val arg = annotation.getValueArgument(i) ?: continue - when (arg) { - is IrVararg -> annotation.putValueArgument(i, arg.transformVarArg()) - else -> annotation.putValueArgument(i, arg.transformSingleArg(annotation.symbol.owner.valueParameters[i].type)) - } + transformAnnotation(annotation) + } + } + + private fun transformAnnotation(annotation: IrConstructorCall) { + for (i in 0 until annotation.valueArgumentsCount) { + val arg = annotation.getValueArgument(i) ?: continue + when (arg) { + is IrVararg -> annotation.putValueArgument(i, arg.transformVarArg()) + else -> annotation.putValueArgument(i, arg.transformSingleArg(annotation.symbol.owner.valueParameters[i].type)) } } } @@ -92,6 +96,8 @@ class IrConstTransformer(irBuiltIns: IrBuiltIns) : IrElementTransformerVoid() { if (this.accept(IrCompileTimeChecker(mode = EvaluationMode.ONLY_BUILTINS), null)) { val const = interpreter.interpret(this).replaceIfError(this) return const.convertToConstIfPossible(expectedType) + } else if (this is IrConstructorCall) { + transformAnnotation(this) } return this } diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index 7248524446e..f226f6c6345 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -1717,6 +1717,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/firProblems"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @TestMetadata("AnnotationInAnnotation.kt") + public void testAnnotationInAnnotation() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.kt"); + } + @TestMetadata("candidateSymbol.kt") public void testCandidateSymbol() throws Exception { runTest("compiler/testData/ir/irText/firProblems/candidateSymbol.kt"); diff --git a/compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.fir.txt b/compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.fir.txt new file mode 100644 index 00000000000..5ee804ae50d --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.fir.txt @@ -0,0 +1,90 @@ +FILE fqName: fileName:/AnnotationInAnnotation.kt + CLASS ANNOTATION_CLASS name:Storage modality:FINAL visibility:public superTypes:[kotlin.Annotation] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Storage + CONSTRUCTOR visibility:public <> (value:kotlin.String) returnType:.Storage [primary] + VALUE_PARAMETER name:value index:0 type:kotlin.String + PROPERTY name:value visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:value type:kotlin.String visibility:private [final] + EXPRESSION_BODY + GET_VAR 'value: kotlin.String declared in .Storage.' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Storage) returnType:kotlin.String + correspondingProperty: PROPERTY name:value visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Storage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .Storage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:value type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .Storage declared in .Storage.' type=.Storage origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS ANNOTATION_CLASS name:State modality:FINAL visibility:public superTypes:[kotlin.Annotation] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.State + CONSTRUCTOR visibility:public <> (name:kotlin.String, storages:kotlin.Array<.Storage>) returnType:.State [primary] + VALUE_PARAMETER name:name index:0 type:kotlin.String + VALUE_PARAMETER name:storages index:1 type:kotlin.Array<.Storage> + PROPERTY name:name visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final] + EXPRESSION_BODY + GET_VAR 'name: kotlin.String declared in .State.' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.State) returnType:kotlin.String + correspondingProperty: PROPERTY name:name visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.State + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .State' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .State declared in .State.' type=.State origin=null + PROPERTY name:storages visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:storages type:kotlin.Array<.Storage> visibility:private [final] + EXPRESSION_BODY + GET_VAR 'storages: kotlin.Array<.Storage> declared in .State.' type=kotlin.Array<.Storage> origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.State) returnType:kotlin.Array<.Storage> + correspondingProperty: PROPERTY name:storages visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.State + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Array<.Storage> declared in .State' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:storages type:kotlin.Array<.Storage> visibility:private [final]' type=kotlin.Array<.Storage> origin=null + receiver: GET_VAR ': .State declared in .State.' type=.State origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:Test modality:FINAL visibility:public superTypes:[kotlin.Any] + annotations: + State(name = '1', storages = [Storage(value = 'HELLO')]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Test + CONSTRUCTOR visibility:public <> () returnType:.Test [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test modality:FINAL visibility:public superTypes:[kotlin.Any]' + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.kt b/compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.kt new file mode 100644 index 00000000000..c7b07c1b040 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.kt @@ -0,0 +1,17 @@ +// FILE: Some.java + +public class Some { + public static final String HELLO = "HELLO"; +} + +// FILE: AnnotationInAnnotation.kt + +annotation class Storage(val value: String) + +annotation class State(val name: String, val storages: Array) + +@State( + name = "1", + storages = [Storage(value = Some.HELLO)] +) +class Test \ No newline at end of file diff --git a/compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.txt b/compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.txt new file mode 100644 index 00000000000..171c725e01f --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.txt @@ -0,0 +1,90 @@ +FILE fqName: fileName:/AnnotationInAnnotation.kt + CLASS ANNOTATION_CLASS name:Storage modality:FINAL visibility:public superTypes:[kotlin.Annotation] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Storage + CONSTRUCTOR visibility:public <> (value:kotlin.String) returnType:.Storage [primary] + VALUE_PARAMETER name:value index:0 type:kotlin.String + PROPERTY name:value visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:value type:kotlin.String visibility:private [final] + EXPRESSION_BODY + GET_VAR 'value: kotlin.String declared in .Storage.' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Storage) returnType:kotlin.String + correspondingProperty: PROPERTY name:value visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.Storage + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .Storage' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:value type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .Storage declared in .Storage.' type=.Storage origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in kotlin.Annotation + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.Annotation + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in kotlin.Annotation + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS ANNOTATION_CLASS name:State modality:FINAL visibility:public superTypes:[kotlin.Annotation] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.State + CONSTRUCTOR visibility:public <> (name:kotlin.String, storages:kotlin.Array<.Storage>) returnType:.State [primary] + VALUE_PARAMETER name:name index:0 type:kotlin.String + VALUE_PARAMETER name:storages index:1 type:kotlin.Array<.Storage> + PROPERTY name:name visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final] + EXPRESSION_BODY + GET_VAR 'name: kotlin.String declared in .State.' type=kotlin.String origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.State) returnType:kotlin.String + correspondingProperty: PROPERTY name:name visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.State + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.String declared in .State' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:name type:kotlin.String visibility:private [final]' type=kotlin.String origin=null + receiver: GET_VAR ': .State declared in .State.' type=.State origin=null + PROPERTY name:storages visibility:public modality:FINAL [val] + FIELD PROPERTY_BACKING_FIELD name:storages type:kotlin.Array<.Storage> visibility:private [final] + EXPRESSION_BODY + GET_VAR 'storages: kotlin.Array<.Storage> declared in .State.' type=kotlin.Array<.Storage> origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.State) returnType:kotlin.Array<.Storage> + correspondingProperty: PROPERTY name:storages visibility:public modality:FINAL [val] + $this: VALUE_PARAMETER name: type:.State + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Array<.Storage> declared in .State' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:storages type:kotlin.Array<.Storage> visibility:private [final]' type=kotlin.Array<.Storage> origin=null + receiver: GET_VAR ': .State declared in .State.' type=.State origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in kotlin.Annotation + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.Annotation + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in kotlin.Annotation + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:Test modality:FINAL visibility:public superTypes:[kotlin.Any] + annotations: + State(name = '1', storages = [Storage(value = 'HELLO')]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Test + CONSTRUCTOR visibility:public <> () returnType:.Test [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Test modality:FINAL visibility:public superTypes:[kotlin.Any]' + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 9a29d5dd9d8..4e7e08e9157 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -1716,6 +1716,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/ir/irText/firProblems"), Pattern.compile("^(.+)\\.kt$"), null, true); } + @TestMetadata("AnnotationInAnnotation.kt") + public void testAnnotationInAnnotation() throws Exception { + runTest("compiler/testData/ir/irText/firProblems/AnnotationInAnnotation.kt"); + } + @TestMetadata("candidateSymbol.kt") public void testCandidateSymbol() throws Exception { runTest("compiler/testData/ir/irText/firProblems/candidateSymbol.kt");