[NI] Redo how we take care of postpone arguments
The main change here is the following: before callable reference resolution starts directly after choosing candidate. Since now we start resolution before call completion.
This commit is contained in:
committed by
Mikhail Zarechenskiy
parent
b344865c15
commit
ab2f99542a
+2
-2
@@ -156,7 +156,7 @@ class KotlinResolutionCallbacksImpl(
|
||||
}
|
||||
|
||||
override fun completeCallableReference(
|
||||
callableReferenceArgument: ResolvedCallableReferenceArgument,
|
||||
callableReferenceArgument: PostponedCallableReferenceArgument,
|
||||
resultTypeParameters: List<UnwrappedType>
|
||||
) {
|
||||
val callableCandidate = callableReferenceArgument.callableResolutionCandidate
|
||||
@@ -208,7 +208,7 @@ class KotlinResolutionCallbacksImpl(
|
||||
doubleColonExpressionResolver.checkReferenceIsToAllowedMember(callableCandidate.candidate, topLevelCallContext.trace, callableReferenceExpression)
|
||||
}
|
||||
|
||||
override fun completeCollectionLiteralCalls(collectionLiteralArgument: ResolvedCollectionLiteralArgument) {
|
||||
override fun completeCollectionLiteralCalls(collectionLiteralArgument: PostponedCollectionLiteralArgument) {
|
||||
val psiCallArgument = collectionLiteralArgument.argument.psiCallArgument as CollectionLiteralKotlinCallArgumentImpl
|
||||
val context = psiCallArgument.outerCallContext
|
||||
|
||||
|
||||
+2
-2
@@ -160,7 +160,7 @@ class KotlinToResolvedCallTransformer(
|
||||
private fun runLambdaArgumentsChecks(
|
||||
context: BasicCallResolutionContext,
|
||||
trace: BindingTrace,
|
||||
lambdaArguments: List<ResolvedLambdaArgument>
|
||||
lambdaArguments: List<PostponedLambdaArgument>
|
||||
) {
|
||||
for (lambdaArgument in lambdaArguments) {
|
||||
val returnType = lambdaArgument.finalReturnType
|
||||
@@ -180,7 +180,7 @@ class KotlinToResolvedCallTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateTraceForLambdaReturnType(lambdaArgument: ResolvedLambdaArgument, trace: BindingTrace, returnType: UnwrappedType) {
|
||||
private fun updateTraceForLambdaReturnType(lambdaArgument: PostponedLambdaArgument, trace: BindingTrace, returnType: UnwrappedType) {
|
||||
val psiCallArgument = lambdaArgument.argument.psiCallArgument
|
||||
|
||||
val ktArgumentExpression: KtExpression
|
||||
|
||||
+34
-6
@@ -18,12 +18,12 @@ package org.jetbrains.kotlin.resolve.calls.components
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.resolve.calls.context.CheckArgumentTypesMode
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintInjector
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.SimpleConstraintSystemImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.resolve.calls.results.FlatSignature
|
||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadingConflictResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||
@@ -52,10 +52,38 @@ class CallableReferenceOverloadConflictResolver(
|
||||
}
|
||||
}
|
||||
|
||||
class PostponeCallableReferenceArgument(
|
||||
val argument: CallableReferenceKotlinCallArgument,
|
||||
val expectedType: UnwrappedType
|
||||
)
|
||||
fun processCallableReferenceArgument(
|
||||
callContext: KotlinCallContext,
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
postponedArgument: PostponedCallableReferenceArgument
|
||||
): KotlinCallDiagnostic? {
|
||||
val argument = postponedArgument.argument
|
||||
val expectedType = postponedArgument.expectedType
|
||||
|
||||
val subLHSCall = ((argument.lhsResult as? LHSResult.Expression)?.lshCallArgument as? SubKotlinCallArgument)
|
||||
if (subLHSCall != null) {
|
||||
csBuilder.addInnerCall(subLHSCall.resolvedCall)
|
||||
}
|
||||
val candidates = callContext.callableReferenceResolver.runRLSResolution(callContext, argument, expectedType) { checkCallableReference ->
|
||||
csBuilder.runTransaction { checkCallableReference(this); false }
|
||||
}
|
||||
val chosenCandidate = when (candidates.size) {
|
||||
0 -> return NoneCallableReferenceCandidates(argument)
|
||||
1 -> candidates.single()
|
||||
else -> return CallableReferenceCandidatesAmbiguity(argument, candidates)
|
||||
}
|
||||
val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) {
|
||||
csBuilder.checkCallableReference(argument, dispatchReceiver, extensionReceiver, candidate,
|
||||
reflectionCandidateType, expectedType, callContext.scopeTower.lexicalScope.ownerDescriptor)
|
||||
}
|
||||
|
||||
postponedArgument.analyzedAndThereIsResult = true
|
||||
postponedArgument.myTypeVariables = toFreshSubstitutor.freshVariables
|
||||
postponedArgument.callableResolutionCandidate = chosenCandidate
|
||||
|
||||
return diagnostic
|
||||
}
|
||||
|
||||
|
||||
class CallableReferenceResolver(
|
||||
val towerResolver: TowerResolver,
|
||||
|
||||
+2
-2
@@ -44,8 +44,8 @@ interface KotlinResolutionCallbacks {
|
||||
// todo this is hack for some client which try to read ResolvedCall from trace before all calls completed
|
||||
fun bindStubResolvedCallForCandidate(candidate: KotlinResolutionCandidate)
|
||||
|
||||
fun completeCallableReference(callableReferenceArgument: ResolvedCallableReferenceArgument,
|
||||
fun completeCallableReference(callableReferenceArgument: PostponedCallableReferenceArgument,
|
||||
resultTypeParameters: List<UnwrappedType>)
|
||||
|
||||
fun completeCollectionLiteralCalls(collectionLiteralArgument: ResolvedCollectionLiteralArgument)
|
||||
fun completeCollectionLiteralCalls(collectionLiteralArgument: PostponedCollectionLiteralArgument)
|
||||
}
|
||||
+24
-24
@@ -50,9 +50,8 @@ class KotlinCallCompleter(
|
||||
val hasContradiction: Boolean
|
||||
fun buildCurrentSubstitutor(): NewTypeSubstitutor
|
||||
fun buildResultingSubstitutor(): NewTypeSubstitutor
|
||||
val lambdaArguments: List<ResolvedLambdaArgument>
|
||||
val callableReferenceArguments: List<ResolvedCallableReferenceArgument>
|
||||
val collectionLiteralArguments: List<ResolvedCollectionLiteralArgument>
|
||||
val postponedArguments: List<PostponedKotlinCallArgument>
|
||||
val lambdaArguments: List<PostponedLambdaArgument>
|
||||
|
||||
// type can be proper if it not contains not fixed type variables
|
||||
fun canBeProper(type: UnwrappedType): Boolean
|
||||
@@ -83,27 +82,23 @@ class KotlinCallCompleter(
|
||||
}
|
||||
|
||||
if (topLevelCall.prepareForCompletion(expectedType)) {
|
||||
resolveCallableReferenceArguments(topLevelCall)
|
||||
|
||||
val c = candidate.lastCall.constraintSystem.asCallCompleterContext()
|
||||
|
||||
resolveCallableReferenceArguments(c, candidate.lastCall)
|
||||
|
||||
topLevelCall.competeCall(c, resolutionCallbacks)
|
||||
return toCompletedBaseResolvedCall(c, candidate, resolutionCallbacks)
|
||||
}
|
||||
else {
|
||||
// todo I'm not sure that we should do this
|
||||
resolveCallableReferenceArguments(topLevelCall)
|
||||
}
|
||||
|
||||
return ResolvedKotlinCall.OnlyResolvedKotlinCall(candidate)
|
||||
}
|
||||
|
||||
private fun resolveCallableReferenceArguments(candidate: SimpleKotlinResolutionCandidate) {
|
||||
for (callableReferenceArgument in candidate.postponeCallableReferenceArguments) {
|
||||
processCallableReferenceArgument(candidate.callContext, candidate.kotlinCall, candidate.csBuilder,
|
||||
callableReferenceArgument.argument, callableReferenceArgument.expectedType)
|
||||
// todo do not use topLevelCall
|
||||
private fun resolveCallableReferenceArguments(c: Context, topLevelCall: SimpleKotlinResolutionCandidate) {
|
||||
for (callableReferenceArgument in c.postponedArguments) {
|
||||
if (callableReferenceArgument !is PostponedCallableReferenceArgument) continue
|
||||
processCallableReferenceArgument(topLevelCall.callContext, c.getBuilder(), callableReferenceArgument)
|
||||
}
|
||||
candidate.postponeCallableReferenceArguments.clear()
|
||||
}
|
||||
|
||||
private fun toCompletedBaseResolvedCall(
|
||||
@@ -116,14 +111,19 @@ class KotlinCallCompleter(
|
||||
val competedCalls = c.innerCalls.map {
|
||||
it.candidate.toCompletedCall(currentSubstitutor)
|
||||
}
|
||||
c.lambdaArguments.forEach {
|
||||
it.finalReturnType = currentSubstitutor.safeSubstitute(it.returnType)
|
||||
}
|
||||
c.callableReferenceArguments.forEach {
|
||||
resolutionCallbacks.completeCallableReference(it, it.myTypeVariables.map { currentSubstitutor.safeSubstitute(it.defaultType) })
|
||||
}
|
||||
c.collectionLiteralArguments.forEach {
|
||||
resolutionCallbacks.completeCollectionLiteralCalls(it)
|
||||
for (postponedArgument in c.postponedArguments) {
|
||||
when (postponedArgument) {
|
||||
is PostponedLambdaArgument -> {
|
||||
postponedArgument.finalReturnType = currentSubstitutor.safeSubstitute(postponedArgument.returnType)
|
||||
}
|
||||
is PostponedCallableReferenceArgument -> {
|
||||
val resultTypeParameters = postponedArgument.myTypeVariables.map { currentSubstitutor.safeSubstitute(it.defaultType) }
|
||||
resolutionCallbacks.completeCallableReference(postponedArgument, resultTypeParameters)
|
||||
}
|
||||
is PostponedCollectionLiteralArgument -> {
|
||||
resolutionCallbacks.completeCollectionLiteralCalls(postponedArgument)
|
||||
}
|
||||
}
|
||||
}
|
||||
return ResolvedKotlinCall.CompletedResolvedKotlinCall(completedCall, competedCalls, c.lambdaArguments)
|
||||
}
|
||||
@@ -209,7 +209,7 @@ class KotlinCallCompleter(
|
||||
return true
|
||||
}
|
||||
|
||||
private fun analyzeLambda(c: Context, resolutionCallbacks: KotlinResolutionCallbacks, lambda: ResolvedLambdaArgument) {
|
||||
private fun analyzeLambda(c: Context, resolutionCallbacks: KotlinResolutionCallbacks, lambda: PostponedLambdaArgument) {
|
||||
val currentSubstitutor = c.buildCurrentSubstitutor()
|
||||
fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(type)
|
||||
|
||||
@@ -229,7 +229,7 @@ class KotlinCallCompleter(
|
||||
}
|
||||
}
|
||||
|
||||
private fun canWeAnalyzeIt(c: Context, lambda: ResolvedLambdaArgument): Boolean {
|
||||
private fun canWeAnalyzeIt(c: Context, lambda: PostponedLambdaArgument): Boolean {
|
||||
if (lambda.analyzed) return false
|
||||
lambda.receiver?.let {
|
||||
if (!c.canBeProper(it)) return false
|
||||
|
||||
+20
-58
@@ -29,29 +29,27 @@ fun createPostponedArgumentAndPerformInitialChecks(
|
||||
kotlinCall: KotlinCall,
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: PostponableKotlinCallArgument,
|
||||
parameterDescriptor: ValueParameterDescriptor,
|
||||
postponeCallableReferenceArguments: MutableList<PostponeCallableReferenceArgument>
|
||||
parameterDescriptor: ValueParameterDescriptor
|
||||
): KotlinCallDiagnostic? {
|
||||
val expectedType = argument.getExpectedType(parameterDescriptor)
|
||||
return when (argument) {
|
||||
is LambdaKotlinCallArgument -> processLambdaArgument(kotlinCall, csBuilder, argument, expectedType)
|
||||
is CallableReferenceKotlinCallArgument -> {
|
||||
// callable reference resolution will be run after choosing single descriptor
|
||||
postponeCallableReferenceArguments.add(PostponeCallableReferenceArgument(argument, expectedType))
|
||||
checkCallableExpectedType(csBuilder, argument, expectedType)
|
||||
}
|
||||
is CollectionLiteralKotlinCallArgument -> processCollectionLiteralArgument(kotlinCall, csBuilder, argument, expectedType)
|
||||
val (postponedArgument, diagnostic) = when (argument) {
|
||||
is LambdaKotlinCallArgument -> preprocessLambdaArgument(kotlinCall, csBuilder, argument, expectedType)
|
||||
is CallableReferenceKotlinCallArgument -> preprocessCallableReference(csBuilder, argument, expectedType)
|
||||
is CollectionLiteralKotlinCallArgument -> preprocessCollectionLiteralArgument(csBuilder, argument, expectedType)
|
||||
else -> unexpectedArgument(argument)
|
||||
}
|
||||
csBuilder.addPostponedArgument(postponedArgument)
|
||||
|
||||
return diagnostic
|
||||
}
|
||||
|
||||
// if expected type isn't function type, then may be it is Function<R>, Any or just `T`
|
||||
private fun processLambdaArgument(
|
||||
private fun preprocessLambdaArgument(
|
||||
kotlinCall: KotlinCall,
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: LambdaKotlinCallArgument,
|
||||
expectedType: UnwrappedType
|
||||
): KotlinCallDiagnostic? {
|
||||
): Pair<PostponedLambdaArgument, KotlinCallDiagnostic?> {
|
||||
val builtIns = expectedType.builtIns
|
||||
val isSuspend = expectedType.isSuspendFunctionType
|
||||
|
||||
@@ -86,16 +84,13 @@ private fun processLambdaArgument(
|
||||
// what about case where expected type is type variable? In old TY such cases was not supported. => do nothing for now. todo design
|
||||
}
|
||||
|
||||
val resolvedArgument = ResolvedLambdaArgument(kotlinCall, argument, isSuspend, receiverType, parameters, returnType)
|
||||
val resolvedArgument = PostponedLambdaArgument(kotlinCall, argument, isSuspend, receiverType, parameters, returnType)
|
||||
|
||||
csBuilder.addSubtypeConstraint(resolvedArgument.type, expectedType, ArgumentConstraintPosition(argument))
|
||||
csBuilder.addLambdaArgument(resolvedArgument)
|
||||
|
||||
return null
|
||||
return resolvedArgument to null
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun createFreshTypeVariableForLambdaReturnType(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: LambdaKotlinCallArgument,
|
||||
@@ -106,54 +101,21 @@ private fun createFreshTypeVariableForLambdaReturnType(
|
||||
return typeVariable.defaultType
|
||||
}
|
||||
|
||||
private fun checkCallableExpectedType(
|
||||
private fun preprocessCallableReference(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: CallableReferenceKotlinCallArgument,
|
||||
expectedType: UnwrappedType
|
||||
): KotlinCallDiagnostic? {
|
||||
): Pair<PostponedCallableReferenceArgument, KotlinCallDiagnostic?> {
|
||||
val notCallableTypeConstructor = csBuilder.getProperSuperTypeConstructors(expectedType).firstOrNull { !ReflectionTypes.isPossibleExpectedCallableType(it) }
|
||||
return notCallableTypeConstructor?.let { NotCallableExpectedType(argument, expectedType, notCallableTypeConstructor) }
|
||||
val diagnostic = notCallableTypeConstructor?.let { NotCallableExpectedType(argument, expectedType, notCallableTypeConstructor) }
|
||||
return PostponedCallableReferenceArgument(argument, expectedType) to diagnostic
|
||||
}
|
||||
|
||||
fun processCallableReferenceArgument(
|
||||
callContext: KotlinCallContext,
|
||||
kotlinCall: KotlinCall,
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
argument: CallableReferenceKotlinCallArgument,
|
||||
expectedType: UnwrappedType
|
||||
): KotlinCallDiagnostic? {
|
||||
val subLHSCall = ((argument.lhsResult as? LHSResult.Expression)?.lshCallArgument as? SubKotlinCallArgument)
|
||||
if (subLHSCall != null) {
|
||||
csBuilder.addInnerCall(subLHSCall.resolvedCall)
|
||||
}
|
||||
val candidates = callContext.callableReferenceResolver.runRLSResolution(callContext, argument, expectedType) { checkCallableReference ->
|
||||
csBuilder.runTransaction { checkCallableReference(this); false }
|
||||
}
|
||||
val chosenCandidate = when (candidates.size) {
|
||||
0 -> return NoneCallableReferenceCandidates(argument)
|
||||
1 -> candidates.single()
|
||||
else -> return CallableReferenceCandidatesAmbiguity(argument, candidates)
|
||||
}
|
||||
val (toFreshSubstitutor, diagnostic) = with(chosenCandidate) {
|
||||
csBuilder.checkCallableReference(argument, dispatchReceiver, extensionReceiver, candidate,
|
||||
reflectionCandidateType, expectedType, callContext.scopeTower.lexicalScope.ownerDescriptor)
|
||||
}
|
||||
|
||||
val resolvedCallableReference = ResolvedCallableReferenceArgument(
|
||||
kotlinCall, argument, toFreshSubstitutor.freshVariables,
|
||||
chosenCandidate, toFreshSubstitutor.safeSubstitute(chosenCandidate.reflectionCandidateType))
|
||||
|
||||
csBuilder.addCallableReferenceArgument(resolvedCallableReference)
|
||||
|
||||
return diagnostic
|
||||
}
|
||||
|
||||
fun processCollectionLiteralArgument(
|
||||
kotlinCall: KotlinCall,
|
||||
private fun preprocessCollectionLiteralArgument(
|
||||
csBuilder: ConstraintSystemBuilder,
|
||||
collectionLiteralArgument: CollectionLiteralKotlinCallArgument,
|
||||
expectedType: UnwrappedType
|
||||
): KotlinCallDiagnostic? {
|
||||
csBuilder.addCollectionLiteralArgument(ResolvedCollectionLiteralArgument(kotlinCall, collectionLiteralArgument, expectedType))
|
||||
return null
|
||||
): Pair<PostponedCollectionLiteralArgument, KotlinCallDiagnostic?> {
|
||||
// todo add some checks about expected type
|
||||
return PostponedCollectionLiteralArgument(collectionLiteralArgument, expectedType) to null
|
||||
}
|
||||
|
||||
+1
-2
@@ -238,8 +238,7 @@ internal object CheckArguments : ResolutionPart {
|
||||
is SimpleKotlinCallArgument ->
|
||||
checkSimpleArgument(csBuilder, argument, argument.getExpectedType(parameterDescriptor))
|
||||
is PostponableKotlinCallArgument ->
|
||||
createPostponedArgumentAndPerformInitialChecks(
|
||||
kotlinCall, csBuilder, argument, parameterDescriptor, postponeCallableReferenceArguments)
|
||||
createPostponedArgumentAndPerformInitialChecks(kotlinCall, csBuilder, argument, parameterDescriptor)
|
||||
else -> unexpectedArgument(argument)
|
||||
}
|
||||
diagnostics.addIfNotNull(diagnostic)
|
||||
|
||||
+2
-7
@@ -19,10 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.inference
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallableReferenceArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCollectionLiteralArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedKotlinCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedLambdaArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.UnwrappedType
|
||||
|
||||
@@ -40,9 +37,7 @@ interface ConstraintSystemOperation {
|
||||
|
||||
interface ConstraintSystemBuilder : ConstraintSystemOperation {
|
||||
fun addInnerCall(innerCall: ResolvedKotlinCall.OnlyResolvedKotlinCall)
|
||||
fun addLambdaArgument(resolvedLambdaArgument: ResolvedLambdaArgument)
|
||||
fun addCallableReferenceArgument(resolvedCallableReferenceArgument: ResolvedCallableReferenceArgument)
|
||||
fun addCollectionLiteralArgument(collectionLiteralArgument: ResolvedCollectionLiteralArgument)
|
||||
fun addPostponedArgument(postponedArgument: PostponedKotlinCallArgument)
|
||||
|
||||
// if runOperations return true, then this operation will be applied, and function return true
|
||||
fun runTransaction(runOperations: ConstraintSystemOperation.() -> Boolean): Boolean
|
||||
|
||||
+6
-7
@@ -19,8 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.Constraint
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentWithPostponeResolution
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedLambdaArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedLambdaArgument
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.checker.isIntersectionType
|
||||
@@ -43,7 +42,7 @@ class FixationOrderCalculator {
|
||||
|
||||
interface Context {
|
||||
val notFixedTypeVariables: Map<TypeConstructor, VariableWithConstraints>
|
||||
val lambdaAndCallableReferenceArguments: List<ArgumentWithPostponeResolution>
|
||||
val lambdaArguments: List<PostponedLambdaArgument>
|
||||
}
|
||||
|
||||
fun computeCompletionOrder(
|
||||
@@ -88,11 +87,11 @@ class FixationOrderCalculator {
|
||||
}
|
||||
|
||||
private fun buildLambdaEdges() {
|
||||
for (lambdaArgument in c.lambdaAndCallableReferenceArguments) {
|
||||
if (lambdaArgument is ResolvedLambdaArgument && lambdaArgument.analyzed) continue // optimization
|
||||
for (lambdaArgument in c.lambdaArguments) {
|
||||
if (lambdaArgument.analyzed) continue // optimization
|
||||
|
||||
val typeVariablesInReturnType = SmartList<Variable>()
|
||||
lambdaArgument.outputType?.findTypeVariables(typeVariablesInReturnType)
|
||||
lambdaArgument.outputType.findTypeVariables(typeVariablesInReturnType)
|
||||
|
||||
if (typeVariablesInReturnType.isEmpty()) continue // optimization
|
||||
|
||||
@@ -132,7 +131,7 @@ class FixationOrderCalculator {
|
||||
topReturnType.visitType(ResolveDirection.TO_SUBTYPE) { variableWithConstraints, direction ->
|
||||
enterToNode(variableWithConstraints, direction)
|
||||
}
|
||||
for (resolvedLambdaArgument in c.lambdaAndCallableReferenceArguments) {
|
||||
for (resolvedLambdaArgument in c.lambdaArguments) {
|
||||
inner@ for (inputType in resolvedLambdaArgument.inputTypes) {
|
||||
inputType.visitType(ResolveDirection.TO_SUBTYPE) { variableWithConstraints, direction ->
|
||||
enterToNode(variableWithConstraints, direction)
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ class FixVariableConstraintPosition(val variable: NewTypeVariable) : ConstraintP
|
||||
class KnownTypeParameterConstraintPosition(val typeArgument: KotlinType) : ConstraintPosition() {
|
||||
override fun toString() = "TypeArgument $typeArgument"
|
||||
}
|
||||
class LambdaArgumentConstraintPosition(val lambdaArgument: ResolvedLambdaArgument) : ConstraintPosition() {
|
||||
class LambdaArgumentConstraintPosition(val lambdaArgument: PostponedLambdaArgument) : ConstraintPosition() {
|
||||
override fun toString(): String {
|
||||
return "LambdaArgument $lambdaArgument"
|
||||
}
|
||||
|
||||
+2
-6
@@ -52,9 +52,7 @@ interface ConstraintStorage {
|
||||
val maxTypeDepthFromInitialConstraints: Int
|
||||
val errors: List<KotlinCallDiagnostic>
|
||||
val fixedTypeVariables: Map<TypeConstructor, UnwrappedType>
|
||||
val lambdaArguments: List<ResolvedLambdaArgument>
|
||||
val callableReferenceArguments: List<ResolvedCallableReferenceArgument>
|
||||
val collectionLiteralArguments: List<ResolvedCollectionLiteralArgument>
|
||||
val postponedArguments: List<PostponedKotlinCallArgument>
|
||||
val innerCalls: List<ResolvedKotlinCall.OnlyResolvedKotlinCall>
|
||||
|
||||
object Empty : ConstraintStorage {
|
||||
@@ -64,9 +62,7 @@ interface ConstraintStorage {
|
||||
override val maxTypeDepthFromInitialConstraints: Int get() = 1
|
||||
override val errors: List<KotlinCallDiagnostic> get() = emptyList()
|
||||
override val fixedTypeVariables: Map<TypeConstructor, UnwrappedType> get() = emptyMap()
|
||||
override val lambdaArguments: List<ResolvedLambdaArgument> get() = emptyList()
|
||||
override val callableReferenceArguments: List<ResolvedCallableReferenceArgument> get() = emptyList()
|
||||
override val collectionLiteralArguments: List<ResolvedCollectionLiteralArgument> get() = emptyList()
|
||||
override val postponedArguments: List<PostponedKotlinCallArgument> get() = emptyList()
|
||||
override val innerCalls: List<ResolvedKotlinCall.OnlyResolvedKotlinCall> get() = emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -81,8 +81,6 @@ internal class MutableConstraintStorage : ConstraintStorage {
|
||||
override var maxTypeDepthFromInitialConstraints: Int = 1
|
||||
override val errors: MutableList<KotlinCallDiagnostic> = ArrayList()
|
||||
override val fixedTypeVariables: MutableMap<TypeConstructor, UnwrappedType> = LinkedHashMap()
|
||||
override val lambdaArguments: MutableList<ResolvedLambdaArgument> = ArrayList()
|
||||
override val callableReferenceArguments: MutableList<ResolvedCallableReferenceArgument> = ArrayList()
|
||||
override val collectionLiteralArguments: MutableList<ResolvedCollectionLiteralArgument> = ArrayList()
|
||||
override val postponedArguments: MutableList<PostponedKotlinCallArgument> = ArrayList()
|
||||
override val innerCalls: MutableList<ResolvedKotlinCall.OnlyResolvedKotlinCall> = ArrayList()
|
||||
}
|
||||
+8
-33
@@ -143,19 +143,9 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re
|
||||
return false
|
||||
}
|
||||
|
||||
override fun addLambdaArgument(resolvedLambdaArgument: ResolvedLambdaArgument) {
|
||||
override fun addPostponedArgument(postponedArgument: PostponedKotlinCallArgument) {
|
||||
checkState(State.BUILDING, State.COMPLETION)
|
||||
storage.lambdaArguments.add(resolvedLambdaArgument)
|
||||
}
|
||||
|
||||
override fun addCallableReferenceArgument(resolvedCallableReferenceArgument: ResolvedCallableReferenceArgument) {
|
||||
checkState(State.BUILDING, State.COMPLETION)
|
||||
storage.callableReferenceArguments.add(resolvedCallableReferenceArgument)
|
||||
}
|
||||
|
||||
override fun addCollectionLiteralArgument(collectionLiteralArgument: ResolvedCollectionLiteralArgument) {
|
||||
checkState(State.BUILDING, State.COMPLETION)
|
||||
storage.collectionLiteralArguments.add(collectionLiteralArgument)
|
||||
storage.postponedArguments.add(postponedArgument)
|
||||
}
|
||||
|
||||
private fun getVariablesForFixation(): Map<NewTypeVariable, UnwrappedType> {
|
||||
@@ -205,8 +195,7 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re
|
||||
storage.maxTypeDepthFromInitialConstraints = Math.max(storage.maxTypeDepthFromInitialConstraints, otherSystem.maxTypeDepthFromInitialConstraints)
|
||||
storage.errors.addAll(otherSystem.errors)
|
||||
storage.fixedTypeVariables.putAll(otherSystem.fixedTypeVariables)
|
||||
storage.lambdaArguments.addAll(otherSystem.lambdaArguments)
|
||||
storage.callableReferenceArguments.addAll(otherSystem.callableReferenceArguments)
|
||||
storage.postponedArguments.addAll(otherSystem.postponedArguments)
|
||||
storage.innerCalls.addAll(otherSystem.innerCalls)
|
||||
}
|
||||
|
||||
@@ -249,29 +238,15 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re
|
||||
storage.errors.add(error)
|
||||
}
|
||||
|
||||
// KotlinCallCompleter.Context
|
||||
override val lambdaArguments: List<ResolvedLambdaArgument> get() {
|
||||
// KotlinCallCompleter.Context, FixationOrderCalculator.Context
|
||||
override val lambdaArguments: List<PostponedLambdaArgument> get() {
|
||||
checkState(State.COMPLETION)
|
||||
return storage.lambdaArguments
|
||||
return storage.postponedArguments.filterIsInstance<PostponedLambdaArgument>()
|
||||
}
|
||||
|
||||
// FixationOrderCalculator.Context
|
||||
override val lambdaAndCallableReferenceArguments: List<ArgumentWithPostponeResolution> get() {
|
||||
checkState(State.COMPLETION)
|
||||
return storage.lambdaArguments + storage.callableReferenceArguments
|
||||
}
|
||||
|
||||
override val callableReferenceArguments: List<ResolvedCallableReferenceArgument>
|
||||
get() {
|
||||
checkState(State.COMPLETION)
|
||||
return storage.callableReferenceArguments
|
||||
}
|
||||
|
||||
override val collectionLiteralArguments: List<ResolvedCollectionLiteralArgument>
|
||||
get() {
|
||||
checkState(State.COMPLETION)
|
||||
return storage.collectionLiteralArguments
|
||||
}
|
||||
override val postponedArguments: List<PostponedKotlinCallArgument>
|
||||
get() = storage.postponedArguments
|
||||
|
||||
// KotlinCallCompleter.Context
|
||||
override fun asResultTypeResolverContext() = apply { checkState(State.COMPLETION) }
|
||||
|
||||
+16
-24
@@ -25,48 +25,40 @@ import org.jetbrains.kotlin.types.UnwrappedType
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
|
||||
sealed class ArgumentWithPostponeResolution {
|
||||
abstract val outerCall: KotlinCall
|
||||
abstract val argument: KotlinCallArgument
|
||||
abstract val inputTypes: Collection<UnwrappedType> // parameters and implicit receiver
|
||||
abstract val outputType: UnwrappedType?
|
||||
sealed class PostponedKotlinCallArgument {
|
||||
abstract val argument: PostponableKotlinCallArgument
|
||||
}
|
||||
|
||||
class ResolvedLambdaArgument(
|
||||
override val outerCall: KotlinCall,
|
||||
class PostponedLambdaArgument(
|
||||
val outerCall: KotlinCall,
|
||||
override val argument: LambdaKotlinCallArgument,
|
||||
val isSuspend: Boolean,
|
||||
val receiver: UnwrappedType?,
|
||||
val parameters: List<UnwrappedType>,
|
||||
val returnType: UnwrappedType
|
||||
) : ArgumentWithPostponeResolution() {
|
||||
) : PostponedKotlinCallArgument() {
|
||||
var analyzed: Boolean = false
|
||||
|
||||
val type: SimpleType = createFunctionType(returnType.builtIns, Annotations.EMPTY, receiver, parameters, null, returnType, isSuspend) // todo support annotations
|
||||
|
||||
override val inputTypes: Collection<UnwrappedType> get() = receiver?.let { parameters + it } ?: parameters
|
||||
override val outputType: UnwrappedType get() = returnType
|
||||
val inputTypes: Collection<UnwrappedType> get() = receiver?.let { parameters + it } ?: parameters
|
||||
val outputType: UnwrappedType get() = returnType
|
||||
|
||||
lateinit var resultArguments: List<SimpleKotlinCallArgument>
|
||||
lateinit var finalReturnType: UnwrappedType
|
||||
}
|
||||
|
||||
class ResolvedCallableReferenceArgument(
|
||||
override val outerCall: KotlinCall,
|
||||
class PostponedCallableReferenceArgument(
|
||||
override val argument: CallableReferenceKotlinCallArgument,
|
||||
val myTypeVariables: List<NewTypeVariable>,
|
||||
val callableResolutionCandidate: CallableReferenceCandidate,
|
||||
val reflectionType: UnwrappedType // via myTypeVariables variables
|
||||
) : ArgumentWithPostponeResolution() {
|
||||
override val inputTypes: Collection<UnwrappedType> get() = reflectionType.arguments.dropLast(1).map { it.type.unwrap() }
|
||||
override val outputType: UnwrappedType? = reflectionType.arguments.last().type.unwrap()
|
||||
val expectedType: UnwrappedType
|
||||
) : PostponedKotlinCallArgument() {
|
||||
var analyzedAndThereIsResult: Boolean = false
|
||||
|
||||
lateinit var myTypeVariables: List<NewTypeVariable>
|
||||
lateinit var callableResolutionCandidate: CallableReferenceCandidate
|
||||
}
|
||||
|
||||
class ResolvedCollectionLiteralArgument(
|
||||
override val outerCall: KotlinCall,
|
||||
class PostponedCollectionLiteralArgument(
|
||||
override val argument: CollectionLiteralKotlinCallArgument,
|
||||
val expectedType: UnwrappedType
|
||||
) : ArgumentWithPostponeResolution() {
|
||||
override val inputTypes: Collection<UnwrappedType> get() = emptyList()
|
||||
override val outputType: UnwrappedType? = null
|
||||
}
|
||||
) : PostponedKotlinCallArgument()
|
||||
-3
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.resolve.calls.model
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
||||
import org.jetbrains.kotlin.resolve.calls.components.PostponeCallableReferenceArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
||||
@@ -30,7 +29,6 @@ import org.jetbrains.kotlin.resolve.calls.tower.Candidate
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateStatus
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import java.util.*
|
||||
|
||||
|
||||
@@ -116,7 +114,6 @@ open class SimpleKotlinResolutionCandidate(
|
||||
initialDiagnostics: Collection<KotlinCallDiagnostic>
|
||||
) : AbstractSimpleKotlinResolutionCandidate(NewConstraintSystemImpl(callContext.constraintInjector, callContext.resultTypeResolver), initialDiagnostics) {
|
||||
val csBuilder: ConstraintSystemBuilder get() = constraintSystem.getBuilder()
|
||||
val postponeCallableReferenceArguments = SmartList<PostponeCallableReferenceArgument>()
|
||||
|
||||
lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
|
||||
lateinit var argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ sealed class ResolvedKotlinCall {
|
||||
class CompletedResolvedKotlinCall(
|
||||
val completedCall: CompletedKotlinCall,
|
||||
val allInnerCalls: Collection<CompletedKotlinCall>,
|
||||
val lambdaArguments: List<ResolvedLambdaArgument>
|
||||
val lambdaArguments: List<PostponedLambdaArgument>
|
||||
): ResolvedKotlinCall() {
|
||||
override val currentStatus get() = completedCall.resolutionStatus
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user