From 94193c91a00e5001f6fed0ef511f7a13f8a4afcf Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Thu, 19 Mar 2020 13:23:44 +0300 Subject: [PATCH] FIR: Refactor designated body transformers The idea is making their mechanics more transparent and clear Namely, we should move to the next level of designation only for declaration's content Otherwise there might be some wrong steps when somebody just randomly calls "transformElement" on the parent declaration. For example, it happens for local classes when we resolve their supertypes, etc. --- .../body/resolve/FirBodyResolveTransformer.kt | 10 +++++++++- .../FirDeclarationsResolveTransformer.kt | 16 +++++++++------- .../body/resolve/FirImplicitBodyResolve.kt | 17 +++++------------ .../kotlin/idea/fir/FirResolutionApi.kt | 12 +++--------- 4 files changed, 26 insertions(+), 29 deletions(-) diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt index 9669f06661a..a8e8943b002 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/FirBodyResolveTransformer.kt @@ -46,7 +46,9 @@ open class FirBodyResolveTransformer( packageFqName = file.packageFqName return withScopeCleanup(context.fileImportsScope) { context.fileImportsScope.addImportingScopes(file, session, components.scopeSession) - super.transformFile(file, data) + file.replaceResolvePhase(transformerPhase) + @Suppress("UNCHECKED_CAST") + transformDeclarationContent(file, data) as CompositeTransformResult } } @@ -182,6 +184,12 @@ open class FirBodyResolveTransformer( return declarationsTransformer.transformDeclaration(declaration, data) } + open fun transformDeclarationContent( + declaration: FirDeclaration, data: ResolutionMode + ): CompositeTransformResult { + return transformElement(declaration, data) + } + override fun transformDeclarationStatus( declarationStatus: FirDeclarationStatus, data: ResolutionMode 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 822a2d71791..6eaf893b5b5 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 @@ -38,10 +38,12 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) private var containingClass: FirRegularClass? = null - override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult { + private fun transformDeclarationContent( + declaration: FirDeclaration, data: ResolutionMode + ): CompositeTransformResult { return context.withContainer(declaration) { declaration.replaceResolvePhase(transformerPhase) - transformer.transformElement(declaration, data) + transformer.transformDeclarationContent(declaration, data) } } @@ -327,7 +329,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) scope } } - transformDeclaration(regularClass, data) + transformDeclarationContent(regularClass, data) } containingClass = oldContainingClass primaryConstructorParametersScope = oldConstructorScope @@ -344,7 +346,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) this.type = type } val result = withLabelAndReceiverType(null, anonymousObject, type) { - transformDeclaration(anonymousObject, data) + transformDeclarationContent(anonymousObject, data) } dataFlowAnalyzer.exitAnonymousObject(result.single as FirAnonymousObject) @Suppress("UNCHECKED_CAST") @@ -447,7 +449,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) addLocalScope(FirLocalScope()) dataFlowAnalyzer.enterFunction(function) @Suppress("UNCHECKED_CAST") - transformDeclaration(function, data).also { + transformDeclarationContent(function, data).also { val result = it.single as FirFunction<*> dataFlowAnalyzer.exitFunction(result)?.let { controlFlowGraph -> result.transformControlFlowGraphReference(ControlFlowGraphReferenceTransformer, controlFlowGraph) @@ -471,7 +473,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) dataFlowAnalyzer.enterInitBlock(anonymousInitializer) addLocalScope(primaryConstructorParametersScope) addLocalScope(FirLocalScope()) - transformDeclaration(anonymousInitializer, ResolutionMode.ContextIndependent).also { + transformDeclarationContent(anonymousInitializer, ResolutionMode.ContextIndependent).also { dataFlowAnalyzer.exitInitBlock(it.single as FirAnonymousInitializer) } } @@ -485,7 +487,7 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer) } val transformedValueParameter = valueParameter.transformInitializer(integerLiteralTypeApproximator, valueParameter.returnTypeRef.coneTypeSafe()) - return (transformDeclaration( + return (transformDeclarationContent( transformedValueParameter, withExpectedType(transformedValueParameter.returnTypeRef) ).single as FirStatement).compose() } 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 f0967394682..ae1d1b4253e 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 @@ -199,25 +199,18 @@ private class FirDesignatedBodyResolveTransformerForReturnTypeCalculator( returnTypeCalculator, outerBodyResolveContext ) { - var lastResult: FirElement? = null - override fun transformElement(element: E, data: ResolutionMode): CompositeTransformResult { + override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult { if (designation.hasNext()) { - val result = designation.next().transform(this, data).single - if (!designation.hasNext()) { + val result = designation.next().transform(this, data).single + if (!designation.hasNext() && lastResult == null) { lastResult = result } - return result.compose() + return declaration.compose() } - return super.transformElement(element, data) - } - override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult { - return context.withContainer(declaration) { - declaration.replaceResolvePhase(transformerPhase) - transformElement(declaration, data) - } + return super.transformDeclarationContent(declaration, data) } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt index 3054f1e0775..7d37c871fdd 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/fir/FirResolutionApi.kt @@ -214,19 +214,13 @@ private class FirDesignatedBodyResolveTransformerForIDE( scopeSession = scopeSession, returnTypeCalculator = createReturnTypeCalculatorForIDE(session, scopeSession) ) { - override fun transformElement(element: E, data: ResolutionMode): CompositeTransformResult { + override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult { if (designation.hasNext()) { designation.next().visitNoTransform(this, data) - return element.compose() + return declaration.compose() } - return super.transformElement(element, data) - } - override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult { - return context.withContainer(declaration) { - declaration.replaceResolvePhase(transformerPhase) - transformElement(declaration, data) - } + return super.transformDeclarationContent(declaration, data) } }