K2: Get rid of AugmentedAssignmentCallOption resolution mode
It's been used only for regular function call nodes resolution, so I made it more explicit. The main idea behind this change is ResolutionMode hierarchy simplification and the kind of statement that "AugmentedAssignmentCallOption" is only relevant to calls. Instead, CallResolutionMode is introduced that is only used for `transformFunctionCallInternal` call sites.
This commit is contained in:
committed by
Space Team
parent
df2a1d4d02
commit
09b6bbc5e3
@@ -616,7 +616,7 @@ class FirCallResolver(
|
|||||||
|
|
||||||
annotation.transformArgumentList { argumentsToParameters[it]?.returnTypeRef }
|
annotation.transformArgumentList { argumentsToParameters[it]?.returnTypeRef }
|
||||||
} else {
|
} else {
|
||||||
annotation.replaceArgumentList(annotation.argumentList.transform(transformer, ResolutionMode.ContextDependent.Default))
|
annotation.replaceArgumentList(annotation.argumentList.transform(transformer, ResolutionMode.ContextDependent))
|
||||||
}
|
}
|
||||||
|
|
||||||
val callInfo = toCallInfo(annotation, reference)
|
val callInfo = toCallInfo(annotation, reference)
|
||||||
@@ -633,7 +633,7 @@ class FirCallResolver(
|
|||||||
explicitReceiver = null
|
explicitReceiver = null
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
annotation.replaceArgumentList(annotation.argumentList.transform(transformer, ResolutionMode.ContextDependent.Default))
|
annotation.replaceArgumentList(annotation.argumentList.transform(transformer, ResolutionMode.ContextDependent))
|
||||||
|
|
||||||
val callInfo = toCallInfo(annotation, reference)
|
val callInfo = toCallInfo(annotation, reference)
|
||||||
|
|
||||||
|
|||||||
@@ -13,21 +13,9 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
|||||||
|
|
||||||
sealed class ResolutionMode(
|
sealed class ResolutionMode(
|
||||||
val forceFullCompletion: Boolean,
|
val forceFullCompletion: Boolean,
|
||||||
// Only true AugmentedAssignmentCallOption, don't run an even slightest form of completion
|
|
||||||
val skipEvenPartialCompletion: Boolean = false,
|
|
||||||
) {
|
) {
|
||||||
sealed class ContextDependent(
|
data object ContextDependent : ResolutionMode(forceFullCompletion = false)
|
||||||
skipCompletion: Boolean = false,
|
|
||||||
) : ResolutionMode(forceFullCompletion = false, skipCompletion) {
|
|
||||||
companion object Default : ContextDependent() {
|
|
||||||
override fun toString(): String = "ContextDependent"
|
|
||||||
}
|
|
||||||
|
|
||||||
data object AugmentedAssignmentCallOption : ContextDependent(skipCompletion = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
data object Delegate : ResolutionMode(forceFullCompletion = false)
|
data object Delegate : ResolutionMode(forceFullCompletion = false)
|
||||||
|
|
||||||
data object ContextIndependent : ResolutionMode(forceFullCompletion = true)
|
data object ContextIndependent : ResolutionMode(forceFullCompletion = true)
|
||||||
|
|
||||||
sealed class ReceiverResolution(val forCallableReference: Boolean) : ResolutionMode(forceFullCompletion = true) {
|
sealed class ReceiverResolution(val forCallableReference: Boolean) : ResolutionMode(forceFullCompletion = true) {
|
||||||
|
|||||||
+7
-2
@@ -55,7 +55,12 @@ class FirCallCompleter(
|
|||||||
|
|
||||||
val completer = ConstraintSystemCompleter(components, transformer.context)
|
val completer = ConstraintSystemCompleter(components, transformer.context)
|
||||||
|
|
||||||
fun <T> completeCall(call: T, resolutionMode: ResolutionMode): T where T : FirResolvable, T : FirStatement {
|
fun <T> completeCall(
|
||||||
|
call: T,
|
||||||
|
resolutionMode: ResolutionMode,
|
||||||
|
// Only expected to be true for resolving different versions of augmented assignments
|
||||||
|
skipEvenPartialCompletion: Boolean = false,
|
||||||
|
): T where T : FirResolvable, T : FirStatement {
|
||||||
val typeRef = components.typeFromCallee(call)
|
val typeRef = components.typeFromCallee(call)
|
||||||
|
|
||||||
val reference = call.calleeReference as? FirNamedReferenceWithCandidate ?: return call
|
val reference = call.calleeReference as? FirNamedReferenceWithCandidate ?: return call
|
||||||
@@ -74,7 +79,7 @@ class FirCallCompleter(
|
|||||||
resolutionMode,
|
resolutionMode,
|
||||||
)
|
)
|
||||||
|
|
||||||
if (resolutionMode.skipEvenPartialCompletion) return call
|
if (skipEvenPartialCompletion) return call
|
||||||
|
|
||||||
val completionMode = candidate.computeCompletionMode(
|
val completionMode = candidate.computeCompletionMode(
|
||||||
session.inferenceComponents, resolutionMode, initialType
|
session.inferenceComponents, resolutionMode, initialType
|
||||||
|
|||||||
+1
-1
@@ -403,7 +403,7 @@ open class FirDeclarationsResolveTransformer(
|
|||||||
// TODO: this generates some nodes in the control flow graph which we don't want if we
|
// TODO: this generates some nodes in the control flow graph which we don't want if we
|
||||||
// end up not selecting this option, KT-59684
|
// end up not selecting this option, KT-59684
|
||||||
transformer.expressionsTransformer?.transformFunctionCallInternal(
|
transformer.expressionsTransformer?.transformFunctionCallInternal(
|
||||||
provideDelegateCall, ResolutionMode.ReceiverResolution, provideDelegate = true
|
provideDelegateCall, ResolutionMode.ReceiverResolution, FirExpressionsResolveTransformer.CallResolutionMode.PROVIDE_DELEGATE,
|
||||||
)
|
)
|
||||||
|
|
||||||
// If we got successful candidate for provideDelegate, let's select it
|
// If we got successful candidate for provideDelegate, let's select it
|
||||||
|
|||||||
+31
-10
@@ -392,12 +392,29 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement =
|
override fun transformFunctionCall(functionCall: FirFunctionCall, data: ResolutionMode): FirStatement =
|
||||||
transformFunctionCallInternal(functionCall, data, provideDelegate = false)
|
transformFunctionCallInternal(functionCall, data, CallResolutionMode.REGULAR)
|
||||||
|
|
||||||
|
internal enum class CallResolutionMode {
|
||||||
|
REGULAR,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For PROVIDE_DELEGATE we skip transforming explicit receiver of the call since it's already been resolved
|
||||||
|
* at [org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer.transformPropertyAccessorsWithDelegate]
|
||||||
|
*/
|
||||||
|
PROVIDE_DELEGATE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When we're resolving an operator like `a += b` we try to resolve it with different options of desugaring like
|
||||||
|
* `a = a.plus(b)` and `a.plusAssign(b)` until find something that looks successful.
|
||||||
|
* But at this stage, we skip transformation of receiver, arguments and skip completion in any form.
|
||||||
|
*/
|
||||||
|
OPTION_FOR_AUGMENTED_ASSIGNMENT,
|
||||||
|
}
|
||||||
|
|
||||||
internal fun transformFunctionCallInternal(
|
internal fun transformFunctionCallInternal(
|
||||||
functionCall: FirFunctionCall,
|
functionCall: FirFunctionCall,
|
||||||
data: ResolutionMode,
|
data: ResolutionMode,
|
||||||
provideDelegate: Boolean,
|
callResolutionMode: CallResolutionMode,
|
||||||
): FirStatement =
|
): FirStatement =
|
||||||
whileAnalysing(session, functionCall) {
|
whileAnalysing(session, functionCall) {
|
||||||
val calleeReference = functionCall.calleeReference
|
val calleeReference = functionCall.calleeReference
|
||||||
@@ -419,8 +436,8 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
functionCall.transformAnnotations(transformer, data)
|
functionCall.transformAnnotations(transformer, data)
|
||||||
functionCall.replaceLambdaArgumentInvocationKinds(session)
|
functionCall.replaceLambdaArgumentInvocationKinds(session)
|
||||||
functionCall.transformTypeArguments(transformer, ResolutionMode.ContextIndependent)
|
functionCall.transformTypeArguments(transformer, ResolutionMode.ContextIndependent)
|
||||||
val resolvingAugmentedAssignment = data == ResolutionMode.ContextDependent.AugmentedAssignmentCallOption
|
val choosingOptionForAugmentedAssignment = callResolutionMode == CallResolutionMode.OPTION_FOR_AUGMENTED_ASSIGNMENT
|
||||||
val withTransformedArguments = if (!resolvingAugmentedAssignment) {
|
val withTransformedArguments = if (!choosingOptionForAugmentedAssignment) {
|
||||||
dataFlowAnalyzer.enterCallArguments(functionCall, functionCall.arguments)
|
dataFlowAnalyzer.enterCallArguments(functionCall, functionCall.arguments)
|
||||||
// In provideDelegate mode the explicitReceiver is already resolved
|
// In provideDelegate mode the explicitReceiver is already resolved
|
||||||
// E.g. we have val some by someDelegate
|
// E.g. we have val some by someDelegate
|
||||||
@@ -428,7 +445,8 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
// at 2nd stage in provideDelegate mode we are trying to resolve someDelegate.provideDelegate(),
|
// at 2nd stage in provideDelegate mode we are trying to resolve someDelegate.provideDelegate(),
|
||||||
// and 'someDelegate' explicit receiver is resolved at 1st stage
|
// and 'someDelegate' explicit receiver is resolved at 1st stage
|
||||||
// See also FirDeclarationsResolveTransformer.transformWrappedDelegateExpression
|
// See also FirDeclarationsResolveTransformer.transformWrappedDelegateExpression
|
||||||
val withResolvedExplicitReceiver = if (provideDelegate) functionCall else transformExplicitReceiver(functionCall)
|
val withResolvedExplicitReceiver =
|
||||||
|
if (callResolutionMode == CallResolutionMode.PROVIDE_DELEGATE) functionCall else transformExplicitReceiver(functionCall)
|
||||||
withResolvedExplicitReceiver.also {
|
withResolvedExplicitReceiver.also {
|
||||||
it.replaceArgumentList(it.argumentList.transform(this, ResolutionMode.ContextDependent))
|
it.replaceArgumentList(it.argumentList.transform(this, ResolutionMode.ContextDependent))
|
||||||
dataFlowAnalyzer.exitCallArguments()
|
dataFlowAnalyzer.exitCallArguments()
|
||||||
@@ -439,9 +457,12 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
|
|
||||||
val resultExpression = callResolver.resolveCallAndSelectCandidate(withTransformedArguments, data)
|
val resultExpression = callResolver.resolveCallAndSelectCandidate(withTransformedArguments, data)
|
||||||
|
|
||||||
val completeInference = callCompleter.completeCall(resultExpression, data)
|
val completeInference = callCompleter.completeCall(
|
||||||
|
resultExpression, data,
|
||||||
|
skipEvenPartialCompletion = choosingOptionForAugmentedAssignment,
|
||||||
|
)
|
||||||
val result = completeInference.transformToIntegerOperatorCallOrApproximateItIfNeeded(data)
|
val result = completeInference.transformToIntegerOperatorCallOrApproximateItIfNeeded(data)
|
||||||
if (!resolvingAugmentedAssignment) {
|
if (!choosingOptionForAugmentedAssignment) {
|
||||||
dataFlowAnalyzer.exitFunctionCall(result, data.forceFullCompletion)
|
dataFlowAnalyzer.exitFunctionCall(result, data.forceFullCompletion)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -818,8 +839,8 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
private fun FirFunctionCall.resolveCandidateForAssignmentOperatorCall(): FirFunctionCall {
|
private fun FirFunctionCall.resolveCandidateForAssignmentOperatorCall(): FirFunctionCall {
|
||||||
return transformFunctionCallInternal(
|
return transformFunctionCallInternal(
|
||||||
this,
|
this,
|
||||||
ResolutionMode.ContextDependent.AugmentedAssignmentCallOption,
|
ResolutionMode.ContextDependent,
|
||||||
provideDelegate = false
|
CallResolutionMode.OPTION_FOR_AUGMENTED_ASSIGNMENT
|
||||||
) as FirFunctionCall
|
) as FirFunctionCall
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1641,7 +1662,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
|
|||||||
override fun transformArrayLiteral(arrayLiteral: FirArrayLiteral, data: ResolutionMode): FirStatement =
|
override fun transformArrayLiteral(arrayLiteral: FirArrayLiteral, data: ResolutionMode): FirStatement =
|
||||||
whileAnalysing(session, arrayLiteral) {
|
whileAnalysing(session, arrayLiteral) {
|
||||||
when (data) {
|
when (data) {
|
||||||
is ResolutionMode.ContextDependent.Default -> {
|
is ResolutionMode.ContextDependent -> {
|
||||||
// Argument in non-annotation call (unsupported) or if type of array parameter is unresolved.
|
// Argument in non-annotation call (unsupported) or if type of array parameter is unresolved.
|
||||||
arrayLiteral.transformChildren(transformer, data)
|
arrayLiteral.transformChildren(transformer, data)
|
||||||
arrayLiteral
|
arrayLiteral
|
||||||
|
|||||||
Reference in New Issue
Block a user