[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
sealed class ResolutionMode(val forceFullCompletion: Boolean) {
object ContextDependent : ResolutionMode(forceFullCompletion = false) {
override fun toString(): String = "ContextDependent"
sealed class ContextDependent : ResolutionMode(forceFullCompletion = false) {
companion object Default : ContextDependent() {
override fun toString(): String = "ContextDependent"
}
data object Delegate : ContextDependent()
}
object ContextDependentDelegate : ResolutionMode(forceFullCompletion = false) {
override fun toString(): String = "ContextDependentDelegate"
}
object ContextIndependent : ResolutionMode(forceFullCompletion = true) {
override fun toString(): String = "ContextIndependent"
}
object ReceiverResolution : ResolutionMode(forceFullCompletion = true) {
override fun toString(): String = "ReceiverResolution"
}
data object ContextIndependent : ResolutionMode(forceFullCompletion = true)
data object ReceiverResolution : ResolutionMode(forceFullCompletion = true)
class WithExpectedType(
val expectedTypeRef: FirResolvedTypeRef,
@@ -112,7 +112,7 @@ class FirCallCompleter(
runCompletionForCall(candidate, completionMode, call, initialType, analyzer)
// 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)
inferenceSession.addPartiallyResolvedCall(call)
}
@@ -685,7 +685,7 @@ class BodyResolveContext(
mode: ResolutionMode,
f: () -> T
): T {
require(mode !is ResolutionMode.ContextDependent && mode !is ResolutionMode.ContextDependentDelegate)
require(mode !is ResolutionMode.ContextDependent)
if (mode !is ResolutionMode.LambdaResolution) {
storeContextForAnonymousFunction(anonymousFunction)
}
@@ -271,10 +271,10 @@ open class FirDeclarationsResolveTransformer(
dataFlowAnalyzer.enterDelegateExpression()
// Resolve delegate expression, after that, delegate will contain either expr.provideDelegate or expr
if (property.isLocal) {
property.transformDelegate(transformer, ResolutionMode.ContextDependentDelegate)
property.transformDelegate(transformer, ResolutionMode.ContextDependent.Delegate)
} else {
context.forPropertyInitializer {
property.transformDelegate(transformer, ResolutionMode.ContextDependentDelegate)
property.transformDelegate(transformer, ResolutionMode.ContextDependent.Delegate)
}
}
@@ -326,8 +326,8 @@ open class FirDeclarationsResolveTransformer(
data: ResolutionMode,
): FirStatement {
// 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)
val delegateExpression = wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependentDelegate)
// (that is why we use ContextDependent.Delegate instead of plain ContextDependent)
val delegateExpression = wrappedDelegateExpression.expression.transformSingle(transformer, ResolutionMode.ContextDependent.Delegate)
.transformSingle(components.integerLiteralAndOperatorApproximationTransformer, null)
// 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) {
is ResolutionMode.ContextDependent, is ResolutionMode.ContextDependentDelegate -> {
is ResolutionMode.ContextDependent -> {
context.storeContextForAnonymousFunction(anonymousFunction)
anonymousFunction
}
@@ -498,7 +498,10 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
)
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 {
source = originalCall.source
@@ -1075,17 +1078,14 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
transformedLHS?.let { callableReferenceAccess.replaceExplicitReceiver(transformedLHS) }
return when (data) {
is ResolutionMode.ContextDependent -> {
context.storeCallableReferenceContext(callableReferenceAccess)
callableReferenceAccess
}
else -> {
components.syntheticCallGenerator.resolveCallableReferenceWithSyntheticOuterCall(
callableReferenceAccess, data.expectedType, resolutionContext,
) ?: callableReferenceAccess
}
// TODO check why we need a special case for ContextDependent.Delegate
return if (data is ResolutionMode.ContextDependent && data !is ResolutionMode.ContextDependent.Delegate) {
context.storeCallableReferenceContext(callableReferenceAccess)
callableReferenceAccess
} else {
components.syntheticCallGenerator.resolveCallableReferenceWithSyntheticOuterCall(
callableReferenceAccess, data.expectedType, resolutionContext,
) ?: callableReferenceAccess
}.also {
dataFlowAnalyzer.exitCallableReference(it)
}
@@ -1636,7 +1636,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
override fun transformArrayOfCall(arrayOfCall: FirArrayOfCall, data: ResolutionMode): FirStatement =
whileAnalysing(session, arrayOfCall) {
if (data is ResolutionMode.ContextDependent) {
if (data is ResolutionMode.ContextDependent.Default) {
arrayOfCall.transformChildren(transformer, data)
arrayOfCall
} else if (data is ResolutionMode.WithExpectedType && !data.expectedTypeRef.coneType.isPrimitiveOrUnsignedArray) {