From ab2f99542ab4e29634a8062778b8b8f4ad35f44f Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Fri, 23 Jun 2017 14:43:18 +0300 Subject: [PATCH] [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. --- .../tower/KotlinResolutionCallbacksImpl.kt | 4 +- .../tower/KotlinToResolvedCallTransformer.kt | 4 +- .../components/CallableReferenceResolver.kt | 40 ++++++++-- .../calls/components/ExternalComponents.kt | 4 +- .../calls/components/KotlinCallCompleter.kt | 48 ++++++------ .../components/PostponeArgumentsChecks.kt | 78 +++++-------------- .../calls/components/ResolutionParts.kt | 3 +- .../inference/ConstraintSystemBuilder.kt | 9 +-- .../components/FixationOrderCalculator.kt | 13 ++-- .../model/ConstraintPositionAndErrors.kt | 2 +- .../inference/model/ConstraintStorage.kt | 8 +- .../model/MutableConstraintStorage.kt | 4 +- .../model/NewConstraintSystemImpl.kt | 41 ++-------- ...nts.kt => PostponedKotlinCallArguments.kt} | 40 ++++------ .../calls/model/ResolutionCandidate.kt | 3 - .../resolve/calls/model/ResolvedKotlinCall.kt | 2 +- 16 files changed, 122 insertions(+), 181 deletions(-) rename compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/{ResolvedCallElements.kt => PostponedKotlinCallArguments.kt} (57%) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt index 78ad50b89a7..956d33d2587 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinResolutionCallbacksImpl.kt @@ -156,7 +156,7 @@ class KotlinResolutionCallbacksImpl( } override fun completeCallableReference( - callableReferenceArgument: ResolvedCallableReferenceArgument, + callableReferenceArgument: PostponedCallableReferenceArgument, resultTypeParameters: List ) { 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 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt index 46fd83d597c..6939d3a889d 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/tower/KotlinToResolvedCallTransformer.kt @@ -160,7 +160,7 @@ class KotlinToResolvedCallTransformer( private fun runLambdaArgumentsChecks( context: BasicCallResolutionContext, trace: BindingTrace, - lambdaArguments: List + lambdaArguments: List ) { 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 diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt index 46ddefd6e68..1a492cb2aee 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/CallableReferenceResolver.kt @@ -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, diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt index e753b748673..b9fad7bfc54 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ExternalComponents.kt @@ -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) - fun completeCollectionLiteralCalls(collectionLiteralArgument: ResolvedCollectionLiteralArgument) + fun completeCollectionLiteralCalls(collectionLiteralArgument: PostponedCollectionLiteralArgument) } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt index 7e7c3e78281..99381e8a61b 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/KotlinCallCompleter.kt @@ -50,9 +50,8 @@ class KotlinCallCompleter( val hasContradiction: Boolean fun buildCurrentSubstitutor(): NewTypeSubstitutor fun buildResultingSubstitutor(): NewTypeSubstitutor - val lambdaArguments: List - val callableReferenceArguments: List - val collectionLiteralArguments: List + val postponedArguments: List + val lambdaArguments: List // 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 diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt index ca7a2fc415e..a0f4d5b9801 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponeArgumentsChecks.kt @@ -29,29 +29,27 @@ fun createPostponedArgumentAndPerformInitialChecks( kotlinCall: KotlinCall, csBuilder: ConstraintSystemBuilder, argument: PostponableKotlinCallArgument, - parameterDescriptor: ValueParameterDescriptor, - postponeCallableReferenceArguments: MutableList + 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, Any or just `T` -private fun processLambdaArgument( +private fun preprocessLambdaArgument( kotlinCall: KotlinCall, csBuilder: ConstraintSystemBuilder, argument: LambdaKotlinCallArgument, expectedType: UnwrappedType -): KotlinCallDiagnostic? { +): Pair { 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 { 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 { + // todo add some checks about expected type + return PostponedCollectionLiteralArgument(collectionLiteralArgument, expectedType) to null } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt index f4806f3f44c..9f7b38b5fdf 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ResolutionParts.kt @@ -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) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt index 07b2d55cb74..b974c8a0051 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/ConstraintSystemBuilder.kt @@ -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 diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/FixationOrderCalculator.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/FixationOrderCalculator.kt index ec35ddc0d7b..85aea2112a0 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/FixationOrderCalculator.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/FixationOrderCalculator.kt @@ -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 - val lambdaAndCallableReferenceArguments: List + val lambdaArguments: List } 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() - 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) diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt index ce4b4d5dd4d..1868290d790 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintPositionAndErrors.kt @@ -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" } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt index 58fa552be50..35bee549b5e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/ConstraintStorage.kt @@ -52,9 +52,7 @@ interface ConstraintStorage { val maxTypeDepthFromInitialConstraints: Int val errors: List val fixedTypeVariables: Map - val lambdaArguments: List - val callableReferenceArguments: List - val collectionLiteralArguments: List + val postponedArguments: List val innerCalls: List object Empty : ConstraintStorage { @@ -64,9 +62,7 @@ interface ConstraintStorage { override val maxTypeDepthFromInitialConstraints: Int get() = 1 override val errors: List get() = emptyList() override val fixedTypeVariables: Map get() = emptyMap() - override val lambdaArguments: List get() = emptyList() - override val callableReferenceArguments: List get() = emptyList() - override val collectionLiteralArguments: List get() = emptyList() + override val postponedArguments: List get() = emptyList() override val innerCalls: List get() = emptyList() } } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt index dbf93ffc467..e55fed8dc59 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/MutableConstraintStorage.kt @@ -81,8 +81,6 @@ internal class MutableConstraintStorage : ConstraintStorage { override var maxTypeDepthFromInitialConstraints: Int = 1 override val errors: MutableList = ArrayList() override val fixedTypeVariables: MutableMap = LinkedHashMap() - override val lambdaArguments: MutableList = ArrayList() - override val callableReferenceArguments: MutableList = ArrayList() - override val collectionLiteralArguments: MutableList = ArrayList() + override val postponedArguments: MutableList = ArrayList() override val innerCalls: MutableList = ArrayList() } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt index 18a5d33d748..10a2d8e4039 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/model/NewConstraintSystemImpl.kt @@ -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 { @@ -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 get() { + // KotlinCallCompleter.Context, FixationOrderCalculator.Context + override val lambdaArguments: List get() { checkState(State.COMPLETION) - return storage.lambdaArguments + return storage.postponedArguments.filterIsInstance() } // FixationOrderCalculator.Context - override val lambdaAndCallableReferenceArguments: List get() { - checkState(State.COMPLETION) - return storage.lambdaArguments + storage.callableReferenceArguments - } - - override val callableReferenceArguments: List - get() { - checkState(State.COMPLETION) - return storage.callableReferenceArguments - } - - override val collectionLiteralArguments: List - get() { - checkState(State.COMPLETION) - return storage.collectionLiteralArguments - } + override val postponedArguments: List + get() = storage.postponedArguments // KotlinCallCompleter.Context override fun asResultTypeResolverContext() = apply { checkState(State.COMPLETION) } diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallElements.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/PostponedKotlinCallArguments.kt similarity index 57% rename from compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallElements.kt rename to compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/PostponedKotlinCallArguments.kt index 6819c9ad7b9..c53c4939172 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedCallElements.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/PostponedKotlinCallArguments.kt @@ -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 // 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, 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 get() = receiver?.let { parameters + it } ?: parameters - override val outputType: UnwrappedType get() = returnType + val inputTypes: Collection get() = receiver?.let { parameters + it } ?: parameters + val outputType: UnwrappedType get() = returnType lateinit var resultArguments: List lateinit var finalReturnType: UnwrappedType } -class ResolvedCallableReferenceArgument( - override val outerCall: KotlinCall, +class PostponedCallableReferenceArgument( override val argument: CallableReferenceKotlinCallArgument, - val myTypeVariables: List, - val callableResolutionCandidate: CallableReferenceCandidate, - val reflectionType: UnwrappedType // via myTypeVariables variables -) : ArgumentWithPostponeResolution() { - override val inputTypes: Collection 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 + lateinit var callableResolutionCandidate: CallableReferenceCandidate } -class ResolvedCollectionLiteralArgument( - override val outerCall: KotlinCall, +class PostponedCollectionLiteralArgument( override val argument: CollectionLiteralKotlinCallArgument, val expectedType: UnwrappedType -) : ArgumentWithPostponeResolution() { - override val inputTypes: Collection get() = emptyList() - override val outputType: UnwrappedType? = null -} \ No newline at end of file +) : PostponedKotlinCallArgument() \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt index 720527b393a..0e592c9a55f 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolutionCandidate.kt @@ -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 ) : AbstractSimpleKotlinResolutionCandidate(NewConstraintSystemImpl(callContext.constraintInjector, callContext.resultTypeResolver), initialDiagnostics) { val csBuilder: ConstraintSystemBuilder get() = constraintSystem.getBuilder() - val postponeCallableReferenceArguments = SmartList() lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping lateinit var argumentMappingByOriginal: Map diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt index f1bd6c105a0..213eb30c2fb 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/model/ResolvedKotlinCall.kt @@ -29,7 +29,7 @@ sealed class ResolvedKotlinCall { class CompletedResolvedKotlinCall( val completedCall: CompletedKotlinCall, val allInnerCalls: Collection, - val lambdaArguments: List + val lambdaArguments: List ): ResolvedKotlinCall() { override val currentStatus get() = completedCall.resolutionStatus }