From 3cf240340c0af66242b8d7ced7a187a76e285137 Mon Sep 17 00:00:00 2001 From: Stanislav Erokhin Date: Wed, 12 Jul 2017 18:42:05 +0300 Subject: [PATCH] [NI] Extract logic about fixation order to separated component --- .../calls/KotlinResolutionConfiguration.kt | 6 + .../components/ConstraintSystemCompleter.kt | 53 +++++++++ .../InitialConstraintSystemCompleterImpl.kt | 79 +++++++++++++ .../calls/components/KotlinCallCompleter.kt | 110 ++++-------------- .../components/PostponedArgumentsAnalyzer.kt | 69 +++++++++++ .../calls/inference/NewConstraintSystem.kt | 4 + .../components/InferenceStepResolver.kt | 6 +- .../model/NewConstraintSystemImpl.kt | 37 +++--- 8 files changed, 263 insertions(+), 101 deletions(-) create mode 100644 compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ConstraintSystemCompleter.kt create mode 100644 compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InitialConstraintSystemCompleterImpl.kt create mode 100644 compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinResolutionConfiguration.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinResolutionConfiguration.kt index c7a276c08a6..882b346c666 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinResolutionConfiguration.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/KotlinResolutionConfiguration.kt @@ -19,3 +19,9 @@ package org.jetbrains.kotlin.resolve.calls val USE_NEW_INFERENCE = false val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC = false + +val USE_CS_COMPLETER_TYPE = CSCompleterType.INITIAL + +enum class CSCompleterType { + INITIAL +} diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ConstraintSystemCompleter.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ConstraintSystemCompleter.kt new file mode 100644 index 00000000000..f1d8a9bca0f --- /dev/null +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/ConstraintSystemCompleter.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.calls.components + +import org.jetbrains.kotlin.resolve.calls.inference.components.FixationOrderCalculator +import org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver +import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable +import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic +import org.jetbrains.kotlin.resolve.calls.model.PostponedKotlinCallArgument +import org.jetbrains.kotlin.types.UnwrappedType + +interface ConstraintSystemCompleter { + enum class CompletionType { + FULL, + PARTIAL + } + + interface Context { + val hasContradiction: Boolean + val postponedArguments: List + + // type can be proper if it not contains not fixed type variables + fun canBeProper(type: UnwrappedType): Boolean + fun asFixationOrderCalculatorContext(): FixationOrderCalculator.Context + fun asResultTypeResolverContext(): ResultTypeResolver.Context + + // mutable operations + fun addError(error: KotlinCallDiagnostic) + fun fixVariable(variable: NewTypeVariable, resultType: UnwrappedType) + } + + fun runCompletion( + c: Context, + type: CompletionType, + topLevelType: UnwrappedType, + analyze: (PostponedKotlinCallArgument) -> Unit + ) + +} \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InitialConstraintSystemCompleterImpl.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InitialConstraintSystemCompleterImpl.kt new file mode 100644 index 00000000000..b3b30660207 --- /dev/null +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/InitialConstraintSystemCompleterImpl.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.calls.components + +import org.jetbrains.kotlin.resolve.calls.components.ConstraintSystemCompleter.Context +import org.jetbrains.kotlin.resolve.calls.inference.components.FixationOrderCalculator +import org.jetbrains.kotlin.resolve.calls.inference.components.InferenceStepResolver +import org.jetbrains.kotlin.resolve.calls.model.PostponedCallableReferenceArgument +import org.jetbrains.kotlin.resolve.calls.model.PostponedKotlinCallArgument +import org.jetbrains.kotlin.resolve.calls.model.PostponedLambdaArgument +import org.jetbrains.kotlin.types.UnwrappedType + +class InitialConstraintSystemCompleterImpl( + private val fixationOrderCalculator: FixationOrderCalculator, + private val inferenceStepResolver: InferenceStepResolver +) : ConstraintSystemCompleter { + + override fun runCompletion( + c: Context, + type: ConstraintSystemCompleter.CompletionType, + topLevelType: UnwrappedType, + analyze: (PostponedKotlinCallArgument) -> Unit + ) { + if (type == ConstraintSystemCompleter.CompletionType.PARTIAL) return + + resolveCallableReferenceArguments(c, analyze) + + while (!oneStepToEndOrLambda(c, topLevelType, analyze)) { + // do nothing -- be happy + } + } + + private fun resolveCallableReferenceArguments(c: Context, analyze: (PostponedKotlinCallArgument) -> Unit) { + c.postponedArguments.filterIsInstance().forEach(analyze) + } + + // true if it is the end (happy or not) + // every step we fix type variable or analyzeLambda + private fun oneStepToEndOrLambda( + c: Context, + topLevelType: UnwrappedType, + analyze: (PostponedKotlinCallArgument) -> Unit + ): Boolean { + val lambda = c.postponedArguments.find { it is PostponedLambdaArgument && canWeAnalyzeIt(c, it) } + if (lambda != null) { + analyze(lambda) + return false + } + + val completionOrder = fixationOrderCalculator.computeCompletionOrder(c.asFixationOrderCalculatorContext(), topLevelType) + return inferenceStepResolver.resolveVariables(c, completionOrder) + } + + + private fun canWeAnalyzeIt(c: Context, lambda: PostponedLambdaArgument): Boolean { + if (lambda.analyzed) return false + + if (c.hasContradiction) return true + + lambda.receiver?.let { + if (!c.canBeProper(it)) return false + } + return lambda.parameters.all { c.canBeProper(it) } + } +} \ 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 883bfbda49f..6bca96c81ea 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 @@ -19,11 +19,11 @@ package org.jetbrains.kotlin.resolve.calls.components import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor -import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder -import org.jetbrains.kotlin.resolve.calls.inference.components.* +import org.jetbrains.kotlin.resolve.calls.CSCompleterType +import org.jetbrains.kotlin.resolve.calls.USE_CS_COMPLETER_TYPE +import org.jetbrains.kotlin.resolve.calls.components.ConstraintSystemCompleter.CompletionType +import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor import org.jetbrains.kotlin.resolve.calls.inference.model.ExpectedTypeConstraintPosition -import org.jetbrains.kotlin.resolve.calls.inference.model.LambdaArgumentConstraintPosition -import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable import org.jetbrains.kotlin.resolve.calls.inference.returnTypeOrNothing import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateCapturedTypes import org.jetbrains.kotlin.resolve.calls.model.* @@ -32,33 +32,22 @@ import org.jetbrains.kotlin.types.TypeApproximatorConfiguration import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.UnwrappedType import org.jetbrains.kotlin.types.checker.NewCapturedType -import org.jetbrains.kotlin.types.typeUtil.builtIns import org.jetbrains.kotlin.types.typeUtil.contains class KotlinCallCompleter( - private val fixationOrderCalculator: FixationOrderCalculator, private val additionalDiagnosticReporter: AdditionalDiagnosticReporter, - private val inferenceStepResolver: InferenceStepResolver, - private val callableReferenceResolver: CallableReferenceResolver + private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer, + initialConstraintSystemCompleter: InitialConstraintSystemCompleterImpl ) { + private val constraintSystemCompleter: ConstraintSystemCompleter = when(USE_CS_COMPLETER_TYPE) { + CSCompleterType.INITIAL -> initialConstraintSystemCompleter + } + interface Context { val innerCalls: List - val hasContradiction: Boolean - fun buildCurrentSubstitutor(): NewTypeSubstitutor fun buildResultingSubstitutor(): NewTypeSubstitutor val postponedArguments: List val lambdaArguments: List - - // type can be proper if it not contains not fixed type variables - fun canBeProper(type: UnwrappedType): Boolean - fun asFixationOrderCalculatorContext(): FixationOrderCalculator.Context - fun asResultTypeResolverContext(): ResultTypeResolver.Context - - // mutable operations - fun asConstraintInjectorContext(): ConstraintInjector.Context - fun addError(error: KotlinCallDiagnostic) - fun fixVariable(variable: NewTypeVariable, resultType: UnwrappedType) - fun getBuilder(): ConstraintSystemBuilder } fun transformWhenAmbiguity(candidate: KotlinResolutionCandidate, resolutionCallbacks: KotlinResolutionCallbacks): ResolvedKotlinCall = @@ -77,22 +66,18 @@ class KotlinCallCompleter( else -> candidate as SimpleKotlinResolutionCandidate } - if (topLevelCall.prepareForCompletion(expectedType)) { - val c = candidate.lastCall.constraintSystem.asCallCompleterContext() + val completionType = topLevelCall.prepareForCompletion(expectedType) + val constraintSystem = candidate.lastCall.constraintSystem - resolveCallableReferenceArguments(c) - - topLevelCall.competeCall(c, resolutionCallbacks) - return toCompletedBaseResolvedCall(c, candidate, resolutionCallbacks) + constraintSystemCompleter.runCompletion( + constraintSystem.asConstraintSystemCompleterContext(), completionType, candidate.lastCall.descriptorWithFreshTypes.returnTypeOrNothing + ) { + postponedArgumentsAnalyzer.analyze(constraintSystem.asPostponedArgumentsAnalyzerContext(), resolutionCallbacks, it) } - return ResolvedKotlinCall.OnlyResolvedKotlinCall(candidate) - } - - private fun resolveCallableReferenceArguments(c: Context) { - for (callableReferenceArgument in c.postponedArguments) { - if (callableReferenceArgument !is PostponedCallableReferenceArgument) continue - callableReferenceResolver.processCallableReferenceArgument(c.getBuilder(), callableReferenceArgument) + return when (completionType) { + CompletionType.FULL -> toCompletedBaseResolvedCall(constraintSystem.asCallCompleterContext(), candidate, resolutionCallbacks) + CompletionType.PARTIAL -> ResolvedKotlinCall.OnlyResolvedKotlinCall(candidate) } } @@ -169,62 +154,17 @@ class KotlinCallCompleter( } // true if we should complete this call - private fun SimpleKotlinResolutionCandidate.prepareForCompletion(expectedType: UnwrappedType?): Boolean { - val returnType = descriptorWithFreshTypes.returnType?.unwrap() ?: return false + private fun SimpleKotlinResolutionCandidate.prepareForCompletion(expectedType: UnwrappedType?): CompletionType { + val returnType = descriptorWithFreshTypes.returnType?.unwrap() ?: return CompletionType.PARTIAL if (expectedType != null && !TypeUtils.noExpectedType(expectedType)) { csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPosition(kotlinCall)) } - return expectedType != null || csBuilder.isProperType(returnType) - } - - private fun SimpleKotlinResolutionCandidate.competeCall(c: Context, resolutionCallbacks: KotlinResolutionCallbacks) { - while (!oneStepToEndOrLambda(c, resolutionCallbacks)) { - // do nothing -- be happy + return if (expectedType != null || csBuilder.isProperType(returnType)) { + CompletionType.FULL } - } - - // true if it is the end (happy or not) - // every step we fix type variable or analyzeLambda - private fun SimpleKotlinResolutionCandidate.oneStepToEndOrLambda(c: Context, resolutionCallbacks: KotlinResolutionCallbacks): Boolean { - val lambda = c.lambdaArguments.find { canWeAnalyzeIt(c, it) } - if (lambda != null) { - analyzeLambda(c, resolutionCallbacks, lambda) - return false + else { + CompletionType.PARTIAL } - - val completionOrder = fixationOrderCalculator.computeCompletionOrder(c.asFixationOrderCalculatorContext(), descriptorWithFreshTypes.returnTypeOrNothing) - return inferenceStepResolver.resolveVariables(c, completionOrder) - } - - private fun analyzeLambda(c: Context, resolutionCallbacks: KotlinResolutionCallbacks, lambda: PostponedLambdaArgument) { - val currentSubstitutor = c.buildCurrentSubstitutor() - fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(type) - - val receiver = lambda.receiver?.let(::substitute) - val parameters = lambda.parameters.map(::substitute) - val expectedType = lambda.returnType.takeIf { c.canBeProper(it) }?.let(::substitute) - lambda.analyzed = true - lambda.resultArguments = resolutionCallbacks.analyzeAndGetLambdaResultArguments(lambda.argument, lambda.isSuspend, receiver, parameters, expectedType) - - for (resultLambdaArgument in lambda.resultArguments) { - checkSimpleArgument(c.getBuilder(), resultLambdaArgument, lambda.returnType.let(::substitute)) - } - - if (lambda.resultArguments.isEmpty()) { - val unitType = lambda.returnType.builtIns.unitType - c.getBuilder().addSubtypeConstraint(lambda.returnType.let(::substitute), unitType, LambdaArgumentConstraintPosition(lambda)) - } - } - - private fun canWeAnalyzeIt(c: Context, lambda: PostponedLambdaArgument): Boolean { - if (lambda.analyzed) return false - - if (c.hasContradiction) return true // to record info about lambda and avoid exceptions - - lambda.receiver?.let { - if (!c.canBeProper(it)) return false - } - return lambda.parameters.all { c.canBeProper(it) } } } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt new file mode 100644 index 00000000000..2746f628dec --- /dev/null +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/components/PostponedArgumentsAnalyzer.kt @@ -0,0 +1,69 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.resolve.calls.components + +import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder +import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor +import org.jetbrains.kotlin.resolve.calls.inference.model.LambdaArgumentConstraintPosition +import org.jetbrains.kotlin.resolve.calls.model.PostponedCallableReferenceArgument +import org.jetbrains.kotlin.resolve.calls.model.PostponedCollectionLiteralArgument +import org.jetbrains.kotlin.resolve.calls.model.PostponedKotlinCallArgument +import org.jetbrains.kotlin.resolve.calls.model.PostponedLambdaArgument +import org.jetbrains.kotlin.types.UnwrappedType +import org.jetbrains.kotlin.types.typeUtil.builtIns + +class PostponedArgumentsAnalyzer( + private val callableReferenceResolver: CallableReferenceResolver +) { + interface Context { + fun buildCurrentSubstitutor(): NewTypeSubstitutor + + // type can be proper if it not contains not fixed type variables + fun canBeProper(type: UnwrappedType): Boolean + + // mutable operations + fun getBuilder(): ConstraintSystemBuilder + } + + fun analyze(c: Context, resolutionCallbacks: KotlinResolutionCallbacks, argument: PostponedKotlinCallArgument) { + when (argument) { + is PostponedLambdaArgument -> analyzeLambda(c, resolutionCallbacks, argument) + is PostponedCallableReferenceArgument -> callableReferenceResolver.processCallableReferenceArgument(c.getBuilder(), argument) + is PostponedCollectionLiteralArgument -> TODO("Not supported") + } + } + + private fun analyzeLambda(c: Context, resolutionCallbacks: KotlinResolutionCallbacks, lambda: PostponedLambdaArgument) { + val currentSubstitutor = c.buildCurrentSubstitutor() + fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(type) + + val receiver = lambda.receiver?.let(::substitute) + val parameters = lambda.parameters.map(::substitute) + val expectedType = lambda.returnType.takeIf { c.canBeProper(it) }?.let(::substitute) + lambda.analyzed = true + lambda.resultArguments = resolutionCallbacks.analyzeAndGetLambdaResultArguments(lambda.argument, lambda.isSuspend, receiver, parameters, expectedType) + + for (resultLambdaArgument in lambda.resultArguments) { + checkSimpleArgument(c.getBuilder(), resultLambdaArgument, lambda.returnType.let(::substitute)) + } + + if (lambda.resultArguments.isEmpty()) { + val unitType = lambda.returnType.builtIns.unitType + c.getBuilder().addSubtypeConstraint(lambda.returnType.let(::substitute), unitType, LambdaArgumentConstraintPosition(lambda)) + } + } +} \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/NewConstraintSystem.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/NewConstraintSystem.kt index 879c72220ec..78bac0781fe 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/NewConstraintSystem.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/NewConstraintSystem.kt @@ -16,7 +16,9 @@ package org.jetbrains.kotlin.resolve.calls.inference +import org.jetbrains.kotlin.resolve.calls.components.ConstraintSystemCompleter import org.jetbrains.kotlin.resolve.calls.components.KotlinCallCompleter +import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic @@ -28,4 +30,6 @@ interface NewConstraintSystem { // after this method we shouldn't mutate system via ConstraintSystemBuilder fun asReadOnlyStorage(): ConstraintStorage fun asCallCompleterContext(): KotlinCallCompleter.Context + fun asConstraintSystemCompleterContext(): ConstraintSystemCompleter.Context + fun asPostponedArgumentsAnalyzerContext(): PostponedArgumentsAnalyzer.Context } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/InferenceStepResolver.kt b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/InferenceStepResolver.kt index 85073847f9a..b2f93b35542 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/InferenceStepResolver.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/resolve/calls/inference/components/InferenceStepResolver.kt @@ -17,7 +17,7 @@ package org.jetbrains.kotlin.resolve.calls.inference.components import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.resolve.calls.components.KotlinCallCompleter +import org.jetbrains.kotlin.resolve.calls.components.ConstraintSystemCompleter 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.NotEnoughInformationForTypeParameter @@ -32,7 +32,7 @@ class InferenceStepResolver( * Resolves one or more of the `variables`. * Returns `true` if type variable resolution should stop. */ - fun resolveVariables(c: KotlinCallCompleter.Context, variables: List): Boolean { + fun resolveVariables(c: ConstraintSystemCompleter.Context, variables: List): Boolean { if (variables.isEmpty()) return true if (c.hasContradiction) return true @@ -50,7 +50,7 @@ class InferenceStepResolver( return false } - private fun VariableWithConstraints.hasProperConstraint(c: KotlinCallCompleter.Context) = + private fun VariableWithConstraints.hasProperConstraint(c: ConstraintSystemCompleter.Context) = constraints.any { !it.isTrivial() && c.canBeProper(it.type) } private fun Constraint.isTrivial() = 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 10a2d8e4039..2526685d18a 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 @@ -16,7 +16,9 @@ package org.jetbrains.kotlin.resolve.calls.inference.model +import org.jetbrains.kotlin.resolve.calls.components.ConstraintSystemCompleter import org.jetbrains.kotlin.resolve.calls.components.KotlinCallCompleter +import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer import org.jetbrains.kotlin.resolve.calls.inference.* import org.jetbrains.kotlin.resolve.calls.inference.components.* import org.jetbrains.kotlin.resolve.calls.model.* @@ -34,7 +36,9 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re ConstraintInjector.Context, ResultTypeResolver.Context, KotlinCallCompleter.Context, - FixationOrderCalculator.Context + FixationOrderCalculator.Context, + ConstraintSystemCompleter.Context, + PostponedArgumentsAnalyzer.Context { private val storage = MutableConstraintStorage() private var state = State.BUILDING @@ -58,8 +62,6 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re override fun getBuilder() = apply { checkState(State.BUILDING, State.COMPLETION) } - override fun asConstraintInjectorContext() = apply { checkState(State.BUILDING, State.COMPLETION) } - override fun asReadOnlyStorage(): ConstraintStorage { checkState(State.BUILDING, State.FREEZED) state = State.FREEZED @@ -72,6 +74,10 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re return this } + override fun asConstraintSystemCompleterContext() = apply { checkState(State.BUILDING) } + + override fun asPostponedArgumentsAnalyzerContext() = apply { checkState(State.BUILDING) } + // ConstraintSystemOperation override fun registerVariable(variable: NewTypeVariable) { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) @@ -178,10 +184,11 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re return storage.buildCurrentSubstitutor() } - // ConstraintSystemBuilder, KotlinCallCompleter.Context + // ConstraintSystemBuilder, ConstraintSystemCompleter.Context override val hasContradiction: Boolean get() = diagnostics.any { !it.candidateApplicability.isSuccess }.apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) } + // ConstraintSystemBuilder override fun addInnerCall(innerCall: ResolvedKotlinCall.OnlyResolvedKotlinCall) { checkState(State.BUILDING, State.COMPLETION) storage.innerCalls.add(innerCall) @@ -232,7 +239,7 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re return storage.notFixedTypeVariables } - // ConstraintInjector.Context, KotlinCallCompleter.Context + // ConstraintInjector.Context, ConstraintSystemCompleter.Context override fun addError(error: KotlinCallDiagnostic) { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) storage.errors.add(error) @@ -240,18 +247,18 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re // KotlinCallCompleter.Context, FixationOrderCalculator.Context override val lambdaArguments: List get() { - checkState(State.COMPLETION) + checkState(State.BUILDING, State.COMPLETION) return storage.postponedArguments.filterIsInstance() } - // FixationOrderCalculator.Context + // FixationOrderCalculator.Context, KotlinCallCompleter.Context, ConstraintSystemCompleter.Context override val postponedArguments: List - get() = storage.postponedArguments + get() = storage.postponedArguments.apply { checkState(State.BUILDING, State.COMPLETION) } - // KotlinCallCompleter.Context - override fun asResultTypeResolverContext() = apply { checkState(State.COMPLETION) } + // ConstraintSystemCompleter.Context + override fun asResultTypeResolverContext() = apply { checkState(State.BUILDING, State.COMPLETION) } - override fun asFixationOrderCalculatorContext() = apply { checkState(State.COMPLETION) } + override fun asFixationOrderCalculatorContext() = apply { checkState(State.BUILDING, State.COMPLETION) } override fun fixVariable(variable: NewTypeVariable, resultType: UnwrappedType) { checkState(State.BUILDING, State.COMPLETION) @@ -268,21 +275,25 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re storage.fixedTypeVariables[variable.freshTypeConstructor] = resultType } + // KotlinCallCompleter.Context override val innerCalls: List get() { checkState(State.COMPLETION) return storage.innerCalls } + // ConstraintSystemCompleter.Context, PostponedArgumentsAnalyzer.Context override fun canBeProper(type: UnwrappedType): Boolean { - checkState(State.COMPLETION) + checkState(State.BUILDING, State.COMPLETION) return !type.contains { storage.notFixedTypeVariables.containsKey(it.constructor) } } + // PostponedArgumentsAnalyzer.Context override fun buildCurrentSubstitutor(): NewTypeSubstitutor { - checkState(State.COMPLETION) + checkState(State.BUILDING, State.COMPLETION) return storage.buildCurrentSubstitutor() } + // KotlinCallCompleter.Context override fun buildResultingSubstitutor(): NewTypeSubstitutor { checkState(State.COMPLETION) val currentSubstitutorMap = storage.fixedTypeVariables.entries.associate {