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() }