[NI] Extract logic about fixation order to separated component

This commit is contained in:
Stanislav Erokhin
2017-07-12 18:42:05 +03:00
parent ff1e230828
commit 3cf240340c
8 changed files with 263 additions and 101 deletions
@@ -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
}
@@ -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<PostponedKotlinCallArgument>
// 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
)
}
@@ -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<PostponedCallableReferenceArgument>().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) }
}
}
@@ -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<ResolvedKotlinCall.OnlyResolvedKotlinCall>
val hasContradiction: Boolean
fun buildCurrentSubstitutor(): NewTypeSubstitutor
fun buildResultingSubstitutor(): NewTypeSubstitutor
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
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) }
}
}
@@ -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))
}
}
}
@@ -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
}
@@ -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<VariableResolutionNode>): Boolean {
fun resolveVariables(c: ConstraintSystemCompleter.Context, variables: List<VariableResolutionNode>): 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() =
@@ -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<PostponedLambdaArgument> get() {
checkState(State.COMPLETION)
checkState(State.BUILDING, State.COMPLETION)
return storage.postponedArguments.filterIsInstance<PostponedLambdaArgument>()
}
// FixationOrderCalculator.Context
// FixationOrderCalculator.Context, KotlinCallCompleter.Context, ConstraintSystemCompleter.Context
override val postponedArguments: List<PostponedKotlinCallArgument>
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<ResolvedKotlinCall.OnlyResolvedKotlinCall> 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 {