From eee66ab43f987aef851fbf90df76e7fe7e8aed50 Mon Sep 17 00:00:00 2001 From: Kirill Rakhman Date: Thu, 23 Feb 2023 10:27:15 +0100 Subject: [PATCH] [FIR] Remove duplicate annotations from primary ctor params/properties If an annotation doesn't specify an explicit use-site target, previously it was added to both, the primary constructor value parameter and the property in the FIR. Then, in FIR2IR, only the "correct" one was added to the IR. Move up the deduplication logic into the frontend. ^KT-56177 Fixed --- .../annotation.descriptors.rendered | 27 -- .../renderDeclaration/annotation.rendered | 2 +- .../resolve/annotations/kt55286.fir.txt | 4 +- .../annotationUseSites.fir.txt | 2 +- .../FirNativeSharedImmutableChecker.kt | 4 +- .../analysis/checkers/FirAnnotationHelpers.kt | 12 +- .../declaration/FirAnnotationChecker.kt | 3 - .../fir/backend/Fir2IrDeclarationStorage.kt | 2 +- .../backend/generators/AnnotationGenerator.kt | 32 +- .../generators/ClassMemberGenerator.kt | 2 +- ...LightTreeBlackBoxCodegenTestGenerated.java | 18 + .../FirPsiBlackBoxCodegenTestGenerated.java | 18 + .../fir/declarations/FirAnnotationUtils.kt | 30 +- .../kotlin/fir/resolve/FirTypeResolver.kt | 1 + .../providers/impl/FirTypeResolverImpl.kt | 16 +- .../FirSpecificTypeResolverTransformer.kt | 3 + .../transformers/FirTypeResolveTransformer.kt | 46 ++- ...FirSpecificAnnotationResolveTransformer.kt | 147 +++++++- ...irAnnotationArgumentsResolveTransformer.kt | 24 +- .../fir/expressions/FirExpressionUtil.kt | 10 + .../lightClassByPsi/annotations.fir.java | 1 - ...avaTargetOnPrimaryCtorParameter.fir.ir.txt | 147 ++++++++ .../javaTargetOnPrimaryCtorParameter.fir.txt | 35 ++ .../javaTargetOnPrimaryCtorParameter.ir.txt | 147 ++++++++ .../javaTargetOnPrimaryCtorParameter.kt | 59 ++++ .../targetOnPrimaryCtorParameter.fir.ir.txt | 326 ++++++++++++++++++ .../targetOnPrimaryCtorParameter.fir.txt | 81 +++++ .../targetOnPrimaryCtorParameter.ir.txt | 326 ++++++++++++++++++ .../targetOnPrimaryCtorParameter.kt | 49 +++ ...targetOnPrimaryCtorParameterMultiModule.kt | 53 +++ ...sivelyIncorrectlyAnnotatedParameter.fir.kt | 2 +- .../experimental/wasExperimental.fir.kt | 12 +- .../IrBlackBoxCodegenTestGenerated.java | 18 + .../firMembers/metaSerializable.fir.txt | 2 +- 34 files changed, 1537 insertions(+), 124 deletions(-) delete mode 100644 analysis/analysis-api/testData/components/symbolDeclarationRenderer/renderDeclaration/annotation.descriptors.rendered create mode 100644 compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.fir.ir.txt create mode 100644 compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.fir.txt create mode 100644 compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.ir.txt create mode 100644 compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.kt create mode 100644 compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.fir.ir.txt create mode 100644 compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.fir.txt create mode 100644 compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.ir.txt create mode 100644 compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.kt create mode 100644 compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameterMultiModule.kt diff --git a/analysis/analysis-api/testData/components/symbolDeclarationRenderer/renderDeclaration/annotation.descriptors.rendered b/analysis/analysis-api/testData/components/symbolDeclarationRenderer/renderDeclaration/annotation.descriptors.rendered deleted file mode 100644 index ac488d0784c..00000000000 --- a/analysis/analysis-api/testData/components/symbolDeclarationRenderer/renderDeclaration/annotation.descriptors.rendered +++ /dev/null @@ -1,27 +0,0 @@ -@Target(allowedTargets = [kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS]) -annotation class base - -@base -annotation class derived - -@base -class correct(x: Int) { - @base - constructor() - - @base - val x: Int -} - -@base -enum class My { - @base FIRST, - @base SECOND -} - -@base -fun foo(@base y: @base Int): Int - -@base -val z: Int - diff --git a/analysis/analysis-api/testData/components/symbolDeclarationRenderer/renderDeclaration/annotation.rendered b/analysis/analysis-api/testData/components/symbolDeclarationRenderer/renderDeclaration/annotation.rendered index fedba85be85..ac488d0784c 100644 --- a/analysis/analysis-api/testData/components/symbolDeclarationRenderer/renderDeclaration/annotation.rendered +++ b/analysis/analysis-api/testData/components/symbolDeclarationRenderer/renderDeclaration/annotation.rendered @@ -5,7 +5,7 @@ annotation class base annotation class derived @base -class correct(@base x: Int) { +class correct(x: Int) { @base constructor() diff --git a/compiler/fir/analysis-tests/testData/resolve/annotations/kt55286.fir.txt b/compiler/fir/analysis-tests/testData/resolve/annotations/kt55286.fir.txt index 2ac69a60292..81e449a131d 100644 --- a/compiler/fir/analysis-tests/testData/resolve/annotations/kt55286.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolve/annotations/kt55286.fir.txt @@ -10,7 +10,7 @@ FILE: kt55286.kt super() } - @R|Deprecated|() public final val a: R|kotlin/String| = R|/a| + public final val a: R|kotlin/String| = R|/a| public get(): R|kotlin/String| public final class Nested : R|kotlin/Any| { @@ -26,7 +26,7 @@ FILE: kt55286.kt super(String()) } - @R|Deprecated|() public final val b: R|kotlin/String| = R|/b| + public final val b: R|kotlin/String| = R|/b| public get(): R|kotlin/String| } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/annotationUseSites.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/annotationUseSites.fir.txt index ab55a81fe66..49aa68b10b7 100644 --- a/compiler/fir/analysis-tests/testData/resolveWithStdlib/annotationUseSites.fir.txt +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/annotationUseSites.fir.txt @@ -10,7 +10,7 @@ FILE: test.kt super() } - @R|KotlinMessage|() public final val message: R|kotlin/String| = R|/message| + public final val message: R|kotlin/String| = R|/message| @PROPERTY_GETTER:R|KotlinMessage|() public get(): R|kotlin/String| public final operator fun component1(): R|kotlin/String| diff --git a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeSharedImmutableChecker.kt b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeSharedImmutableChecker.kt index 03c801fe201..3b709812be6 100644 --- a/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeSharedImmutableChecker.kt +++ b/compiler/fir/checkers/checkers.native/src/org/jetbrains/kotlin/fir/analysis/native/checkers/FirNativeSharedImmutableChecker.kt @@ -46,8 +46,6 @@ object FirNativeSharedImmutableChecker : FirBasicDeclarationChecker() { return } - if (declaration.source?.kind is KtFakeSourceElementKind) return - if (!context.isTopLevel) { reporter.reportIfHasAnnotation( declaration, @@ -57,4 +55,4 @@ object FirNativeSharedImmutableChecker : FirBasicDeclarationChecker() { ) } } -} \ No newline at end of file +} diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt index eeecab4c14a..029c4482608 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/FirAnnotationHelpers.kt @@ -72,7 +72,7 @@ fun FirRegularClass.getAllowedAnnotationTargets(session: FirSession): Set.getAllowedAnnotationTargets(session: FirSession): Set { lazyResolveToPhase(FirResolvePhase.ANNOTATIONS_ARGUMENTS_MAPPING) val targetAnnotation = getTargetAnnotation(session) ?: return defaultAnnotationTargets - val arguments = targetAnnotation.findArgumentByName(ParameterNames.targetAllowedTargets)?.unfoldArrayOrVararg().orEmpty() + val arguments = targetAnnotation.findArgumentByName(ParameterNames.targetAllowedTargets)?.unwrapAndFlattenArgument().orEmpty() return arguments.mapNotNullTo(mutableSetOf()) { argument -> val targetExpression = argument as? FirQualifiedAccessExpression @@ -94,7 +94,7 @@ fun FirClassLikeSymbol<*>.getTargetAnnotation(session: FirSession): FirAnnotatio } fun FirExpression.extractClassesFromArgument(session: FirSession): List { - return unfoldArrayOrVararg().mapNotNull { + return unwrapAndFlattenArgument().mapNotNull { it.extractClassFromArgument(session) } } @@ -178,14 +178,6 @@ fun FirAnnotationContainer.getImplicitUseSiteTargetList(context: CheckerContext) } } -private fun FirExpression.unfoldArrayOrVararg(): List { - return when (this) { - is FirVarargArgumentsExpression -> arguments - is FirArrayOfCall -> arguments - else -> return emptyList() - } -} - fun checkRepeatedAnnotation( annotationContainer: FirAnnotationContainer?, annotations: List, diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt index b0bea8175e1..63c7c483b1c 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/declaration/FirAnnotationChecker.kt @@ -162,7 +162,6 @@ object FirAnnotationChecker : FirBasicDeclarationChecker() { context ) } else { - if (declaration is FirProperty && declaration.source?.kind == KtFakeSourceElementKind.PropertyFromParameter) return reporter.reportOn( annotation.source, FirErrors.WRONG_ANNOTATION_TARGET, @@ -213,8 +212,6 @@ object FirAnnotationChecker : FirBasicDeclarationChecker() { reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_PARAM_TARGET, context) } } - annotated is FirProperty && annotated.source?.kind == KtFakeSourceElementKind.PropertyFromParameter -> { - } else -> reporter.reportOn(annotation.source, FirErrors.INAPPLICABLE_PARAM_TARGET, context) } FILE -> { diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 6594925380e..4e8b2ac6759 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -1657,7 +1657,7 @@ class Fir2IrDeclarationStorage( annotationGenerator.generate(this, firAnnotationContainer) if (this is IrFunction && firAnnotationContainer is FirSimpleFunction) { valueParameters.zip(firAnnotationContainer.valueParameters).forEach { (irParameter, firParameter) -> - annotationGenerator.generate(irParameter, firParameter, isInConstructor = false) + annotationGenerator.generate(irParameter, firParameter) } } } diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AnnotationGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AnnotationGenerator.kt index c20a5226439..59726bb95fe 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AnnotationGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/AnnotationGenerator.kt @@ -24,6 +24,9 @@ import org.jetbrains.kotlin.ir.util.isSetter * need special handling: [AnnotationUseSiteTarget]. In particular, [FirProperty] contains all annotations associated with that property, * whose targets may vary. After all the necessary pieces of IR elements, e.g., backing field, are ready, this generator splits those * annotations to the specified targets. + * + * Note: Annotations on primary constructor properties are already split between value parameters and properties in FIR. Before this change, + * it used to be done here. */ class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComponents by components { @@ -40,32 +43,16 @@ class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComp useSiteTarget ?: applicable.firstOrNull(useSiteTargetsFromMetaAnnotation(session)::contains) companion object { - // Priority order: constructor parameter (if applicable) -> property -> field. So, for example, if `A` - // can be attached to all three, then in a declaration like - // class C(@A val x: Int) { @A val y = 1 } - // the parameter `x` and the property `y` will have the annotation, while the property `x` and both backing fields will not. private val propertyTargets = listOf(AnnotationUseSiteTarget.PROPERTY, AnnotationUseSiteTarget.FIELD) - private val constructorPropertyTargets = listOf(AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER) + propertyTargets private val delegatedPropertyTargets = propertyTargets + listOf(AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD) } - // TODO: third argument should be whether this parameter is a property declaration (though this probably makes no difference) - fun generate(irValueParameter: IrValueParameter, firValueParameter: FirValueParameter, isInConstructor: Boolean) { - if (isInConstructor) { - irValueParameter.annotations += firValueParameter.annotations - .filter { it.target(constructorPropertyTargets) == AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER } - .toIrAnnotations() - } else { - irValueParameter.annotations += firValueParameter.annotations.toIrAnnotations() - } + fun generate(irValueParameter: IrValueParameter, firValueParameter: FirValueParameter) { + irValueParameter.annotations += firValueParameter.annotations.toIrAnnotations() } fun generate(irProperty: IrProperty, property: FirProperty) { - val applicableTargets = when { - property.source?.kind == KtFakeSourceElementKind.PropertyFromParameter -> constructorPropertyTargets - irProperty.isDelegated -> delegatedPropertyTargets - else -> propertyTargets - } + val applicableTargets = if (irProperty.isDelegated) delegatedPropertyTargets else propertyTargets irProperty.annotations += property.annotations .filter { it.target(applicableTargets) == AnnotationUseSiteTarget.PROPERTY } .toIrAnnotations() @@ -73,11 +60,8 @@ class AnnotationGenerator(private val components: Fir2IrComponents) : Fir2IrComp fun generate(irField: IrField, property: FirProperty) { val irProperty = irField.correspondingPropertySymbol?.owner ?: throw AssertionError("$irField is not a property field") - val applicableTargets = when { - property.source?.kind == KtFakeSourceElementKind.PropertyFromParameter -> constructorPropertyTargets - irProperty.isDelegated -> delegatedPropertyTargets - else -> propertyTargets - } + + val applicableTargets = if (irProperty.isDelegated) delegatedPropertyTargets else propertyTargets irField.annotations += property.annotations.filter { val target = it.target(applicableTargets) target == AnnotationUseSiteTarget.FIELD || target == AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt index 58bf2a2d832..c0dc5d6c80d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/ClassMemberGenerator.kt @@ -110,7 +110,7 @@ internal class ClassMemberGenerator( val annotationMode = containingClass?.classKind == ClassKind.ANNOTATION_CLASS && irFunction is IrConstructor for ((valueParameter, firValueParameter) in irParameters.zip(firFunction.valueParameters)) { valueParameter.setDefaultValue(firValueParameter, annotationMode) - annotationGenerator.generate(valueParameter, firValueParameter, irFunction is IrConstructor) + annotationGenerator.generate(valueParameter, firValueParameter) } annotationGenerator.generate(irFunction, firFunction) } diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index 9d287524b36..2bbd72170b4 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -233,6 +233,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/annotations/javaPropertyWithIntInitializer.kt"); } + @Test + @TestMetadata("javaTargetOnPrimaryCtorParameter.kt") + public void testJavaTargetOnPrimaryCtorParameter() throws Exception { + runTest("compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.kt"); + } + @Test @TestMetadata("jvmAnnotationFlags.kt") public void testJvmAnnotationFlags() throws Exception { @@ -371,6 +377,18 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr runTest("compiler/testData/codegen/box/annotations/syntheticMethodForProperty.kt"); } + @Test + @TestMetadata("targetOnPrimaryCtorParameter.kt") + public void testTargetOnPrimaryCtorParameter() throws Exception { + runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.kt"); + } + + @Test + @TestMetadata("targetOnPrimaryCtorParameterMultiModule.kt") + public void testTargetOnPrimaryCtorParameterMultiModule() throws Exception { + runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameterMultiModule.kt"); + } + @Test @TestMetadata("typeAnnotationOnJdk6.kt") public void testTypeAnnotationOnJdk6() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index 0a4fd158bbb..e916bab3b8c 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -233,6 +233,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/annotations/javaPropertyWithIntInitializer.kt"); } + @Test + @TestMetadata("javaTargetOnPrimaryCtorParameter.kt") + public void testJavaTargetOnPrimaryCtorParameter() throws Exception { + runTest("compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.kt"); + } + @Test @TestMetadata("jvmAnnotationFlags.kt") public void testJvmAnnotationFlags() throws Exception { @@ -371,6 +377,18 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo runTest("compiler/testData/codegen/box/annotations/syntheticMethodForProperty.kt"); } + @Test + @TestMetadata("targetOnPrimaryCtorParameter.kt") + public void testTargetOnPrimaryCtorParameter() throws Exception { + runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.kt"); + } + + @Test + @TestMetadata("targetOnPrimaryCtorParameterMultiModule.kt") + public void testTargetOnPrimaryCtorParameterMultiModule() throws Exception { + runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameterMultiModule.kt"); + } + @Test @TestMetadata("typeAnnotationOnJdk6.kt") public void testTypeAnnotationOnJdk6() throws Exception { diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt index f283b58f5f9..1c82e10f8b2 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/FirAnnotationUtils.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.declarations import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference @@ -64,6 +65,7 @@ fun List.nonSourceAnnotations(session: FirSession): List = annotations.nonSourceAnnotations(session) @@ -77,21 +79,31 @@ fun FirAnnotation.useSiteTargetsFromMetaAnnotation(session: FirSession): Set.toAnnotationUseSiteTargets(): Set = - flatMapTo(mutableSetOf()) { arg -> - when (val unwrappedArg = if (arg is FirNamedArgumentExpression) arg.expression else arg) { - is FirArrayOfCall -> unwrappedArg.argumentList.arguments.toAnnotationUseSiteTargets() - is FirVarargArgumentsExpression -> unwrappedArg.arguments.toAnnotationUseSiteTargets() - else -> USE_SITE_TARGET_NAME_MAP[unwrappedArg.callableNameOfMetaAnnotationArgument?.identifier] ?: setOf() +private fun FirAnnotation.findUseSiteTargets(): Set = buildSet { + fun addIfMatching(arg: FirExpression) { + if (arg !is FirQualifiedAccessExpression) return + val callableSymbol = arg.calleeReference.toResolvedCallableSymbol() ?: return + if (callableSymbol.containingClassLookupTag()?.classId == StandardClassIds.AnnotationTarget) { + USE_SITE_TARGET_NAME_MAP[callableSymbol.callableId.callableName.identifier]?.let { addAll(it) } } } + if (this@findUseSiteTargets is FirAnnotationCall) { + for (arg in argumentList.arguments) { + arg.unwrapAndFlattenArgument().forEach(::addIfMatching) + } + } else { + argumentMapping.mapping[StandardClassIds.Annotations.ParameterNames.targetAllowedTargets] + ?.unwrapAndFlattenArgument() + ?.forEach(::addIfMatching) + } +} + + // See [org.jetbrains.kotlin.descriptors.annotations.KotlinTarget.USE_SITE_MAPPING] (it's in reverse) private val USE_SITE_TARGET_NAME_MAP = mapOf( "FIELD" to setOf(AnnotationUseSiteTarget.FIELD, AnnotationUseSiteTarget.PROPERTY_DELEGATE_FIELD), diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt index 88fd608ec78..c49003faa44 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirTypeResolver.kt @@ -19,6 +19,7 @@ abstract class FirTypeResolver : FirSessionComponent { scopeClassDeclaration: ScopeClassDeclaration, areBareTypesAllowed: Boolean, isOperandOfIsOperator: Boolean, + resolveDeprecations: Boolean, // Note: sometimes we don't have useSiteFile in IDE context useSiteFile: FirFile?, supertypeSupplier: SupertypeSupplier diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt index 8e54db3c33f..69ce6756242 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/providers/impl/FirTypeResolverImpl.kt @@ -82,7 +82,8 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { typeRef: FirUserTypeRef, scopeClassDeclaration: ScopeClassDeclaration, useSiteFile: FirFile?, - supertypeSupplier: SupertypeSupplier + supertypeSupplier: SupertypeSupplier, + resolveDeprecations: Boolean ): TypeResolutionResult { val qualifierResolver = session.qualifierResolver var applicability: CandidateApplicability? = null @@ -101,10 +102,12 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { diagnostic = ConeVisibilityError(symbol) } - val deprecation = symbol.getDeprecation(session, useSiteFile) - if (deprecation != null && deprecation.deprecationLevel == DeprecationLevelValue.HIDDEN) { - symbolApplicability = minOf(CandidateApplicability.HIDDEN, symbolApplicability) - diagnostic = null + if (resolveDeprecations) { + val deprecation = symbol.getDeprecation(session, useSiteFile) + if (deprecation != null && deprecation.deprecationLevel == DeprecationLevelValue.HIDDEN) { + symbolApplicability = minOf(CandidateApplicability.HIDDEN, symbolApplicability) + diagnostic = null + } } if (applicability == null || symbolApplicability > applicability!!) { @@ -491,13 +494,14 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { scopeClassDeclaration: ScopeClassDeclaration, areBareTypesAllowed: Boolean, isOperandOfIsOperator: Boolean, + resolveDeprecations: Boolean, useSiteFile: FirFile?, supertypeSupplier: SupertypeSupplier ): Pair { return when (typeRef) { is FirResolvedTypeRef -> error("Do not resolve, resolved type-refs") is FirUserTypeRef -> { - val result = resolveUserTypeToSymbol(typeRef, scopeClassDeclaration, useSiteFile, supertypeSupplier) + val result = resolveUserTypeToSymbol(typeRef, scopeClassDeclaration, useSiteFile, supertypeSupplier, resolveDeprecations) resolveUserType( typeRef, result, diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSpecificTypeResolverTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSpecificTypeResolverTransformer.kt index 60e899897fd..937b906a6bd 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSpecificTypeResolverTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirSpecificTypeResolverTransformer.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef class FirSpecificTypeResolverTransformer( override val session: FirSession, private val errorTypeAsResolved: Boolean = true, + private val resolveDeprecations: Boolean = true, private val supertypeSupplier: SupertypeSupplier = SupertypeSupplier.Default ) : FirAbstractTreeTransformer(phase = FirResolvePhase.SUPER_TYPES) { private val typeResolver = session.typeResolver @@ -85,6 +86,7 @@ class FirSpecificTypeResolverTransformer( data, areBareTypesAllowed, isOperandOfIsOperator, + resolveDeprecations, currentFile, supertypeSupplier ) @@ -104,6 +106,7 @@ class FirSpecificTypeResolverTransformer( data, areBareTypesAllowed, isOperandOfIsOperator, + resolveDeprecations, currentFile, supertypeSupplier ) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt index 34f0d4659f5..28f8653dee9 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/FirTypeResolveTransformer.kt @@ -7,7 +7,9 @@ package org.jetbrains.kotlin.fir.resolve.transformers import kotlinx.collections.immutable.toImmutableList import org.jetbrains.kotlin.KtFakeSourceElementKind +import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.correspondingProperty import org.jetbrains.kotlin.fir.copyWithNewSourceKind import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.isFromVararg @@ -115,8 +117,18 @@ open class FirTypeResolveTransformer( override fun transformConstructor(constructor: FirConstructor, data: Any?): FirConstructor = whileAnalysing(session, constructor) { return withScopeCleanup { constructor.addTypeParametersScope() - transformDeclaration(constructor, data) - } as FirConstructor + val result = transformDeclaration(constructor, data) as FirConstructor + + if (result.isPrimary) { + for (valueParameter in result.valueParameters) { + if (valueParameter.correspondingProperty != null) { + valueParameter.removeDuplicateAnnotationsOfPrimaryConstructorElement() + } + } + } + + result + } } override fun transformTypeAlias(typeAlias: FirTypeAlias, data: Any?): FirTypeAlias = whileAnalysing(session, typeAlias) { @@ -170,6 +182,10 @@ open class FirTypeResolveTransformer( unboundCyclesInTypeParametersSupertypes(property) + if (property.source?.kind == KtFakeSourceElementKind.PropertyFromParameter) { + property.removeDuplicateAnnotationsOfPrimaryConstructorElement() + } + property } } @@ -380,4 +396,30 @@ open class FirTypeResolveTransformer( scopes.add(FirMemberTypeParameterScope(this)) } } + + /** + * In a scenario like + * + * ``` + * annotation class Ann + * class Foo(@Ann val x: String) + * ``` + * + * both, the primary ctor value parameter and the property `x` will be annotated with `@Ann`. This is due to the fact, that the + * annotation needs to be resolved in order to determine its annotation targets. We remove annotations from the wrong target if they + * don't explicitly specify the use-site target (in which case they shouldn't have been added to the element in the raw FIR). + * + * For value parameters, we remove the annotation if the targets don't include [AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER]. + * For properties, we remove the annotation, if the targets include [AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER]. + */ + private fun FirVariable.removeDuplicateAnnotationsOfPrimaryConstructorElement() { + val isParameter = this is FirValueParameter + replaceAnnotations(annotations.filter { + it.useSiteTarget != null || + // equivalent to + // CONSTRUCTOR_PARAMETER in targets && isParameter || + // CONSTRUCTOR_PARAMETER !in targets && !isParameter + AnnotationUseSiteTarget.CONSTRUCTOR_PARAMETER in it.useSiteTargetsFromMetaAnnotation(session) == isParameter + }) + } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt index f09d663ae63..f7ee78dc751 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/AbstractFirSpecificAnnotationResolveTransformer.kt @@ -7,41 +7,48 @@ package org.jetbrains.kotlin.fir.resolve.transformers.plugin import kotlinx.collections.immutable.PersistentList import kotlinx.collections.immutable.persistentListOf -import org.jetbrains.kotlin.fir.FirAnnotationContainer -import org.jetbrains.kotlin.fir.FirElement -import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.PrivateForInline +import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.expressions.FirAnnotation -import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall -import org.jetbrains.kotlin.fir.expressions.FirAnnotationResolvePhase -import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.expressions.builder.buildResolvedQualifier import org.jetbrains.kotlin.fir.extensions.* +import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference +import org.jetbrains.kotlin.fir.references.impl.FirSimpleNamedReference import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession import org.jetbrains.kotlin.fir.resolve.transformers.DesignationState import org.jetbrains.kotlin.fir.resolve.transformers.FirSpecificTypeResolverTransformer import org.jetbrains.kotlin.fir.resolve.transformers.ScopeClassDeclaration +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer +import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirExpressionsResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS import org.jetbrains.kotlin.fir.resolve.transformers.plugin.CompilerRequiredAnnotationsHelper.REQUIRED_ANNOTATIONS_WITH_ARGUMENTS import org.jetbrains.kotlin.fir.resolve.transformers.withClassDeclarationCleanup import org.jetbrains.kotlin.fir.scopes.FirScope import org.jetbrains.kotlin.fir.scopes.createImportingScopes +import org.jetbrains.kotlin.fir.scopes.getProperties +import org.jetbrains.kotlin.fir.scopes.getSingleClassifier +import org.jetbrains.kotlin.fir.scopes.impl.FirAbstractImportingScope +import org.jetbrains.kotlin.fir.symbols.impl.FirCallableSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol import org.jetbrains.kotlin.fir.types.* -import org.jetbrains.kotlin.fir.types.builder.buildPlaceholderProjection -import org.jetbrains.kotlin.fir.types.builder.buildStarProjection -import org.jetbrains.kotlin.fir.types.builder.buildTypeProjectionWithVariance -import org.jetbrains.kotlin.fir.types.builder.buildUserTypeRef +import org.jetbrains.kotlin.fir.types.builder.* +import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl +import org.jetbrains.kotlin.fir.types.impl.FirImplicitUnitTypeRef import org.jetbrains.kotlin.fir.types.impl.FirQualifierPartImpl import org.jetbrains.kotlin.fir.types.impl.FirTypeArgumentListImpl import org.jetbrains.kotlin.fir.visitors.FirDefaultTransformer import org.jetbrains.kotlin.fir.visitors.transformSingle import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Deprecated import org.jetbrains.kotlin.name.StandardClassIds.Annotations.DeprecatedSinceKotlin import org.jetbrains.kotlin.name.StandardClassIds.Annotations.JvmRecord import org.jetbrains.kotlin.name.StandardClassIds.Annotations.WasExperimental +import org.jetbrains.kotlin.name.StandardClassIds.Annotations.Target import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled /** @@ -50,6 +57,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.shouldNotBeCalled object CompilerRequiredAnnotationsHelper { internal val REQUIRED_ANNOTATIONS_WITH_ARGUMENTS: Set = setOf( Deprecated, + Target, ) val REQUIRED_ANNOTATIONS: Set = REQUIRED_ANNOTATIONS_WITH_ARGUMENTS + setOf( @@ -69,6 +77,112 @@ internal abstract class AbstractFirSpecificAnnotationResolveTransformer( private val REQUIRED_ANNOTATION_NAMES: Set = REQUIRED_ANNOTATIONS.mapTo(mutableSetOf()) { it.shortClassName } } + inner class FirEnumAnnotationArgumentsTransformerDispatcher : FirAbstractBodyResolveTransformerDispatcher( + session, + FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS, + scopeSession = scopeSession, + implicitTypeOnly = false, + ) { + override val expressionsTransformer: FirExpressionsResolveTransformer = FirEnumAnnotationArgumentsTransformer(this) + override val declarationsTransformer: FirDeclarationsResolveTransformer get() = throw NotImplementedError() + } + + /** + * Special transformer that resolves qualified expressions exclusively to enums from import scope. This doesn't + * trigger body resolve. + */ + private inner class FirEnumAnnotationArgumentsTransformer(transformer: FirAbstractBodyResolveTransformerDispatcher) : + AbstractFirExpressionsResolveTransformerForAnnotations(transformer) { + + override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement { + // transform arrayOf arguments to handle `@Foo(bar = arrayOf(X))` + functionCall.transformChildren(transformer, data) + return super.transformFunctionCall(functionCall, data) + } + + override fun resolveQualifiedAccessAndSelectCandidate( + qualifiedAccessExpression: FirQualifiedAccessExpression, + isUsedAsReceiver: Boolean, + callSite: FirElement + ): FirStatement { + qualifiedAccessExpression.resolveFromImportScope() + return qualifiedAccessExpression + } + + private fun FirQualifiedAccessExpression.resolveFromImportScope() { + val calleeReference = calleeReference as? FirSimpleNamedReference ?: return + val receiver = explicitReceiver as? FirQualifiedAccessExpression + + if (receiver != null) { + // Simple case X.Y or fully qualified case a.b.X.Y + // Resolve receiver from import scope. + + val receiverCalleeReference = receiver.calleeReference as? FirSimpleNamedReference ?: return + val receiverName = receiverCalleeReference.name.takeIf { !it.isSpecial } ?: return + + val symbol = scopes.filterIsInstance().firstNotNullOfOrNull { + it.getSingleClassifier(receiverName) as? FirClassSymbol<*> + } ?: return + + // If fully qualified, check that given package name matches the resolved one. + val segments = generateSequence(receiver.explicitReceiver) { (it as? FirQualifiedAccessExpression)?.explicitReceiver } + .mapNotNull { (it.calleeReference as? FirSimpleNamedReference)?.name?.identifier } + .toList() + + if (segments.isNotEmpty() && FqName.fromSegments(segments.asReversed()) != symbol.classId.packageFqName) { + return + } + + val resolvedReceiver = buildResolvedQualifier { + source = receiver.source + packageFqName = symbol.classId.packageFqName + relativeClassFqName = symbol.classId.relativeClassName + typeRef = FirImplicitUnitTypeRef(receiver.typeRef.source) + this.symbol = symbol + } + + // Resolve enum entry by name from the declarations of the receiver. + val calleeSymbol = symbol.fir.declarations.firstOrNull { + it is FirEnumEntry && it.name == calleeReference.name + }?.symbol as? FirEnumEntrySymbol ?: return + + updateCallee(calleeReference, calleeSymbol) + + replaceExplicitReceiver(resolvedReceiver) + replaceDispatchReceiver(resolvedReceiver) + } else { + // Case where enum entry is explicitly imported. + val calleeSymbol = scopes.firstNotNullOfOrNull { + it.getProperties(calleeReference.name).firstOrNull() + } as? FirEnumEntrySymbol ?: return + + updateCallee(calleeReference, calleeSymbol) + } + } + + private fun FirQualifiedAccessExpression.updateCallee( + calleeReference: FirSimpleNamedReference, + calleeSymbol: FirEnumEntrySymbol + ) { + session.lookupTracker?.recordLookup( + calleeReference.name, + calleeSymbol.dispatchReceiverType?.classId?.asFqNameString() ?: calleeSymbol.callableId.packageName.asString(), + this.source, + context.file.source, + ) + + replaceCalleeReference(buildResolvedNamedReference { + source = calleeReference.source + name = calleeReference.name + resolvedSymbol = calleeSymbol + }) + + calleeSymbol.containingClassLookupTag() + ?.let { ConeClassLikeTypeImpl(it, emptyArray(), false) } + ?.let { replaceTypeRef(typeRef.resolvedTypeFromPrototype(it)) } + } + } + private val predicateBasedProvider = session.predicateBasedProvider private val annotationsFromPlugins: Set = session.registeredPluginAnnotations.annotations @@ -80,15 +194,12 @@ internal abstract class AbstractFirSpecificAnnotationResolveTransformer( @PrivateForInline val typeResolverTransformer: FirSpecificTypeResolverTransformer = FirSpecificTypeResolverTransformer( session, - errorTypeAsResolved = false + errorTypeAsResolved = false, + resolveDeprecations = false, ) @PrivateForInline - val argumentsTransformer = FirAnnotationArgumentsResolveTransformer( - session, - scopeSession, - FirResolvePhase.COMPILER_REQUIRED_ANNOTATIONS - ) + val argumentsTransformer = FirEnumAnnotationArgumentsTransformerDispatcher() private var owners: PersistentList = persistentListOf() private val classDeclarationsStack = ArrayDeque().apply { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt index 20eca46498c..87a8d29daba 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsResolveTransformer.kt @@ -139,9 +139,8 @@ private class FirDeclarationsResolveTransformerForArgumentAnnotations( } } -private class FirExpressionsResolveTransformerForSpecificAnnotations( - transformer: FirAbstractBodyResolveTransformerDispatcher -) : FirExpressionsResolveTransformer(transformer) { +abstract class AbstractFirExpressionsResolveTransformerForAnnotations(transformer: FirAbstractBodyResolveTransformerDispatcher) : + FirExpressionsResolveTransformer(transformer) { override fun transformAnnotation(annotation: FirAnnotation, data: ResolutionMode): FirStatement { dataFlowAnalyzer.enterAnnotation() @@ -166,13 +165,11 @@ private class FirExpressionsResolveTransformerForSpecificAnnotations( return calleeReference !is FirErrorNamedReference } - override fun resolveQualifiedAccessAndSelectCandidate( + abstract override fun resolveQualifiedAccessAndSelectCandidate( qualifiedAccessExpression: FirQualifiedAccessExpression, isUsedAsReceiver: Boolean, callSite: FirElement, - ): FirStatement { - return callResolver.resolveOnlyEnumOrQualifierAccessAndSelectCandidate(qualifiedAccessExpression, isUsedAsReceiver) - } + ): FirStatement override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement { return functionCall @@ -254,3 +251,16 @@ private class FirExpressionsResolveTransformerForSpecificAnnotations( return false } } + +private class FirExpressionsResolveTransformerForSpecificAnnotations(transformer: FirAbstractBodyResolveTransformerDispatcher) : + AbstractFirExpressionsResolveTransformerForAnnotations(transformer) { + + override fun resolveQualifiedAccessAndSelectCandidate( + qualifiedAccessExpression: FirQualifiedAccessExpression, + isUsedAsReceiver: Boolean, + callSite: FirElement, + ): FirStatement { + return callResolver.resolveOnlyEnumOrQualifierAccessAndSelectCandidate(qualifiedAccessExpression, isUsedAsReceiver) + } + +} diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt index 1d308b5ab36..0079c234a46 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt @@ -128,6 +128,16 @@ fun FirBlock.replaceFirstStatement(factory: (T) -> FirStateme fun FirExpression.unwrapArgument(): FirExpression = (this as? FirWrappedArgumentExpression)?.expression ?: this +fun FirExpression.unwrapAndFlattenArgument(): List = buildList { unwrapAndFlattenArgumentTo(this) } + +private fun FirExpression.unwrapAndFlattenArgumentTo(list: MutableList) { + when (val unwrapped = unwrapArgument()) { + is FirArrayOfCall, is FirFunctionCall -> (unwrapped as FirCall).arguments.forEach { it.unwrapAndFlattenArgumentTo(list) } + is FirVarargArgumentsExpression -> unwrapped.arguments.forEach { it.unwrapAndFlattenArgumentTo(list) } + else -> list.add(unwrapped) + } +} + val FirVariableAssignment.explicitReceiver: FirExpression? get() = unwrapLValue()?.explicitReceiver val FirVariableAssignment.dispatchReceiver: FirExpression get() = unwrapLValue()?.dispatchReceiver ?: FirNoReceiverExpression diff --git a/compiler/testData/asJava/lightClasses/lightClassByPsi/annotations.fir.java b/compiler/testData/asJava/lightClasses/lightClassByPsi/annotations.fir.java index bd1fc5c350f..7b55c8d5f63 100644 --- a/compiler/testData/asJava/lightClasses/lightClassByPsi/annotations.fir.java +++ b/compiler/testData/asJava/lightClasses/lightClassByPsi/annotations.fir.java @@ -66,7 +66,6 @@ public static final class Companion /* AnnoWithCompanion.Companion*/ { } public final class CtorAnnotations /* CtorAnnotations*/ { - @Anno() @org.jetbrains.annotations.NotNull() private final java.lang.String x; diff --git a/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.fir.ir.txt b/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.fir.ir.txt new file mode 100644 index 00000000000..7b98a7d6bae --- /dev/null +++ b/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.fir.ir.txt @@ -0,0 +1,147 @@ +FILE fqName: fileName:/test.kt + CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Foo + CONSTRUCTOR visibility:public <> (param:kotlin.Int) returnType:.Foo [primary] + VALUE_PARAMETER name:param index:0 type:kotlin.Int + annotations: + NoTarget + PropValueField + ParameterOnly + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:param visibility:public modality:FINAL [var] + FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private + annotations: + FieldOnly + EXPRESSION_BODY + GET_VAR 'param: kotlin.Int declared in .Foo.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Foo) returnType:kotlin.Int + correspondingProperty: PROPERTY name:param visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Foo + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .Foo' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private' type=kotlin.Int origin=null + receiver: GET_VAR ': .Foo declared in .Foo.' type=.Foo origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Foo, :kotlin.Int) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:param visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Foo + VALUE_PARAMETER name: index:0 type:kotlin.Int + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private' type=kotlin.Unit origin=null + receiver: GET_VAR ': .Foo declared in .Foo.' type=.Foo origin=null + value: GET_VAR ': kotlin.Int declared in .Foo.' type=kotlin.Int 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 + FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + VAR name:clazz type:kotlin.reflect.KClass<.Foo> [val] + CLASS_REFERENCE 'CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<.Foo> + VAR name:parameterAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.CollectionsKt' type=kotlin.collections.List origin=null + : kotlin.Annotation + : kotlin.String + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KParameter' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KParameter origin=null + : kotlin.reflect.KParameter + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KFunction' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KFunction<.Foo> origin=null + : kotlin.reflect.KFunction<.Foo> + $receiver: CALL 'public abstract fun (): kotlin.collections.Collection> declared in kotlin.reflect.KClass' type=kotlin.collections.Collection.Foo>> origin=GET_PROPERTY + $this: GET_VAR 'val clazz: kotlin.reflect.KClass<.Foo> [val] declared in .box' type=kotlin.reflect.KClass<.Foo> origin=null + transform: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Annotation) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:kotlin.Annotation + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Annotation): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : kotlin.Annotation + $receiver: GET_VAR 'it: kotlin.Annotation declared in .box.' type=kotlin.Annotation origin=null + WHEN type=kotlin.String origin=ELVIS + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + VAR name:fieldAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.ArraysKt' type=kotlin.collections.List origin=null + : @[FlexibleNullability] kotlin.Annotation? + : kotlin.String + $receiver: TYPE_OP type=kotlin.Array origin=IMPLICIT_NOTNULL typeOperand=kotlin.Array + CALL 'public open fun getAnnotations (): @[FlexibleNullability] kotlin.Array? [fake_override] declared in java.lang.reflect.Field' type=@[FlexibleNullability] kotlin.Array? origin=GET_PROPERTY + $this: CALL 'public open fun getDeclaredField (p0: @[FlexibleNullability] kotlin.String?): @[FlexibleNullability] java.lang.reflect.Field? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Field? origin=null + $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm.JvmClassMappingKt' type=java.lang.Class<.Foo> origin=GET_PROPERTY + : .Foo + $receiver: CLASS_REFERENCE 'CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<.Foo> + p0: CONST String type=kotlin.String value="param" + transform: FUN_EXPR type=kotlin.Function1<@[FlexibleNullability] kotlin.Annotation?, kotlin.String> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.Annotation?) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.Annotation? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: @[FlexibleNullability] kotlin.Annotation?): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : @[FlexibleNullability] kotlin.Annotation? + $receiver: TYPE_OP type=kotlin.Annotation origin=IMPLICIT_NOTNULL typeOperand=kotlin.Annotation + GET_VAR 'it: @[FlexibleNullability] kotlin.Annotation? declared in .box.' type=@[FlexibleNullability] kotlin.Annotation? origin=null + WHEN type=kotlin.String origin=ELVIS + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val parameterAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (vararg elements: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + elements: VARARG type=kotlin.Array varargElementType=kotlin.String + CONST String type=kotlin.String value="NoTarget" + CONST String type=kotlin.String value="PropValueField" + CONST String type=kotlin.String value="ParameterOnly" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Parameters:" + other: GET_VAR 'val parameterAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val fieldAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (element: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + element: CONST String type=kotlin.String value="FieldOnly" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Field:" + other: GET_VAR 'val fieldAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CONST String type=kotlin.String value="OK" diff --git a/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.fir.txt b/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.fir.txt new file mode 100644 index 00000000000..50739e0ba22 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.fir.txt @@ -0,0 +1,35 @@ +FILE: test.kt + public final class Foo : R|kotlin/Any| { + public constructor(@R|NoTarget|() @R|PropValueField|() @R|ParameterOnly|() param: R|kotlin/Int|): R|Foo| { + super() + } + + @R|FieldOnly|() public final var param: R|kotlin/Int| = R|/param| + public get(): R|kotlin/Int| + public set(value: R|kotlin/Int|): R|kotlin/Unit| + + } + public final fun box(): R|kotlin/String| { + lval clazz: R|kotlin/reflect/KClass| = (Q|Foo|) + lval parameterAnnotations: R|kotlin/collections/Set| = R|/clazz|.R|SubstitutionOverride>|>|.R|kotlin/collections/single||>().R|SubstitutionOverride|>|.R|kotlin/collections/single|().R|kotlin/reflect/KAnnotatedElement.annotations|.R|kotlin/collections/map|( = map@fun (it: R|kotlin/Annotation|): R|kotlin/String| { + ^ R|/it|.R|kotlin/jvm/annotationClass|.R|SubstitutionOverride| ?: String() + } + ).R|kotlin/collections/toSet|() + lval fieldAnnotations: R|kotlin/collections/Set| = (Q|Foo|).R|kotlin/jvm/java|.R|SubstitutionOverride|(String(param)).R|java/lang/reflect/AccessibleObject.annotations|.R|kotlin/collections/map|( = map@fun (it: R|kotlin/Annotation!|): R|kotlin/String| { + ^ R|/it|.R|kotlin/jvm/annotationClass|.R|SubstitutionOverride| ?: String() + } + ).R|kotlin/collections/toSet|() + when () { + !=(R|/parameterAnnotations|, R|kotlin/collections/setOf|(vararg(String(NoTarget), String(PropValueField), String(ParameterOnly)))) -> { + ^box String(Parameters:).R|kotlin/String.plus|(R|/parameterAnnotations|) + } + } + + when () { + !=(R|/fieldAnnotations|, R|kotlin/collections/setOf|(String(FieldOnly))) -> { + ^box String(Field:).R|kotlin/String.plus|(R|/fieldAnnotations|) + } + } + + ^box String(OK) + } diff --git a/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.ir.txt b/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.ir.txt new file mode 100644 index 00000000000..1dd0c6ef53b --- /dev/null +++ b/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.ir.txt @@ -0,0 +1,147 @@ +FILE fqName: fileName:/test.kt + CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Foo + CONSTRUCTOR visibility:public <> (param:kotlin.Int) returnType:.Foo [primary] + VALUE_PARAMETER name:param index:0 type:kotlin.Int + annotations: + NoTarget + PropValueField + ParameterOnly + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:param visibility:public modality:FINAL [var] + FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private + annotations: + FieldOnly + EXPRESSION_BODY + GET_VAR 'param: kotlin.Int declared in .Foo.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Foo) returnType:kotlin.Int + correspondingProperty: PROPERTY name:param visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Foo + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .Foo' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private' type=kotlin.Int origin=null + receiver: GET_VAR ': .Foo declared in .Foo.' type=.Foo origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Foo, :kotlin.Int) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:param visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Foo + VALUE_PARAMETER name: index:0 type:kotlin.Int + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private' type=kotlin.Unit origin=null + receiver: GET_VAR ': .Foo declared in .Foo.' type=.Foo origin=null + value: GET_VAR ': kotlin.Int declared in .Foo.' type=kotlin.Int 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 + FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + VAR name:clazz type:kotlin.reflect.KClass<.Foo> [val] + CLASS_REFERENCE 'CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<.Foo> + VAR name:parameterAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.CollectionsKt' type=kotlin.collections.List origin=null + : kotlin.Annotation + : kotlin.String + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KParameter' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KParameter origin=null + : kotlin.reflect.KParameter + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KFunction' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KFunction<.Foo> origin=null + : kotlin.reflect.KFunction<.Foo> + $receiver: CALL 'public abstract fun (): kotlin.collections.Collection> declared in kotlin.reflect.KClass' type=kotlin.collections.Collection.Foo>> origin=GET_PROPERTY + $this: GET_VAR 'val clazz: kotlin.reflect.KClass<.Foo> [val] declared in .box' type=kotlin.reflect.KClass<.Foo> origin=null + transform: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Annotation) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:kotlin.Annotation + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Annotation): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : kotlin.Annotation + $receiver: GET_VAR 'it: kotlin.Annotation declared in .box.' type=kotlin.Annotation origin=null + WHEN type=kotlin.String origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + VAR name:fieldAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.ArraysKt' type=kotlin.collections.List origin=null + : @[FlexibleNullability] kotlin.Annotation? + : kotlin.String + $receiver: TYPE_OP type=kotlin.Array origin=IMPLICIT_NOTNULL typeOperand=kotlin.Array + CALL 'public open fun getAnnotations (): @[FlexibleNullability] kotlin.Array? [fake_override] declared in java.lang.reflect.Field' type=@[FlexibleNullability] kotlin.Array? origin=GET_PROPERTY + $this: TYPE_OP type=java.lang.reflect.Field origin=IMPLICIT_NOTNULL typeOperand=java.lang.reflect.Field + CALL 'public open fun getDeclaredField (p0: @[FlexibleNullability] kotlin.String?): @[FlexibleNullability] java.lang.reflect.Field? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Field? origin=null + $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm.JvmClassMappingKt' type=java.lang.Class<.Foo> origin=GET_PROPERTY + : .Foo + $receiver: CLASS_REFERENCE 'CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<.Foo> + p0: CONST String type=kotlin.String value="param" + transform: FUN_EXPR type=kotlin.Function1<@[FlexibleNullability] kotlin.Annotation?, kotlin.String> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.Annotation?) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.Annotation? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: @[FlexibleNullability] kotlin.Annotation?): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : @[FlexibleNullability] kotlin.Annotation? + $receiver: GET_VAR 'it: @[FlexibleNullability] kotlin.Annotation? declared in .box.' type=@[FlexibleNullability] kotlin.Annotation? origin=null + WHEN type=kotlin.String origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val parameterAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (vararg elements: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + elements: VARARG type=kotlin.Array varargElementType=kotlin.String + CONST String type=kotlin.String value="NoTarget" + CONST String type=kotlin.String value="PropValueField" + CONST String type=kotlin.String value="ParameterOnly" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Parameters:" + other: GET_VAR 'val parameterAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val fieldAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (element: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + element: CONST String type=kotlin.String value="FieldOnly" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Field:" + other: GET_VAR 'val fieldAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CONST String type=kotlin.String value="OK" diff --git a/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.kt b/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.kt new file mode 100644 index 00000000000..f93029e1aad --- /dev/null +++ b/compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.kt @@ -0,0 +1,59 @@ +// WITH_STDLIB +// WITH_REFLECT +// TARGET_BACKEND: JVM_IR +// FIR_DUMP +// DUMP_IR + +// FILE: NoTarget.java +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +public @interface NoTarget { +} + +// FILE: PropValueField.java +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER, ElementType.FIELD}) +public @interface PropValueField { +} + +// FILE: ParameterOnly.java +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.PARAMETER}) +public @interface ParameterOnly { +} + +// FILE: FieldOnly.java +import java.lang.annotation.*; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD}) +public @interface FieldOnly { +} + +// FILE: test.kt +import kotlin.reflect.full.declaredMemberProperties + +class Foo( + @NoTarget + @PropValueField + @ParameterOnly + @FieldOnly + var param: Int +) + +fun box(): String { + val clazz = Foo::class + + val parameterAnnotations = clazz.constructors.single().parameters.single().annotations.map { it.annotationClass.simpleName ?: "" }.toSet() + val fieldAnnotations = Foo::class.java.getDeclaredField("param").annotations.map { it.annotationClass.simpleName ?: "" }.toSet() + + if (parameterAnnotations != setOf("NoTarget", "PropValueField", "ParameterOnly")) return "Parameters:" + parameterAnnotations + if (fieldAnnotations != setOf("FieldOnly")) return "Field:" + fieldAnnotations + + return "OK" +} diff --git a/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.fir.ir.txt b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.fir.ir.txt new file mode 100644 index 00000000000..2f42411d119 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.fir.ir.txt @@ -0,0 +1,326 @@ +FILE fqName: fileName:/targetOnPrimaryCtorParameter.kt + CLASS ANNOTATION_CLASS name:NoTarget modality:OPEN visibility:public superTypes:[kotlin.Annotation] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.NoTarget + CONSTRUCTOR visibility:public <> () returnType:.NoTarget [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:NoTarget modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:PropValueField modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:PROPERTY' type=kotlin.annotation.AnnotationTarget, GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:VALUE_PARAMETER' type=kotlin.annotation.AnnotationTarget, GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:FIELD' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.PropValueField + CONSTRUCTOR visibility:public <> () returnType:.PropValueField [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:PropValueField modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:PropertyOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:PROPERTY' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.PropertyOnly + CONSTRUCTOR visibility:public <> () returnType:.PropertyOnly [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:PropertyOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:ParameterOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:VALUE_PARAMETER' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.ParameterOnly + CONSTRUCTOR visibility:public <> () returnType:.ParameterOnly [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:ParameterOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:FieldOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:FIELD' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FieldOnly + CONSTRUCTOR visibility:public <> () returnType:.FieldOnly [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:FieldOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:PropertyOnly2 modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:PROPERTY' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.PropertyOnly2 + CONSTRUCTOR visibility:public <> () returnType:.PropertyOnly2 [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:PropertyOnly2 modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:Foo modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Foo + CONSTRUCTOR visibility:public <> (param:kotlin.Int) returnType:.Foo [primary] + VALUE_PARAMETER name:param index:0 type:kotlin.Int + annotations: + NoTarget + PropValueField + ParameterOnly + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:param visibility:public modality:FINAL [var] + annotations: + PropertyOnly + PropertyOnly2 + FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private + annotations: + FieldOnly + EXPRESSION_BODY + GET_VAR 'param: kotlin.Int declared in .Foo.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Foo) returnType:kotlin.Int + correspondingProperty: PROPERTY name:param visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Foo + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .Foo' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private' type=kotlin.Int origin=null + receiver: GET_VAR ': .Foo declared in .Foo.' type=.Foo origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Foo, :kotlin.Int) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:param visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Foo + VALUE_PARAMETER name: index:0 type:kotlin.Int + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private' type=kotlin.Unit origin=null + receiver: GET_VAR ': .Foo declared in .Foo.' type=.Foo origin=null + value: GET_VAR ': kotlin.Int declared in .Foo.' type=kotlin.Int 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 + FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + VAR name:clazz type:kotlin.reflect.KClass<.Foo> [val] + CLASS_REFERENCE 'CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<.Foo> + VAR name:parameterAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.CollectionsKt' type=kotlin.collections.List origin=null + : kotlin.Annotation + : kotlin.String + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KParameter' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KParameter origin=null + : kotlin.reflect.KParameter + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KFunction' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KFunction<.Foo> origin=null + : kotlin.reflect.KFunction<.Foo> + $receiver: CALL 'public abstract fun (): kotlin.collections.Collection> declared in kotlin.reflect.KClass' type=kotlin.collections.Collection.Foo>> origin=GET_PROPERTY + $this: GET_VAR 'val clazz: kotlin.reflect.KClass<.Foo> [val] declared in .box' type=kotlin.reflect.KClass<.Foo> origin=null + transform: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Annotation) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:kotlin.Annotation + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Annotation): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : kotlin.Annotation + $receiver: GET_VAR 'it: kotlin.Annotation declared in .box.' type=kotlin.Annotation origin=null + WHEN type=kotlin.String origin=ELVIS + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + VAR name:propertyAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.CollectionsKt' type=kotlin.collections.List origin=null + : kotlin.Annotation + : kotlin.String + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KProperty1' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KProperty1<.Foo, *> origin=null + : kotlin.reflect.KProperty1<.Foo, *> + $receiver: CALL 'public final fun (): kotlin.collections.Collection, *>> declared in kotlin.reflect.full.KClasses' type=kotlin.collections.Collection.Foo, *>> origin=GET_PROPERTY + : .Foo + $receiver: GET_VAR 'val clazz: kotlin.reflect.KClass<.Foo> [val] declared in .box' type=kotlin.reflect.KClass<.Foo> origin=null + transform: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Annotation) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:kotlin.Annotation + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Annotation): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : kotlin.Annotation + $receiver: GET_VAR 'it: kotlin.Annotation declared in .box.' type=kotlin.Annotation origin=null + WHEN type=kotlin.String origin=ELVIS + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + VAR name:fieldAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.ArraysKt' type=kotlin.collections.List origin=null + : @[FlexibleNullability] kotlin.Annotation? + : kotlin.String + $receiver: TYPE_OP type=kotlin.Array origin=IMPLICIT_NOTNULL typeOperand=kotlin.Array + CALL 'public open fun getAnnotations (): @[FlexibleNullability] kotlin.Array? [fake_override] declared in java.lang.reflect.Field' type=@[FlexibleNullability] kotlin.Array? origin=GET_PROPERTY + $this: CALL 'public open fun getDeclaredField (p0: @[FlexibleNullability] kotlin.String?): @[FlexibleNullability] java.lang.reflect.Field? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Field? origin=null + $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm.JvmClassMappingKt' type=java.lang.Class<.Foo> origin=GET_PROPERTY + : .Foo + $receiver: CLASS_REFERENCE 'CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<.Foo> + p0: CONST String type=kotlin.String value="param" + transform: FUN_EXPR type=kotlin.Function1<@[FlexibleNullability] kotlin.Annotation?, kotlin.String> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.Annotation?) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.Annotation? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: @[FlexibleNullability] kotlin.Annotation?): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : @[FlexibleNullability] kotlin.Annotation? + $receiver: TYPE_OP type=kotlin.Annotation origin=IMPLICIT_NOTNULL typeOperand=kotlin.Annotation + GET_VAR 'it: @[FlexibleNullability] kotlin.Annotation? declared in .box.' type=@[FlexibleNullability] kotlin.Annotation? origin=null + WHEN type=kotlin.String origin=ELVIS + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val parameterAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (vararg elements: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + elements: VARARG type=kotlin.Array varargElementType=kotlin.String + CONST String type=kotlin.String value="NoTarget" + CONST String type=kotlin.String value="PropValueField" + CONST String type=kotlin.String value="ParameterOnly" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Parameters:" + other: CALL 'public final fun joinToString (separator: kotlin.CharSequence, prefix: kotlin.CharSequence, postfix: kotlin.CharSequence, limit: kotlin.Int, truncated: kotlin.CharSequence, transform: kotlin.Function1?): kotlin.String declared in kotlin.collections.CollectionsKt' type=kotlin.String origin=null + : kotlin.String + $receiver: GET_VAR 'val parameterAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val propertyAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (vararg elements: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + elements: VARARG type=kotlin.Array varargElementType=kotlin.String + CONST String type=kotlin.String value="PropertyOnly" + CONST String type=kotlin.String value="PropertyOnly2" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Property:" + other: CALL 'public final fun joinToString (separator: kotlin.CharSequence, prefix: kotlin.CharSequence, postfix: kotlin.CharSequence, limit: kotlin.Int, truncated: kotlin.CharSequence, transform: kotlin.Function1?): kotlin.String declared in kotlin.collections.CollectionsKt' type=kotlin.String origin=null + : kotlin.String + $receiver: GET_VAR 'val propertyAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val fieldAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (element: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + element: CONST String type=kotlin.String value="FieldOnly" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Field:" + other: CALL 'public final fun joinToString (separator: kotlin.CharSequence, prefix: kotlin.CharSequence, postfix: kotlin.CharSequence, limit: kotlin.Int, truncated: kotlin.CharSequence, transform: kotlin.Function1?): kotlin.String declared in kotlin.collections.CollectionsKt' type=kotlin.String origin=null + : kotlin.String + $receiver: GET_VAR 'val fieldAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CONST String type=kotlin.String value="OK" diff --git a/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.fir.txt b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.fir.txt new file mode 100644 index 00000000000..0eec06f2927 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.fir.txt @@ -0,0 +1,81 @@ +FILE: targetOnPrimaryCtorParameter.kt + public final annotation class NoTarget : R|kotlin/Annotation| { + public constructor(): R|NoTarget| { + super() + } + + } + @R|kotlin/annotation/Target|(allowedTargets = vararg(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.PROPERTY|, R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|, Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FIELD|)) public final annotation class PropValueField : R|kotlin/Annotation| { + public constructor(): R|PropValueField| { + super() + } + + } + @R|kotlin/annotation/Target|(allowedTargets = vararg(allowedTargets = (Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.PROPERTY|))) public final annotation class PropertyOnly : R|kotlin/Annotation| { + public constructor(): R|PropertyOnly| { + super() + } + + } + @R|kotlin/annotation/Target|(allowedTargets = vararg(allowedTargets = (Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.VALUE_PARAMETER|))) public final annotation class ParameterOnly : R|kotlin/Annotation| { + public constructor(): R|ParameterOnly| { + super() + } + + } + @R|kotlin/annotation/Target|(allowedTargets = vararg(allowedTargets = *(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.FIELD|))) public final annotation class FieldOnly : R|kotlin/Annotation| { + public constructor(): R|FieldOnly| { + super() + } + + } + @R|kotlin/annotation/Target|(allowedTargets = vararg(*(Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.PROPERTY|))) public final annotation class PropertyOnly2 : R|kotlin/Annotation| { + public constructor(): R|PropertyOnly2| { + super() + } + + } + public final class Foo : R|kotlin/Any| { + public constructor(@R|NoTarget|() @R|PropValueField|() @R|ParameterOnly|() param: R|kotlin/Int|): R|Foo| { + super() + } + + @R|PropertyOnly|() @R|PropertyOnly2|() @R|FieldOnly|() public final var param: R|kotlin/Int| = R|/param| + public get(): R|kotlin/Int| + public set(value: R|kotlin/Int|): R|kotlin/Unit| + + } + public final fun box(): R|kotlin/String| { + lval clazz: R|kotlin/reflect/KClass| = (Q|Foo|) + lval parameterAnnotations: R|kotlin/collections/Set| = R|/clazz|.R|SubstitutionOverride>|>|.R|kotlin/collections/single||>().R|SubstitutionOverride|>|.R|kotlin/collections/single|().R|kotlin/reflect/KAnnotatedElement.annotations|.R|kotlin/collections/map|( = map@fun (it: R|kotlin/Annotation|): R|kotlin/String| { + ^ R|/it|.R|kotlin/jvm/annotationClass|.R|SubstitutionOverride| ?: String() + } + ).R|kotlin/collections/toSet|() + lval propertyAnnotations: R|kotlin/collections/Set| = R|/clazz|.R|kotlin/reflect/full/declaredMemberProperties|.R|kotlin/collections/single||>().R|kotlin/reflect/KAnnotatedElement.annotations|.R|kotlin/collections/map|( = map@fun (it: R|kotlin/Annotation|): R|kotlin/String| { + ^ R|/it|.R|kotlin/jvm/annotationClass|.R|SubstitutionOverride| ?: String() + } + ).R|kotlin/collections/toSet|() + lval fieldAnnotations: R|kotlin/collections/Set| = (Q|Foo|).R|kotlin/jvm/java|.R|SubstitutionOverride|(String(param)).R|java/lang/reflect/AccessibleObject.annotations|.R|kotlin/collections/map|( = map@fun (it: R|kotlin/Annotation!|): R|kotlin/String| { + ^ R|/it|.R|kotlin/jvm/annotationClass|.R|SubstitutionOverride| ?: String() + } + ).R|kotlin/collections/toSet|() + when () { + !=(R|/parameterAnnotations|, R|kotlin/collections/setOf|(vararg(String(NoTarget), String(PropValueField), String(ParameterOnly)))) -> { + ^box String(Parameters:).R|kotlin/String.plus|(R|/parameterAnnotations|.R|kotlin/collections/joinToString|()) + } + } + + when () { + !=(R|/propertyAnnotations|, R|kotlin/collections/setOf|(vararg(String(PropertyOnly), String(PropertyOnly2)))) -> { + ^box String(Property:).R|kotlin/String.plus|(R|/propertyAnnotations|.R|kotlin/collections/joinToString|()) + } + } + + when () { + !=(R|/fieldAnnotations|, R|kotlin/collections/setOf|(String(FieldOnly))) -> { + ^box String(Field:).R|kotlin/String.plus|(R|/fieldAnnotations|.R|kotlin/collections/joinToString|()) + } + } + + ^box String(OK) + } diff --git a/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.ir.txt b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.ir.txt new file mode 100644 index 00000000000..b2f61a8fc16 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.ir.txt @@ -0,0 +1,326 @@ +FILE fqName: fileName:/targetOnPrimaryCtorParameter.kt + CLASS ANNOTATION_CLASS name:NoTarget modality:OPEN visibility:public superTypes:[kotlin.Annotation] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.NoTarget + CONSTRUCTOR visibility:public <> () returnType:.NoTarget [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:NoTarget modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:PropValueField modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:PROPERTY' type=kotlin.annotation.AnnotationTarget, GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:VALUE_PARAMETER' type=kotlin.annotation.AnnotationTarget, GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:FIELD' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.PropValueField + CONSTRUCTOR visibility:public <> () returnType:.PropValueField [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:PropValueField modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:PropertyOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:PROPERTY' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.PropertyOnly + CONSTRUCTOR visibility:public <> () returnType:.PropertyOnly [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:PropertyOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:ParameterOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:VALUE_PARAMETER' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.ParameterOnly + CONSTRUCTOR visibility:public <> () returnType:.ParameterOnly [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:ParameterOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:FieldOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:FIELD' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FieldOnly + CONSTRUCTOR visibility:public <> () returnType:.FieldOnly [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:FieldOnly modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:PropertyOnly2 modality:OPEN visibility:public superTypes:[kotlin.Annotation] + annotations: + Target(allowedTargets = [GET_ENUM 'ENUM_ENTRY IR_EXTERNAL_DECLARATION_STUB name:PROPERTY' type=kotlin.annotation.AnnotationTarget]) + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.PropertyOnly2 + CONSTRUCTOR visibility:public <> () returnType:.PropertyOnly2 [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS ANNOTATION_CLASS name:PropertyOnly2 modality:OPEN visibility:public superTypes:[kotlin.Annotation]' + 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:Foo modality:FINAL visibility:public superTypes:[kotlin.Any] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Foo + CONSTRUCTOR visibility:public <> (param:kotlin.Int) returnType:.Foo [primary] + VALUE_PARAMETER name:param index:0 type:kotlin.Int + annotations: + NoTarget + PropValueField + ParameterOnly + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' + PROPERTY name:param visibility:public modality:FINAL [var] + annotations: + PropertyOnly + PropertyOnly2 + FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private + annotations: + FieldOnly + EXPRESSION_BODY + GET_VAR 'param: kotlin.Int declared in .Foo.' type=kotlin.Int origin=INITIALIZE_PROPERTY_FROM_PARAMETER + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Foo) returnType:kotlin.Int + correspondingProperty: PROPERTY name:param visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Foo + BLOCK_BODY + RETURN type=kotlin.Nothing from='public final fun (): kotlin.Int declared in .Foo' + GET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private' type=kotlin.Int origin=null + receiver: GET_VAR ': .Foo declared in .Foo.' type=.Foo origin=null + FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> ($this:.Foo, :kotlin.Int) returnType:kotlin.Unit + correspondingProperty: PROPERTY name:param visibility:public modality:FINAL [var] + $this: VALUE_PARAMETER name: type:.Foo + VALUE_PARAMETER name: index:0 type:kotlin.Int + BLOCK_BODY + SET_FIELD 'FIELD PROPERTY_BACKING_FIELD name:param type:kotlin.Int visibility:private' type=kotlin.Unit origin=null + receiver: GET_VAR ': .Foo declared in .Foo.' type=.Foo origin=null + value: GET_VAR ': kotlin.Int declared in .Foo.' type=kotlin.Int 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 + FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String + BLOCK_BODY + VAR name:clazz type:kotlin.reflect.KClass<.Foo> [val] + CLASS_REFERENCE 'CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<.Foo> + VAR name:parameterAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.CollectionsKt' type=kotlin.collections.List origin=null + : kotlin.Annotation + : kotlin.String + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KParameter' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KParameter origin=null + : kotlin.reflect.KParameter + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KFunction' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KFunction<.Foo> origin=null + : kotlin.reflect.KFunction<.Foo> + $receiver: CALL 'public abstract fun (): kotlin.collections.Collection> declared in kotlin.reflect.KClass' type=kotlin.collections.Collection.Foo>> origin=GET_PROPERTY + $this: GET_VAR 'val clazz: kotlin.reflect.KClass<.Foo> [val] declared in .box' type=kotlin.reflect.KClass<.Foo> origin=null + transform: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Annotation) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:kotlin.Annotation + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Annotation): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_0 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : kotlin.Annotation + $receiver: GET_VAR 'it: kotlin.Annotation declared in .box.' type=kotlin.Annotation origin=null + WHEN type=kotlin.String origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_0: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + VAR name:propertyAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.CollectionsKt' type=kotlin.collections.List origin=null + : kotlin.Annotation + : kotlin.String + $receiver: CALL 'public abstract fun (): kotlin.collections.List [fake_override] declared in kotlin.reflect.KProperty1' type=kotlin.collections.List origin=GET_PROPERTY + $this: CALL 'public final fun single (): T of kotlin.collections.CollectionsKt.single declared in kotlin.collections.CollectionsKt' type=kotlin.reflect.KProperty1<.Foo, *> origin=null + : kotlin.reflect.KProperty1<.Foo, *> + $receiver: CALL 'public final fun (): kotlin.collections.Collection, *>> declared in kotlin.reflect.full.KClasses' type=kotlin.collections.Collection.Foo, *>> origin=GET_PROPERTY + : .Foo + $receiver: GET_VAR 'val clazz: kotlin.reflect.KClass<.Foo> [val] declared in .box' type=kotlin.reflect.KClass<.Foo> origin=null + transform: FUN_EXPR type=kotlin.Function1 origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:kotlin.Annotation) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:kotlin.Annotation + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: kotlin.Annotation): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_1 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : kotlin.Annotation + $receiver: GET_VAR 'it: kotlin.Annotation declared in .box.' type=kotlin.Annotation origin=null + WHEN type=kotlin.String origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_1: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + VAR name:fieldAnnotations type:kotlin.collections.Set [val] + CALL 'public final fun toSet (): kotlin.collections.Set declared in kotlin.collections.CollectionsKt' type=kotlin.collections.Set origin=null + : kotlin.String + $receiver: CALL 'public final fun map (transform: kotlin.Function1): kotlin.collections.List [inline] declared in kotlin.collections.ArraysKt' type=kotlin.collections.List origin=null + : @[FlexibleNullability] kotlin.Annotation? + : kotlin.String + $receiver: TYPE_OP type=kotlin.Array origin=IMPLICIT_NOTNULL typeOperand=kotlin.Array + CALL 'public open fun getAnnotations (): @[FlexibleNullability] kotlin.Array? [fake_override] declared in java.lang.reflect.Field' type=@[FlexibleNullability] kotlin.Array? origin=GET_PROPERTY + $this: TYPE_OP type=java.lang.reflect.Field origin=IMPLICIT_NOTNULL typeOperand=java.lang.reflect.Field + CALL 'public open fun getDeclaredField (p0: @[FlexibleNullability] kotlin.String?): @[FlexibleNullability] java.lang.reflect.Field? declared in java.lang.Class' type=@[FlexibleNullability] java.lang.reflect.Field? origin=null + $this: CALL 'public final fun (): java.lang.Class> declared in kotlin.jvm.JvmClassMappingKt' type=java.lang.Class<.Foo> origin=GET_PROPERTY + : .Foo + $receiver: CLASS_REFERENCE 'CLASS CLASS name:Foo modality:FINAL visibility:public superTypes:[kotlin.Any]' type=kotlin.reflect.KClass<.Foo> + p0: CONST String type=kotlin.String value="param" + transform: FUN_EXPR type=kotlin.Function1<@[FlexibleNullability] kotlin.Annotation?, kotlin.String> origin=LAMBDA + FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> (it:@[FlexibleNullability] kotlin.Annotation?) returnType:kotlin.String + VALUE_PARAMETER name:it index:0 type:@[FlexibleNullability] kotlin.Annotation? + BLOCK_BODY + RETURN type=kotlin.Nothing from='local final fun (it: @[FlexibleNullability] kotlin.Annotation?): kotlin.String declared in .box' + BLOCK type=kotlin.String origin=ELVIS + VAR IR_TEMPORARY_VARIABLE name:tmp_2 type:kotlin.String? [val] + CALL 'public abstract fun (): kotlin.String? declared in kotlin.reflect.KClass' type=kotlin.String? origin=GET_PROPERTY + $this: CALL 'public final fun (): kotlin.reflect.KClass> declared in kotlin.jvm.JvmClassMappingKt' type=kotlin.reflect.KClass origin=GET_PROPERTY + : @[FlexibleNullability] kotlin.Annotation? + $receiver: GET_VAR 'it: @[FlexibleNullability] kotlin.Annotation? declared in .box.' type=@[FlexibleNullability] kotlin.Annotation? origin=null + WHEN type=kotlin.String origin=null + BRANCH + if: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EQEQ + arg0: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + arg1: CONST Null type=kotlin.Nothing? value=null + then: CONST String type=kotlin.String value="" + BRANCH + if: CONST Boolean type=kotlin.Boolean value=true + then: GET_VAR 'val tmp_2: kotlin.String? [val] declared in .box.' type=kotlin.String? origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val parameterAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (vararg elements: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + elements: VARARG type=kotlin.Array varargElementType=kotlin.String + CONST String type=kotlin.String value="NoTarget" + CONST String type=kotlin.String value="PropValueField" + CONST String type=kotlin.String value="ParameterOnly" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Parameters:" + other: CALL 'public final fun joinToString (separator: kotlin.CharSequence, prefix: kotlin.CharSequence, postfix: kotlin.CharSequence, limit: kotlin.Int, truncated: kotlin.CharSequence, transform: kotlin.Function1?): kotlin.String declared in kotlin.collections.CollectionsKt' type=kotlin.String origin=null + : kotlin.String + $receiver: GET_VAR 'val parameterAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val propertyAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (vararg elements: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + elements: VARARG type=kotlin.Array varargElementType=kotlin.String + CONST String type=kotlin.String value="PropertyOnly" + CONST String type=kotlin.String value="PropertyOnly2" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Property:" + other: CALL 'public final fun joinToString (separator: kotlin.CharSequence, prefix: kotlin.CharSequence, postfix: kotlin.CharSequence, limit: kotlin.Int, truncated: kotlin.CharSequence, transform: kotlin.Function1?): kotlin.String declared in kotlin.collections.CollectionsKt' type=kotlin.String origin=null + : kotlin.String + $receiver: GET_VAR 'val propertyAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + WHEN type=kotlin.Unit origin=IF + BRANCH + if: CALL 'public final fun not (): kotlin.Boolean [operator] declared in kotlin.Boolean' type=kotlin.Boolean origin=EXCLEQ + $this: CALL 'public final fun EQEQ (arg0: kotlin.Any?, arg1: kotlin.Any?): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=EXCLEQ + arg0: GET_VAR 'val fieldAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + arg1: CALL 'public final fun setOf (element: T of kotlin.collections.SetsKt.setOf): kotlin.collections.Set declared in kotlin.collections.SetsKt' type=kotlin.collections.Set origin=null + : kotlin.String + element: CONST String type=kotlin.String value="FieldOnly" + then: RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CALL 'public final fun plus (other: kotlin.Any?): kotlin.String [operator] declared in kotlin.String' type=kotlin.String origin=PLUS + $this: CONST String type=kotlin.String value="Field:" + other: CALL 'public final fun joinToString (separator: kotlin.CharSequence, prefix: kotlin.CharSequence, postfix: kotlin.CharSequence, limit: kotlin.Int, truncated: kotlin.CharSequence, transform: kotlin.Function1?): kotlin.String declared in kotlin.collections.CollectionsKt' type=kotlin.String origin=null + : kotlin.String + $receiver: GET_VAR 'val fieldAnnotations: kotlin.collections.Set [val] declared in .box' type=kotlin.collections.Set origin=null + RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in ' + CONST String type=kotlin.String value="OK" diff --git a/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.kt b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.kt new file mode 100644 index 00000000000..e943e0d496e --- /dev/null +++ b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.kt @@ -0,0 +1,49 @@ +// WITH_STDLIB +// WITH_REFLECT +// TARGET_BACKEND: JVM_IR +// FIR_DUMP +// DUMP_IR + +import kotlin.reflect.full.declaredMemberProperties +import kotlin.annotation.AnnotationTarget.* + +annotation class NoTarget + +@Target(kotlin.annotation.AnnotationTarget.PROPERTY, VALUE_PARAMETER, AnnotationTarget.FIELD) +annotation class PropValueField + +@Target(allowedTargets = [AnnotationTarget.PROPERTY]) +annotation class PropertyOnly + +@Target(allowedTargets = arrayOf(AnnotationTarget.VALUE_PARAMETER)) +annotation class ParameterOnly + +@Target(allowedTargets = *arrayOf(AnnotationTarget.FIELD)) +annotation class FieldOnly + +@Target(*[AnnotationTarget.PROPERTY]) +annotation class PropertyOnly2 + +class Foo( + @NoTarget + @PropValueField + @PropertyOnly + @PropertyOnly2 + @ParameterOnly + @FieldOnly + var param: Int +) + +fun box(): String { + val clazz = Foo::class + + val parameterAnnotations = clazz.constructors.single().parameters.single().annotations.map { it.annotationClass.simpleName ?: "" }.toSet() + val propertyAnnotations = clazz.declaredMemberProperties.single().annotations.map { it.annotationClass.simpleName ?: "" }.toSet() + val fieldAnnotations = Foo::class.java.getDeclaredField("param").annotations.map { it.annotationClass.simpleName ?: "" }.toSet() + + if (parameterAnnotations != setOf("NoTarget", "PropValueField", "ParameterOnly")) return "Parameters:" + parameterAnnotations.joinToString() + if (propertyAnnotations != setOf("PropertyOnly", "PropertyOnly2")) return "Property:" + propertyAnnotations.joinToString() + if (fieldAnnotations != setOf("FieldOnly")) return "Field:" + fieldAnnotations.joinToString() + + return "OK" +} diff --git a/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameterMultiModule.kt b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameterMultiModule.kt new file mode 100644 index 00000000000..e0cc1dfadc8 --- /dev/null +++ b/compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameterMultiModule.kt @@ -0,0 +1,53 @@ +// WITH_STDLIB +// WITH_REFLECT +// TARGET_BACKEND: JVM_IR + +// MODULE: lib +// FILE: lib.kt + +package a + +annotation class NoTarget + +@Target(AnnotationTarget.PROPERTY, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FIELD) +annotation class PropValueField + +@Target(AnnotationTarget.PROPERTY) +annotation class PropertyOnly + +@Target(AnnotationTarget.VALUE_PARAMETER) +annotation class ParameterOnly + +@Target(AnnotationTarget.FIELD) +annotation class FieldOnly + +class Foo( + @NoTarget + @PropValueField + @PropertyOnly + @ParameterOnly + @FieldOnly + var param: Int +) + +// MODULE: app(lib) +// FILE: app.kt + +package test + +import a.Foo +import kotlin.reflect.full.declaredMemberProperties + +fun box(): String { + val clazz = Foo::class + + val parameterAnnotations = clazz.constructors.single().parameters.single().annotations.map { it.annotationClass.simpleName ?: "" }.toSet() + val propertyAnnotations = clazz.declaredMemberProperties.single().annotations.map { it.annotationClass.simpleName ?: "" }.toSet() + val fieldAnnotations = Foo::class.java.getDeclaredField("param").annotations.map { it.annotationClass.simpleName ?: "" }.toSet() + + if (parameterAnnotations != setOf("NoTarget", "PropValueField", "ParameterOnly")) return "Parameters:" + parameterAnnotations + if (propertyAnnotations != setOf("PropertyOnly")) return "Property:" + propertyAnnotations + if (fieldAnnotations != setOf("FieldOnly")) return "Field:" + fieldAnnotations + + return "OK" +} diff --git a/compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.fir.kt b/compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.fir.kt index d329e381e83..3103112b3a1 100644 --- a/compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/RecursivelyIncorrectlyAnnotatedParameter.fir.kt @@ -1,2 +1,2 @@ // Class constructor parameter CAN be recursively annotated -class RecursivelyAnnotated(@RecursivelyAnnotated(1) val x: Int) +class RecursivelyAnnotated(@RecursivelyAnnotated(1) val x: Int) diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/wasExperimental.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/wasExperimental.fir.kt index 7a3985fb487..e4a6acbd670 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/wasExperimental.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/wasExperimental.fir.kt @@ -25,17 +25,17 @@ class NewClassExperimentalInThePast @SinceKotlin("1.4") @WasExperimental(Marker::class) -typealias TypeAliasToNewClass = NewClassExperimentalInThePast +typealias TypeAliasToNewClass = NewClassExperimentalInThePast fun use1( - c1: NewClassExperimentalInThePast, - t1: TypeAliasToNewClass + c1: NewClassExperimentalInThePast, + t1: TypeAliasToNewClass ) { newPublishedFun() - newFunExperimentalInThePast() - newValExperimentalInThePast - NewClassExperimentalInThePast() + newFunExperimentalInThePast() + newValExperimentalInThePast + NewClassExperimentalInThePast() } @OptIn(Marker::class) diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index f3367538c00..d47ffbbf825 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -233,6 +233,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/annotations/javaPropertyWithIntInitializer.kt"); } + @Test + @TestMetadata("javaTargetOnPrimaryCtorParameter.kt") + public void testJavaTargetOnPrimaryCtorParameter() throws Exception { + runTest("compiler/testData/codegen/box/annotations/javaTargetOnPrimaryCtorParameter.kt"); + } + @Test @TestMetadata("jvmAnnotationFlags.kt") public void testJvmAnnotationFlags() throws Exception { @@ -371,6 +377,18 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/annotations/syntheticMethodForProperty.kt"); } + @Test + @TestMetadata("targetOnPrimaryCtorParameter.kt") + public void testTargetOnPrimaryCtorParameter() throws Exception { + runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameter.kt"); + } + + @Test + @TestMetadata("targetOnPrimaryCtorParameterMultiModule.kt") + public void testTargetOnPrimaryCtorParameterMultiModule() throws Exception { + runTest("compiler/testData/codegen/box/annotations/targetOnPrimaryCtorParameterMultiModule.kt"); + } + @Test @TestMetadata("typeAnnotationOnJdk6.kt") public void testTypeAnnotationOnJdk6() throws Exception { diff --git a/plugins/kotlinx-serialization/testData/firMembers/metaSerializable.fir.txt b/plugins/kotlinx-serialization/testData/firMembers/metaSerializable.fir.txt index 3eb7a682689..94e80c230ec 100644 --- a/plugins/kotlinx-serialization/testData/firMembers/metaSerializable.fir.txt +++ b/plugins/kotlinx-serialization/testData/firMembers/metaSerializable.fir.txt @@ -92,7 +92,7 @@ FILE: metaSerializable.kt } @R|kotlinx/serialization/Serializable|() public final class Wrapper : R|kotlin/Any| { - public constructor(@R|MySerializableWithInfo|(value = Int(234), kclass = (Q|kotlin/Int|)) project: R|Project2|): R|Wrapper| { + public constructor(project: R|Project2|): R|Wrapper| { super() }