[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:
Stanislav Erokhin
2017-06-23 14:43:18 +03:00
committed by Mikhail Zarechenskiy
parent b344865c15
commit ab2f99542a
16 changed files with 122 additions and 181 deletions
@@ -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
@@ -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
@@ -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,
@@ -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)
}
@@ -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
@@ -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
}
@@ -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)
@@ -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
@@ -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)
@@ -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"
}
@@ -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()
}
}
@@ -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()
}
@@ -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) }
@@ -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()
@@ -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>
@@ -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
}