[NI] Extract logic about fixation order to separated component
This commit is contained in:
+6
@@ -19,3 +19,9 @@ package org.jetbrains.kotlin.resolve.calls
|
|||||||
val USE_NEW_INFERENCE = false
|
val USE_NEW_INFERENCE = false
|
||||||
|
|
||||||
val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC = false
|
val REPORT_MISSING_NEW_INFERENCE_DIAGNOSTIC = false
|
||||||
|
|
||||||
|
val USE_CS_COMPLETER_TYPE = CSCompleterType.INITIAL
|
||||||
|
|
||||||
|
enum class CSCompleterType {
|
||||||
|
INITIAL
|
||||||
|
}
|
||||||
|
|||||||
+53
@@ -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
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
+79
@@ -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) }
|
||||||
|
}
|
||||||
|
}
|
||||||
+25
-85
@@ -19,11 +19,11 @@ package org.jetbrains.kotlin.resolve.calls.components
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
import org.jetbrains.kotlin.resolve.calls.CSCompleterType
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.*
|
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.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.returnTypeOrNothing
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateCapturedTypes
|
import org.jetbrains.kotlin.resolve.calls.inference.substituteAndApproximateCapturedTypes
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
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.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
import org.jetbrains.kotlin.types.checker.NewCapturedType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
|
|
||||||
class KotlinCallCompleter(
|
class KotlinCallCompleter(
|
||||||
private val fixationOrderCalculator: FixationOrderCalculator,
|
|
||||||
private val additionalDiagnosticReporter: AdditionalDiagnosticReporter,
|
private val additionalDiagnosticReporter: AdditionalDiagnosticReporter,
|
||||||
private val inferenceStepResolver: InferenceStepResolver,
|
private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
|
||||||
private val callableReferenceResolver: CallableReferenceResolver
|
initialConstraintSystemCompleter: InitialConstraintSystemCompleterImpl
|
||||||
) {
|
) {
|
||||||
|
private val constraintSystemCompleter: ConstraintSystemCompleter = when(USE_CS_COMPLETER_TYPE) {
|
||||||
|
CSCompleterType.INITIAL -> initialConstraintSystemCompleter
|
||||||
|
}
|
||||||
|
|
||||||
interface Context {
|
interface Context {
|
||||||
val innerCalls: List<ResolvedKotlinCall.OnlyResolvedKotlinCall>
|
val innerCalls: List<ResolvedKotlinCall.OnlyResolvedKotlinCall>
|
||||||
val hasContradiction: Boolean
|
|
||||||
fun buildCurrentSubstitutor(): NewTypeSubstitutor
|
|
||||||
fun buildResultingSubstitutor(): NewTypeSubstitutor
|
fun buildResultingSubstitutor(): NewTypeSubstitutor
|
||||||
val postponedArguments: List<PostponedKotlinCallArgument>
|
val postponedArguments: List<PostponedKotlinCallArgument>
|
||||||
val lambdaArguments: List<PostponedLambdaArgument>
|
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 =
|
fun transformWhenAmbiguity(candidate: KotlinResolutionCandidate, resolutionCallbacks: KotlinResolutionCallbacks): ResolvedKotlinCall =
|
||||||
@@ -77,22 +66,18 @@ class KotlinCallCompleter(
|
|||||||
else -> candidate as SimpleKotlinResolutionCandidate
|
else -> candidate as SimpleKotlinResolutionCandidate
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topLevelCall.prepareForCompletion(expectedType)) {
|
val completionType = topLevelCall.prepareForCompletion(expectedType)
|
||||||
val c = candidate.lastCall.constraintSystem.asCallCompleterContext()
|
val constraintSystem = candidate.lastCall.constraintSystem
|
||||||
|
|
||||||
resolveCallableReferenceArguments(c)
|
constraintSystemCompleter.runCompletion(
|
||||||
|
constraintSystem.asConstraintSystemCompleterContext(), completionType, candidate.lastCall.descriptorWithFreshTypes.returnTypeOrNothing
|
||||||
topLevelCall.competeCall(c, resolutionCallbacks)
|
) {
|
||||||
return toCompletedBaseResolvedCall(c, candidate, resolutionCallbacks)
|
postponedArgumentsAnalyzer.analyze(constraintSystem.asPostponedArgumentsAnalyzerContext(), resolutionCallbacks, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResolvedKotlinCall.OnlyResolvedKotlinCall(candidate)
|
return when (completionType) {
|
||||||
}
|
CompletionType.FULL -> toCompletedBaseResolvedCall(constraintSystem.asCallCompleterContext(), candidate, resolutionCallbacks)
|
||||||
|
CompletionType.PARTIAL -> ResolvedKotlinCall.OnlyResolvedKotlinCall(candidate)
|
||||||
private fun resolveCallableReferenceArguments(c: Context) {
|
|
||||||
for (callableReferenceArgument in c.postponedArguments) {
|
|
||||||
if (callableReferenceArgument !is PostponedCallableReferenceArgument) continue
|
|
||||||
callableReferenceResolver.processCallableReferenceArgument(c.getBuilder(), callableReferenceArgument)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,62 +154,17 @@ class KotlinCallCompleter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// true if we should complete this call
|
// true if we should complete this call
|
||||||
private fun SimpleKotlinResolutionCandidate.prepareForCompletion(expectedType: UnwrappedType?): Boolean {
|
private fun SimpleKotlinResolutionCandidate.prepareForCompletion(expectedType: UnwrappedType?): CompletionType {
|
||||||
val returnType = descriptorWithFreshTypes.returnType?.unwrap() ?: return false
|
val returnType = descriptorWithFreshTypes.returnType?.unwrap() ?: return CompletionType.PARTIAL
|
||||||
if (expectedType != null && !TypeUtils.noExpectedType(expectedType)) {
|
if (expectedType != null && !TypeUtils.noExpectedType(expectedType)) {
|
||||||
csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPosition(kotlinCall))
|
csBuilder.addSubtypeConstraint(returnType, expectedType, ExpectedTypeConstraintPosition(kotlinCall))
|
||||||
}
|
}
|
||||||
|
|
||||||
return expectedType != null || csBuilder.isProperType(returnType)
|
return if (expectedType != null || csBuilder.isProperType(returnType)) {
|
||||||
}
|
CompletionType.FULL
|
||||||
|
|
||||||
private fun SimpleKotlinResolutionCandidate.competeCall(c: Context, resolutionCallbacks: KotlinResolutionCallbacks) {
|
|
||||||
while (!oneStepToEndOrLambda(c, resolutionCallbacks)) {
|
|
||||||
// do nothing -- be happy
|
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
|
CompletionType.PARTIAL
|
||||||
// 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+69
@@ -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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference
|
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.KotlinCallCompleter
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||||
|
|
||||||
@@ -28,4 +30,6 @@ interface NewConstraintSystem {
|
|||||||
// after this method we shouldn't mutate system via ConstraintSystemBuilder
|
// after this method we shouldn't mutate system via ConstraintSystemBuilder
|
||||||
fun asReadOnlyStorage(): ConstraintStorage
|
fun asReadOnlyStorage(): ConstraintStorage
|
||||||
fun asCallCompleterContext(): KotlinCallCompleter.Context
|
fun asCallCompleterContext(): KotlinCallCompleter.Context
|
||||||
|
fun asConstraintSystemCompleterContext(): ConstraintSystemCompleter.Context
|
||||||
|
fun asPostponedArgumentsAnalyzerContext(): PostponedArgumentsAnalyzer.Context
|
||||||
}
|
}
|
||||||
+3
-3
@@ -17,7 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.resolve.calls.inference.components
|
package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
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.Constraint
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NotEnoughInformationForTypeParameter
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NotEnoughInformationForTypeParameter
|
||||||
@@ -32,7 +32,7 @@ class InferenceStepResolver(
|
|||||||
* Resolves one or more of the `variables`.
|
* Resolves one or more of the `variables`.
|
||||||
* Returns `true` if type variable resolution should stop.
|
* 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 (variables.isEmpty()) return true
|
||||||
if (c.hasContradiction) return true
|
if (c.hasContradiction) return true
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ class InferenceStepResolver(
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun VariableWithConstraints.hasProperConstraint(c: KotlinCallCompleter.Context) =
|
private fun VariableWithConstraints.hasProperConstraint(c: ConstraintSystemCompleter.Context) =
|
||||||
constraints.any { !it.isTrivial() && c.canBeProper(it.type) }
|
constraints.any { !it.isTrivial() && c.canBeProper(it.type) }
|
||||||
|
|
||||||
private fun Constraint.isTrivial() =
|
private fun Constraint.isTrivial() =
|
||||||
|
|||||||
+24
-13
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference.model
|
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.KotlinCallCompleter
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.*
|
import org.jetbrains.kotlin.resolve.calls.inference.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.*
|
import org.jetbrains.kotlin.resolve.calls.inference.components.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
@@ -34,7 +36,9 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re
|
|||||||
ConstraintInjector.Context,
|
ConstraintInjector.Context,
|
||||||
ResultTypeResolver.Context,
|
ResultTypeResolver.Context,
|
||||||
KotlinCallCompleter.Context,
|
KotlinCallCompleter.Context,
|
||||||
FixationOrderCalculator.Context
|
FixationOrderCalculator.Context,
|
||||||
|
ConstraintSystemCompleter.Context,
|
||||||
|
PostponedArgumentsAnalyzer.Context
|
||||||
{
|
{
|
||||||
private val storage = MutableConstraintStorage()
|
private val storage = MutableConstraintStorage()
|
||||||
private var state = State.BUILDING
|
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 getBuilder() = apply { checkState(State.BUILDING, State.COMPLETION) }
|
||||||
|
|
||||||
override fun asConstraintInjectorContext() = apply { checkState(State.BUILDING, State.COMPLETION) }
|
|
||||||
|
|
||||||
override fun asReadOnlyStorage(): ConstraintStorage {
|
override fun asReadOnlyStorage(): ConstraintStorage {
|
||||||
checkState(State.BUILDING, State.FREEZED)
|
checkState(State.BUILDING, State.FREEZED)
|
||||||
state = State.FREEZED
|
state = State.FREEZED
|
||||||
@@ -72,6 +74,10 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun asConstraintSystemCompleterContext() = apply { checkState(State.BUILDING) }
|
||||||
|
|
||||||
|
override fun asPostponedArgumentsAnalyzerContext() = apply { checkState(State.BUILDING) }
|
||||||
|
|
||||||
// ConstraintSystemOperation
|
// ConstraintSystemOperation
|
||||||
override fun registerVariable(variable: NewTypeVariable) {
|
override fun registerVariable(variable: NewTypeVariable) {
|
||||||
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
||||||
@@ -178,10 +184,11 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re
|
|||||||
return storage.buildCurrentSubstitutor()
|
return storage.buildCurrentSubstitutor()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstraintSystemBuilder, KotlinCallCompleter.Context
|
// ConstraintSystemBuilder, ConstraintSystemCompleter.Context
|
||||||
override val hasContradiction: Boolean
|
override val hasContradiction: Boolean
|
||||||
get() = diagnostics.any { !it.candidateApplicability.isSuccess }.apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) }
|
get() = diagnostics.any { !it.candidateApplicability.isSuccess }.apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) }
|
||||||
|
|
||||||
|
// ConstraintSystemBuilder
|
||||||
override fun addInnerCall(innerCall: ResolvedKotlinCall.OnlyResolvedKotlinCall) {
|
override fun addInnerCall(innerCall: ResolvedKotlinCall.OnlyResolvedKotlinCall) {
|
||||||
checkState(State.BUILDING, State.COMPLETION)
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
storage.innerCalls.add(innerCall)
|
storage.innerCalls.add(innerCall)
|
||||||
@@ -232,7 +239,7 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re
|
|||||||
return storage.notFixedTypeVariables
|
return storage.notFixedTypeVariables
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConstraintInjector.Context, KotlinCallCompleter.Context
|
// ConstraintInjector.Context, ConstraintSystemCompleter.Context
|
||||||
override fun addError(error: KotlinCallDiagnostic) {
|
override fun addError(error: KotlinCallDiagnostic) {
|
||||||
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
||||||
storage.errors.add(error)
|
storage.errors.add(error)
|
||||||
@@ -240,18 +247,18 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re
|
|||||||
|
|
||||||
// KotlinCallCompleter.Context, FixationOrderCalculator.Context
|
// KotlinCallCompleter.Context, FixationOrderCalculator.Context
|
||||||
override val lambdaArguments: List<PostponedLambdaArgument> get() {
|
override val lambdaArguments: List<PostponedLambdaArgument> get() {
|
||||||
checkState(State.COMPLETION)
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
return storage.postponedArguments.filterIsInstance<PostponedLambdaArgument>()
|
return storage.postponedArguments.filterIsInstance<PostponedLambdaArgument>()
|
||||||
}
|
}
|
||||||
|
|
||||||
// FixationOrderCalculator.Context
|
// FixationOrderCalculator.Context, KotlinCallCompleter.Context, ConstraintSystemCompleter.Context
|
||||||
override val postponedArguments: List<PostponedKotlinCallArgument>
|
override val postponedArguments: List<PostponedKotlinCallArgument>
|
||||||
get() = storage.postponedArguments
|
get() = storage.postponedArguments.apply { checkState(State.BUILDING, State.COMPLETION) }
|
||||||
|
|
||||||
// KotlinCallCompleter.Context
|
// ConstraintSystemCompleter.Context
|
||||||
override fun asResultTypeResolverContext() = apply { checkState(State.COMPLETION) }
|
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) {
|
override fun fixVariable(variable: NewTypeVariable, resultType: UnwrappedType) {
|
||||||
checkState(State.BUILDING, State.COMPLETION)
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
@@ -268,21 +275,25 @@ class NewConstraintSystemImpl(val constraintInjector: ConstraintInjector, val re
|
|||||||
storage.fixedTypeVariables[variable.freshTypeConstructor] = resultType
|
storage.fixedTypeVariables[variable.freshTypeConstructor] = resultType
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KotlinCallCompleter.Context
|
||||||
override val innerCalls: List<ResolvedKotlinCall.OnlyResolvedKotlinCall> get() {
|
override val innerCalls: List<ResolvedKotlinCall.OnlyResolvedKotlinCall> get() {
|
||||||
checkState(State.COMPLETION)
|
checkState(State.COMPLETION)
|
||||||
return storage.innerCalls
|
return storage.innerCalls
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConstraintSystemCompleter.Context, PostponedArgumentsAnalyzer.Context
|
||||||
override fun canBeProper(type: UnwrappedType): Boolean {
|
override fun canBeProper(type: UnwrappedType): Boolean {
|
||||||
checkState(State.COMPLETION)
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
return !type.contains { storage.notFixedTypeVariables.containsKey(it.constructor) }
|
return !type.contains { storage.notFixedTypeVariables.containsKey(it.constructor) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PostponedArgumentsAnalyzer.Context
|
||||||
override fun buildCurrentSubstitutor(): NewTypeSubstitutor {
|
override fun buildCurrentSubstitutor(): NewTypeSubstitutor {
|
||||||
checkState(State.COMPLETION)
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
return storage.buildCurrentSubstitutor()
|
return storage.buildCurrentSubstitutor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KotlinCallCompleter.Context
|
||||||
override fun buildResultingSubstitutor(): NewTypeSubstitutor {
|
override fun buildResultingSubstitutor(): NewTypeSubstitutor {
|
||||||
checkState(State.COMPLETION)
|
checkState(State.COMPLETION)
|
||||||
val currentSubstitutorMap = storage.fixedTypeVariables.entries.associate {
|
val currentSubstitutorMap = storage.fixedTypeVariables.entries.associate {
|
||||||
|
|||||||
Reference in New Issue
Block a user