FIR: don't call a graph builder method in finally

If an exception is thrown, trying to add more nodes to a graph that's
already missing entire subgraphs may not end well.
This commit is contained in:
pyos
2022-11-24 17:09:01 +01:00
committed by teamcity
parent 38c1ef30bc
commit c231477375
@@ -1122,42 +1122,36 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
}
dataFlowAnalyzer.enterDelegatedConstructorCall()
var callCompleted = true
var result = delegatedConstructorCall
try {
val lastDispatchReceiver = implicitReceiverStack.lastDispatchReceiver()
context.forDelegatedConstructorCall(containingConstructor, containingClass as? FirRegularClass, components) {
delegatedConstructorCall.transformChildren(transformer, ResolutionMode.ContextDependent)
}
val reference = delegatedConstructorCall.calleeReference
val constructorType: ConeClassLikeType? = when (reference) {
is FirThisReference -> lastDispatchReceiver?.type as? ConeClassLikeType
is FirSuperReference -> reference.superTypeRef
.coneTypeSafe<ConeClassLikeType>()
?.takeIf { it !is ConeErrorType }
?.fullyExpandedType(session)
else -> null
}
val resolvedCall = callResolver
.resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType, containingClass.symbol.toLookupTag())
if (reference is FirThisReference && reference.boundSymbol == null) {
resolvedCall.dispatchReceiver.typeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.toSymbol(session)?.let {
reference.replaceBoundSymbol(it)
}
}
// it seems that we may leave this code as is
// without adding `context.withTowerDataContext(context.getTowerDataContextForConstructorResolution())`
val completionResult = callCompleter.completeCall(resolvedCall, noExpectedType)
result = completionResult.result
callCompleted = completionResult.callCompleted
return result
} finally {
dataFlowAnalyzer.exitDelegatedConstructorCall(result, callCompleted)
val lastDispatchReceiver = implicitReceiverStack.lastDispatchReceiver()
context.forDelegatedConstructorCall(containingConstructor, containingClass as? FirRegularClass, components) {
delegatedConstructorCall.transformChildren(transformer, ResolutionMode.ContextDependent)
}
val reference = delegatedConstructorCall.calleeReference
val constructorType: ConeClassLikeType? = when (reference) {
is FirThisReference -> lastDispatchReceiver?.type as? ConeClassLikeType
is FirSuperReference -> reference.superTypeRef
.coneTypeSafe<ConeClassLikeType>()
?.takeIf { it !is ConeErrorType }
?.fullyExpandedType(session)
else -> null
}
val resolvedCall = callResolver
.resolveDelegatingConstructorCall(delegatedConstructorCall, constructorType, containingClass.symbol.toLookupTag())
if (reference is FirThisReference && reference.boundSymbol == null) {
resolvedCall.dispatchReceiver.typeRef.coneTypeSafe<ConeClassLikeType>()?.lookupTag?.toSymbol(session)?.let {
reference.replaceBoundSymbol(it)
}
}
// it seems that we may leave this code as is
// without adding `context.withTowerDataContext(context.getTowerDataContextForConstructorResolution())`
val (result, callCompleted) = callCompleter.completeCall(resolvedCall, noExpectedType)
dataFlowAnalyzer.exitDelegatedConstructorCall(result, callCompleted)
return result
}
private fun extractSuperTypeDeclaration(typeRef: FirTypeRef): FirRegularClass? {