[NI] Resolve receiver of provideDelegate independently

#KT-38259 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2020-04-28 03:28:08 +03:00
parent 59f027e3e9
commit 2cee82a348
25 changed files with 211 additions and 53 deletions
@@ -31,6 +31,8 @@ interface InferenceSession {
override fun computeCompletionMode(
candidate: KotlinResolutionCandidate
): KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode? = null
override fun resolveReceiverIndependently(): Boolean = false
}
}
@@ -49,6 +51,7 @@ interface InferenceSession {
fun callCompleted(resolvedAtom: ResolvedAtom): Boolean
fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom): Boolean
fun computeCompletionMode(candidate: KotlinResolutionCandidate): KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode?
fun resolveReceiverIndependently(): Boolean
}
interface PartialCallInfo {
@@ -36,9 +36,10 @@ fun resolveKtPrimitive(
diagnosticsHolder: KotlinDiagnosticsHolder,
receiverInfo: ReceiverInfo,
convertedType: UnwrappedType?,
inferenceSession: InferenceSession?
): ResolvedAtom = when (argument) {
is SimpleKotlinCallArgument ->
checkSimpleArgument(csBuilder, argument, expectedType, diagnosticsHolder, receiverInfo, convertedType)
checkSimpleArgument(csBuilder, argument, expectedType, diagnosticsHolder, receiverInfo, convertedType, inferenceSession)
is LambdaKotlinCallArgument ->
preprocessLambdaArgument(csBuilder, argument, expectedType, diagnosticsHolder)
@@ -149,7 +149,9 @@ class PostponedArgumentsAnalyzer(
val subResolvedKtPrimitives = allReturnArguments.map {
resolveKtPrimitive(
c.getBuilder(), it, lambda.returnType.let(::substitute), diagnosticHolder, ReceiverInfo.notReceiver, convertedType = null
c.getBuilder(), it, lambda.returnType.let(::substitute),
diagnosticHolder, ReceiverInfo.notReceiver, convertedType = null,
inferenceSession
)
}
@@ -439,6 +439,7 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument(
} else null
val inferenceSession = resolutionCallbacks.inferenceSession
if (candidateExpectedType == null || // Nothing to convert
convertedExpectedType != null || // Type is already converted
isReceiver || // Receivers don't participate in conversions
@@ -452,7 +453,8 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument(
expectedType,
this,
receiverInfo,
convertedArgument?.unknownIntegerType?.unwrap()
convertedArgument?.unknownIntegerType?.unwrap(),
inferenceSession
)
addResolvedKtPrimitive(resolvedAtom)
@@ -465,7 +467,8 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument(
expectedType,
this@resolveKotlinArgument,
receiverInfo,
convertedArgument?.unknownIntegerType?.unwrap()
convertedArgument?.unknownIntegerType?.unwrap(),
inferenceSession
)
if (!hasContradiction) {
@@ -496,7 +499,8 @@ private fun KotlinResolutionCandidate.resolveKotlinArgument(
convertedTypeAfterSubtyping,
this@resolveKotlinArgument,
receiverInfo,
convertedArgument?.unknownIntegerType?.unwrap()
convertedArgument?.unknownIntegerType?.unwrap(),
inferenceSession
)
addResolvedKtPrimitive(resolvedAtom)
}
@@ -51,10 +51,11 @@ fun checkSimpleArgument(
expectedType: UnwrappedType?,
diagnosticsHolder: KotlinDiagnosticsHolder,
receiverInfo: ReceiverInfo,
convertedType: UnwrappedType?
convertedType: UnwrappedType?,
inferenceSession: InferenceSession?
): ResolvedAtom = when (argument) {
is ExpressionKotlinCallArgument -> checkExpressionArgument(csBuilder, argument, expectedType, diagnosticsHolder, receiverInfo.isReceiver, convertedType)
is SubKotlinCallArgument -> checkSubCallArgument(csBuilder, argument, expectedType, diagnosticsHolder, receiverInfo)
is SubKotlinCallArgument -> checkSubCallArgument(csBuilder, argument, expectedType, diagnosticsHolder, receiverInfo, inferenceSession)
else -> unexpectedArgument(argument)
}
@@ -178,8 +179,11 @@ private fun checkSubCallArgument(
expectedType: UnwrappedType?,
diagnosticsHolder: KotlinDiagnosticsHolder,
receiverInfo: ReceiverInfo,
inferenceSession: InferenceSession?
): ResolvedAtom {
val subCallResult = ResolvedSubCallArgument(subCallArgument)
val subCallResult = ResolvedSubCallArgument(
subCallArgument, receiverInfo.isReceiver && inferenceSession?.resolveReceiverIndependently() == true
)
if (expectedType == null) return subCallResult
@@ -65,8 +65,10 @@ class SimpleCandidateFactory(
init {
val baseSystem = NewConstraintSystemImpl(callComponents.constraintInjector, callComponents.builtIns)
baseSystem.addSubsystemFromArgument(kotlinCall.explicitReceiver)
baseSystem.addSubsystemFromArgument(kotlinCall.dispatchReceiverForInvokeExtension)
if (!inferenceSession.resolveReceiverIndependently()) {
baseSystem.addSubsystemFromArgument(kotlinCall.explicitReceiver)
baseSystem.addSubsystemFromArgument(kotlinCall.dispatchReceiverForInvokeExtension)
}
for (argument in kotlinCall.argumentsInParenthesis) {
baseSystem.addSubsystemFromArgument(argument)
}
@@ -83,9 +83,12 @@ class ResolvedExpressionAtom(override val atom: ExpressionKotlinCallArgument) :
}
}
class ResolvedSubCallArgument(override val atom: SubKotlinCallArgument) : ResolvedAtom() {
class ResolvedSubCallArgument(override val atom: SubKotlinCallArgument, resolveIndependently: Boolean) : ResolvedAtom() {
init {
setAnalyzedResults(listOf(atom.callResult))
if (resolveIndependently)
setAnalyzedResults(listOf())
else
setAnalyzedResults(listOf(atom.callResult))
}
}