diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentMappingLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentMappingLazyResolver.kt index e010d29678a..172c804dcf8 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentMappingLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentMappingLazyResolver.kt @@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildArgumentList import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.isError import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession @@ -131,7 +132,7 @@ internal object AnnotationArgumentMappingStateKeepers { source = oldList.source for ((index, argument) in oldList.arguments.withIndex()) { val replacement = when { - argument is FirPropertyAccessExpression && argument.calleeReference.isError() -> argument + argument is FirPropertyAccessExpression && argument.calleeReference.let { it.isError() || it is FirResolvedNamedReference } -> argument else -> newArguments[index] } diff --git a/analysis/low-level-api-fir/testData/lazyResolve/classes/compilerRequiredAnnotationConflict.txt b/analysis/low-level-api-fir/testData/lazyResolve/classes/compilerRequiredAnnotationConflict.txt index 08899b0dfcd..ff95193fd59 100644 --- a/analysis/low-level-api-fir/testData/lazyResolve/classes/compilerRequiredAnnotationConflict.txt +++ b/analysis/low-level-api-fir/testData/lazyResolve/classes/compilerRequiredAnnotationConflict.txt @@ -269,31 +269,27 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict.kt LAZY_super } - @R|kotlin/annotation/Target|[Types](Q|Some.AnnotationTarget|.< - Annotation symbol resolved differently on compiler annotation and symbols stages: - - compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.CLASS - - compiler arguments stage: FirEnumEntrySymbol /Some.AnnotationTarget.CLASS - >#) public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] annotation class Ann : R|kotlin/Annotation| { + @R|kotlin/annotation/Target|[Types](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.CLASS|) public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] annotation class Ann : R|kotlin/Annotation| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| { LAZY_super } } - public final [ResolvedTo(STATUS)] enum class AnnotationTarget : R|kotlin/Enum| { - private [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| { + public? final? [ResolvedTo(RAW_FIR)] enum class AnnotationTarget : R|kotlin/Enum| { + private [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| { LAZY_super|> } - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget| - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array| { + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget| + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array| { } - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(STATUS)] value: R|kotlin/String|): R|Some.AnnotationTarget| { + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(RAW_FIR)] value: R|kotlin/String|): R|Some.AnnotationTarget| { } - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries| - public [ResolvedTo(STATUS)] get(): R|kotlin/enums/EnumEntries| + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries| + public [ResolvedTo(RAW_FIR)] get(): R|kotlin/enums/EnumEntries| } @@ -306,31 +302,27 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict.kt LAZY_super } - @R|kotlin/annotation/Target|[Types](Q|Some.AnnotationTarget|.< - Annotation symbol resolved differently on compiler annotation and symbols stages: - - compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.CLASS - - compiler arguments stage: FirEnumEntrySymbol /Some.AnnotationTarget.CLASS - >#) public final [ResolvedTo(CONTRACTS)] annotation class Ann : R|kotlin/Annotation| { + @R|kotlin/annotation/Target|[Types](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.CLASS|) public final [ResolvedTo(CONTRACTS)] annotation class Ann : R|kotlin/Annotation| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| { LAZY_super } } - public final [ResolvedTo(STATUS)] enum class AnnotationTarget : R|kotlin/Enum| { - private [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| { + public? final? [ResolvedTo(RAW_FIR)] enum class AnnotationTarget : R|kotlin/Enum| { + private [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| { LAZY_super|> } - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget| - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array| { + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget| + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array| { } - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(STATUS)] value: R|kotlin/String|): R|Some.AnnotationTarget| { + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(RAW_FIR)] value: R|kotlin/String|): R|Some.AnnotationTarget| { } - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries| - public [ResolvedTo(STATUS)] get(): R|kotlin/enums/EnumEntries| + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries| + public [ResolvedTo(RAW_FIR)] get(): R|kotlin/enums/EnumEntries| } @@ -343,31 +335,27 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict.kt LAZY_super } - @R|kotlin/annotation/Target|[Types](Q|Some.AnnotationTarget|.< - Annotation symbol resolved differently on compiler annotation and symbols stages: - - compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.CLASS - - compiler arguments stage: FirEnumEntrySymbol /Some.AnnotationTarget.CLASS - >#) public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| { + @R|kotlin/annotation/Target|[Types](Q|kotlin/annotation/AnnotationTarget|.R|kotlin/annotation/AnnotationTarget.CLASS|) public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| { LAZY_super } } - public final [ResolvedTo(STATUS)] enum class AnnotationTarget : R|kotlin/Enum| { - private [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| { + public? final? [ResolvedTo(RAW_FIR)] enum class AnnotationTarget : R|kotlin/Enum| { + private [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] constructor(): R|Some.AnnotationTarget| { LAZY_super|> } - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget| - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array| { + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] enum entry CLASS: R|Some.AnnotationTarget| + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun values(): R|kotlin/Array| { } - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(STATUS)] value: R|kotlin/String|): R|Some.AnnotationTarget| { + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] fun valueOf([ResolvedTo(RAW_FIR)] value: R|kotlin/String|): R|Some.AnnotationTarget| { } - public final static [ResolvedTo(STATUS)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries| - public [ResolvedTo(STATUS)] get(): R|kotlin/enums/EnumEntries| + public final static [ResolvedTo(RAW_FIR)] [ContainingClassKey=AnnotationTarget] val entries: R|kotlin/enums/EnumEntries| + public [ResolvedTo(RAW_FIR)] get(): R|kotlin/enums/EnumEntries| } diff --git a/analysis/low-level-api-fir/testData/lazyResolve/classes/compilerRequiredAnnotationConflict2.txt b/analysis/low-level-api-fir/testData/lazyResolve/classes/compilerRequiredAnnotationConflict2.txt index a07873ddb76..6f5c9c307cb 100644 --- a/analysis/low-level-api-fir/testData/lazyResolve/classes/compilerRequiredAnnotationConflict2.txt +++ b/analysis/low-level-api-fir/testData/lazyResolve/classes/compilerRequiredAnnotationConflict2.txt @@ -157,11 +157,7 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt LAZY_super } - @R|kotlin/annotation/Target|[Types](< - Annotation symbol resolved differently on compiler annotation and symbols stages: - - compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD - - compiler arguments stage: null - >#) public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] annotation class Ann : R|kotlin/Annotation| { + @R|kotlin/annotation/Target|[Types](R|kotlin/annotation/AnnotationTarget.FIELD|) public final [ResolvedTo(ARGUMENTS_OF_ANNOTATIONS)] annotation class Ann : R|kotlin/Annotation| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| { LAZY_super } @@ -180,11 +176,7 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt LAZY_super } - @R|kotlin/annotation/Target|[Types](< - Annotation symbol resolved differently on compiler annotation and symbols stages: - - compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD - - compiler arguments stage: null - >#) public final [ResolvedTo(CONTRACTS)] annotation class Ann : R|kotlin/Annotation| { + @R|kotlin/annotation/Target|[Types](R|kotlin/annotation/AnnotationTarget.FIELD|) public final [ResolvedTo(CONTRACTS)] annotation class Ann : R|kotlin/Annotation| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| { LAZY_super } @@ -203,11 +195,7 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt LAZY_super } - @R|kotlin/annotation/Target|[Types](< - Annotation symbol resolved differently on compiler annotation and symbols stages: - - compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD - - compiler arguments stage: null - >#) public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| { + @R|kotlin/annotation/Target|[Types](R|kotlin/annotation/AnnotationTarget.FIELD|) public final [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| { LAZY_super } @@ -226,19 +214,19 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt LAZY_super } - @R|kotlin/annotation/Target|[Types](allowedTargets = vararg(< + @R|kotlin/annotation/Target|[Types](allowedTargets = this@R|/Some|.< Annotation symbol resolved differently on compiler annotation and symbols stages: - compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD - - compiler arguments stage: null - >#)) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] annotation class Ann : R|kotlin/Annotation| { + - compiler arguments stage: FirPropertySymbol /Some.FIELD + >#) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] annotation class Ann : R|kotlin/Annotation| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| { LAZY_super } } - public final const [ResolvedTo(STATUS)] val FIELD: = LAZY_EXPRESSION - public [ResolvedTo(STATUS)] [ContainingClassKey=Some] get(): + public final const [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] val FIELD: R|kotlin/String| = String() + public [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] [ContainingClassKey=Some] get(): R|kotlin/String| } @@ -249,19 +237,19 @@ FILE: [ResolvedTo(IMPORTS)] compilerRequiredAnnotationConflict2.kt LAZY_super } - @R|kotlin/annotation/Target|[Types](allowedTargets = vararg(< + @R|kotlin/annotation/Target|[Types](allowedTargets = this@R|/Some|.< Annotation symbol resolved differently on compiler annotation and symbols stages: - compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD - - compiler arguments stage: null - >#)) public final [ResolvedTo(BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| { + - compiler arguments stage: FirPropertySymbol /Some.FIELD + >#) public final [ResolvedTo(BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| { public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| { super() } } - public final const [ResolvedTo(STATUS)] val FIELD: = LAZY_EXPRESSION - public [ResolvedTo(STATUS)] [ContainingClassKey=Some] get(): + public final const [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] val FIELD: R|kotlin/String| = String() + public [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] [ContainingClassKey=Some] get(): R|kotlin/String| } @@ -272,11 +260,11 @@ FILE: [ResolvedTo(BODY_RESOLVE)] compilerRequiredAnnotationConflict2.kt super() } - @R|kotlin/annotation/Target|[Types](allowedTargets = vararg(< + @R|kotlin/annotation/Target|[Types](allowedTargets = this@R|/Some|.< Annotation symbol resolved differently on compiler annotation and symbols stages: - compiler annotations: FirEnumEntrySymbol kotlin/annotation/AnnotationTarget.FIELD - - compiler arguments stage: null - >#)) public final [ResolvedTo(BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| { + - compiler arguments stage: FirPropertySymbol /Some.FIELD + >#) public final [ResolvedTo(BODY_RESOLVE)] annotation class Ann : R|kotlin/Annotation| { public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Ann] constructor(): R|Some.Ann| { super() } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt index 600c1d68452..7e42b21df1b 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirDeclarationsResolveTransformer.kt @@ -630,18 +630,21 @@ open class FirDeclarationsResolveTransformer( override fun transformRegularClass( regularClass: FirRegularClass, - data: ResolutionMode - ): FirRegularClass = - whileAnalysing(session, regularClass) { - return context.withContainingClass(regularClass) { - if (regularClass.isLocal && regularClass !in context.targetedLocalClasses) { - return regularClass.runAllPhasesForLocalClass(transformer, components, data, transformer.firResolveContextCollector) - } - - doTransformTypeParameters(regularClass) - doTransformRegularClass(regularClass, data) + data: ResolutionMode, + ): FirRegularClass = whileAnalysing(session, regularClass) { + context.withContainingClass(regularClass) { + val isLocal = regularClass.isLocal + if (isLocal && regularClass !in context.targetedLocalClasses) { + return regularClass.runAllPhasesForLocalClass(transformer, components, data, transformer.firResolveContextCollector) } + + if (isLocal || !implicitTypeOnly) { + doTransformTypeParameters(regularClass) + } + + doTransformRegularClass(regularClass, data) } + } fun withScript(script: FirScript, action: () -> FirScript): FirScript { dataFlowAnalyzer.enterScript(script) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirImplicitBodyResolve.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirImplicitBodyResolve.kt index c742f35214c..a101e30451d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirImplicitBodyResolve.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirImplicitBodyResolve.kt @@ -125,6 +125,18 @@ open class FirImplicitAwareBodyResolveTransformer( outerBodyResolveContext, firResolveContextCollector ) { + /** + * This is required to avoid transformations of class annotations + */ + override fun transformDeclarationContent( + declaration: FirDeclaration, + data: ResolutionMode, + ): FirDeclaration = if (implicitTypeOnly && declaration is FirRegularClass && !declaration.isLocal) { + declaration.transformDeclarations(this, data) + } else { + super.transformDeclarationContent(declaration, data) + } + override fun transformSimpleFunction( simpleFunction: FirSimpleFunction, data: ResolutionMode diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt index 876cf770e76..e9374423149 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/plugin/FirAnnotationArgumentsMappingTransformer.kt @@ -5,17 +5,32 @@ package org.jetbrains.kotlin.fir.resolve.transformers.plugin +import org.jetbrains.kotlin.KtSourceElement import org.jetbrains.kotlin.fir.FirSession +import org.jetbrains.kotlin.fir.containingClassLookupTag import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirErrorAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirPropertyAccessExpression +import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression +import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier import org.jetbrains.kotlin.fir.expressions.FirStatement +import org.jetbrains.kotlin.fir.expressions.builder.buildPropertyAccessExpression +import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference +import org.jetbrains.kotlin.fir.references.builder.buildErrorNamedReference +import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference +import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession +import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeAmbiguouslyResolvedAnnotationArgument import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculator import org.jetbrains.kotlin.fir.resolve.transformers.ReturnTypeCalculatorForFullBodyResolve import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.* +import org.jetbrains.kotlin.fir.symbols.impl.FirEnumEntrySymbol import org.jetbrains.kotlin.fir.visitors.transformSingle +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.util.PrivateForInline open class FirAnnotationArgumentsMappingTransformer( @@ -64,6 +79,11 @@ open class FirAnnotationArgumentsMappingTransformer( } } +/** + * Set of enum class IDs that are resolved in COMPILER_REQUIRED_ANNOTATIONS phase that need to be rechecked here. + */ +private val classIdsToCheck: Set = setOf(StandardClassIds.DeprecationLevel, StandardClassIds.AnnotationTarget) + private class FirExpressionTransformerForAnnotationArgumentsMapping( private val annotationArgumentsMappingTransformer: FirAnnotationArgumentsMappingTransformer, ) : FirExpressionsResolveTransformer(annotationArgumentsMappingTransformer) { @@ -80,6 +100,81 @@ private class FirExpressionTransformerForAnnotationArgumentsMapping( } } + override fun transformQualifiedAccessExpression( + qualifiedAccessExpression: FirQualifiedAccessExpression, + data: ResolutionMode + ): FirStatement { + if (qualifiedAccessExpression is FirPropertyAccessExpression) { + val calleeReference = qualifiedAccessExpression.calleeReference + if (calleeReference is FirResolvedNamedReference) { + val resolvedSymbol = calleeReference.resolvedSymbol + if (resolvedSymbol is FirEnumEntrySymbol && resolvedSymbol.containingClassLookupTag()?.classId in classIdsToCheck) { + return resolveSpecialPropertyAccess(qualifiedAccessExpression, calleeReference, resolvedSymbol, data) + } + } + } + + return super.transformQualifiedAccessExpression(qualifiedAccessExpression, data) + } + + private fun resolveSpecialPropertyAccess( + originalAccess: FirPropertyAccessExpression, + originalCalleeReference: FirResolvedNamedReference, + originalResolvedSymbol: FirEnumEntrySymbol, + data: ResolutionMode, + ): FirStatement { + val accessCopyForResolution = buildPropertyAccessExpression { + source = originalAccess.source + typeArguments.addAll(originalAccess.typeArguments) + + val originalResolvedQualifier = originalAccess.explicitReceiver + if (originalResolvedQualifier is FirResolvedQualifier) { + val fqName = originalResolvedQualifier.classId + ?.let { if (originalResolvedQualifier.isFullyQualified) it.asSingleFqName() else it.relativeClassName } + ?: originalResolvedQualifier.packageFqName + explicitReceiver = generatePropertyAccessExpression(fqName, originalResolvedQualifier.source) + } + + calleeReference = buildSimpleNamedReference { + source = originalCalleeReference.source + name = originalCalleeReference.name + } + } + + val resolved = super.transformQualifiedAccessExpression(accessCopyForResolution, data) + + if (resolved is FirQualifiedAccessExpression) { + // The initial resolution must have been to an enum entry. Report ambiguity if symbolFromArgumentsPhase is different to + // original symbol including null (meaning we would resolve to something other than an enum entry). + val symbolFromArgumentsPhase = resolved.calleeReference.toResolvedBaseSymbol() + if (originalResolvedSymbol != symbolFromArgumentsPhase) { + resolved.replaceCalleeReference(buildErrorNamedReference { + source = resolved.calleeReference.source + diagnostic = ConeAmbiguouslyResolvedAnnotationArgument(originalResolvedSymbol, symbolFromArgumentsPhase) + }) + } + } + + return resolved + } + + private fun generatePropertyAccessExpression(fqName: FqName, accessSource: KtSourceElement?): FirPropertyAccessExpression { + var result: FirPropertyAccessExpression? = null + + val pathSegments = fqName.pathSegments() + for ((index, pathSegment) in pathSegments.withIndex()) { + result = buildPropertyAccessExpression { + calleeReference = buildSimpleNamedReference { name = pathSegment } + explicitReceiver = result + + if (index == pathSegments.lastIndex) { + source = accessSource + } + } + } + + return result ?: error("Got an empty ClassId") + } } private class FirDeclarationsResolveTransformerForAnnotationArgumentsMapping( @@ -92,9 +187,11 @@ private class FirDeclarationsResolveTransformerForAnnotationArgumentsMapping( } override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): FirRegularClass { - regularClass.transformAnnotations(this, data) - doTransformTypeParameters(regularClass) - regularClass.transformSuperTypeRefs(this, data) + context.insideClassHeader { + regularClass.transformAnnotations(this, ResolutionMode.ContextIndependent) + regularClass.transformTypeParameters(this, ResolutionMode.ContextIndependent) + regularClass.transformSuperTypeRefs(this, ResolutionMode.ContextIndependent) + } doTransformRegularClass(regularClass, data) return regularClass 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 0d5803905df..509c508913d 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 @@ -314,90 +314,9 @@ abstract class AbstractFirExpressionsResolveTransformerForAnnotations(transforme } } -/** - * Set of enum class IDs that are resolved in COMPILER_REQUIRED_ANNOTATIONS phase that need to be rechecked here. - */ -private val classIdsToCheck: Set = setOf(StandardClassIds.DeprecationLevel, StandardClassIds.AnnotationTarget) - private class FirExpressionsResolveTransformerForSpecificAnnotations(transformer: FirAbstractBodyResolveTransformerDispatcher) : AbstractFirExpressionsResolveTransformerForAnnotations(transformer) { - override fun transformQualifiedAccessExpression( - qualifiedAccessExpression: FirQualifiedAccessExpression, - data: ResolutionMode - ): FirStatement { - if (qualifiedAccessExpression is FirPropertyAccessExpression) { - val calleeReference = qualifiedAccessExpression.calleeReference - if (calleeReference is FirResolvedNamedReference) { - val resolvedSymbol = calleeReference.resolvedSymbol - if (resolvedSymbol is FirEnumEntrySymbol && resolvedSymbol.containingClassLookupTag()?.classId in classIdsToCheck) { - return resolveSpecialPropertyAccess(qualifiedAccessExpression, calleeReference, resolvedSymbol, data) - } - } - } - - return super.transformQualifiedAccessExpression(qualifiedAccessExpression, data) - } - - private fun resolveSpecialPropertyAccess( - originalAccess: FirPropertyAccessExpression, - originalCalleeReference: FirResolvedNamedReference, - originalResolvedSymbol: FirEnumEntrySymbol, - data: ResolutionMode, - ): FirStatement { - val accessCopyForResolution = buildPropertyAccessExpression { - source = originalAccess.source - typeArguments.addAll(originalAccess.typeArguments) - - val originalResolvedQualifier = originalAccess.explicitReceiver - if (originalResolvedQualifier is FirResolvedQualifier) { - val fqName = originalResolvedQualifier.classId - ?.let { if (originalResolvedQualifier.isFullyQualified) it.asSingleFqName() else it.relativeClassName } - ?: originalResolvedQualifier.packageFqName - explicitReceiver = generatePropertyAccessExpression(fqName, originalResolvedQualifier.source) - } - - calleeReference = buildSimpleNamedReference { - source = originalCalleeReference.source - name = originalCalleeReference.name - } - } - - val resolved = super.transformQualifiedAccessExpression(accessCopyForResolution, data) - - if (resolved is FirQualifiedAccessExpression) { - // The initial resolution must have been to an enum entry. Report ambiguity if symbolFromArgumentsPhase is different to - // original symbol including null (meaning we would resolve to something other than an enum entry). - val symbolFromArgumentsPhase = resolved.calleeReference.toResolvedBaseSymbol() - if (originalResolvedSymbol != symbolFromArgumentsPhase) { - resolved.replaceCalleeReference(buildErrorNamedReference { - source = resolved.calleeReference.source - diagnostic = ConeAmbiguouslyResolvedAnnotationArgument(originalResolvedSymbol, symbolFromArgumentsPhase) - }) - } - } - - return resolved - } - - private fun generatePropertyAccessExpression(fqName: FqName, accessSource: KtSourceElement?): FirPropertyAccessExpression { - var result: FirPropertyAccessExpression? = null - - val pathSegments = fqName.pathSegments() - for ((index, pathSegment) in pathSegments.withIndex()) { - result = buildPropertyAccessExpression { - calleeReference = buildSimpleNamedReference { name = pathSegment } - explicitReceiver = result - - if (index == pathSegments.lastIndex) { - source = accessSource - } - } - } - - return result ?: error("Got an empty ClassId") - } - override fun resolveQualifiedAccessAndSelectCandidate( qualifiedAccessExpression: FirQualifiedAccessExpression, isUsedAsReceiver: Boolean, diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.fir.kt index 42b6cd5a77f..c2bcf8da194 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationTargetResolvedAmbiguously.fir.kt @@ -8,7 +8,7 @@ object Some { CLASS } - @Target(FIELD) + @Target(FIELD) annotation class Ann2 const val FIELD = ""