FIR: extract BodyResolveContext.withAnonymousFunction

This commit is contained in:
Mikhail Glukhikh
2021-03-09 17:09:10 +03:00
parent d7b2ab6b99
commit 4235075f35
2 changed files with 39 additions and 32 deletions
@@ -380,11 +380,30 @@ class BodyResolveContext(
} }
return withTypeParametersOf(simpleFunction) { return withTypeParametersOf(simpleFunction) {
val receiverTypeRef = simpleFunction.receiverTypeRef withTowerDataCleanup {
if (receiverTypeRef != null) { addLocalScope(FirLocalScope())
withLabelAndReceiverType(simpleFunction.name, simpleFunction, receiverTypeRef.coneType, holder, f) val receiverTypeRef = simpleFunction.receiverTypeRef
} else { withLabelAndReceiverType(simpleFunction.name, simpleFunction, receiverTypeRef?.coneType, holder, f)
f() }
}
}
inline fun <T> withAnonymousFunction(
anonymousFunction: FirAnonymousFunction,
holder: SessionHolder,
isInDependentContext: Boolean = false,
crossinline f: () -> T
): T {
return withTowerDataCleanup {
addLocalScope(FirLocalScope())
val receiverTypeRef = anonymousFunction.receiverTypeRef
val labelName = anonymousFunction.label?.name?.let { Name.identifier(it) }
withLabelAndReceiverType(labelName, anonymousFunction, receiverTypeRef?.coneType, holder) {
if (isInDependentContext) {
withLambdaBeingAnalyzedInDependentContext(anonymousFunction.symbol, f)
} else {
f()
}
} }
} }
} }
@@ -419,10 +438,10 @@ class BodyResolveContext(
): T { ): T {
return withTowerDataCleanup { return withTowerDataCleanup {
val receiverTypeRef = property.receiverTypeRef val receiverTypeRef = property.receiverTypeRef
addLocalScope(FirLocalScope())
if (receiverTypeRef == null && property.returnTypeRef !is FirImplicitTypeRef && if (receiverTypeRef == null && property.returnTypeRef !is FirImplicitTypeRef &&
!property.isLocal && property.delegate == null !property.isLocal && property.delegate == null
) { ) {
addLocalScope(FirLocalScope())
storeBackingField(property) storeBackingField(property)
} }
if (receiverTypeRef != null) { if (receiverTypeRef != null) {
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctiona
import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType import org.jetbrains.kotlin.fir.resolve.inference.isSuspendFunctionType
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
import org.jetbrains.kotlin.fir.resolve.transformers.* import org.jetbrains.kotlin.fir.resolve.transformers.*
import org.jetbrains.kotlin.fir.scopes.impl.FirLocalScope
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
import org.jetbrains.kotlin.fir.symbols.constructStarProjectedType import org.jetbrains.kotlin.fir.symbols.constructStarProjectedType
import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirVariableSymbol
@@ -427,14 +426,11 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
private fun transformAnonymousFunctionWithLambdaResolution( private fun transformAnonymousFunctionWithLambdaResolution(
anonymousFunction: FirAnonymousFunction, lambdaResolution: ResolutionMode.LambdaResolution anonymousFunction: FirAnonymousFunction, lambdaResolution: ResolutionMode.LambdaResolution
): FirAnonymousFunction { ): FirAnonymousFunction {
val receiverTypeRef = anonymousFunction.receiverTypeRef
fun transform(): FirAnonymousFunction { fun transform(): FirAnonymousFunction {
val expectedReturnType = val expectedReturnType =
lambdaResolution.expectedReturnTypeRef ?: anonymousFunction.returnTypeRef.takeUnless { it is FirImplicitTypeRef } lambdaResolution.expectedReturnTypeRef ?: anonymousFunction.returnTypeRef.takeUnless { it is FirImplicitTypeRef }
val result = context.withLambdaBeingAnalyzedInDependentContext(anonymousFunction.symbol) { val result = transformFunction(anonymousFunction, withExpectedType(expectedReturnType)).single as FirAnonymousFunction
transformFunction(anonymousFunction, withExpectedType(expectedReturnType)).single as FirAnonymousFunction
}
val body = result.body val body = result.body
if (result.returnTypeRef is FirImplicitTypeRef && body != null) { if (result.returnTypeRef is FirImplicitTypeRef && body != null) {
@@ -459,12 +455,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
return result return result
} }
val label = anonymousFunction.label return context.withAnonymousFunction(anonymousFunction, components, isInDependentContext = true) {
return if (label != null || receiverTypeRef is FirResolvedTypeRef) {
withLabelAndReceiverType(label?.name?.let { Name.identifier(it) }, anonymousFunction, receiverTypeRef?.coneTypeSafe()) {
transform()
}
} else {
transform() transform()
} }
} }
@@ -536,20 +527,18 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
function: FirFunction<F>, function: FirFunction<F>,
data: ResolutionMode data: ResolutionMode
): CompositeTransformResult<FirStatement> { ): CompositeTransformResult<FirStatement> {
return withNewLocalScope { val functionIsNotAnalyzed = transformerPhase != function.resolvePhase
val functionIsNotAnalyzed = transformerPhase != function.resolvePhase if (functionIsNotAnalyzed) {
if (functionIsNotAnalyzed) { dataFlowAnalyzer.enterFunction(function)
dataFlowAnalyzer.enterFunction(function)
}
@Suppress("UNCHECKED_CAST")
transformDeclarationContent(function, data).also {
if (functionIsNotAnalyzed) {
val result = it.single as FirFunction<*>
val controlFlowGraphReference = dataFlowAnalyzer.exitFunction(result)
result.replaceControlFlowGraphReference(controlFlowGraphReference)
}
} as CompositeTransformResult<FirStatement>
} }
@Suppress("UNCHECKED_CAST")
return transformDeclarationContent(function, data).also {
if (functionIsNotAnalyzed) {
val result = it.single as FirFunction<*>
val controlFlowGraphReference = dataFlowAnalyzer.exitFunction(result)
result.replaceControlFlowGraphReference(controlFlowGraphReference)
}
} as CompositeTransformResult<FirStatement>
} }
override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): CompositeTransformResult<FirDeclaration> { override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): CompositeTransformResult<FirDeclaration> {
@@ -711,8 +700,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
) )
lambda = lambda.transformValueParameters(ImplicitToErrorTypeTransformer, null) lambda = lambda.transformValueParameters(ImplicitToErrorTypeTransformer, null)
val bodyExpectedType = returnTypeRefFromResolvedAtom ?: expectedTypeRef val bodyExpectedType = returnTypeRefFromResolvedAtom ?: expectedTypeRef
val labelName = lambda.label?.name?.let { Name.identifier(it) } context.withAnonymousFunction(lambda, components) {
withLabelAndReceiverType(labelName, lambda, lambda.receiverTypeRef?.coneType) {
lambda = transformFunction(lambda, withExpectedType(bodyExpectedType)).single as FirAnonymousFunction lambda = transformFunction(lambda, withExpectedType(bodyExpectedType)).single as FirAnonymousFunction
} }
// To separate function and separate commit // To separate function and separate commit