From 41dd00c2419870f4d2072fff8eaad4424596109e Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Mon, 6 Jun 2022 15:15:05 +0300 Subject: [PATCH] FIR: Use outer scope for annotation arguments resolution ^KT-41980 Fixed --- .../resolve/FirRegularTowerDataContexts.kt | 6 +++++- .../body/resolve/BodyResolveContext.kt | 11 ++++++++++ .../FirDeclarationsResolveTransformer.kt | 10 +++++----- .../FirExpressionsResolveTransformer.kt | 20 ++++++++++--------- .../classHeader/annotationOnClass.fir.kt | 18 ++++++++--------- 5 files changed, 41 insertions(+), 24 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirRegularTowerDataContexts.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirRegularTowerDataContexts.kt index 2a3a29c0639..003492d4569 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirRegularTowerDataContexts.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/FirRegularTowerDataContexts.kt @@ -11,6 +11,7 @@ import java.util.* enum class FirTowerDataMode { REGULAR, + CLASS_HEADER_ANNOTATIONS, NESTED_CLASS, COMPANION_OBJECT, CONSTRUCTOR_HEADER, @@ -26,6 +27,7 @@ class FirRegularTowerDataContexts private constructor( ) { constructor( regular: FirTowerDataContext, + forClassHeaderAnnotations: FirTowerDataContext? = null, forNestedClasses: FirTowerDataContext? = null, forCompanionObject: FirTowerDataContext? = null, forConstructorHeaders: FirTowerDataContext? = null, @@ -33,7 +35,7 @@ class FirRegularTowerDataContexts private constructor( primaryConstructorPureParametersScope: FirLocalScope? = null, primaryConstructorAllParametersScope: FirLocalScope? = null, ) : this( - enumMap(regular, forNestedClasses, forCompanionObject, forConstructorHeaders, forEnumEntries), + enumMap(regular, forClassHeaderAnnotations, forNestedClasses, forCompanionObject, forConstructorHeaders, forEnumEntries), primaryConstructorPureParametersScope, primaryConstructorAllParametersScope, FirTowerDataMode.REGULAR @@ -68,6 +70,7 @@ class FirRegularTowerDataContexts private constructor( companion object { private fun enumMap( regular: FirTowerDataContext, + forClassHeaderAnnotations: FirTowerDataContext?, forNestedClasses: FirTowerDataContext?, forCompanionObject: FirTowerDataContext?, forConstructorHeaders: FirTowerDataContext?, @@ -75,6 +78,7 @@ class FirRegularTowerDataContexts private constructor( ): EnumMap { val modeMap = EnumMap(FirTowerDataMode::class.java) modeMap[FirTowerDataMode.REGULAR] = regular + modeMap[FirTowerDataMode.CLASS_HEADER_ANNOTATIONS] = forClassHeaderAnnotations modeMap[FirTowerDataMode.NESTED_CLASS] = forNestedClasses modeMap[FirTowerDataMode.COMPANION_OBJECT] = forCompanionObject modeMap[FirTowerDataMode.CONSTRUCTOR_HEADER] = forConstructorHeaders 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 1d165ef5277..75fff853075 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 @@ -478,6 +478,7 @@ class BodyResolveContext( val newContexts = FirRegularTowerDataContexts( forMembersResolution, + forClassHeaderAnnotations = base, newTowerDataContextForStaticNestedClasses, statics, scopeForConstructorHeader, @@ -655,6 +656,16 @@ class BodyResolveContext( f: () -> T ): T = withTowerDataMode(FirTowerDataMode.ENUM_ENTRY, f) + @OptIn(PrivateForInline::class) + inline fun forAnnotation( + f: () -> T + ): T { + return when (containerIfAny) { + is FirRegularClass -> withTowerDataMode(FirTowerDataMode.CLASS_HEADER_ANNOTATIONS, f) + else -> f() + } + } + @OptIn(PrivateForInline::class) inline fun withAnonymousInitializer( anonymousInitializer: FirAnonymousInitializer, 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 a04492a4623..414cc954deb 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 @@ -685,12 +685,12 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor dataFlowAnalyzer.enterFunction(constructor) - constructor.transformTypeParameters(transformer, data) - .transformAnnotations(transformer, data) - .transformReceiverTypeRef(transformer, data) - .transformReturnTypeRef(transformer, data) - context.withConstructor(constructor) { + constructor.transformTypeParameters(transformer, data) + .transformAnnotations(transformer, data) + .transformReceiverTypeRef(transformer, data) + .transformReturnTypeRef(transformer, data) + context.forConstructorParameters(constructor, owningClass, components) { constructor.transformValueParameters(transformer, data) } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt index 74f0654b916..716dc7fc12e 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirExpressionsResolveTransformer.kt @@ -1021,15 +1021,17 @@ open class FirExpressionsResolveTransformer(transformer: FirBodyResolveTransform override fun transformAnnotationCall(annotationCall: FirAnnotationCall, data: ResolutionMode): FirStatement { if (annotationCall.resolved) return annotationCall annotationCall.transformAnnotationTypeRef(transformer, ResolutionMode.ContextIndependent) - return withFirArrayOfCallTransformer { - dataFlowAnalyzer.enterAnnotation(annotationCall) - val result = callResolver.resolveAnnotationCall(annotationCall) - dataFlowAnalyzer.exitAnnotation(result ?: annotationCall) - if (result == null) return annotationCall - callCompleter.completeCall(result, noExpectedType) - // TODO: FirBlackBoxCodegenTestGenerated.Annotations.testDelegatedPropertySetter, it fails with hard cast - (result.argumentList as? FirResolvedArgumentList)?.let { annotationCall.replaceArgumentMapping((it).toAnnotationArgumentMapping()) } - annotationCall + return context.forAnnotation { + withFirArrayOfCallTransformer { + dataFlowAnalyzer.enterAnnotation(annotationCall) + val result = callResolver.resolveAnnotationCall(annotationCall) + dataFlowAnalyzer.exitAnnotation(result ?: annotationCall) + if (result == null) return annotationCall + callCompleter.completeCall(result, noExpectedType) + // TODO: FirBlackBoxCodegenTestGenerated.Annotations.testDelegatedPropertySetter, it fails with hard cast + (result.argumentList as? FirResolvedArgumentList)?.let { annotationCall.replaceArgumentMapping((it).toAnnotationArgumentMapping()) } + annotationCall + } } } diff --git a/compiler/testData/diagnostics/tests/scopes/classHeader/annotationOnClass.fir.kt b/compiler/testData/diagnostics/tests/scopes/classHeader/annotationOnClass.fir.kt index a53fac7af81..cc5e64f33f7 100644 --- a/compiler/testData/diagnostics/tests/scopes/classHeader/annotationOnClass.fir.kt +++ b/compiler/testData/diagnostics/tests/scopes/classHeader/annotationOnClass.fir.kt @@ -15,15 +15,15 @@ annotation class Ann( ) @Ann( - Nested::class, - Inner::class, - Interface::class, - CONST, - Companion.CONST, - Nested.CONST, - Interface.CONST, - a, - b() + Nested::class, + Inner::class, + Interface::class, + CONST, + Companion.CONST, + Nested.CONST, + Interface.CONST, + a, + b() ) class A {