K2: Unify completeCall overloads and usages

- Leave only the overload with ResolutionMode parameter
- Get rid of boolean flags that belong to ResolutionMode.WithExpectedType
This commit is contained in:
Denis.Zharkov
2022-12-01 13:55:10 +01:00
committed by Space Team
parent 73fa41f7fb
commit 28ff276320
4 changed files with 28 additions and 65 deletions
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.expressions.FirEmptyArgumentList
import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.builder.buildFunctionCall
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.createConeDiagnosticForCandidateWithError
import org.jetbrains.kotlin.fir.resolve.inference.FirCallCompleter
@@ -74,8 +75,10 @@ class SingleCandidateResolver(
return null
}
val expectedType = resolutionParameters.expectedType ?: bodyResolveComponents.noExpectedType
val completionResult = firCallCompleter.completeCall(fakeCall, expectedType)
val completionResult = firCallCompleter.completeCall(
fakeCall,
resolutionParameters.expectedType?.let(ResolutionMode::WithExpectedType) ?: ResolutionMode.ContextIndependent
)
return completionResult.takeIf { it.callCompleted }?.result
}
@@ -56,39 +56,7 @@ class FirCallCompleter(
data class CompletionResult<T>(val result: T, val callCompleted: Boolean)
fun <T> completeCall(
call: T,
expectedTypeRef: FirTypeRef?,
expectedTypeMismatchIsReportedInChecker: Boolean = false,
): CompletionResult<T> where T : FirResolvable, T : FirStatement =
completeCall(
call,
expectedTypeRef,
mayBeCoercionToUnitApplied = false,
expectedTypeMismatchIsReportedInChecker,
isFromCast = false,
shouldEnforceExpectedType = true,
)
fun <T> completeCall(call: T, data: ResolutionMode): CompletionResult<T> where T : FirResolvable, T : FirStatement =
completeCall(
call,
data.expectedType(components, allowFromCast = true),
(data as? ResolutionMode.WithExpectedType)?.mayBeCoercionToUnitApplied == true,
(data as? ResolutionMode.WithExpectedType)?.expectedTypeMismatchIsReportedInChecker == true,
isFromCast = (data as? ResolutionMode.WithExpectedType)?.fromCast == true,
shouldEnforceExpectedType = (data as? ResolutionMode.WithExpectedType)?.shouldBeStrictlyEnforced == true,
)
private fun <T> completeCall(
call: T,
expectedTypeRef: FirTypeRef?,
mayBeCoercionToUnitApplied: Boolean,
expectedTypeMismatchIsReportedInChecker: Boolean,
isFromCast: Boolean,
shouldEnforceExpectedType: Boolean,
): CompletionResult<T>
where T : FirResolvable, T : FirStatement {
fun <T> completeCall(call: T, resolutionMode: ResolutionMode): CompletionResult<T> where T : FirResolvable, T : FirStatement {
val typeRef = components.typeFromCallee(call)
val reference = call.calleeReference as? FirNamedReferenceWithCandidate ?: return CompletionResult(call, true)
@@ -103,16 +71,14 @@ class FirCallCompleter(
}
addConstraintFromExpectedType(
expectedTypeMismatchIsReportedInChecker,
expectedTypeRef,
shouldEnforceExpectedType,
candidate,
initialType,
isFromCast,
mayBeCoercionToUnitApplied
resolutionMode,
)
val completionMode = candidate.computeCompletionMode(session.inferenceComponents, expectedTypeRef, initialType)
val completionMode = candidate.computeCompletionMode(
session.inferenceComponents, resolutionMode.expectedType(components, allowFromCast = true), initialType
)
val analyzer = createPostponedArgumentsAnalyzer(transformer.resolutionContext)
if (call is FirFunctionCall) {
@@ -157,15 +123,12 @@ class FirCallCompleter(
}
private fun addConstraintFromExpectedType(
expectedTypeMismatchIsReportedInChecker: Boolean,
expectedTypeRef: FirTypeRef?,
shouldEnforceExpectedType: Boolean,
candidate: Candidate,
initialType: ConeKotlinType,
isFromCast: Boolean,
mayBeCoercionToUnitApplied: Boolean
resolutionMode: ResolutionMode,
) {
val expectedType = expectedTypeRef?.coneTypeSafe<ConeKotlinType>() ?: return
if (resolutionMode !is ResolutionMode.WithExpectedType) return
val expectedType = resolutionMode.expectedTypeRef.coneTypeSafe<ConeKotlinType>() ?: return
val system = candidate.system
when {
@@ -175,10 +138,10 @@ class FirCallCompleter(
// It's assumed to be safe & sound, because if constraint system has contradictions when expected type is added,
// the resulting expression type cannot be inferred to something that is a subtype of `expectedType`,
// thus the diagnostic should be reported.
!shouldEnforceExpectedType || expectedTypeMismatchIsReportedInChecker -> {
!resolutionMode.shouldBeStrictlyEnforced || resolutionMode.expectedTypeMismatchIsReportedInChecker -> {
system.addSubtypeConstraintIfCompatible(initialType, expectedType, ConeExpectedTypeConstraintPosition)
}
isFromCast -> {
resolutionMode.fromCast -> {
if (candidate.isFunctionForExpectTypeFromCastFeature()) {
system.addSubtypeConstraint(
initialType, expectedType,
@@ -186,7 +149,7 @@ class FirCallCompleter(
)
}
}
!expectedType.isUnitOrFlexibleUnit || (!mayBeCoercionToUnitApplied && !expectedTypeMismatchIsReportedInChecker) -> {
!expectedType.isUnitOrFlexibleUnit || !resolutionMode.mayBeCoercionToUnitApplied -> {
system.addSubtypeConstraint(initialType, expectedType, ConeExpectedTypeConstraintPosition)
}
system.notFixedTypeVariables.isEmpty() -> return
@@ -411,4 +374,3 @@ internal fun FirFunction.isFunctionForExpectTypeFromCastFeature(): Boolean {
private fun ConeKotlinType.unwrap(): ConeSimpleKotlinType = lowerBoundIfFlexible().let {
if (it is ConeDefinitelyNotNullType) it.original.unwrap() else it
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.references.FirReference
import org.jetbrains.kotlin.fir.references.impl.FirStubReference
import org.jetbrains.kotlin.fir.resolve.BodyResolveComponents
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
import org.jetbrains.kotlin.fir.resolve.calls.*
import org.jetbrains.kotlin.fir.resolve.createErrorReferenceWithExistingCandidate
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeInapplicableCandidateError
@@ -182,7 +183,7 @@ class FirSyntheticCallGenerator(
this.argumentList = argumentList
}
val argument = components.callCompleter.completeCall(fakeCallElement, expectedTypeRef = null).result.argument
val argument = components.callCompleter.completeCall(fakeCallElement, ResolutionMode.ContextIndependent).result.argument
return argument as FirCallableReferenceAccess?
}
@@ -421,7 +421,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val resultExplicitReceiver = resultExpression.explicitReceiver?.unwrapSmartcastExpression()
if (initialExplicitReceiver !== resultExplicitReceiver && resultExplicitReceiver is FirQualifiedAccessExpression) {
// name.invoke() case
callCompleter.completeCall(resultExplicitReceiver, noExpectedType)
callCompleter.completeCall(resultExplicitReceiver, ResolutionMode.ContextIndependent)
}
callCompleter.completeCall(resultExpression, data)
}
@@ -607,7 +607,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val lhsIsVar = lhsVariable?.isVar == true
fun chooseAssign(): FirStatement {
callCompleter.completeCall(resolvedAssignCall, noExpectedType)
callCompleter.completeCall(resolvedAssignCall, ResolutionMode.ContextIndependent)
dataFlowAnalyzer.exitFunctionCall(resolvedAssignCall, callCompleted = true)
return resolvedAssignCall
}
@@ -615,8 +615,9 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
fun chooseOperator(): FirStatement {
callCompleter.completeCall(
resolvedOperatorCall,
lhsVariable?.returnTypeRef ?: noExpectedType,
expectedTypeMismatchIsReportedInChecker = true
lhsVariable?.returnTypeRef?.let {
ResolutionMode.WithExpectedType(it, expectedTypeMismatchIsReportedInChecker = true)
} ?: ResolutionMode.ContextIndependent,
)
dataFlowAnalyzer.exitFunctionCall(resolvedOperatorCall, callCompleted = true)
@@ -1116,7 +1117,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val result = callResolver.resolveAnnotationCall(annotationCall)
dataFlowAnalyzer.exitAnnotation()
if (result == null) return annotationCall
callCompleter.completeCall(result, noExpectedType)
callCompleter.completeCall(result, ResolutionMode.ContextIndependent)
(result.argumentList as FirResolvedArgumentList).let { annotationCall.replaceArgumentMapping((it).toAnnotationArgumentMapping()) }
annotationCall
}
@@ -1188,7 +1189,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
// it seems that we may leave this code as is
// without adding `context.withTowerDataContext(context.getTowerDataContextForConstructorResolution())`
val (result, callCompleted) = callCompleter.completeCall(resolvedCall, noExpectedType)
val (result, callCompleted) = callCompleter.completeCall(resolvedCall, ResolutionMode.ContextIndependent)
dataFlowAnalyzer.exitDelegatedConstructorCall(result, callCompleted)
return result
}
@@ -1280,7 +1281,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val assignIsSuccessful = assignCallReference?.isError == false
fun chooseAssign(): FirFunctionCall {
callCompleter.completeCall(resolvedAssignCall, noExpectedType)
callCompleter.completeCall(resolvedAssignCall, ResolutionMode.ContextIndependent)
dataFlowAnalyzer.exitFunctionCall(resolvedAssignCall, callCompleted = true)
return resolvedAssignCall
}
@@ -1308,11 +1309,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
val setIsSuccessful = setCallReference?.isError == false
fun chooseSetOperator(): FirStatement {
callCompleter.completeCall(
resolvedSetCall,
noExpectedType,
expectedTypeMismatchIsReportedInChecker = true
)
callCompleter.completeCall(resolvedSetCall, ResolutionMode.ContextIndependent)
dataFlowAnalyzer.exitFunctionCall(resolvedSetCall, callCompleted = true)
return info.toBlock()
}
@@ -1488,7 +1485,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
}
val syntheticIdCall = components.syntheticCallGenerator.generateSyntheticCallForArrayOfCall(arrayOfCall, resolutionContext)
arrayOfCall.transformChildren(transformer, ResolutionMode.ContextDependent)
callCompleter.completeCall(syntheticIdCall, data.expectedType ?: components.noExpectedType)
callCompleter.completeCall(syntheticIdCall, data)
return arrayOfCall
}