diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentsLazyResolver.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentsLazyResolver.kt index fa323eccc1a..1eb91390ab7 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentsLazyResolver.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/transformers/LLFirAnnotationArgumentsLazyResolver.kt @@ -12,7 +12,6 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.lazy.resolve.FirLazyBodie import org.jetbrains.kotlin.fir.FirElementWithResolveState import org.jetbrains.kotlin.fir.FirFileAnnotationsContainer import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.util.PrivateForInline import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.resolve.ResolutionMode import org.jetbrains.kotlin.fir.resolve.ScopeSession @@ -20,6 +19,7 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveCon import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirResolveContextCollector import org.jetbrains.kotlin.fir.resolve.transformers.plugin.FirAnnotationArgumentsResolveTransformer import org.jetbrains.kotlin.fir.visitors.transformSingle +import org.jetbrains.kotlin.util.PrivateForInline internal object LLFirAnnotationArgumentsLazyResolver : LLFirLazyResolver(FirResolvePhase.ARGUMENTS_OF_ANNOTATIONS) { override fun resolve( @@ -154,9 +154,17 @@ private class LLFirAnnotationArgumentsTargetResolver( internal fun LLFirAbstractBodyTargetResolver.transformAnnotations(target: FirElementWithResolveState) { when { target is FirRegularClass -> transformer.declarationsTransformer?.let { declarationsTransformer -> - target.transformAnnotations(declarationsTransformer, ResolutionMode.ContextIndependent) - target.transformTypeParameters(declarationsTransformer, ResolutionMode.ContextIndependent) - target.transformSuperTypeRefs(declarationsTransformer, ResolutionMode.ContextIndependent) + if (this is LLFirAnnotationArgumentsTargetResolver) { + target.transformAnnotations(declarationsTransformer, ResolutionMode.ContextIndependent) + target.transformTypeParameters(declarationsTransformer, ResolutionMode.ContextIndependent) + target.transformSuperTypeRefs(declarationsTransformer, ResolutionMode.ContextIndependent) + } else { + declarationsTransformer.context.insideClassHeader { + target.transformAnnotations(declarationsTransformer, ResolutionMode.ContextIndependent) + target.transformTypeParameters(declarationsTransformer, ResolutionMode.ContextIndependent) + target.transformSuperTypeRefs(declarationsTransformer, ResolutionMode.ContextIndependent) + } + } } target is FirScript -> { diff --git a/analysis/low-level-api-fir/testData/lazyResolve/classes/annotationWithConstantFromNestedClass.txt b/analysis/low-level-api-fir/testData/lazyResolve/classes/annotationWithConstantFromNestedClass.txt index 0849622d989..0586a32df0d 100644 --- a/analysis/low-level-api-fir/testData/lazyResolve/classes/annotationWithConstantFromNestedClass.txt +++ b/analysis/low-level-api-fir/testData/lazyResolve/classes/annotationWithConstantFromNestedClass.txt @@ -404,10 +404,10 @@ FILE: [ResolvedTo(IMPORTS)] annotationWithConstantFromNestedClass.kt LAZY_super } - public final const [ResolvedTo(STATUS)] val CONSTANT_FROM_COMPANION: = LAZY_EXPRESSION - public [ResolvedTo(STATUS)] [ContainingClassKey=Companion] get(): + public final const [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] val CONSTANT_FROM_COMPANION: R|kotlin/Int| = Int(42) + public [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] [ContainingClassKey=Companion] get(): R|kotlin/Int| - @R|Anno|[Types](number = #) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class Nested : R|kotlin/Any| { + @R|Anno|[Types](number = this@R|/Outer.Companion|.R|/Outer.Companion.CONSTANT_FROM_COMPANION|) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class Nested : R|kotlin/Any| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Nested] constructor(): R|Outer.Companion.Nested| { LAZY_super } @@ -439,10 +439,10 @@ FILE: [ResolvedTo(IMPORTS)] annotationWithConstantFromNestedClass.kt LAZY_super } - public final const [ResolvedTo(STATUS)] val CONSTANT_FROM_COMPANION: = LAZY_EXPRESSION - public [ResolvedTo(STATUS)] [ContainingClassKey=Companion] get(): + public final const [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] val CONSTANT_FROM_COMPANION: R|kotlin/Int| = Int(42) + public [ResolvedTo(IMPLICIT_TYPES_BODY_RESOLVE)] [ContainingClassKey=Companion] get(): R|kotlin/Int| - @R|Anno|[Types](number = #) public final [ResolvedTo(BODY_RESOLVE)] class Nested : R|kotlin/Any| { + @R|Anno|[Types](number = this@R|/Outer.Companion|.R|/Outer.Companion.CONSTANT_FROM_COMPANION|) public final [ResolvedTo(BODY_RESOLVE)] class Nested : R|kotlin/Any| { public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Nested] constructor(): R|Outer.Companion.Nested| { super() } @@ -477,7 +477,7 @@ FILE: [ResolvedTo(BODY_RESOLVE)] annotationWithConstantFromNestedClass.kt public final const [ResolvedTo(BODY_RESOLVE)] val CONSTANT_FROM_COMPANION: R|kotlin/Int| = Int(42) public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Companion] get(): R|kotlin/Int| - @R|Anno|[Types](number = #) public final [ResolvedTo(BODY_RESOLVE)] class Nested : R|kotlin/Any| { + @R|Anno|[Types](number = this@R|/Outer.Companion|.R|/Outer.Companion.CONSTANT_FROM_COMPANION|) public final [ResolvedTo(BODY_RESOLVE)] class Nested : R|kotlin/Any| { public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Nested] constructor(): R|Outer.Companion.Nested| { super() } diff --git a/analysis/low-level-api-fir/testData/lazyResolve/classes/nestedClassAsAnnotationArgument.txt b/analysis/low-level-api-fir/testData/lazyResolve/classes/nestedClassAsAnnotationArgument.txt index ccbc7a6d2e8..f9c04179189 100644 --- a/analysis/low-level-api-fir/testData/lazyResolve/classes/nestedClassAsAnnotationArgument.txt +++ b/analysis/low-level-api-fir/testData/lazyResolve/classes/nestedClassAsAnnotationArgument.txt @@ -313,7 +313,7 @@ FILE: [ResolvedTo(IMPORTS)] nestedClassAsAnnotationArgument.kt LAZY_super } - @R|Special|[Types](why = (#)) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class Nested<@R|Special|[Types](why = (Q|Outer.Nested|)) [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] T> : R|@R|Special|(why = (#)) Interface| { + @R|Special|[Types](why = (Q|Outer.Nested|)) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class Nested<@R|Special|[Types](why = (Q|Outer.Nested|)) [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] T> : R|@R|Special|(why = (Q|Outer.Nested|)) Interface| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Nested] constructor<@R|Special|[Types](why = (Q|Outer.Nested|)) [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] T>(): R|Outer.Nested| { LAZY_super<> } @@ -340,7 +340,7 @@ FILE: [ResolvedTo(IMPORTS)] nestedClassAsAnnotationArgument.kt LAZY_super } - @R|Special|[Types](why = (#)) public final [ResolvedTo(BODY_RESOLVE)] class Nested<@R|Special|[Types](why = (Q|Outer.Nested|)) [ResolvedTo(BODY_RESOLVE)] T> : R|@R|Special|(why = (#)) Interface| { + @R|Special|[Types](why = (Q|Outer.Nested|)) public final [ResolvedTo(BODY_RESOLVE)] class Nested<@R|Special|[Types](why = (Q|Outer.Nested|)) [ResolvedTo(BODY_RESOLVE)] T> : R|@R|Special|(why = (Q|Outer.Nested|)) Interface| { public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Nested] constructor<@R|Special|[Types](why = (Q|Outer.Nested|)) [ResolvedTo(BODY_RESOLVE)] T>(): R|Outer.Nested| { super() } @@ -367,7 +367,7 @@ FILE: [ResolvedTo(BODY_RESOLVE)] nestedClassAsAnnotationArgument.kt super() } - @R|Special|[Types](why = (#)) public final [ResolvedTo(BODY_RESOLVE)] class Nested<@R|Special|[Types](why = (Q|Outer.Nested|)) [ResolvedTo(BODY_RESOLVE)] T> : R|@R|Special|(why = (#)) Interface| { + @R|Special|[Types](why = (Q|Outer.Nested|)) public final [ResolvedTo(BODY_RESOLVE)] class Nested<@R|Special|[Types](why = (Q|Outer.Nested|)) [ResolvedTo(BODY_RESOLVE)] T> : R|@R|Special|(why = (Q|Outer.Nested|)) Interface| { public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Nested] constructor<@R|Special|[Types](why = (Q|Outer.Nested|)) [ResolvedTo(BODY_RESOLVE)] T>(): R|Outer.Nested| { super() } diff --git a/analysis/low-level-api-fir/testData/lazyResolve/classes/nestedClassAsAnnotationArgument2.txt b/analysis/low-level-api-fir/testData/lazyResolve/classes/nestedClassAsAnnotationArgument2.txt index 2e16225982c..5a10ffcf04e 100644 --- a/analysis/low-level-api-fir/testData/lazyResolve/classes/nestedClassAsAnnotationArgument2.txt +++ b/analysis/low-level-api-fir/testData/lazyResolve/classes/nestedClassAsAnnotationArgument2.txt @@ -313,7 +313,7 @@ FILE: [ResolvedTo(IMPORTS)] nestedClassAsAnnotationArgument2.kt LAZY_super } - @R|Special|[Types](why = #) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class Nested<@R|Special|[Types](why = Q|Outer.Nested|) [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] T> : R|@R|Special|(why = #) Interface| { + @R|Special|[Types](why = Q|Outer.Nested|) public final [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] class Nested<@R|Special|[Types](why = Q|Outer.Nested|) [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] T> : R|@R|Special|(why = Q|Outer.Nested|) Interface| { public? [ResolvedTo(RAW_FIR)] [ContainingClassKey=Nested] constructor<@R|Special|[Types](why = Q|Outer.Nested|) [ResolvedTo(ANNOTATIONS_ARGUMENTS_MAPPING)] T>(): R|Outer.Nested| { LAZY_super<> } @@ -340,7 +340,7 @@ FILE: [ResolvedTo(IMPORTS)] nestedClassAsAnnotationArgument2.kt LAZY_super } - @R|Special|[Types](why = #) public final [ResolvedTo(BODY_RESOLVE)] class Nested<@R|Special|[Types](why = Q|Outer.Nested|) [ResolvedTo(BODY_RESOLVE)] T> : R|@R|Special|(why = #) Interface| { + @R|Special|[Types](why = Q|Outer.Nested|) public final [ResolvedTo(BODY_RESOLVE)] class Nested<@R|Special|[Types](why = Q|Outer.Nested|) [ResolvedTo(BODY_RESOLVE)] T> : R|@R|Special|(why = Q|Outer.Nested|) Interface| { public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Nested] constructor<@R|Special|[Types](why = Q|Outer.Nested|) [ResolvedTo(BODY_RESOLVE)] T>(): R|Outer.Nested| { super() } @@ -367,7 +367,7 @@ FILE: [ResolvedTo(BODY_RESOLVE)] nestedClassAsAnnotationArgument2.kt super() } - @R|Special|[Types](why = #) public final [ResolvedTo(BODY_RESOLVE)] class Nested<@R|Special|[Types](why = Q|Outer.Nested|) [ResolvedTo(BODY_RESOLVE)] T> : R|@R|Special|(why = #) Interface| { + @R|Special|[Types](why = Q|Outer.Nested|) public final [ResolvedTo(BODY_RESOLVE)] class Nested<@R|Special|[Types](why = Q|Outer.Nested|) [ResolvedTo(BODY_RESOLVE)] T> : R|@R|Special|(why = Q|Outer.Nested|) Interface| { public [ResolvedTo(BODY_RESOLVE)] [ContainingClassKey=Nested] constructor<@R|Special|[Types](why = Q|Outer.Nested|) [ResolvedTo(BODY_RESOLVE)] T>(): R|Outer.Nested| { super() } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt index 39a7f9ac33c..20f24b76225 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt @@ -90,6 +90,24 @@ class BodyResolveContext( @set:PrivateForInline var inferenceSession: FirInferenceSession = FirInferenceSession.DEFAULT + /** + * This is required to avoid changing current mode into [FirTowerDataMode.CLASS_HEADER_ANNOTATIONS]. + * E.g., we can visit the same annotation in two ways – during a class visiting and outside of this class + */ + @set:PrivateForInline + var insideClassHeader: Boolean = false + + @OptIn(PrivateForInline::class) + inline fun insideClassHeader(action: () -> Unit) { + val old = insideClassHeader + insideClassHeader = true + try { + action() + } finally { + insideClassHeader = old + } + } + /** * CS for an outer type system if it's relevant, for example, in the case of `val x by myGenericDelegateCall()`, * relevant `getValue` call is expected to be resolved in the context of an outer CS built from `myGenericDelegateCall()` and @@ -751,8 +769,8 @@ class BodyResolveContext( inline fun forAnnotation( f: () -> T ): T { - return when (containerIfAny) { - is FirRegularClass -> withTowerDataMode(FirTowerDataMode.CLASS_HEADER_ANNOTATIONS, f) + return when { + containerIfAny is FirRegularClass && !insideClassHeader -> withTowerDataMode(FirTowerDataMode.CLASS_HEADER_ANNOTATIONS, f) else -> f() } } diff --git a/compiler/testData/diagnostics/tests/annotations/constantFromOuterScopeAsAnnotaionParameter.ll.kt b/compiler/testData/diagnostics/tests/annotations/constantFromOuterScopeAsAnnotaionParameter.ll.kt deleted file mode 100644 index cfc04908357..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/constantFromOuterScopeAsAnnotaionParameter.ll.kt +++ /dev/null @@ -1,14 +0,0 @@ -// LL_FIR_DIVERGENCE -// KT-62587 -// LL_FIR_DIVERGENCE -// FIR_IDENTICAL -annotation class Anno(val number: Int) - -class Outer { - companion object { - const val CONSTANT_FROM_COMPANION = 42 - - @Anno(CONSTANT_FROM_COMPANION) - class Nested - } -} diff --git a/compiler/testData/diagnostics/tests/annotations/nestedClassAsAnnotationParameter.ll.kt b/compiler/testData/diagnostics/tests/annotations/nestedClassAsAnnotationParameter.ll.kt deleted file mode 100644 index 8c411b52b0e..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/nestedClassAsAnnotationParameter.ll.kt +++ /dev/null @@ -1,15 +0,0 @@ -// LL_FIR_DIVERGENCE -// KT-62587 -// LL_FIR_DIVERGENCE -// FIR_IDENTICAL -import kotlin.reflect.KClass - -@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPE) -annotation class Special(val why: KClass<*>) - -interface Interface - -class Outer { - @Special(Nested::class) - class Nested<@Special(Nested::class) T> : @Special(Nested::class) Interface -} diff --git a/compiler/testData/diagnostics/tests/annotations/nestedClassAsIsAsAnnotationParameter.ll.kt b/compiler/testData/diagnostics/tests/annotations/nestedClassAsIsAsAnnotationParameter.ll.kt deleted file mode 100644 index 041d4262185..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/nestedClassAsIsAsAnnotationParameter.ll.kt +++ /dev/null @@ -1,14 +0,0 @@ -// LL_FIR_DIVERGENCE -// KT-62587 -// LL_FIR_DIVERGENCE -import kotlin.reflect.KClass - -@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.TYPE) -annotation class Special(val why: KClass<*>) - -interface Interface - -class Outer { - @Special(Nested) - class Nested<@Special(Nested) T> : @Special(Nested) Interface -} diff --git a/compiler/testData/diagnostics/tests/annotations/nestedObjectAsAnnotationParameter.ll.kt b/compiler/testData/diagnostics/tests/annotations/nestedObjectAsAnnotationParameter.ll.kt deleted file mode 100644 index 714b4592ce4..00000000000 --- a/compiler/testData/diagnostics/tests/annotations/nestedObjectAsAnnotationParameter.ll.kt +++ /dev/null @@ -1,15 +0,0 @@ -// LL_FIR_DIVERGENCE -// KT-62587 -// LL_FIR_DIVERGENCE -// FIR_IDENTICAL -import kotlin.reflect.KClass - -@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE) -annotation class Special(val why: KClass<*>) - -interface Interface - -object Outer { - @Special(Nested::class) - object Nested : @Special(Nested::class) Interface -}