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.
This commit is contained in:
Denis Zharkov
2020-03-19 13:23:44 +03:00
parent 1b974f9d65
commit 94193c91a0
4 changed files with 26 additions and 29 deletions
@@ -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<FirFile>
}
}
@@ -182,6 +184,12 @@ open class FirBodyResolveTransformer(
return declarationsTransformer.transformDeclaration(declaration, data)
}
open fun transformDeclarationContent(
declaration: FirDeclaration, data: ResolutionMode
): CompositeTransformResult<FirDeclaration> {
return transformElement(declaration, data)
}
override fun transformDeclarationStatus(
declarationStatus: FirDeclarationStatus,
data: ResolutionMode
@@ -38,10 +38,12 @@ class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransformer)
private var containingClass: FirRegularClass? = null
override fun transformDeclaration(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
private fun transformDeclarationContent(
declaration: FirDeclaration, data: ResolutionMode
): CompositeTransformResult<FirDeclaration> {
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()
}
@@ -199,25 +199,18 @@ private class FirDesignatedBodyResolveTransformerForReturnTypeCalculator(
returnTypeCalculator,
outerBodyResolveContext
) {
var lastResult: FirElement? = null
override fun <E : FirElement> transformElement(element: E, data: ResolutionMode): CompositeTransformResult<E> {
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
if (designation.hasNext()) {
val result = designation.next().transform<E, ResolutionMode>(this, data).single
if (!designation.hasNext()) {
val result = designation.next().transform<FirDeclaration, ResolutionMode>(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<FirDeclaration> {
return context.withContainer(declaration) {
declaration.replaceResolvePhase(transformerPhase)
transformElement(declaration, data)
}
return super.transformDeclarationContent(declaration, data)
}
}
@@ -214,19 +214,13 @@ private class FirDesignatedBodyResolveTransformerForIDE(
scopeSession = scopeSession,
returnTypeCalculator = createReturnTypeCalculatorForIDE(session, scopeSession)
) {
override fun <E : FirElement> transformElement(element: E, data: ResolutionMode): CompositeTransformResult<E> {
override fun transformDeclarationContent(declaration: FirDeclaration, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
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<FirDeclaration> {
return context.withContainer(declaration) {
declaration.replaceResolvePhase(transformerPhase)
transformElement(declaration, data)
}
return super.transformDeclarationContent(declaration, data)
}
}