[NI] Introduce inference for coroutines and builder-like constructions
This commit is contained in:
+8
-7
@@ -9,16 +9,14 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
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.VariableDescriptorWithAccessors
|
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.ErrorCallInfo
|
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.PartialCallInfo
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.DelegatedPropertyConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.DelegatedPropertyConstraintPosition
|
||||||
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.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallComponents
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallComponents
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallAtom
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCallAtom
|
||||||
@@ -26,6 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.ManyCandidatesResolver
|
|||||||
import org.jetbrains.kotlin.resolve.calls.tower.PSICallResolver
|
import org.jetbrains.kotlin.resolve.calls.tower.PSICallResolver
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.PSIPartialCallInfo
|
import org.jetbrains.kotlin.resolve.calls.tower.PSIPartialCallInfo
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
@@ -83,6 +82,8 @@ class DelegatedPropertyInferenceSession(
|
|||||||
|
|
||||||
addConstraintForThis(candidateDescriptor, commonSystem)
|
addConstraintForThis(candidateDescriptor, commonSystem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun inferPostponedVariables(initialStorage: ConstraintStorage): Map<TypeConstructor, UnwrappedType> = emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
object InferenceSessionForExistingCandidates : InferenceSession {
|
object InferenceSessionForExistingCandidates : InferenceSession {
|
||||||
@@ -91,9 +92,9 @@ object InferenceSessionForExistingCandidates : InferenceSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun addPartialCallInfo(callInfo: PartialCallInfo) {}
|
override fun addPartialCallInfo(callInfo: PartialCallInfo) {}
|
||||||
|
override fun addCompletedCallInfo(callInfo: CompletedCallInfo) {}
|
||||||
override fun addErrorCallInfo(callInfo: ErrorCallInfo) {}
|
override fun addErrorCallInfo(callInfo: ErrorCallInfo) {}
|
||||||
|
|
||||||
override fun currentConstraintSystem(): ConstraintStorage {
|
override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty
|
||||||
return ConstraintStorage.Empty
|
override fun inferPostponedVariables(initialStorage: ConstraintStorage): Map<TypeConstructor, UnwrappedType> = emptyMap()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -145,6 +145,14 @@ public abstract class ResolutionContext<Context extends ResolutionContext<Contex
|
|||||||
inferenceSession);
|
inferenceSession);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public Context replaceInferenceSession(@NotNull InferenceSession newInferenceSession) {
|
||||||
|
if (newInferenceSession == inferenceSession) return self();
|
||||||
|
return create(trace, scope, dataFlowInfo, expectedType, contextDependency, resolutionResultsCache, statementFilter,
|
||||||
|
collectAllCandidates, callPosition, expressionContextProvider, languageVersionSettings, dataFlowValueFactory,
|
||||||
|
newInferenceSession);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Context replaceExpectedType(@Nullable KotlinType newExpectedType) {
|
public Context replaceExpectedType(@Nullable KotlinType newExpectedType) {
|
||||||
if (newExpectedType == null) return replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE);
|
if (newExpectedType == null) return replaceExpectedType(TypeUtils.NO_EXPECTED_TYPE);
|
||||||
|
|||||||
+154
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.resolve.calls.inference
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.CompletedCallInfo
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintKind
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallComponents
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||||
|
import org.jetbrains.kotlin.types.NonFixedType
|
||||||
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
|
|
||||||
|
class CoroutineInferenceSession(
|
||||||
|
psiCallResolver: PSICallResolver,
|
||||||
|
postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
|
||||||
|
kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter,
|
||||||
|
callComponents: KotlinCallComponents,
|
||||||
|
builtIns: KotlinBuiltIns,
|
||||||
|
private val stubsForPostponedVariables: Map<NewTypeVariable, NonFixedType>,
|
||||||
|
private val trace: BindingTrace,
|
||||||
|
private val kotlinToResolvedCallTransformer: KotlinToResolvedCallTransformer
|
||||||
|
) : ManyCandidatesResolver<CallableDescriptor>(
|
||||||
|
psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns
|
||||||
|
) {
|
||||||
|
private val suspendCompletedCalls = arrayListOf<PSICompletedCallInfo>()
|
||||||
|
private val normalCompletedCalls = arrayListOf<PSICompletedCallInfo>()
|
||||||
|
|
||||||
|
override fun shouldRunCompletion(candidate: KotlinResolutionCandidate): Boolean = true
|
||||||
|
|
||||||
|
override fun addCompletedCallInfo(callInfo: CompletedCallInfo) {
|
||||||
|
require(callInfo is PSICompletedCallInfo) { "Wrong instance of callInfo: $callInfo" }
|
||||||
|
|
||||||
|
val candidateDescriptor = callInfo.callResolutionResult.resultCallAtom.candidateDescriptor
|
||||||
|
if (candidateDescriptor is FunctionDescriptor && candidateDescriptor.isSuspend)
|
||||||
|
suspendCompletedCalls.add(callInfo)
|
||||||
|
else
|
||||||
|
normalCompletedCalls.add(callInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun currentConstraintSystem(): ConstraintStorage {
|
||||||
|
return ConstraintStorage.Empty
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun inferPostponedVariables(initialStorage: ConstraintStorage): Map<TypeConstructor, UnwrappedType> {
|
||||||
|
val commonSystem = buildCommonSystem(initialStorage)
|
||||||
|
|
||||||
|
val context = commonSystem.asConstraintSystemCompleterContext()
|
||||||
|
kotlinConstraintSystemCompleter.completeConstraintSystem(context, builtIns.unitType)
|
||||||
|
|
||||||
|
updateCalls(initialStorage, commonSystem)
|
||||||
|
|
||||||
|
return commonSystem.fixedTypeVariables
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNonFixedTypeToVariableSubstitutor(): NewTypeSubstitutorByConstructorMap {
|
||||||
|
val bindings = hashMapOf<TypeConstructor, UnwrappedType>()
|
||||||
|
for ((variable, nonFixedType) in stubsForPostponedVariables) {
|
||||||
|
bindings[nonFixedType.constructor] = variable.defaultType
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewTypeSubstitutorByConstructorMap(bindings)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun integrateConstraints(
|
||||||
|
commonSystem: NewConstraintSystemImpl,
|
||||||
|
storage: ConstraintStorage,
|
||||||
|
nonFixedToVariablesSubstitutor: NewTypeSubstitutor
|
||||||
|
) {
|
||||||
|
storage.notFixedTypeVariables.values.forEach { commonSystem.registerVariable(it.typeVariable) }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* storage can contain the following substitutions:
|
||||||
|
* TypeVariable(A) -> ProperType
|
||||||
|
* TypeVariable(B) -> Special-Non-Fixed-Type
|
||||||
|
*
|
||||||
|
* while substitutor from parameter map non-fixed types to the original type variable
|
||||||
|
* */
|
||||||
|
val callSubstitutor = storage.buildResultingSubstitutor()
|
||||||
|
|
||||||
|
for (initialConstraint in storage.initialConstraints) {
|
||||||
|
val lower = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.a))
|
||||||
|
val upper = nonFixedToVariablesSubstitutor.safeSubstitute(callSubstitutor.safeSubstitute(initialConstraint.b))
|
||||||
|
|
||||||
|
if (commonSystem.isProperType(lower) && commonSystem.isProperType(upper)) continue
|
||||||
|
|
||||||
|
when (initialConstraint.constraintKind) {
|
||||||
|
ConstraintKind.LOWER -> error("LOWER constraint shouldn't be used, please use UPPER")
|
||||||
|
|
||||||
|
ConstraintKind.UPPER -> commonSystem.addSubtypeConstraint(lower, upper, initialConstraint.position)
|
||||||
|
|
||||||
|
ConstraintKind.EQUALITY ->
|
||||||
|
with(commonSystem) {
|
||||||
|
addSubtypeConstraint(lower, upper, initialConstraint.position)
|
||||||
|
addSubtypeConstraint(upper, lower, initialConstraint.position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildCommonSystem(initialStorage: ConstraintStorage): NewConstraintSystemImpl {
|
||||||
|
val commonSystem = NewConstraintSystemImpl(callComponents.constraintInjector, builtIns)
|
||||||
|
|
||||||
|
val nonFixedToVariablesSubstitutor = createNonFixedTypeToVariableSubstitutor()
|
||||||
|
|
||||||
|
integrateConstraints(commonSystem, initialStorage, nonFixedToVariablesSubstitutor)
|
||||||
|
|
||||||
|
for (suspendCall in suspendCompletedCalls) {
|
||||||
|
integrateConstraints(commonSystem, suspendCall.callResolutionResult.constraintSystem, nonFixedToVariablesSubstitutor)
|
||||||
|
}
|
||||||
|
|
||||||
|
return commonSystem
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateCalls(initialStorage: ConstraintStorage, commonSystem: NewConstraintSystemImpl) {
|
||||||
|
val nonFixedToResult = mutableMapOf<TypeConstructor, UnwrappedType>()
|
||||||
|
for (variable in initialStorage.postponedTypeVariables) {
|
||||||
|
nonFixedToResult[variable.freshTypeConstructor] = commonSystem.fixedTypeVariables[variable.freshTypeConstructor] ?: continue
|
||||||
|
}
|
||||||
|
|
||||||
|
val commonSystemSubstitutor = NewTypeSubstitutorByConstructorMap(nonFixedToResult)
|
||||||
|
|
||||||
|
for (completedCall in suspendCompletedCalls + normalCompletedCalls) {
|
||||||
|
val resultCallAtom = completedCall.callResolutionResult.resultCallAtom
|
||||||
|
val call = resultCallAtom.atom.getResolvedPsiKotlinCall<CallableDescriptor>(trace) ?: continue
|
||||||
|
|
||||||
|
val resultingCallSubstitutor = completedCall
|
||||||
|
.callResolutionResult
|
||||||
|
.constraintSystem
|
||||||
|
.fixedTypeVariables
|
||||||
|
.entries
|
||||||
|
.associate { it.key to commonSystemSubstitutor.safeSubstitute(it.value) }
|
||||||
|
|
||||||
|
call.setResultingSubstitutor(NewTypeSubstitutorByConstructorMap(resultingCallSubstitutor))
|
||||||
|
|
||||||
|
val resultingDescriptor = call.resultingDescriptor
|
||||||
|
kotlinToResolvedCallTransformer.reportCallDiagnostic(
|
||||||
|
completedCall.context, trace, resultCallAtom, resultingDescriptor, commonSystem.diagnostics
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+26
-9
@@ -23,7 +23,11 @@ import org.jetbrains.kotlin.resolve.TypeResolver
|
|||||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionCallbacks
|
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionCallbacks
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.CoroutineInferenceSession
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
|
||||||
@@ -33,10 +37,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||||
import org.jetbrains.kotlin.types.TypeApproximator
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
|
||||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
|
||||||
import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
|
import org.jetbrains.kotlin.types.expressions.KotlinTypeInfo
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||||
@@ -60,7 +61,11 @@ class KotlinResolutionCallbacksImpl(
|
|||||||
val dataFlowValueFactory: DataFlowValueFactory,
|
val dataFlowValueFactory: DataFlowValueFactory,
|
||||||
override val inferenceSession: InferenceSession,
|
override val inferenceSession: InferenceSession,
|
||||||
val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
||||||
val typeResolver: TypeResolver
|
val typeResolver: TypeResolver,
|
||||||
|
val psiCallResolver: PSICallResolver,
|
||||||
|
val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
|
||||||
|
val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter,
|
||||||
|
val callComponents: KotlinCallComponents
|
||||||
) : KotlinResolutionCallbacks {
|
) : KotlinResolutionCallbacks {
|
||||||
class LambdaInfo(val expectedType: UnwrappedType, val contextDependency: ContextDependency) {
|
class LambdaInfo(val expectedType: UnwrappedType, val contextDependency: ContextDependency) {
|
||||||
val returnStatements = ArrayList<Pair<KtReturnExpression, LambdaContextInfo?>>()
|
val returnStatements = ArrayList<Pair<KtReturnExpression, LambdaContextInfo?>>()
|
||||||
@@ -76,8 +81,9 @@ class KotlinResolutionCallbacksImpl(
|
|||||||
isSuspend: Boolean,
|
isSuspend: Boolean,
|
||||||
receiverType: UnwrappedType?,
|
receiverType: UnwrappedType?,
|
||||||
parameters: List<UnwrappedType>,
|
parameters: List<UnwrappedType>,
|
||||||
expectedReturnType: UnwrappedType?
|
expectedReturnType: UnwrappedType?,
|
||||||
): List<KotlinCallArgument> {
|
stubsForPostponedVariables: Map<NewTypeVariable, NonFixedType>
|
||||||
|
): Pair<List<KotlinCallArgument>, InferenceSession?> {
|
||||||
val psiCallArgument = lambdaArgument.psiCallArgument as PSIFunctionKotlinCallArgument
|
val psiCallArgument = lambdaArgument.psiCallArgument as PSIFunctionKotlinCallArgument
|
||||||
val outerCallContext = psiCallArgument.outerCallContext
|
val outerCallContext = psiCallArgument.outerCallContext
|
||||||
|
|
||||||
@@ -122,11 +128,22 @@ class KotlinResolutionCallbacksImpl(
|
|||||||
val approximatesExpectedType =
|
val approximatesExpectedType =
|
||||||
typeApproximator.approximateToSubType(expectedType, TypeApproximatorConfiguration.LocalDeclaration) ?: expectedType
|
typeApproximator.approximateToSubType(expectedType, TypeApproximatorConfiguration.LocalDeclaration) ?: expectedType
|
||||||
|
|
||||||
|
val coroutineSession =
|
||||||
|
if (stubsForPostponedVariables.isNotEmpty())
|
||||||
|
CoroutineInferenceSession(
|
||||||
|
psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter,
|
||||||
|
callComponents, builtIns, stubsForPostponedVariables, trace, kotlinToResolvedCallTransformer
|
||||||
|
)
|
||||||
|
else
|
||||||
|
null
|
||||||
|
|
||||||
val actualContext = outerCallContext
|
val actualContext = outerCallContext
|
||||||
.replaceBindingTrace(trace)
|
.replaceBindingTrace(trace)
|
||||||
.replaceContextDependency(lambdaInfo.contextDependency)
|
.replaceContextDependency(lambdaInfo.contextDependency)
|
||||||
.replaceExpectedType(approximatesExpectedType)
|
.replaceExpectedType(approximatesExpectedType)
|
||||||
.replaceDataFlowInfo(psiCallArgument.lambdaInitialDataFlowInfo)
|
.replaceDataFlowInfo(psiCallArgument.lambdaInitialDataFlowInfo).let {
|
||||||
|
if (coroutineSession != null) it.replaceInferenceSession(coroutineSession) else it
|
||||||
|
}
|
||||||
|
|
||||||
val functionTypeInfo = expressionTypingServices.getTypeInfo(psiCallArgument.expression, actualContext)
|
val functionTypeInfo = expressionTypingServices.getTypeInfo(psiCallArgument.expression, actualContext)
|
||||||
trace.record(BindingContext.NEW_INFERENCE_LAMBDA_INFO, psiCallArgument.ktFunction, LambdaInfo.STUB_EMPTY)
|
trace.record(BindingContext.NEW_INFERENCE_LAMBDA_INFO, psiCallArgument.ktFunction, LambdaInfo.STUB_EMPTY)
|
||||||
@@ -159,7 +176,7 @@ class KotlinResolutionCallbacksImpl(
|
|||||||
|
|
||||||
returnArguments.addIfNotNull(lastExpressionArgument)
|
returnArguments.addIfNotNull(lastExpressionArgument)
|
||||||
|
|
||||||
return returnArguments
|
return Pair(returnArguments, coroutineSession)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLastDeparentesizedExpression(psiCallArgument: PSIKotlinCallArgument): KtExpression? {
|
private fun getLastDeparentesizedExpression(psiCallArgument: PSIKotlinCallArgument): KtExpression? {
|
||||||
|
|||||||
+6
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtSuperExpression
|
import org.jetbrains.kotlin.psi.KtSuperExpression
|
||||||
import org.jetbrains.kotlin.resolve.DeprecationResolver
|
import org.jetbrains.kotlin.resolve.DeprecationResolver
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||||
@@ -25,8 +26,10 @@ import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isConventionCall
|
|||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isInfixCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isSuperOrDelegatingConstructorCall
|
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isSuperOrDelegatingConstructorCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionStatelessCallbacks
|
import org.jetbrains.kotlin.resolve.calls.components.KotlinResolutionStatelessCallbacks
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.isCoroutineCallWithAdditionalInference
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgument
|
import org.jetbrains.kotlin.resolve.calls.model.CallableReferenceKotlinCallArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCall
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCall
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
|
import org.jetbrains.kotlin.resolve.calls.model.SimpleKotlinCallArgument
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -57,4 +60,7 @@ class KotlinResolutionStatelessCallbacksImpl(
|
|||||||
|
|
||||||
override fun getVariableCandidateIfInvoke(functionCall: KotlinCall) =
|
override fun getVariableCandidateIfInvoke(functionCall: KotlinCall) =
|
||||||
functionCall.safeAs<PSIKotlinCallForInvoke>()?.variableCall
|
functionCall.safeAs<PSIKotlinCallForInvoke>()?.variableCall
|
||||||
|
|
||||||
|
override fun isCoroutineCall(argument: KotlinCallArgument, parameter: ValueParameterDescriptor): Boolean =
|
||||||
|
isCoroutineCallWithAdditionalInference(parameter, argument.psiCallArgument.valueArgument)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-3
@@ -96,6 +96,10 @@ class KotlinToResolvedCallTransformer(
|
|||||||
is CompletedCallResolutionResult, is ErrorCallResolutionResult -> {
|
is CompletedCallResolutionResult, is ErrorCallResolutionResult -> {
|
||||||
val candidate = (baseResolvedCall as SingleCallResolutionResult).resultCallAtom
|
val candidate = (baseResolvedCall as SingleCallResolutionResult).resultCallAtom
|
||||||
|
|
||||||
|
context.inferenceSession.addCompletedCallInfo(
|
||||||
|
PSICompletedCallInfo(baseResolvedCall as CompletedCallResolutionResult, context, tracingStrategy)
|
||||||
|
)
|
||||||
|
|
||||||
val resultSubstitutor = baseResolvedCall.constraintSystem.buildResultingSubstitutor()
|
val resultSubstitutor = baseResolvedCall.constraintSystem.buildResultingSubstitutor()
|
||||||
val ktPrimitiveCompleter = ResolvedAtomCompleter(
|
val ktPrimitiveCompleter = ResolvedAtomCompleter(
|
||||||
resultSubstitutor, context.trace, context, this, expressionTypingServices, argumentTypeResolver,
|
resultSubstitutor, context.trace, context, this, expressionTypingServices, argumentTypeResolver,
|
||||||
@@ -153,8 +157,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
diagnostics: Collection<KotlinCallDiagnostic>
|
diagnostics: Collection<KotlinCallDiagnostic>
|
||||||
): NewResolvedCallImpl<D> {
|
): NewResolvedCallImpl<D> {
|
||||||
if (trace != null) {
|
if (trace != null) {
|
||||||
val storedResolvedCall =
|
val storedResolvedCall = completedSimpleAtom.atom.psiKotlinCall.getResolvedPsiKotlinCall<D>(trace)
|
||||||
completedSimpleAtom.atom.psiKotlinCall.psiCall.getResolvedCall(trace.bindingContext)?.safeAs<NewResolvedCallImpl<D>>()
|
|
||||||
if (storedResolvedCall != null) {
|
if (storedResolvedCall != null) {
|
||||||
storedResolvedCall.setResultingSubstitutor(resultSubstitutor)
|
storedResolvedCall.setResultingSubstitutor(resultSubstitutor)
|
||||||
storedResolvedCall.updateDiagnostics(diagnostics)
|
storedResolvedCall.updateDiagnostics(diagnostics)
|
||||||
@@ -339,7 +342,7 @@ class KotlinToResolvedCallTransformer(
|
|||||||
reportCallDiagnostic(context, trace, functionCall.resolvedCallAtom, functionCall.resultingDescriptor, emptyList())
|
reportCallDiagnostic(context, trace, functionCall.resolvedCallAtom, functionCall.resultingDescriptor, emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reportCallDiagnostic(
|
fun reportCallDiagnostic(
|
||||||
context: BasicCallResolutionContext,
|
context: BasicCallResolutionContext,
|
||||||
trace: BindingTrace,
|
trace: BindingTrace,
|
||||||
completedCallAtom: ResolvedCallAtom,
|
completedCallAtom: ResolvedCallAtom,
|
||||||
|
|||||||
+17
-4
@@ -7,28 +7,31 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.*
|
import org.jetbrains.kotlin.resolve.calls.components.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
|
import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||||
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
|
|
||||||
abstract class ManyCandidatesResolver<D : CallableDescriptor>(
|
abstract class ManyCandidatesResolver<D : CallableDescriptor>(
|
||||||
private val psiCallResolver: PSICallResolver,
|
private val psiCallResolver: PSICallResolver,
|
||||||
private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
|
private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
|
||||||
private val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter,
|
protected val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter,
|
||||||
private val callComponents: KotlinCallComponents,
|
protected val callComponents: KotlinCallComponents,
|
||||||
val builtIns: KotlinBuiltIns
|
val builtIns: KotlinBuiltIns
|
||||||
) : InferenceSession {
|
) : InferenceSession {
|
||||||
private val partiallyResolvedCallsInfo = arrayListOf<PSIPartialCallInfo>()
|
private val partiallyResolvedCallsInfo = arrayListOf<PSIPartialCallInfo>()
|
||||||
private val errorCallsInfo = arrayListOf<PSIErrorCallInfo<D>>()
|
private val errorCallsInfo = arrayListOf<PSIErrorCallInfo<D>>()
|
||||||
|
|
||||||
abstract fun prepareForCompletion(commonSystem: NewConstraintSystem, resolvedCallsInfo: List<PSIPartialCallInfo>)
|
open fun prepareForCompletion(commonSystem: NewConstraintSystem, resolvedCallsInfo: List<PSIPartialCallInfo>) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
override fun shouldRunCompletion(candidate: KotlinResolutionCandidate): Boolean {
|
override fun shouldRunCompletion(candidate: KotlinResolutionCandidate): Boolean {
|
||||||
return false
|
return false
|
||||||
@@ -41,6 +44,10 @@ abstract class ManyCandidatesResolver<D : CallableDescriptor>(
|
|||||||
partiallyResolvedCallsInfo.add(callInfo)
|
partiallyResolvedCallsInfo.add(callInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun addCompletedCallInfo(callInfo: CompletedCallInfo) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
override fun addErrorCallInfo(callInfo: ErrorCallInfo) {
|
override fun addErrorCallInfo(callInfo: ErrorCallInfo) {
|
||||||
if (callInfo !is PSIErrorCallInfo<*>) {
|
if (callInfo !is PSIErrorCallInfo<*>) {
|
||||||
throw AssertionError("Error call info for $callInfo should be instance of PSIErrorCallInfo")
|
throw AssertionError("Error call info for $callInfo should be instance of PSIErrorCallInfo")
|
||||||
@@ -108,6 +115,12 @@ class PSIPartialCallInfo(
|
|||||||
val tracingStrategy: TracingStrategy
|
val tracingStrategy: TracingStrategy
|
||||||
) : PartialCallInfo
|
) : PartialCallInfo
|
||||||
|
|
||||||
|
class PSICompletedCallInfo(
|
||||||
|
override val callResolutionResult: CompletedCallResolutionResult,
|
||||||
|
val context: BasicCallResolutionContext,
|
||||||
|
val tracingStrategy: TracingStrategy
|
||||||
|
) : CompletedCallInfo
|
||||||
|
|
||||||
class PSIErrorCallInfo<D : CallableDescriptor>(
|
class PSIErrorCallInfo<D : CallableDescriptor>(
|
||||||
override val callResolutionResult: CallResolutionResult,
|
override val callResolutionResult: CallResolutionResult,
|
||||||
val result: OverloadResolutionResults<D>
|
val result: OverloadResolutionResults<D>
|
||||||
|
|||||||
@@ -24,9 +24,11 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
|
|||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.isSafeCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
import org.jetbrains.kotlin.resolve.calls.components.InferenceSession
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
import org.jetbrains.kotlin.resolve.calls.context.ContextDependency
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.buildResultingSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.buildResultingSubstitutor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.results.*
|
import org.jetbrains.kotlin.resolve.calls.results.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
@@ -61,7 +63,9 @@ class PSICallResolver(
|
|||||||
private val argumentTypeResolver: ArgumentTypeResolver,
|
private val argumentTypeResolver: ArgumentTypeResolver,
|
||||||
private val effectSystem: EffectSystem,
|
private val effectSystem: EffectSystem,
|
||||||
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
private val constantExpressionEvaluator: ConstantExpressionEvaluator,
|
||||||
private val dataFlowValueFactory: DataFlowValueFactory
|
private val dataFlowValueFactory: DataFlowValueFactory,
|
||||||
|
private val postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
|
||||||
|
private val kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter
|
||||||
) {
|
) {
|
||||||
private val givenCandidatesName = Name.special("<given candidates>")
|
private val givenCandidatesName = Name.special("<given candidates>")
|
||||||
|
|
||||||
@@ -160,7 +164,8 @@ class PSICallResolver(
|
|||||||
KotlinResolutionCallbacksImpl(
|
KotlinResolutionCallbacksImpl(
|
||||||
trace, expressionTypingServices, typeApproximator,
|
trace, expressionTypingServices, typeApproximator,
|
||||||
argumentTypeResolver, languageVersionSettings, kotlinToResolvedCallTransformer,
|
argumentTypeResolver, languageVersionSettings, kotlinToResolvedCallTransformer,
|
||||||
dataFlowValueFactory, inferenceSession, constantExpressionEvaluator, typeResolver
|
dataFlowValueFactory, inferenceSession, constantExpressionEvaluator, typeResolver,
|
||||||
|
this, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun calculateExpectedType(context: BasicCallResolutionContext): UnwrappedType? {
|
private fun calculateExpectedType(context: BasicCallResolutionContext): UnwrappedType? {
|
||||||
|
|||||||
@@ -16,9 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.tower
|
package org.jetbrains.kotlin.resolve.calls.tower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.Call
|
import org.jetbrains.kotlin.psi.Call
|
||||||
|
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||||
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
import org.jetbrains.kotlin.resolve.calls.CallTransformer
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
|
||||||
@@ -26,6 +29,7 @@ import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategyForInvoke
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
val KotlinCall.psiKotlinCall: PSIKotlinCall
|
val KotlinCall.psiKotlinCall: PSIKotlinCall
|
||||||
get() {
|
get() {
|
||||||
@@ -35,6 +39,9 @@ val KotlinCall.psiKotlinCall: PSIKotlinCall
|
|||||||
return this as PSIKotlinCall
|
return this as PSIKotlinCall
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <D : CallableDescriptor> KotlinCall.getResolvedPsiKotlinCall(trace: BindingTrace): NewResolvedCallImpl<D>? =
|
||||||
|
psiKotlinCall.psiCall.getResolvedCall(trace.bindingContext) as? NewResolvedCallImpl<D>
|
||||||
|
|
||||||
abstract class PSIKotlinCall : KotlinCall {
|
abstract class PSIKotlinCall : KotlinCall {
|
||||||
abstract val psiCall: Call
|
abstract val psiCall: Call
|
||||||
abstract val startingDataFlowInfo: DataFlowInfo
|
abstract val startingDataFlowInfo: DataFlowInfo
|
||||||
|
|||||||
+7
-2
@@ -7,9 +7,12 @@ package org.jetbrains.kotlin.resolve.calls.components
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
|
||||||
|
import org.jetbrains.kotlin.types.NonFixedType
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
|
|
||||||
// stateless component
|
// stateless component
|
||||||
@@ -22,6 +25,7 @@ interface KotlinResolutionStatelessCallbacks {
|
|||||||
fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean
|
fun isSuperExpression(receiver: SimpleKotlinCallArgument?): Boolean
|
||||||
fun getScopeTowerForCallableReferenceArgument(argument: CallableReferenceKotlinCallArgument): ImplicitScopeTower
|
fun getScopeTowerForCallableReferenceArgument(argument: CallableReferenceKotlinCallArgument): ImplicitScopeTower
|
||||||
fun getVariableCandidateIfInvoke(functionCall: KotlinCall): KotlinResolutionCandidate?
|
fun getVariableCandidateIfInvoke(functionCall: KotlinCall): KotlinResolutionCandidate?
|
||||||
|
fun isCoroutineCall(argument: KotlinCallArgument, parameter: ValueParameterDescriptor): Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
// This components hold state (trace). Work with this carefully.
|
// This components hold state (trace). Work with this carefully.
|
||||||
@@ -31,8 +35,9 @@ interface KotlinResolutionCallbacks {
|
|||||||
isSuspend: Boolean,
|
isSuspend: Boolean,
|
||||||
receiverType: UnwrappedType?,
|
receiverType: UnwrappedType?,
|
||||||
parameters: List<UnwrappedType>,
|
parameters: List<UnwrappedType>,
|
||||||
expectedReturnType: UnwrappedType? // null means, that return type is not proper i.e. it depends on some type variables
|
expectedReturnType: UnwrappedType?, // null means, that return type is not proper i.e. it depends on some type variables
|
||||||
): List<KotlinCallArgument>
|
stubsForPostponedVariables: Map<NewTypeVariable, NonFixedType>
|
||||||
|
): Pair<List<KotlinCallArgument>, InferenceSession?>
|
||||||
|
|
||||||
fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom)
|
fun bindStubResolvedCallForCandidate(candidate: ResolvedCallAtom)
|
||||||
|
|
||||||
|
|||||||
+12
@@ -6,9 +6,13 @@
|
|||||||
package org.jetbrains.kotlin.resolve.calls.components
|
package org.jetbrains.kotlin.resolve.calls.components
|
||||||
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.CallResolutionResult
|
import org.jetbrains.kotlin.resolve.calls.model.CallResolutionResult
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.CompletedCallResolutionResult
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinResolutionCandidate
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.PartialCallResolutionResult
|
import org.jetbrains.kotlin.resolve.calls.model.PartialCallResolutionResult
|
||||||
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
|
|
||||||
interface InferenceSession {
|
interface InferenceSession {
|
||||||
companion object {
|
companion object {
|
||||||
@@ -16,20 +20,28 @@ interface InferenceSession {
|
|||||||
override fun shouldRunCompletion(candidate: KotlinResolutionCandidate): Boolean = true
|
override fun shouldRunCompletion(candidate: KotlinResolutionCandidate): Boolean = true
|
||||||
override fun addPartialCallInfo(callInfo: PartialCallInfo) {}
|
override fun addPartialCallInfo(callInfo: PartialCallInfo) {}
|
||||||
override fun addErrorCallInfo(callInfo: ErrorCallInfo) {}
|
override fun addErrorCallInfo(callInfo: ErrorCallInfo) {}
|
||||||
|
override fun addCompletedCallInfo(callInfo: CompletedCallInfo) {}
|
||||||
override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty
|
override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty
|
||||||
|
override fun inferPostponedVariables(initialStorage: ConstraintStorage): Map<TypeConstructor, UnwrappedType> = emptyMap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun shouldRunCompletion(candidate: KotlinResolutionCandidate): Boolean
|
fun shouldRunCompletion(candidate: KotlinResolutionCandidate): Boolean
|
||||||
fun addPartialCallInfo(callInfo: PartialCallInfo)
|
fun addPartialCallInfo(callInfo: PartialCallInfo)
|
||||||
|
fun addCompletedCallInfo(callInfo: CompletedCallInfo)
|
||||||
fun addErrorCallInfo(callInfo: ErrorCallInfo)
|
fun addErrorCallInfo(callInfo: ErrorCallInfo)
|
||||||
fun currentConstraintSystem(): ConstraintStorage
|
fun currentConstraintSystem(): ConstraintStorage
|
||||||
|
fun inferPostponedVariables(initialStorage: ConstraintStorage): Map<TypeConstructor, UnwrappedType>
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PartialCallInfo {
|
interface PartialCallInfo {
|
||||||
val callResolutionResult: PartialCallResolutionResult
|
val callResolutionResult: PartialCallResolutionResult
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface CompletedCallInfo {
|
||||||
|
val callResolutionResult: CompletedCallResolutionResult
|
||||||
|
}
|
||||||
|
|
||||||
interface ErrorCallInfo {
|
interface ErrorCallInfo {
|
||||||
val callResolutionResult: CallResolutionResult
|
val callResolutionResult: CallResolutionResult
|
||||||
}
|
}
|
||||||
+28
-7
@@ -8,9 +8,10 @@ package org.jetbrains.kotlin.resolve.calls.components
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.addSubsystemFromArgument
|
import org.jetbrains.kotlin.resolve.calls.inference.addSubsystemFromArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.LambdaArgumentConstraintPosition
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
|
import org.jetbrains.kotlin.types.NonFixedType
|
||||||
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||||
|
|
||||||
@@ -18,7 +19,8 @@ class PostponedArgumentsAnalyzer(
|
|||||||
private val callableReferenceResolver: CallableReferenceResolver
|
private val callableReferenceResolver: CallableReferenceResolver
|
||||||
) {
|
) {
|
||||||
interface Context {
|
interface Context {
|
||||||
fun buildCurrentSubstitutor(): NewTypeSubstitutor
|
fun buildCurrentSubstitutor(additionalBindings: Map<TypeConstructor, NonFixedType>): NewTypeSubstitutor
|
||||||
|
fun bindingStubsForPostponedVariables(): Map<NewTypeVariable, NonFixedType>
|
||||||
|
|
||||||
// type can be proper if it not contains not fixed type variables
|
// type can be proper if it not contains not fixed type variables
|
||||||
fun canBeProper(type: UnwrappedType): Boolean
|
fun canBeProper(type: UnwrappedType): Boolean
|
||||||
@@ -42,7 +44,9 @@ class PostponedArgumentsAnalyzer(
|
|||||||
analyzeLambda(c, resolutionCallbacks, argument, diagnosticsHolder)
|
analyzeLambda(c, resolutionCallbacks, argument, diagnosticsHolder)
|
||||||
|
|
||||||
is LambdaWithTypeVariableAsExpectedTypeAtom ->
|
is LambdaWithTypeVariableAsExpectedTypeAtom ->
|
||||||
analyzeLambda(c, resolutionCallbacks, argument.transformToResolvedLambda(c.getBuilder()), diagnosticsHolder)
|
analyzeLambda(
|
||||||
|
c, resolutionCallbacks, argument.transformToResolvedLambda(c.getBuilder()), diagnosticsHolder
|
||||||
|
)
|
||||||
|
|
||||||
is ResolvedCallableReferenceAtom ->
|
is ResolvedCallableReferenceAtom ->
|
||||||
callableReferenceResolver.processCallableReferenceArgument(c.getBuilder(), argument, diagnosticsHolder)
|
callableReferenceResolver.processCallableReferenceArgument(c.getBuilder(), argument, diagnosticsHolder)
|
||||||
@@ -59,7 +63,9 @@ class PostponedArgumentsAnalyzer(
|
|||||||
lambda: ResolvedLambdaAtom,
|
lambda: ResolvedLambdaAtom,
|
||||||
diagnosticHolder: KotlinDiagnosticsHolder
|
diagnosticHolder: KotlinDiagnosticsHolder
|
||||||
) {
|
) {
|
||||||
val currentSubstitutor = c.buildCurrentSubstitutor()
|
val stubsForPostponedVariables = c.bindingStubsForPostponedVariables()
|
||||||
|
val currentSubstitutor = c.buildCurrentSubstitutor(stubsForPostponedVariables.mapKeys { it.key.freshTypeConstructor })
|
||||||
|
|
||||||
fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(type)
|
fun substitute(type: UnwrappedType) = currentSubstitutor.safeSubstitute(type)
|
||||||
|
|
||||||
val receiver = lambda.receiver?.let(::substitute)
|
val receiver = lambda.receiver?.let(::substitute)
|
||||||
@@ -75,12 +81,13 @@ class PostponedArgumentsAnalyzer(
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
val returnArguments = resolutionCallbacks.analyzeAndGetLambdaReturnArguments(
|
val (returnArguments, inferenceSession) = resolutionCallbacks.analyzeAndGetLambdaReturnArguments(
|
||||||
lambda.atom,
|
lambda.atom,
|
||||||
lambda.isSuspend,
|
lambda.isSuspend,
|
||||||
receiver,
|
receiver,
|
||||||
parameters,
|
parameters,
|
||||||
expectedTypeForReturnArguments
|
expectedTypeForReturnArguments,
|
||||||
|
stubsForPostponedVariables
|
||||||
)
|
)
|
||||||
|
|
||||||
returnArguments.forEach { c.addSubsystemFromArgument(it) }
|
returnArguments.forEach { c.addSubsystemFromArgument(it) }
|
||||||
@@ -94,6 +101,20 @@ class PostponedArgumentsAnalyzer(
|
|||||||
c.getBuilder().addSubtypeConstraint(lambda.returnType.let(::substitute), unitType, LambdaArgumentConstraintPosition(lambda))
|
c.getBuilder().addSubtypeConstraint(lambda.returnType.let(::substitute), unitType, LambdaArgumentConstraintPosition(lambda))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inferenceSession != null) {
|
||||||
|
val storageSnapshot = c.getBuilder().copyCurrentStorage()
|
||||||
|
|
||||||
|
val postponedVariables = inferenceSession.inferPostponedVariables(storageSnapshot)
|
||||||
|
|
||||||
|
for ((constructor, resultType) in postponedVariables) {
|
||||||
|
val variableWithConstraints = storageSnapshot.notFixedTypeVariables[constructor] ?: continue
|
||||||
|
val variable = variableWithConstraints.typeVariable
|
||||||
|
|
||||||
|
c.getBuilder().unmarkPostponedVariable(variable)
|
||||||
|
c.getBuilder().addEqualityConstraint(variable.defaultType, resultType, CoroutinePosition())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
lambda.setAnalyzedResults(returnArguments, subResolvedKtPrimitives)
|
lambda.setAnalyzedResults(returnArguments, subResolvedKtPrimitives)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+16
-4
@@ -9,10 +9,7 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemOperation
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ExplicitTypeParameterConstraintPosition
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.KnownTypeParameterConstraintPosition
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
import org.jetbrains.kotlin.resolve.calls.smartcasts.getReceiverValueWithSmartCast
|
||||||
@@ -21,6 +18,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.InfixCallNoInfixModifier
|
|||||||
import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorModifier
|
import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorModifier
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
internal object CheckInstantiationOfAbstractClass : ResolutionPart() {
|
internal object CheckInstantiationOfAbstractClass : ResolutionPart() {
|
||||||
@@ -194,6 +192,20 @@ internal object CreateFreshVariablesSubstitutor : ResolutionPart() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal object InferLaterInitializerResolutionPart : ResolutionPart() {
|
||||||
|
override fun KotlinResolutionCandidate.process(workIndex: Int) {
|
||||||
|
resolvedCall.argumentToCandidateParameter
|
||||||
|
.filter { (argument, parameter) -> callComponents.statelessCallbacks.isCoroutineCall(argument, parameter) }
|
||||||
|
.flatMap { (_, parameter) ->
|
||||||
|
resolvedCall.substitutor.freshVariables.filter { variable ->
|
||||||
|
parameter.type.contains { it.constructor == variable.originalTypeParameter.typeConstructor }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.distinct()
|
||||||
|
.forEach { csBuilder.markPostponedVariable(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal object CheckExplicitReceiverKindConsistency : ResolutionPart() {
|
internal object CheckExplicitReceiverKindConsistency : ResolutionPart() {
|
||||||
private fun KotlinResolutionCandidate.hasError(): Nothing =
|
private fun KotlinResolutionCandidate.hasError(): Nothing =
|
||||||
error(
|
error(
|
||||||
|
|||||||
+5
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
import org.jetbrains.kotlin.resolve.calls.components.PostponedArgumentsAnalyzer
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
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.ConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
@@ -29,6 +30,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|||||||
interface ConstraintSystemOperation {
|
interface ConstraintSystemOperation {
|
||||||
val hasContradiction: Boolean
|
val hasContradiction: Boolean
|
||||||
fun registerVariable(variable: NewTypeVariable)
|
fun registerVariable(variable: NewTypeVariable)
|
||||||
|
fun markPostponedVariable(variable: NewTypeVariable)
|
||||||
|
fun unmarkPostponedVariable(variable: NewTypeVariable)
|
||||||
|
|
||||||
fun addSubtypeConstraint(lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition)
|
fun addSubtypeConstraint(lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition)
|
||||||
fun addEqualityConstraint(a: UnwrappedType, b: UnwrappedType, position: ConstraintPosition)
|
fun addEqualityConstraint(a: UnwrappedType, b: UnwrappedType, position: ConstraintPosition)
|
||||||
@@ -45,6 +48,8 @@ interface ConstraintSystemBuilder : ConstraintSystemOperation {
|
|||||||
fun runTransaction(runOperations: ConstraintSystemOperation.() -> Boolean): Boolean
|
fun runTransaction(runOperations: ConstraintSystemOperation.() -> Boolean): Boolean
|
||||||
|
|
||||||
fun buildCurrentSubstitutor(): NewTypeSubstitutor
|
fun buildCurrentSubstitutor(): NewTypeSubstitutor
|
||||||
|
|
||||||
|
fun copyCurrentStorage(): ConstraintStorage
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible(
|
fun ConstraintSystemBuilder.addSubtypeConstraintIfCompatible(
|
||||||
|
|||||||
+3
-4
@@ -20,13 +20,12 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutorByConstructorMap
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
|
||||||
fun ConstraintStorage.buildCurrentSubstitutor() = NewTypeSubstitutorByConstructorMap(fixedTypeVariables.entries.associate {
|
fun ConstraintStorage.buildCurrentSubstitutor(additionalBindings: Map<TypeConstructor, NonFixedType>): NewTypeSubstitutorByConstructorMap =
|
||||||
it.key to it.value
|
NewTypeSubstitutorByConstructorMap(fixedTypeVariables.entries.associate { it.key to it.value } + additionalBindings)
|
||||||
})
|
|
||||||
|
|
||||||
fun ConstraintStorage.buildResultingSubstitutor(): NewTypeSubstitutor {
|
fun ConstraintStorage.buildResultingSubstitutor(): NewTypeSubstitutor {
|
||||||
val currentSubstitutorMap = fixedTypeVariables.entries.associate {
|
val currentSubstitutorMap = fixedTypeVariables.entries.associate {
|
||||||
|
|||||||
+1
@@ -38,6 +38,7 @@ class ConstraintInjector(val constraintIncorporator: ConstraintIncorporator, val
|
|||||||
|
|
||||||
var maxTypeDepthFromInitialConstraints: Int
|
var maxTypeDepthFromInitialConstraints: Int
|
||||||
val notFixedTypeVariables: MutableMap<TypeConstructor, MutableVariableWithConstraints>
|
val notFixedTypeVariables: MutableMap<TypeConstructor, MutableVariableWithConstraints>
|
||||||
|
val fixedTypeVariables: MutableMap<TypeConstructor, UnwrappedType>
|
||||||
|
|
||||||
fun addInitialConstraint(initialConstraint: InitialConstraint)
|
fun addInitialConstraint(initialConstraint: InitialConstraint)
|
||||||
fun addError(error: KotlinCallDiagnostic)
|
fun addError(error: KotlinCallDiagnostic)
|
||||||
|
|||||||
+41
-4
@@ -27,9 +27,13 @@ class KotlinConstraintSystemCompleter(
|
|||||||
interface Context : VariableFixationFinder.Context, ResultTypeResolver.Context {
|
interface Context : VariableFixationFinder.Context, ResultTypeResolver.Context {
|
||||||
override val notFixedTypeVariables: Map<TypeConstructor, VariableWithConstraints>
|
override val notFixedTypeVariables: Map<TypeConstructor, VariableWithConstraints>
|
||||||
|
|
||||||
|
override val postponedTypeVariables: List<NewTypeVariable>
|
||||||
|
|
||||||
// type can be proper if it not contains not fixed type variables
|
// type can be proper if it not contains not fixed type variables
|
||||||
fun canBeProper(type: UnwrappedType): Boolean
|
fun canBeProper(type: UnwrappedType): Boolean
|
||||||
|
|
||||||
|
fun containsOnlyFixedOrPostponedVariables(type: UnwrappedType): Boolean
|
||||||
|
|
||||||
// mutable operations
|
// mutable operations
|
||||||
fun addError(error: KotlinCallDiagnostic)
|
fun addError(error: KotlinCallDiagnostic)
|
||||||
|
|
||||||
@@ -42,11 +46,28 @@ class KotlinConstraintSystemCompleter(
|
|||||||
topLevelAtoms: List<ResolvedAtom>,
|
topLevelAtoms: List<ResolvedAtom>,
|
||||||
topLevelType: UnwrappedType,
|
topLevelType: UnwrappedType,
|
||||||
analyze: (PostponedResolvedAtom) -> Unit
|
analyze: (PostponedResolvedAtom) -> Unit
|
||||||
|
) {
|
||||||
|
runCompletion(c, completionMode, topLevelAtoms, topLevelType, collectVariablesFromContext = false, analyze = analyze)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun completeConstraintSystem(c: Context, topLevelType: UnwrappedType) {
|
||||||
|
runCompletion(c, ConstraintSystemCompletionMode.FULL, emptyList(), topLevelType, collectVariablesFromContext = true) {
|
||||||
|
error("Shouldn't be called in complete constraint system mode")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runCompletion(
|
||||||
|
c: Context,
|
||||||
|
completionMode: ConstraintSystemCompletionMode,
|
||||||
|
topLevelAtoms: List<ResolvedAtom>,
|
||||||
|
topLevelType: UnwrappedType,
|
||||||
|
collectVariablesFromContext: Boolean,
|
||||||
|
analyze: (PostponedResolvedAtom) -> Unit
|
||||||
) {
|
) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (analyzePostponeArgumentIfPossible(c, topLevelAtoms, analyze)) continue
|
if (analyzePostponeArgumentIfPossible(c, topLevelAtoms, analyze)) continue
|
||||||
|
|
||||||
val allTypeVariables = getOrderedAllTypeVariables(c, topLevelAtoms)
|
val allTypeVariables = getOrderedAllTypeVariables(c, collectVariablesFromContext, topLevelAtoms)
|
||||||
val postponedKtPrimitives = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms)
|
val postponedKtPrimitives = getOrderedNotAnalyzedPostponedArguments(topLevelAtoms)
|
||||||
val variableForFixation = variableFixationFinder.findFirstVariableForFixation(
|
val variableForFixation = variableFixationFinder.findFirstVariableForFixation(
|
||||||
c, allTypeVariables, postponedKtPrimitives, completionMode, topLevelType
|
c, allTypeVariables, postponedKtPrimitives, completionMode, topLevelType
|
||||||
@@ -75,6 +96,10 @@ class KotlinConstraintSystemCompleter(
|
|||||||
if (completionMode == ConstraintSystemCompletionMode.FULL) {
|
if (completionMode == ConstraintSystemCompletionMode.FULL) {
|
||||||
// force resolution for all not-analyzed argument's
|
// force resolution for all not-analyzed argument's
|
||||||
getOrderedNotAnalyzedPostponedArguments(topLevelAtoms).forEach(analyze)
|
getOrderedNotAnalyzedPostponedArguments(topLevelAtoms).forEach(analyze)
|
||||||
|
|
||||||
|
if (c.notFixedTypeVariables.isNotEmpty() && c.postponedTypeVariables.isEmpty()) {
|
||||||
|
runCompletion(c, completionMode, topLevelAtoms, topLevelType, analyze)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,7 +155,13 @@ class KotlinConstraintSystemCompleter(
|
|||||||
return notAnalyzedArguments
|
return notAnalyzedArguments
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getOrderedAllTypeVariables(c: Context, topLevelAtoms: List<ResolvedAtom>): List<TypeConstructor> {
|
private fun getOrderedAllTypeVariables(
|
||||||
|
c: Context,
|
||||||
|
collectVariablesFromContext: Boolean,
|
||||||
|
topLevelAtoms: List<ResolvedAtom>
|
||||||
|
): List<TypeConstructor> {
|
||||||
|
if (collectVariablesFromContext) return c.notFixedTypeVariables.keys.toList()
|
||||||
|
|
||||||
fun ResolvedAtom.process(to: LinkedHashSet<TypeConstructor>) {
|
fun ResolvedAtom.process(to: LinkedHashSet<TypeConstructor>) {
|
||||||
val typeVariables = when (this) {
|
val typeVariables = when (this) {
|
||||||
is ResolvedCallAtom -> substitutor.freshVariables
|
is ResolvedCallAtom -> substitutor.freshVariables
|
||||||
@@ -166,7 +197,7 @@ class KotlinConstraintSystemCompleter(
|
|||||||
private fun canWeAnalyzeIt(c: Context, argument: PostponedResolvedAtom): Boolean {
|
private fun canWeAnalyzeIt(c: Context, argument: PostponedResolvedAtom): Boolean {
|
||||||
if (argument.analyzed) return false
|
if (argument.analyzed) return false
|
||||||
|
|
||||||
return argument.inputTypes.all { c.canBeProper(it) }
|
return argument.inputTypes.all { c.containsOnlyFixedOrPostponedVariables(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fixVariable(
|
private fun fixVariable(
|
||||||
@@ -176,9 +207,15 @@ class KotlinConstraintSystemCompleter(
|
|||||||
postponedResolveKtPrimitives: List<PostponedResolvedAtom>
|
postponedResolveKtPrimitives: List<PostponedResolvedAtom>
|
||||||
) {
|
) {
|
||||||
val direction = TypeVariableDirectionCalculator(c, postponedResolveKtPrimitives, topLevelType).getDirection(variableWithConstraints)
|
val direction = TypeVariableDirectionCalculator(c, postponedResolveKtPrimitives, topLevelType).getDirection(variableWithConstraints)
|
||||||
|
fixVariable(c, variableWithConstraints, direction)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun fixVariable(
|
||||||
|
c: Context,
|
||||||
|
variableWithConstraints: VariableWithConstraints,
|
||||||
|
direction: TypeVariableDirectionCalculator.ResolveDirection
|
||||||
|
) {
|
||||||
val resultType = resultTypeResolver.findResultType(c, variableWithConstraints, direction)
|
val resultType = resultTypeResolver.findResultType(c, variableWithConstraints, direction)
|
||||||
|
|
||||||
c.fixVariable(variableWithConstraints.typeVariable, resultType)
|
c.fixVariable(variableWithConstraints.typeVariable, resultType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+6
-2
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintS
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.PARTIAL
|
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter.ConstraintSystemCompletionMode.PARTIAL
|
||||||
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.DeclaredUpperBoundConstraintPosition
|
import org.jetbrains.kotlin.resolve.calls.inference.model.DeclaredUpperBoundConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints
|
import org.jetbrains.kotlin.resolve.calls.inference.model.VariableWithConstraints
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtom
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtom
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
@@ -29,6 +30,7 @@ import org.jetbrains.kotlin.types.typeUtil.contains
|
|||||||
class VariableFixationFinder {
|
class VariableFixationFinder {
|
||||||
interface Context {
|
interface Context {
|
||||||
val notFixedTypeVariables: Map<TypeConstructor, VariableWithConstraints>
|
val notFixedTypeVariables: Map<TypeConstructor, VariableWithConstraints>
|
||||||
|
val postponedTypeVariables: List<NewTypeVariable>
|
||||||
}
|
}
|
||||||
|
|
||||||
data class VariableForFixation(val variable: TypeConstructor, val hasProperConstraint: Boolean)
|
data class VariableForFixation(val variable: TypeConstructor, val hasProperConstraint: Boolean)
|
||||||
@@ -67,10 +69,12 @@ class VariableFixationFinder {
|
|||||||
completionMode: ConstraintSystemCompletionMode,
|
completionMode: ConstraintSystemCompletionMode,
|
||||||
topLevelType: UnwrappedType
|
topLevelType: UnwrappedType
|
||||||
): VariableForFixation? {
|
): VariableForFixation? {
|
||||||
val dependencyProvider = TypeVariableDependencyInformationProvider(notFixedTypeVariables, postponedKtPrimitives,
|
val dependencyProvider = TypeVariableDependencyInformationProvider(
|
||||||
topLevelType.takeIf { completionMode == PARTIAL })
|
notFixedTypeVariables, postponedKtPrimitives, topLevelType.takeIf { completionMode == PARTIAL }
|
||||||
|
)
|
||||||
|
|
||||||
val candidate = allTypeVariables.maxBy { getTypeVariableReadiness(it, dependencyProvider) } ?: return null
|
val candidate = allTypeVariables.maxBy { getTypeVariableReadiness(it, dependencyProvider) } ?: return null
|
||||||
|
|
||||||
val candidateReadiness = getTypeVariableReadiness(candidate, dependencyProvider)
|
val candidateReadiness = getTypeVariableReadiness(candidate, dependencyProvider)
|
||||||
return when (candidateReadiness) {
|
return when (candidateReadiness) {
|
||||||
TypeVariableFixationReadiness.FORBIDDEN -> null
|
TypeVariableFixationReadiness.FORBIDDEN -> null
|
||||||
|
|||||||
+4
@@ -69,6 +69,10 @@ class IncorporationConstraintPosition(val from: ConstraintPosition, val initialC
|
|||||||
override fun toString() = "Incorporate $initialConstraint from position $from"
|
override fun toString() = "Incorporate $initialConstraint from position $from"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class CoroutinePosition() : ConstraintPosition() {
|
||||||
|
override fun toString(): String = "for coroutine call"
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated("Should be used only in SimpleConstraintSystemImpl")
|
@Deprecated("Should be used only in SimpleConstraintSystemImpl")
|
||||||
object SimpleConstraintSystemConstraintPosition : ConstraintPosition()
|
object SimpleConstraintSystemConstraintPosition : ConstraintPosition()
|
||||||
|
|
||||||
|
|||||||
+3
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference.model
|
package org.jetbrains.kotlin.resolve.calls.inference.model
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
import org.jetbrains.kotlin.resolve.calls.inference.substitute
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
@@ -42,6 +43,7 @@ interface ConstraintStorage {
|
|||||||
val errors: List<KotlinCallDiagnostic>
|
val errors: List<KotlinCallDiagnostic>
|
||||||
val hasContradiction: Boolean
|
val hasContradiction: Boolean
|
||||||
val fixedTypeVariables: Map<TypeConstructor, UnwrappedType>
|
val fixedTypeVariables: Map<TypeConstructor, UnwrappedType>
|
||||||
|
val postponedTypeVariables: List<NewTypeVariable>
|
||||||
|
|
||||||
object Empty : ConstraintStorage {
|
object Empty : ConstraintStorage {
|
||||||
override val allTypeVariables: Map<TypeConstructor, NewTypeVariable> get() = emptyMap()
|
override val allTypeVariables: Map<TypeConstructor, NewTypeVariable> get() = emptyMap()
|
||||||
@@ -51,6 +53,7 @@ interface ConstraintStorage {
|
|||||||
override val errors: List<KotlinCallDiagnostic> get() = emptyList()
|
override val errors: List<KotlinCallDiagnostic> get() = emptyList()
|
||||||
override val hasContradiction: Boolean get() = false
|
override val hasContradiction: Boolean get() = false
|
||||||
override val fixedTypeVariables: Map<TypeConstructor, UnwrappedType> get() = emptyMap()
|
override val fixedTypeVariables: Map<TypeConstructor, UnwrappedType> get() = emptyMap()
|
||||||
|
override val postponedTypeVariables: List<NewTypeVariable> get() = emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+32
-1
@@ -5,13 +5,14 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference.model
|
package org.jetbrains.kotlin.resolve.calls.inference.model
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.trimToSize
|
import org.jetbrains.kotlin.resolve.calls.inference.trimToSize
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
import org.jetbrains.kotlin.resolve.calls.tower.isSuccess
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
import kotlin.collections.LinkedHashMap
|
||||||
|
|
||||||
|
|
||||||
class MutableVariableWithConstraints(
|
class MutableVariableWithConstraints(
|
||||||
@@ -25,6 +26,7 @@ class MutableVariableWithConstraints(
|
|||||||
}
|
}
|
||||||
return simplifiedConstraints!!
|
return simplifiedConstraints!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private val mutableConstraints = ArrayList(constraints)
|
private val mutableConstraints = ArrayList(constraints)
|
||||||
|
|
||||||
private var simplifiedConstraints: List<Constraint>? = null
|
private var simplifiedConstraints: List<Constraint>? = null
|
||||||
@@ -94,4 +96,33 @@ internal class MutableConstraintStorage : ConstraintStorage {
|
|||||||
override val errors: MutableList<KotlinCallDiagnostic> = ArrayList()
|
override val errors: MutableList<KotlinCallDiagnostic> = ArrayList()
|
||||||
override val hasContradiction: Boolean get() = errors.any { !it.candidateApplicability.isSuccess }
|
override val hasContradiction: Boolean get() = errors.any { !it.candidateApplicability.isSuccess }
|
||||||
override val fixedTypeVariables: MutableMap<TypeConstructor, UnwrappedType> = LinkedHashMap()
|
override val fixedTypeVariables: MutableMap<TypeConstructor, UnwrappedType> = LinkedHashMap()
|
||||||
|
override val postponedTypeVariables: ArrayList<NewTypeVariable> = ArrayList()
|
||||||
|
|
||||||
|
fun copy(): ConstraintStorage {
|
||||||
|
return object : ConstraintStorage {
|
||||||
|
override val allTypeVariables: Map<TypeConstructor, NewTypeVariable> =
|
||||||
|
this@MutableConstraintStorage.allTypeVariables.toMap()
|
||||||
|
|
||||||
|
override val notFixedTypeVariables: Map<TypeConstructor, VariableWithConstraints> =
|
||||||
|
this@MutableConstraintStorage.notFixedTypeVariables.toMap()
|
||||||
|
|
||||||
|
override val initialConstraints: List<InitialConstraint> =
|
||||||
|
this@MutableConstraintStorage.initialConstraints.toList()
|
||||||
|
|
||||||
|
override val maxTypeDepthFromInitialConstraints: Int =
|
||||||
|
this@MutableConstraintStorage.maxTypeDepthFromInitialConstraints
|
||||||
|
|
||||||
|
override val errors: List<KotlinCallDiagnostic> =
|
||||||
|
this@MutableConstraintStorage.errors.toList()
|
||||||
|
|
||||||
|
override val hasContradiction: Boolean =
|
||||||
|
this@MutableConstraintStorage.hasContradiction
|
||||||
|
|
||||||
|
override val fixedTypeVariables: Map<TypeConstructor, UnwrappedType> =
|
||||||
|
this@MutableConstraintStorage.fixedTypeVariables.toMap()
|
||||||
|
|
||||||
|
override val postponedTypeVariables: List<NewTypeVariable> =
|
||||||
|
this@MutableConstraintStorage.postponedTypeVariables.toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+46
-1
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintS
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver
|
import org.jetbrains.kotlin.resolve.calls.inference.components.ResultTypeResolver
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
|
||||||
|
import org.jetbrains.kotlin.types.NonFixedType
|
||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||||
@@ -70,6 +71,14 @@ class NewConstraintSystemImpl(
|
|||||||
storage.notFixedTypeVariables[variable.freshTypeConstructor] = MutableVariableWithConstraints(variable)
|
storage.notFixedTypeVariables[variable.freshTypeConstructor] = MutableVariableWithConstraints(variable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun markPostponedVariable(variable: NewTypeVariable) {
|
||||||
|
storage.postponedTypeVariables += variable
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun unmarkPostponedVariable(variable: NewTypeVariable) {
|
||||||
|
storage.postponedTypeVariables -= variable
|
||||||
|
}
|
||||||
|
|
||||||
override fun addSubtypeConstraint(lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition) =
|
override fun addSubtypeConstraint(lowerType: UnwrappedType, upperType: UnwrappedType, position: ConstraintPosition) =
|
||||||
constraintInjector.addInitialSubtypeConstraint(
|
constraintInjector.addInitialSubtypeConstraint(
|
||||||
apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) },
|
apply { checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION) },
|
||||||
@@ -163,6 +172,7 @@ class NewConstraintSystemImpl(
|
|||||||
Math.max(storage.maxTypeDepthFromInitialConstraints, otherSystem.maxTypeDepthFromInitialConstraints)
|
Math.max(storage.maxTypeDepthFromInitialConstraints, otherSystem.maxTypeDepthFromInitialConstraints)
|
||||||
storage.errors.addAll(otherSystem.errors)
|
storage.errors.addAll(otherSystem.errors)
|
||||||
storage.fixedTypeVariables.putAll(otherSystem.fixedTypeVariables)
|
storage.fixedTypeVariables.putAll(otherSystem.fixedTypeVariables)
|
||||||
|
storage.postponedTypeVariables.addAll(otherSystem.postponedTypeVariables)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResultTypeResolver.Context, ConstraintSystemBuilder
|
// ResultTypeResolver.Context, ConstraintSystemBuilder
|
||||||
@@ -204,6 +214,18 @@ class NewConstraintSystemImpl(
|
|||||||
return storage.notFixedTypeVariables
|
return storage.notFixedTypeVariables
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val fixedTypeVariables: MutableMap<TypeConstructor, UnwrappedType>
|
||||||
|
get() {
|
||||||
|
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
||||||
|
return storage.fixedTypeVariables
|
||||||
|
}
|
||||||
|
|
||||||
|
override val postponedTypeVariables: List<NewTypeVariable>
|
||||||
|
get() {
|
||||||
|
checkState(State.BUILDING, State.COMPLETION, State.TRANSACTION)
|
||||||
|
return storage.postponedTypeVariables
|
||||||
|
}
|
||||||
|
|
||||||
// ConstraintInjector.Context, KotlinConstraintSystemCompleter.Context
|
// ConstraintInjector.Context, KotlinConstraintSystemCompleter.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)
|
||||||
@@ -232,10 +254,33 @@ class NewConstraintSystemImpl(
|
|||||||
return !type.contains { storage.notFixedTypeVariables.containsKey(it.constructor) }
|
return !type.contains { storage.notFixedTypeVariables.containsKey(it.constructor) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun containsOnlyFixedOrPostponedVariables(type: UnwrappedType): Boolean {
|
||||||
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
|
return !type.contains {
|
||||||
|
val variable = storage.notFixedTypeVariables[it.constructor]?.typeVariable
|
||||||
|
variable !in storage.postponedTypeVariables && storage.notFixedTypeVariables.containsKey(it.constructor)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// PostponedArgumentsAnalyzer.Context
|
// PostponedArgumentsAnalyzer.Context
|
||||||
override fun buildCurrentSubstitutor(): NewTypeSubstitutor {
|
override fun buildCurrentSubstitutor(): NewTypeSubstitutor {
|
||||||
checkState(State.BUILDING, State.COMPLETION)
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
return storage.buildCurrentSubstitutor()
|
return buildCurrentSubstitutor(emptyMap())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun buildCurrentSubstitutor(additionalBindings: Map<TypeConstructor, NonFixedType>): NewTypeSubstitutor {
|
||||||
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
|
return storage.buildCurrentSubstitutor(additionalBindings)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bindingStubsForPostponedVariables(): Map<NewTypeVariable, NonFixedType> {
|
||||||
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
|
return storage.postponedTypeVariables.associate { it to NonFixedType(it.freshTypeConstructor) }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun copyCurrentStorage(): ConstraintStorage {
|
||||||
|
checkState(State.BUILDING, State.COMPLETION)
|
||||||
|
return storage.copy()
|
||||||
}
|
}
|
||||||
|
|
||||||
// PostponedArgumentsAnalyzer.Context
|
// PostponedArgumentsAnalyzer.Context
|
||||||
|
|||||||
+4
-2
@@ -191,7 +191,8 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
|
|||||||
NoArguments,
|
NoArguments,
|
||||||
CreateFreshVariablesSubstitutor,
|
CreateFreshVariablesSubstitutor,
|
||||||
CheckExplicitReceiverKindConsistency,
|
CheckExplicitReceiverKindConsistency,
|
||||||
CheckReceivers
|
CheckReceivers,
|
||||||
|
InferLaterInitializerResolutionPart
|
||||||
),
|
),
|
||||||
FUNCTION(
|
FUNCTION(
|
||||||
CheckInstantiationOfAbstractClass,
|
CheckInstantiationOfAbstractClass,
|
||||||
@@ -205,7 +206,8 @@ enum class KotlinCallKind(vararg resolutionPart: ResolutionPart) {
|
|||||||
CheckExplicitReceiverKindConsistency,
|
CheckExplicitReceiverKindConsistency,
|
||||||
CheckReceivers,
|
CheckReceivers,
|
||||||
CheckArguments,
|
CheckArguments,
|
||||||
CheckExternalArgument
|
CheckExternalArgument,
|
||||||
|
InferLaterInitializerResolutionPart
|
||||||
),
|
),
|
||||||
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),
|
INVOKE(*FUNCTION.resolutionSequence.toTypedArray()),
|
||||||
UNSUPPORTED();
|
UNSUPPORTED();
|
||||||
|
|||||||
+1
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
|
|||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintSystemImpl
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
|
||||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.*
|
import org.jetbrains.kotlin.resolve.calls.tower.*
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
|
|||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_EXPRESSION -UNUSED_PARAMETER -UNUSED_ANONYMOUS_PARAMETER -UNUSED_VARIABLE
|
||||||
|
// !WITH_NEW_INFERENCE
|
||||||
|
|
||||||
|
class Controller<T> {
|
||||||
|
suspend fun yield(t: T) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <S> generate(g: suspend Controller<S>.() -> Unit): S = TODO()
|
||||||
|
|
||||||
|
val test1 = <!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
|
||||||
|
apply {
|
||||||
|
yield(4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val test2 = <!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
|
||||||
|
yield(B)
|
||||||
|
apply {
|
||||||
|
yield(C)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val test3 = <!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
|
||||||
|
this.<!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>let<!> {
|
||||||
|
yield(B)
|
||||||
|
}
|
||||||
|
|
||||||
|
apply {
|
||||||
|
yield(C)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface A
|
||||||
|
object B : A
|
||||||
|
object C : A
|
||||||
Vendored
+34
@@ -0,0 +1,34 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val test1: kotlin.Int
|
||||||
|
public val test2: A
|
||||||
|
public val test3: A
|
||||||
|
public fun </*0*/ S> generate(/*0*/ g: suspend Controller<S>.() -> kotlin.Unit): S
|
||||||
|
|
||||||
|
public interface A {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public object B : A {
|
||||||
|
private constructor B()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public object C : A {
|
||||||
|
private constructor C()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Controller</*0*/ T> {
|
||||||
|
public constructor Controller</*0*/ T>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
public final suspend fun yield(/*0*/ t: T): kotlin.Unit
|
||||||
|
}
|
||||||
+1
-1
@@ -4,7 +4,7 @@ class GenericController<T> {
|
|||||||
suspend fun yield(t: T) {}
|
suspend fun yield(t: T) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun <S> GenericController<S>.yieldAll(s: Collection<S>) {}
|
suspend fun <K> GenericController<K>.yieldAll(s: Collection<K>) {}
|
||||||
|
|
||||||
fun <S> generate(g: suspend GenericController<S>.() -> Unit): S = TODO()
|
fun <S> generate(g: suspend GenericController<S>.() -> Unit): S = TODO()
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ public val test3: A
|
|||||||
public val test4: A
|
public val test4: A
|
||||||
public fun </*0*/ S> generate(/*0*/ g: suspend GenericController<S>.() -> kotlin.Unit): S
|
public fun </*0*/ S> generate(/*0*/ g: suspend GenericController<S>.() -> kotlin.Unit): S
|
||||||
public fun </*0*/ X> setOf(/*0*/ vararg x: X /*kotlin.Array<out X>*/): kotlin.collections.Set<X>
|
public fun </*0*/ X> setOf(/*0*/ vararg x: X /*kotlin.Array<out X>*/): kotlin.collections.Set<X>
|
||||||
public suspend fun </*0*/ S> GenericController<S>.yieldAll(/*0*/ s: kotlin.collections.Collection<S>): kotlin.Unit
|
public suspend fun </*0*/ K> GenericController<K>.yieldAll(/*0*/ s: kotlin.collections.Collection<K>): kotlin.Unit
|
||||||
|
|
||||||
public interface A {
|
public interface A {
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
|||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// !WITH_NEW_INFERENCE
|
||||||
|
|
||||||
|
class Controller<T> {
|
||||||
|
suspend fun yield(t: T) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <S> generate(g: suspend Controller<S>.() -> Unit): S = TODO()
|
||||||
|
|
||||||
|
class A
|
||||||
|
|
||||||
|
val test1 = <!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
|
||||||
|
yield(<!NO_COMPANION_OBJECT!>A<!>)
|
||||||
|
}
|
||||||
|
|
||||||
|
val test2: Int = <!NI;TYPE_MISMATCH, OI;TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH!>generate {
|
||||||
|
yield(<!NI;TYPE_MISMATCH, NI;TYPE_MISMATCH!>A()<!>)
|
||||||
|
}<!>
|
||||||
Vendored
+20
@@ -0,0 +1,20 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val test1: [ERROR : Error type for ParseError-argument VALUE_ARGUMENT]
|
||||||
|
public val test2: kotlin.Int
|
||||||
|
public fun </*0*/ S> generate(/*0*/ g: suspend Controller<S>.() -> kotlin.Unit): S
|
||||||
|
|
||||||
|
public final class A {
|
||||||
|
public constructor A()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Controller</*0*/ T> {
|
||||||
|
public constructor Controller</*0*/ T>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
public final suspend fun yield(/*0*/ t: T): kotlin.Unit
|
||||||
|
}
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
// !WITH_NEW_INFERENCE
|
||||||
|
|
||||||
|
class Controller<T : Number> {
|
||||||
|
suspend fun yield(t: T) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <S : Number> generate(g: suspend Controller<S>.() -> Unit): S = TODO()
|
||||||
|
|
||||||
|
val test = <!OI;TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>generate<!> {
|
||||||
|
yield(<!NI;TYPE_MISMATCH!>"foo"<!>)
|
||||||
|
}
|
||||||
Vendored
+12
@@ -0,0 +1,12 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val test: kotlin.String
|
||||||
|
public fun </*0*/ S : kotlin.Number> generate(/*0*/ g: suspend Controller<S>.() -> kotlin.Unit): S
|
||||||
|
|
||||||
|
public final class Controller</*0*/ T : kotlin.Number> {
|
||||||
|
public constructor Controller</*0*/ T : kotlin.Number>()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
public final suspend fun yield(/*0*/ t: T): kotlin.Unit
|
||||||
|
}
|
||||||
+15
@@ -1533,6 +1533,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("applyInsideCoroutine.kt")
|
||||||
|
public void testApplyInsideCoroutine() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/applyInsideCoroutine.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("correctMember.kt")
|
@TestMetadata("correctMember.kt")
|
||||||
public void testCorrectMember() throws Exception {
|
public void testCorrectMember() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.kt");
|
||||||
@@ -1583,6 +1588,16 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendCallsWithErrors.kt")
|
||||||
|
public void testSuspendCallsWithErrors() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWithErrors.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendCallsWrongUpperBound.kt")
|
||||||
|
public void testSuspendCallsWrongUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWrongUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeFromReceiver.kt")
|
@TestMetadata("typeFromReceiver.kt")
|
||||||
public void testTypeFromReceiver() throws Exception {
|
public void testTypeFromReceiver() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt");
|
||||||
|
|||||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+15
@@ -1533,6 +1533,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("applyInsideCoroutine.kt")
|
||||||
|
public void testApplyInsideCoroutine() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/applyInsideCoroutine.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("correctMember.kt")
|
@TestMetadata("correctMember.kt")
|
||||||
public void testCorrectMember() throws Exception {
|
public void testCorrectMember() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/correctMember.kt");
|
||||||
@@ -1583,6 +1588,16 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
|||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/simpleGenerator.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendCallsWithErrors.kt")
|
||||||
|
public void testSuspendCallsWithErrors() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWithErrors.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("suspendCallsWrongUpperBound.kt")
|
||||||
|
public void testSuspendCallsWrongUpperBound() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/suspendCallsWrongUpperBound.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("typeFromReceiver.kt")
|
@TestMetadata("typeFromReceiver.kt")
|
||||||
public void testTypeFromReceiver() throws Exception {
|
public void testTypeFromReceiver() throws Exception {
|
||||||
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt");
|
runTest("compiler/testData/diagnostics/testsWithStdLib/coroutines/inference/typeFromReceiver.kt");
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||||
|
|
||||||
|
class NonFixedType(val originalTypeVariable: TypeConstructor) : SimpleType() {
|
||||||
|
override val constructor: TypeConstructor =
|
||||||
|
ErrorUtils.createErrorTypeConstructor("Constructor for non fixed type: $originalTypeVariable")
|
||||||
|
|
||||||
|
override val arguments: List<TypeProjection>
|
||||||
|
get() = emptyList()
|
||||||
|
|
||||||
|
override val isMarkedNullable: Boolean
|
||||||
|
get() = false
|
||||||
|
|
||||||
|
override val memberScope: MemberScope =
|
||||||
|
ErrorUtils.createErrorScope("Scope for non fixed type: $originalTypeVariable")
|
||||||
|
|
||||||
|
override val annotations: Annotations
|
||||||
|
get() = Annotations.EMPTY
|
||||||
|
|
||||||
|
override fun replaceAnnotations(newAnnotations: Annotations): SimpleType = this
|
||||||
|
|
||||||
|
override fun makeNullableAsSpecified(newNullability: Boolean): SimpleType = this
|
||||||
|
|
||||||
|
override fun toString(): String {
|
||||||
|
return "NonFixed: $originalTypeVariable"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -186,6 +186,8 @@ object NewKotlinTypeChecker : KotlinTypeChecker {
|
|||||||
return StrictEqualityTypeChecker.strictEqualTypes(subType.makeNullableAsSpecified(false), superType.makeNullableAsSpecified(false))
|
return StrictEqualityTypeChecker.strictEqualTypes(subType.makeNullableAsSpecified(false), superType.makeNullableAsSpecified(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (subType is NonFixedType || superType is NonFixedType) return true
|
||||||
|
|
||||||
if (superType is NewCapturedType && superType.lowerType != null) {
|
if (superType is NewCapturedType && superType.lowerType != null) {
|
||||||
when (getLowerCapturedTypePolicy(subType, superType)) {
|
when (getLowerCapturedTypePolicy(subType, superType)) {
|
||||||
CHECK_ONLY_LOWER -> return isSubtypeOf(subType, superType.lowerType)
|
CHECK_ONLY_LOWER -> return isSubtypeOf(subType, superType.lowerType)
|
||||||
|
|||||||
Reference in New Issue
Block a user