[FIR] Introduce common super type for context dependent resolution modes

This commit is contained in:
Kirill Rakhman
2023-07-18 12:00:01 +02:00
committed by Space Team
parent ff6b3350ae
commit e69b695efd
5 changed files with 28 additions and 33 deletions
@@ -12,21 +12,16 @@ import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
sealed class ResolutionMode(val forceFullCompletion: Boolean) { sealed class ResolutionMode(val forceFullCompletion: Boolean) {
object ContextDependent : ResolutionMode(forceFullCompletion = false) { sealed class ContextDependent : ResolutionMode(forceFullCompletion = false) {
override fun toString(): String = "ContextDependent" companion object Default : ContextDependent() {
override fun toString(): String = "ContextDependent"
}
data object Delegate : ContextDependent()
} }
object ContextDependentDelegate : ResolutionMode(forceFullCompletion = false) { data object ContextIndependent : ResolutionMode(forceFullCompletion = true)
override fun toString(): String = "ContextDependentDelegate" data object ReceiverResolution : ResolutionMode(forceFullCompletion = true)
}
object ContextIndependent : ResolutionMode(forceFullCompletion = true) {
override fun toString(): String = "ContextIndependent"
}
object ReceiverResolution : ResolutionMode(forceFullCompletion = true) {
override fun toString(): String = "ReceiverResolution"
}
class WithExpectedType( class WithExpectedType(
val expectedTypeRef: FirResolvedTypeRef, val expectedTypeRef: FirResolvedTypeRef,
@@ -112,7 +112,7 @@ class FirCallCompleter(
runCompletionForCall(candidate, completionMode, call, initialType, analyzer) runCompletionForCall(candidate, completionMode, call, initialType, analyzer)
// Add top-level delegate call as partially resolved to inference session // Add top-level delegate call as partially resolved to inference session
if (resolutionMode is ResolutionMode.ContextDependentDelegate) { if (resolutionMode is ResolutionMode.ContextDependent.Delegate) {
require(inferenceSession is FirDelegatedPropertyInferenceSession) require(inferenceSession is FirDelegatedPropertyInferenceSession)
inferenceSession.addPartiallyResolvedCall(call) inferenceSession.addPartiallyResolvedCall(call)
} }
@@ -685,7 +685,7 @@ class BodyResolveContext(
mode: ResolutionMode, mode: ResolutionMode,
f: () -> T f: () -> T
): T { ): T {
require(mode !is ResolutionMode.ContextDependent && mode !is ResolutionMode.ContextDependentDelegate) require(mode !is ResolutionMode.ContextDependent)
if (mode !is ResolutionMode.LambdaResolution) { if (mode !is ResolutionMode.LambdaResolution) {
storeContextForAnonymousFunction(anonymousFunction) storeContextForAnonymousFunction(anonymousFunction)
} }
@@ -271,10 +271,10 @@ open class FirDeclarationsResolveTransformer(
dataFlowAnalyzer.enterDelegateExpression() dataFlowAnalyzer.enterDelegateExpression()
// Resolve delegate expression, after that, delegate will contain either expr.provideDelegate or expr // Resolve delegate expression, after that, delegate will contain either expr.provideDelegate or expr
if (property.isLocal) { if (property.isLocal) {
property.transformDelegate(transformer, ResolutionMode.ContextDependentDelegate) property.transformDelegate(transformer, ResolutionMode.ContextDependent.Delegate)
} else { } else {
context.forPropertyInitializer { context.forPropertyInitializer {
property.transformDelegate(transformer, ResolutionMode.ContextDependentDelegate) property.transformDelegate(transformer, ResolutionMode.ContextDependent.Delegate)
} }
} }
@@ -326,8 +326,8 @@ open class FirDeclarationsResolveTransformer(
data: ResolutionMode, data: ResolutionMode,
): FirStatement { ): FirStatement {
// First, resolve delegate expression in dependent context, and add potentially partially resolved call to inference session // First, resolve delegate expression in dependent context, and add potentially partially resolved call to inference session
// (that is why we use ContextDependentDelegate instead of plain ContextDependent) // (that is why we use ContextDependent.Delegate instead of plain ContextDependent)
val delegateExpression = wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependentDelegate) val delegateExpression = wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependent.Delegate)
.transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null) .transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null)
// Second, replace result type of delegate expression with stub type if delegate not yet resolved // Second, replace result type of delegate expression with stub type if delegate not yet resolved
@@ -773,7 +773,7 @@ open class FirDeclarationsResolveTransformer(
} }
return when (data) { return when (data) {
is ResolutionMode.ContextDependent, is ResolutionMode.ContextDependentDelegate -> { is ResolutionMode.ContextDependent -> {
context.storeContextForAnonymousFunction(anonymousFunction) context.storeContextForAnonymousFunction(anonymousFunction)
anonymousFunction anonymousFunction
} }
@@ -498,7 +498,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
) )
val approximationIsNeeded = val approximationIsNeeded =
resolutionMode !is ResolutionMode.ReceiverResolution && resolutionMode !is ResolutionMode.ContextDependent resolutionMode !is ResolutionMode.ReceiverResolution &&
(resolutionMode !is ResolutionMode.ContextDependent ||
// TODO check why we need a special case for ContextDependent.Delegate
resolutionMode is ResolutionMode.ContextDependent.Delegate)
val integerOperatorCall = buildIntegerLiteralOperatorCall { val integerOperatorCall = buildIntegerLiteralOperatorCall {
source = originalCall.source source = originalCall.source
@@ -1075,17 +1078,14 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
transformedLHS?.let { callableReferenceAccess.replaceExplicitReceiver(transformedLHS) } transformedLHS?.let { callableReferenceAccess.replaceExplicitReceiver(transformedLHS) }
return when (data) { // TODO check why we need a special case for ContextDependent.Delegate
is ResolutionMode.ContextDependent -> { return if (data is ResolutionMode.ContextDependent && data !is ResolutionMode.ContextDependent.Delegate) {
context.storeCallableReferenceContext(callableReferenceAccess) context.storeCallableReferenceContext(callableReferenceAccess)
callableReferenceAccess callableReferenceAccess
} } else {
components.syntheticCallGenerator.resolveCallableReferenceWithSyntheticOuterCall(
else -> { callableReferenceAccess, data.expectedType, resolutionContext,
components.syntheticCallGenerator.resolveCallableReferenceWithSyntheticOuterCall( ) ?: callableReferenceAccess
callableReferenceAccess, data.expectedType, resolutionContext,
) ?: callableReferenceAccess
}
}.also { }.also {
dataFlowAnalyzer.exitCallableReference(it) dataFlowAnalyzer.exitCallableReference(it)
} }
@@ -1636,7 +1636,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement = override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement =
whileAnalysing(session, arrayOfCall) { whileAnalysing(session, arrayOfCall) {
if (data is ResolutionMode.ContextDependent) { if (data is ResolutionMode.ContextDependent.Default) {
arrayOfCall.transformChildren(transformer, data) arrayOfCall.transformChildren(transformer, data)
arrayOfCall arrayOfCall
} else if (data is ResolutionMode.WithExpectedType && !data.expectedTypeRef.coneType.isPrimitiveOrUnsignedArray) { } else if (data is ResolutionMode.WithExpectedType && !data.expectedTypeRef.coneType.isPrimitiveOrUnsignedArray) {