[FIR] Prepare commonization of PostponedArgumentInputTypesResolver
This commit is contained in:
+69
@@ -7,7 +7,12 @@ package org.jetbrains.kotlin.fir.resolve.inference
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemUtilContext
|
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemUtilContext
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.FixVariableConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.LambdaWithTypeVariableAsExpectedTypeMarker
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedAtomWithRevisableExpectedType
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||||
|
|
||||||
object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext {
|
object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext {
|
||||||
@@ -35,4 +40,68 @@ object ConeConstraintSystemUtilContext : ConstraintSystemUtilContext {
|
|||||||
override fun KotlinTypeMarker.refineType(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.refineType(): KotlinTypeMarker {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.isFunctionOrKFunctionTypeWithAnySuspendability(): Boolean {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.isSuspendFunctionTypeOrSubtype(): Boolean {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun extractFunctionalTypeFromSupertypes(type: KotlinTypeMarker): KotlinTypeMarker {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.extractArgumentsForFunctionalTypeOrSubtype(): List<KotlinTypeMarker> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> createArgumentConstraintPosition(argument: T): ArgumentConstraintPosition<T> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> createFixVariableConstraintPosition(variable: TypeVariableMarker, atom: T): FixVariableConstraintPosition<T> {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun extractParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List<ConeKotlinType?>? {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.isExtensionFunctionType(): Boolean {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getKFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isAnonymousFunction(argument: PostponedAtomWithRevisableExpectedType): Boolean {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun PostponedAtomWithRevisableExpectedType.isFunctionExpressionWithReceiver(): Boolean {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTypeVariableForLambdaReturnType(): TypeVariableMarker {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTypeVariableForLambdaParameterType(argument: PostponedAtomWithRevisableExpectedType, index: Int): TypeVariableMarker {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTypeVariableForCallableReferenceParameterType(argument: PostponedAtomWithRevisableExpectedType, index: Int): TypeVariableMarker {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTypeVariableForCallableReferenceReturnType(): TypeVariableMarker {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-2
@@ -17,8 +17,10 @@ import org.jetbrains.kotlin.fir.types.ConeKotlinType
|
|||||||
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
|
import org.jetbrains.kotlin.fir.types.ConeTypeVariable
|
||||||
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
import org.jetbrains.kotlin.fir.types.FirTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedAtomWithRevisableExpectedType
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedResolvedAtomMarker
|
||||||
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability
|
||||||
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
|
||||||
// --------------------------- Variables ---------------------------
|
// --------------------------- Variables ---------------------------
|
||||||
|
|
||||||
@@ -30,7 +32,7 @@ sealed class PostponedResolvedAtom : PostponedResolvedAtomMarker {
|
|||||||
abstract override val inputTypes: Collection<ConeKotlinType>
|
abstract override val inputTypes: Collection<ConeKotlinType>
|
||||||
abstract override val outputType: ConeKotlinType?
|
abstract override val outputType: ConeKotlinType?
|
||||||
override var analyzed: Boolean = false
|
override var analyzed: Boolean = false
|
||||||
abstract val expectedType: ConeKotlinType?
|
abstract override val expectedType: ConeKotlinType?
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------- Lambdas -------------
|
// ------------- Lambdas -------------
|
||||||
@@ -62,13 +64,20 @@ class LambdaWithTypeVariableAsExpectedTypeAtom(
|
|||||||
override val expectedType: ConeKotlinType,
|
override val expectedType: ConeKotlinType,
|
||||||
val expectedTypeRef: FirTypeRef,
|
val expectedTypeRef: FirTypeRef,
|
||||||
val candidateOfOuterCall: Candidate
|
val candidateOfOuterCall: Candidate
|
||||||
) : PostponedResolvedAtom() {
|
) : PostponedResolvedAtom(), PostponedAtomWithRevisableExpectedType {
|
||||||
init {
|
init {
|
||||||
candidateOfOuterCall.postponedAtoms += this
|
candidateOfOuterCall.postponedAtoms += this
|
||||||
}
|
}
|
||||||
|
|
||||||
override val inputTypes: Collection<ConeKotlinType> get() = listOf(expectedType)
|
override val inputTypes: Collection<ConeKotlinType> get() = listOf(expectedType)
|
||||||
override val outputType: ConeKotlinType? get() = null
|
override val outputType: ConeKotlinType? get() = null
|
||||||
|
override var revisedExpectedType: ConeKotlinType? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun reviseExpectedType(expectedType: KotlinTypeMarker) {
|
||||||
|
require(expectedType is ConeKotlinType)
|
||||||
|
revisedExpectedType = expectedType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------- References -------------
|
// ------------- References -------------
|
||||||
|
|||||||
@@ -160,6 +160,12 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
?: session.builtinTypes.anyType.type//StandardClassIds.Any(session.firSymbolProvider).constructType(emptyArray(), false) // TODO wtf
|
?: session.builtinTypes.anyType.type//StandardClassIds.Any(session.firSymbolProvider).constructType(emptyArray(), false) // TODO wtf
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.getArguments(): List<TypeArgumentMarker> {
|
||||||
|
require(this is ConeKotlinType)
|
||||||
|
|
||||||
|
return this.typeArguments.toList()
|
||||||
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.asTypeArgument(): TypeArgumentMarker {
|
override fun KotlinTypeMarker.asTypeArgument(): TypeArgumentMarker {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
|
|
||||||
|
|||||||
@@ -94,6 +94,12 @@ interface IrTypeSystemContext : TypeSystemContext, TypeSystemCommonSuperTypesCon
|
|||||||
else -> error("Type $this has no arguments")
|
else -> error("Type $this has no arguments")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.getArguments(): List<TypeArgumentMarker> =
|
||||||
|
when (this) {
|
||||||
|
is IrSimpleType -> arguments
|
||||||
|
else -> error("Type $this has no arguments")
|
||||||
|
}
|
||||||
|
|
||||||
override fun KotlinTypeMarker.asTypeArgument() = this as IrTypeArgument
|
override fun KotlinTypeMarker.asTypeArgument() = this as IrTypeArgument
|
||||||
|
|
||||||
override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? = error("Captured Type is not valid for IrTypes")
|
override fun CapturedTypeMarker.lowerType(): KotlinTypeMarker? = error("Captured Type is not valid for IrTypes")
|
||||||
|
|||||||
+25
@@ -5,7 +5,11 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference.components
|
package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.ArgumentConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.FixVariableConstraintPosition
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.PostponedAtomWithRevisableExpectedType
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -19,4 +23,25 @@ interface ConstraintSystemUtilContext {
|
|||||||
fun KotlinTypeMarker.unCapture(): KotlinTypeMarker
|
fun KotlinTypeMarker.unCapture(): KotlinTypeMarker
|
||||||
fun TypeVariableMarker.isReified(): Boolean
|
fun TypeVariableMarker.isReified(): Boolean
|
||||||
fun KotlinTypeMarker.refineType(): KotlinTypeMarker
|
fun KotlinTypeMarker.refineType(): KotlinTypeMarker
|
||||||
|
|
||||||
|
// PostponedArgumentInputTypesResolver
|
||||||
|
fun extractFunctionalTypeFromSupertypes(type: KotlinTypeMarker): KotlinTypeMarker
|
||||||
|
fun KotlinTypeMarker.extractArgumentsForFunctionalTypeOrSubtype(): List<KotlinTypeMarker>
|
||||||
|
fun KotlinTypeMarker.isFunctionOrKFunctionTypeWithAnySuspendability(): Boolean
|
||||||
|
fun KotlinTypeMarker.isSuspendFunctionTypeOrSubtype(): Boolean
|
||||||
|
fun <T> createArgumentConstraintPosition(argument: T): ArgumentConstraintPosition<T>
|
||||||
|
fun <T> createFixVariableConstraintPosition(variable: TypeVariableMarker, atom: T): FixVariableConstraintPosition<T>
|
||||||
|
fun extractParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List<KotlinTypeMarker?>?
|
||||||
|
fun KotlinTypeMarker.isExtensionFunctionType(): Boolean
|
||||||
|
fun getFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker
|
||||||
|
fun getKFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker
|
||||||
|
fun isAnonymousFunction(argument: PostponedAtomWithRevisableExpectedType): Boolean
|
||||||
|
fun PostponedAtomWithRevisableExpectedType.isFunctionExpressionWithReceiver(): Boolean
|
||||||
|
fun createTypeVariableForLambdaReturnType(): TypeVariableMarker
|
||||||
|
fun createTypeVariableForLambdaParameterType(argument: PostponedAtomWithRevisableExpectedType, index: Int): TypeVariableMarker
|
||||||
|
fun createTypeVariableForCallableReferenceParameterType(
|
||||||
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
|
index: Int
|
||||||
|
): TypeVariableMarker
|
||||||
|
fun createTypeVariableForCallableReferenceReturnType(): TypeVariableMarker
|
||||||
}
|
}
|
||||||
|
|||||||
+15
@@ -10,5 +10,20 @@ import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
|||||||
interface PostponedResolvedAtomMarker {
|
interface PostponedResolvedAtomMarker {
|
||||||
val inputTypes: Collection<KotlinTypeMarker>
|
val inputTypes: Collection<KotlinTypeMarker>
|
||||||
val outputType: KotlinTypeMarker?
|
val outputType: KotlinTypeMarker?
|
||||||
|
val expectedType: KotlinTypeMarker?
|
||||||
val analyzed: Boolean
|
val analyzed: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface PostponedAtomWithRevisableExpectedType : PostponedResolvedAtomMarker {
|
||||||
|
val revisedExpectedType: KotlinTypeMarker?
|
||||||
|
|
||||||
|
fun reviseExpectedType(expectedType: KotlinTypeMarker)
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PostponedCallableReferenceMarker : PostponedAtomWithRevisableExpectedType
|
||||||
|
|
||||||
|
interface LambdaWithTypeVariableAsExpectedTypeMarker : PostponedAtomWithRevisableExpectedType {
|
||||||
|
val parameterTypesFromDeclaration: List<KotlinTypeMarker?>?
|
||||||
|
|
||||||
|
fun updateParameterTypesFromDeclaration(types: List<KotlinTypeMarker?>?)
|
||||||
|
}
|
||||||
+119
-3
@@ -5,17 +5,27 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference.components
|
package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.*
|
||||||
|
import org.jetbrains.kotlin.builtins.getPureArgumentsForFunctionalTypeOrSubtype
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.CreateFreshVariablesSubstitutor.shouldBeFlexible
|
import org.jetbrains.kotlin.resolve.calls.components.CreateFreshVariablesSubstitutor.shouldBeFlexible
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.NewTypeVariable
|
import org.jetbrains.kotlin.resolve.calls.inference.components.PostponedArgumentInputTypesResolver.Companion.TYPE_VARIABLE_NAME_FOR_CR_RETURN_TYPE
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableFromCallableDescriptor
|
import org.jetbrains.kotlin.resolve.calls.inference.components.PostponedArgumentInputTypesResolver.Companion.TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.PostponedArgumentInputTypesResolver.Companion.TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.components.PostponedArgumentInputTypesResolver.Companion.TYPE_VARIABLE_NAME_PREFIX_FOR_LAMBDA_PARAMETER_TYPE
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner
|
||||||
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
|
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
|
||||||
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
||||||
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
import org.jetbrains.kotlin.types.refinement.TypeRefinement
|
||||||
import org.jetbrains.kotlin.types.typeUtil.unCapture as unCaptureKotlinType
|
import org.jetbrains.kotlin.types.typeUtil.unCapture as unCaptureKotlinType
|
||||||
|
|
||||||
class ClassicConstraintSystemUtilContext(val kotlinTypeRefiner: KotlinTypeRefiner) : ConstraintSystemUtilContext {
|
class ClassicConstraintSystemUtilContext(
|
||||||
|
val kotlinTypeRefiner: KotlinTypeRefiner,
|
||||||
|
val builtIns: KotlinBuiltIns,
|
||||||
|
) : ConstraintSystemUtilContext {
|
||||||
override fun TypeVariableMarker.shouldBeFlexible(): Boolean {
|
override fun TypeVariableMarker.shouldBeFlexible(): Boolean {
|
||||||
return this is TypeVariableFromCallableDescriptor && this.originalTypeParameter.shouldBeFlexible()
|
return this is TypeVariableFromCallableDescriptor && this.originalTypeParameter.shouldBeFlexible()
|
||||||
}
|
}
|
||||||
@@ -40,4 +50,110 @@ class ClassicConstraintSystemUtilContext(val kotlinTypeRefiner: KotlinTypeRefine
|
|||||||
require(this is KotlinType)
|
require(this is KotlinType)
|
||||||
return kotlinTypeRefiner.refineType(this)
|
return kotlinTypeRefiner.refineType(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun extractFunctionalTypeFromSupertypes(type: KotlinTypeMarker): KotlinTypeMarker {
|
||||||
|
require(type is KotlinType)
|
||||||
|
return type.extractFunctionalTypeFromSupertypes()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.extractArgumentsForFunctionalTypeOrSubtype(): List<KotlinTypeMarker> {
|
||||||
|
require(this is KotlinType)
|
||||||
|
return this.getPureArgumentsForFunctionalTypeOrSubtype()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.isFunctionOrKFunctionTypeWithAnySuspendability(): Boolean {
|
||||||
|
require(this is KotlinType)
|
||||||
|
return this.isFunctionOrKFunctionTypeWithAnySuspendability
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.isSuspendFunctionTypeOrSubtype(): Boolean {
|
||||||
|
require(this is KotlinType)
|
||||||
|
return this.isSuspendFunctionTypeOrSubtype
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> createArgumentConstraintPosition(argument: T): ArgumentConstraintPosition<T> {
|
||||||
|
require(argument is ResolvedAtom)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return ArgumentConstraintPositionImpl(argument.atom as KotlinCallArgument) as ArgumentConstraintPosition<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T> createFixVariableConstraintPosition(variable: TypeVariableMarker, atom: T): FixVariableConstraintPosition<T> {
|
||||||
|
require(atom is ResolvedAtom)
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
return FixVariableConstraintPositionImpl(variable, atom) as FixVariableConstraintPosition<T>
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun extractParameterTypesFromDeclaration(declaration: PostponedAtomWithRevisableExpectedType): List<KotlinTypeMarker?>? {
|
||||||
|
require(declaration is ResolvedAtom)
|
||||||
|
return when (val atom = declaration.atom) {
|
||||||
|
is FunctionExpression -> {
|
||||||
|
val receiverType = atom.receiverType
|
||||||
|
if (receiverType != null) listOf(receiverType) + atom.parametersTypes else atom.parametersTypes.toList()
|
||||||
|
}
|
||||||
|
is LambdaKotlinCallArgument -> atom.parametersTypes?.toList()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.isExtensionFunctionType(): Boolean {
|
||||||
|
require(this is KotlinType)
|
||||||
|
return this.isExtensionFunctionType
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker {
|
||||||
|
return getFunctionDescriptor(builtIns, parametersNumber, isSuspend).typeConstructor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getKFunctionTypeConstructor(parametersNumber: Int, isSuspend: Boolean): TypeConstructorMarker {
|
||||||
|
return getKFunctionDescriptor(builtIns, parametersNumber, isSuspend).typeConstructor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isAnonymousFunction(argument: PostponedAtomWithRevisableExpectedType): Boolean {
|
||||||
|
require(argument is ResolvedAtom)
|
||||||
|
return argument.atom is FunctionExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun PostponedAtomWithRevisableExpectedType.isFunctionExpressionWithReceiver(): Boolean {
|
||||||
|
require(this is ResolvedAtom)
|
||||||
|
val atom = this.atom
|
||||||
|
return atom is FunctionExpression && atom.receiverType != null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTypeVariableForLambdaReturnType(): TypeVariableMarker {
|
||||||
|
return TypeVariableForLambdaReturnType(
|
||||||
|
builtIns,
|
||||||
|
TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTypeVariableForLambdaParameterType(
|
||||||
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
|
index: Int
|
||||||
|
): TypeVariableMarker {
|
||||||
|
require(argument is ResolvedAtom)
|
||||||
|
val atom = argument.atom as PostponableKotlinCallArgument
|
||||||
|
return TypeVariableForLambdaParameterType(
|
||||||
|
atom,
|
||||||
|
index,
|
||||||
|
builtIns,
|
||||||
|
TYPE_VARIABLE_NAME_PREFIX_FOR_LAMBDA_PARAMETER_TYPE + (index + 1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTypeVariableForCallableReferenceParameterType(
|
||||||
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
|
index: Int
|
||||||
|
): TypeVariableMarker {
|
||||||
|
return TypeVariableForCallableReferenceParameterType(
|
||||||
|
builtIns,
|
||||||
|
TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE + (index + 1)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createTypeVariableForCallableReferenceReturnType(): TypeVariableMarker {
|
||||||
|
return TypeVariableForCallableReferenceReturnType(
|
||||||
|
builtIns,
|
||||||
|
TYPE_VARIABLE_NAME_FOR_CR_RETURN_TYPE
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-4
@@ -14,13 +14,15 @@ import org.jetbrains.kotlin.types.model.TypeVariableMarker
|
|||||||
import org.jetbrains.kotlin.types.model.safeSubstitute
|
import org.jetbrains.kotlin.types.model.safeSubstitute
|
||||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class KotlinConstraintSystemCompleter(
|
class KotlinConstraintSystemCompleter(
|
||||||
private val resultTypeResolver: ResultTypeResolver,
|
private val resultTypeResolver: ResultTypeResolver,
|
||||||
val variableFixationFinder: VariableFixationFinder,
|
val variableFixationFinder: VariableFixationFinder,
|
||||||
|
private val ctx: ConstraintSystemUtilContext,
|
||||||
) {
|
) {
|
||||||
private val postponedArgumentInputTypesResolver = PostponedArgumentInputTypesResolver(resultTypeResolver, variableFixationFinder)
|
private val postponedArgumentInputTypesResolver = PostponedArgumentInputTypesResolver(resultTypeResolver, variableFixationFinder, ctx)
|
||||||
|
|
||||||
fun runCompletion(
|
fun runCompletion(
|
||||||
c: ConstraintSystemCompletionContext,
|
c: ConstraintSystemCompletionContext,
|
||||||
@@ -103,9 +105,10 @@ class KotlinConstraintSystemCompleter(
|
|||||||
argument,
|
argument,
|
||||||
postponedArguments,
|
postponedArguments,
|
||||||
topLevelType,
|
topLevelType,
|
||||||
topLevelAtoms,
|
|
||||||
dependencyProvider,
|
dependencyProvider,
|
||||||
)
|
) {
|
||||||
|
findResolvedAtomBy(it, topLevelAtoms) ?: topLevelAtoms.firstOrNull()
|
||||||
|
}
|
||||||
|
|
||||||
if (wasFixedSomeVariable)
|
if (wasFixedSomeVariable)
|
||||||
continue@completion
|
continue@completion
|
||||||
@@ -113,7 +116,7 @@ class KotlinConstraintSystemCompleter(
|
|||||||
|
|
||||||
// Stage 4: create atoms with revised expected types if needed
|
// Stage 4: create atoms with revised expected types if needed
|
||||||
for (argument in postponedArgumentsWithRevisableType) {
|
for (argument in postponedArgumentsWithRevisableType) {
|
||||||
val wasTransformedSomeArgument = postponedArgumentInputTypesResolver.transformToAtomWithNewFunctionalExpectedType(
|
val wasTransformedSomeArgument = transformToAtomWithNewFunctionalExpectedType(
|
||||||
asConstraintSystemCompletionContext(), argument, diagnosticsHolder
|
asConstraintSystemCompletionContext(), argument, diagnosticsHolder
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -143,6 +146,27 @@ class KotlinConstraintSystemCompleter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun transformToAtomWithNewFunctionalExpectedType(
|
||||||
|
c: ConstraintSystemCompletionContext,
|
||||||
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
|
diagnosticsHolder: KotlinDiagnosticsHolder
|
||||||
|
): Boolean = with(ctx) {
|
||||||
|
val revisedExpectedType: UnwrappedType =
|
||||||
|
argument.revisedExpectedType?.takeIf { it.isFunctionOrKFunctionTypeWithAnySuspendability() }?.cast() ?: return false
|
||||||
|
|
||||||
|
when (argument) {
|
||||||
|
is PostponedCallableReferenceAtom ->
|
||||||
|
CallableReferenceWithRevisedExpectedTypeAtom(argument.atom, revisedExpectedType).also {
|
||||||
|
argument.setAnalyzedResults(null, listOf(it))
|
||||||
|
}
|
||||||
|
is LambdaWithTypeVariableAsExpectedTypeAtom ->
|
||||||
|
argument.transformToResolvedLambda(c.getBuilder(), diagnosticsHolder, revisedExpectedType)
|
||||||
|
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
private fun ConstraintSystemCompletionContext.analyzeArgumentWithFixedParameterTypes(
|
private fun ConstraintSystemCompletionContext.analyzeArgumentWithFixedParameterTypes(
|
||||||
postponedArguments: List<PostponedResolvedAtom>,
|
postponedArguments: List<PostponedResolvedAtom>,
|
||||||
analyze: (PostponedResolvedAtom) -> Unit
|
analyze: (PostponedResolvedAtom) -> Unit
|
||||||
|
|||||||
+131
-190
@@ -5,34 +5,31 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve.calls.inference.components
|
package org.jetbrains.kotlin.resolve.calls.inference.components
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.*
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.components.transformToResolvedLambda
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
import org.jetbrains.kotlin.resolve.calls.inference.model.*
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.*
|
import org.jetbrains.kotlin.resolve.calls.model.*
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.model.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
|
||||||
import org.jetbrains.kotlin.utils.SmartSet
|
import org.jetbrains.kotlin.utils.SmartSet
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
private typealias Context = ConstraintSystemCompletionContext
|
private typealias Context = ConstraintSystemCompletionContext
|
||||||
|
private typealias ResolvedAtomProvider = (TypeVariableMarker) -> Any?
|
||||||
|
|
||||||
class PostponedArgumentInputTypesResolver(
|
class PostponedArgumentInputTypesResolver(
|
||||||
private val resultTypeResolver: ResultTypeResolver,
|
private val resultTypeResolver: ResultTypeResolver,
|
||||||
private val variableFixationFinder: VariableFixationFinder
|
private val variableFixationFinder: VariableFixationFinder,
|
||||||
|
private val resolutionTypeSystemContext: ConstraintSystemUtilContext,
|
||||||
) {
|
) {
|
||||||
private class ParameterTypesInfo(
|
private class ParameterTypesInfo(
|
||||||
val parametersFromDeclaration: List<UnwrappedType?>?,
|
val parametersFromDeclaration: List<KotlinTypeMarker?>?,
|
||||||
val parametersFromDeclarationOfRelatedLambdas: Set<List<UnwrappedType?>>?,
|
val parametersFromDeclarationOfRelatedLambdas: Set<List<KotlinTypeMarker?>>?,
|
||||||
val parametersFromConstraints: Set<List<TypeWithKind>>?,
|
val parametersFromConstraints: Set<List<TypeWithKind>>?,
|
||||||
val annotations: Annotations,
|
val isExtensionFunction: Boolean,
|
||||||
val isSuspend: Boolean,
|
val isSuspend: Boolean,
|
||||||
val isNullable: Boolean
|
val isNullable: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
data class TypeWithKind(
|
data class TypeWithKind(
|
||||||
val type: KotlinType,
|
val type: KotlinTypeMarker,
|
||||||
val direction: ConstraintKind = ConstraintKind.UPPER
|
val direction: ConstraintKind = ConstraintKind.UPPER
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -41,38 +38,27 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
variableDependencyProvider: TypeVariableDependencyInformationProvider
|
variableDependencyProvider: TypeVariableDependencyInformationProvider
|
||||||
): List<TypeWithKind>? {
|
): List<TypeWithKind>? {
|
||||||
fun List<Constraint>.extractFunctionalTypes() = mapNotNull { constraint ->
|
fun List<Constraint>.extractFunctionalTypes() = mapNotNull { constraint ->
|
||||||
val type = constraint.type as? KotlinType ?: return@mapNotNull null
|
TypeWithKind(resolutionTypeSystemContext.extractFunctionalTypeFromSupertypes(constraint.type), constraint.kind)
|
||||||
TypeWithKind(type.extractFunctionalTypeFromSupertypes(), constraint.kind)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val typeVariableTypeConstructor = variable.typeVariable.freshTypeConstructor() as? TypeVariableTypeConstructor ?: return null
|
val typeVariableTypeConstructor = variable.typeVariable.freshTypeConstructor()
|
||||||
val dependentVariables =
|
val dependentVariables =
|
||||||
variableDependencyProvider.getShallowlyDependentVariables(typeVariableTypeConstructor).orEmpty() + typeVariableTypeConstructor
|
variableDependencyProvider.getShallowlyDependentVariables(typeVariableTypeConstructor).orEmpty() + typeVariableTypeConstructor
|
||||||
|
|
||||||
return dependentVariables.flatMap { type ->
|
return dependentVariables.flatMap { type ->
|
||||||
val constraints = notFixedTypeVariables[type]?.constraints ?: return@flatMap emptyList()
|
val constraints = notFixedTypeVariables[type]?.constraints ?: return@flatMap emptyList()
|
||||||
val constraintsWithFunctionalType = constraints.filter { (it.type as? KotlinType)?.isBuiltinFunctionalTypeOrSubtype == true }
|
val constraintsWithFunctionalType = constraints.filter { it.type.isBuiltinFunctionalTypeOrSubtype() }
|
||||||
constraintsWithFunctionalType.extractFunctionalTypes()
|
constraintsWithFunctionalType.extractFunctionalTypes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractParameterTypesFromDeclaration(atom: ResolutionAtom) =
|
|
||||||
when (atom) {
|
|
||||||
is FunctionExpression -> {
|
|
||||||
val receiverType = atom.receiverType
|
|
||||||
if (receiverType != null) listOf(receiverType) + atom.parametersTypes else atom.parametersTypes.toList()
|
|
||||||
}
|
|
||||||
is LambdaKotlinCallArgument -> atom.parametersTypes?.toList()
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Context.extractParameterTypesInfo(
|
private fun Context.extractParameterTypesInfo(
|
||||||
argument: PostponedAtomWithRevisableExpectedType,
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
postponedArguments: List<PostponedAtomWithRevisableExpectedType>,
|
postponedArguments: List<PostponedAtomWithRevisableExpectedType>,
|
||||||
variableDependencyProvider: TypeVariableDependencyInformationProvider
|
variableDependencyProvider: TypeVariableDependencyInformationProvider
|
||||||
): ParameterTypesInfo? {
|
): ParameterTypesInfo? = with(resolutionTypeSystemContext) {
|
||||||
val expectedType = argument.expectedType ?: return null
|
val expectedType = argument.expectedType ?: return null
|
||||||
val variableWithConstraints = notFixedTypeVariables[expectedType.constructor] ?: return null
|
val variableWithConstraints = notFixedTypeVariables[expectedType.typeConstructor()] ?: return null
|
||||||
val functionalTypesFromConstraints = findFunctionalTypesInConstraints(variableWithConstraints, variableDependencyProvider)
|
val functionalTypesFromConstraints = findFunctionalTypesInConstraints(variableWithConstraints, variableDependencyProvider)
|
||||||
|
|
||||||
// Don't create functional expected type for further error reporting about a different number of arguments
|
// Don't create functional expected type for further error reporting about a different number of arguments
|
||||||
@@ -80,10 +66,10 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
return null
|
return null
|
||||||
|
|
||||||
val parameterTypesFromDeclaration =
|
val parameterTypesFromDeclaration =
|
||||||
if (argument is LambdaWithTypeVariableAsExpectedTypeAtom) argument.parameterTypesFromDeclaration else null
|
if (argument is LambdaWithTypeVariableAsExpectedTypeMarker) argument.parameterTypesFromDeclaration else null
|
||||||
|
|
||||||
val parameterTypesFromConstraints = functionalTypesFromConstraints?.mapTo(SmartSet.create()) { typeWithKind ->
|
val parameterTypesFromConstraints = functionalTypesFromConstraints?.mapTo(SmartSet.create()) { typeWithKind ->
|
||||||
typeWithKind.type.getPureArgumentsForFunctionalTypeOrSubtype().map {
|
typeWithKind.type.extractArgumentsForFunctionalTypeOrSubtype().map {
|
||||||
// We should use opposite kind as lambda's parameters are contravariant
|
// We should use opposite kind as lambda's parameters are contravariant
|
||||||
TypeWithKind(it, typeWithKind.direction.opposite())
|
TypeWithKind(it, typeWithKind.direction.opposite())
|
||||||
}
|
}
|
||||||
@@ -93,21 +79,15 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
val (parameterTypesFromDeclarationOfRelatedLambdas, isThereExtensionFunctionAmongRelatedLambdas) =
|
val (parameterTypesFromDeclarationOfRelatedLambdas, isThereExtensionFunctionAmongRelatedLambdas) =
|
||||||
getDeclaredParametersFromRelatedLambdas(argument, postponedArguments, variableDependencyProvider)
|
getDeclaredParametersFromRelatedLambdas(argument, postponedArguments, variableDependencyProvider)
|
||||||
|
|
||||||
val annotationsFromConstraints = functionalTypesFromConstraints?.run {
|
val extensionFunctionTypePresentInConstraints = functionalTypesFromConstraints?.any { it.type.isExtensionFunctionType() } == true
|
||||||
Annotations.create(flatMapTo(SmartSet.create()) { it.type.annotations }.toList())
|
|
||||||
} ?: Annotations.EMPTY
|
|
||||||
|
|
||||||
val annotations = if (isThereExtensionFunctionAmongRelatedLambdas) {
|
|
||||||
annotationsFromConstraints.withExtensionFunctionAnnotation(expectedType.builtIns)
|
|
||||||
} else annotationsFromConstraints
|
|
||||||
|
|
||||||
var isSuspend = false
|
var isSuspend = false
|
||||||
var isNullable = false
|
var isNullable = false
|
||||||
if (!functionalTypesFromConstraints.isNullOrEmpty()) {
|
if (!functionalTypesFromConstraints.isNullOrEmpty()) {
|
||||||
isNullable = true
|
isNullable = true
|
||||||
for (funType in functionalTypesFromConstraints) {
|
for (funType in functionalTypesFromConstraints) {
|
||||||
if (!isSuspend && funType.type.isSuspendFunctionTypeOrSubtype) isSuspend = true
|
if (!isSuspend && funType.type.isSuspendFunctionTypeOrSubtype()) isSuspend = true
|
||||||
if (isNullable && !funType.type.isMarkedNullable) isNullable = false
|
if (isNullable && !funType.type.isMarkedNullable()) isNullable = false
|
||||||
if (isSuspend && !isNullable) break
|
if (isSuspend && !isNullable) break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,7 +95,7 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
parameterTypesFromDeclaration,
|
parameterTypesFromDeclaration,
|
||||||
parameterTypesFromDeclarationOfRelatedLambdas,
|
parameterTypesFromDeclarationOfRelatedLambdas,
|
||||||
parameterTypesFromConstraints,
|
parameterTypesFromConstraints,
|
||||||
annotations,
|
isExtensionFunction = isThereExtensionFunctionAmongRelatedLambdas || extensionFunctionTypePresentInConstraints,
|
||||||
isSuspend = isSuspend,
|
isSuspend = isSuspend,
|
||||||
isNullable = isNullable
|
isNullable = isNullable
|
||||||
)
|
)
|
||||||
@@ -125,20 +105,20 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
argument: PostponedAtomWithRevisableExpectedType,
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
postponedArguments: List<PostponedAtomWithRevisableExpectedType>,
|
postponedArguments: List<PostponedAtomWithRevisableExpectedType>,
|
||||||
dependencyProvider: TypeVariableDependencyInformationProvider
|
dependencyProvider: TypeVariableDependencyInformationProvider
|
||||||
): Pair<Set<List<UnwrappedType?>>?, Boolean> {
|
): Pair<Set<List<KotlinTypeMarker?>>?, Boolean> = with(resolutionTypeSystemContext) {
|
||||||
val parameterTypesFromDeclarationOfRelatedLambdas = postponedArguments
|
val parameterTypesFromDeclarationOfRelatedLambdas = postponedArguments
|
||||||
.mapNotNull { anotherArgument ->
|
.mapNotNull { anotherArgument ->
|
||||||
when {
|
when {
|
||||||
anotherArgument !is LambdaWithTypeVariableAsExpectedTypeAtom -> null
|
anotherArgument !is LambdaWithTypeVariableAsExpectedTypeMarker -> null
|
||||||
anotherArgument.parameterTypesFromDeclaration == null || anotherArgument == argument -> null
|
anotherArgument.parameterTypesFromDeclaration == null || anotherArgument == argument -> null
|
||||||
else -> {
|
else -> {
|
||||||
val argumentExpectedTypeConstructor = argument.expectedType?.typeConstructor() ?: return@mapNotNull null
|
val argumentExpectedTypeConstructor = argument.expectedType?.typeConstructor() ?: return@mapNotNull null
|
||||||
val anotherArgumentExpectedTypeConstructor = anotherArgument.expectedType.typeConstructor()
|
val anotherArgumentExpectedTypeConstructor =
|
||||||
|
anotherArgument.expectedType?.typeConstructor() ?: return@mapNotNull null
|
||||||
val areTypeVariablesRelated = dependencyProvider.areVariablesDependentShallowly(
|
val areTypeVariablesRelated = dependencyProvider.areVariablesDependentShallowly(
|
||||||
argumentExpectedTypeConstructor, anotherArgumentExpectedTypeConstructor
|
argumentExpectedTypeConstructor, anotherArgumentExpectedTypeConstructor
|
||||||
)
|
)
|
||||||
val anotherAtom = anotherArgument.atom
|
val isAnonymousExtensionFunction = anotherArgument.isFunctionExpressionWithReceiver()
|
||||||
val isAnonymousExtensionFunction = anotherAtom is FunctionExpression && anotherAtom.receiverType != null
|
|
||||||
val parameterTypesFromDeclarationOfRelatedLambda = anotherArgument.parameterTypesFromDeclaration
|
val parameterTypesFromDeclarationOfRelatedLambda = anotherArgument.parameterTypesFromDeclaration
|
||||||
|
|
||||||
if (areTypeVariablesRelated && parameterTypesFromDeclarationOfRelatedLambda != null) {
|
if (areTypeVariablesRelated && parameterTypesFromDeclarationOfRelatedLambda != null) {
|
||||||
@@ -151,57 +131,44 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
return parameterTypesFromDeclarationOfRelatedLambdas.run { mapTo(SmartSet.create()) { it.first } to any { it.second } }
|
return parameterTypesFromDeclarationOfRelatedLambdas.run { mapTo(SmartSet.create()) { it.first } to any { it.second } }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Context.createTypeVariableForReturnType(argument: PostponedAtomWithRevisableExpectedType): NewTypeVariable {
|
private fun Context.createTypeVariableForReturnType(argument: PostponedAtomWithRevisableExpectedType): TypeVariableMarker =
|
||||||
val expectedType = argument.expectedType
|
with(resolutionTypeSystemContext) {
|
||||||
?: throw IllegalStateException("Postponed argument's expected type must not be null")
|
val expectedType = argument.expectedType
|
||||||
|
?: throw IllegalStateException("Postponed argument's expected type must not be null")
|
||||||
|
|
||||||
val variable = getBuilder().currentStorage().allTypeVariables[expectedType.constructor]
|
val variable = getBuilder().currentStorage().allTypeVariables[expectedType.typeConstructor()]
|
||||||
if (variable != null) {
|
if (variable != null) {
|
||||||
val revisedVariableForReturnType = getBuilder().getRevisedVariableForReturnType(variable)
|
val revisedVariableForReturnType = getBuilder().getRevisedVariableForReturnType(variable)
|
||||||
if (revisedVariableForReturnType != null) return revisedVariableForReturnType as NewTypeVariable
|
if (revisedVariableForReturnType != null) return revisedVariableForReturnType
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (argument) {
|
||||||
|
is LambdaWithTypeVariableAsExpectedTypeMarker -> createTypeVariableForLambdaReturnType()
|
||||||
|
is PostponedCallableReferenceMarker -> createTypeVariableForCallableReferenceReturnType()
|
||||||
|
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
||||||
|
}.also {
|
||||||
|
if (variable != null) getBuilder().putRevisedVariableForReturnType(variable, it)
|
||||||
|
|
||||||
|
getBuilder().registerVariable(it)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (argument) {
|
|
||||||
is LambdaWithTypeVariableAsExpectedTypeAtom -> TypeVariableForLambdaReturnType(
|
|
||||||
expectedType.builtIns,
|
|
||||||
TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE
|
|
||||||
)
|
|
||||||
is PostponedCallableReferenceAtom -> TypeVariableForCallableReferenceReturnType(
|
|
||||||
expectedType.builtIns,
|
|
||||||
TYPE_VARIABLE_NAME_FOR_CR_RETURN_TYPE
|
|
||||||
)
|
|
||||||
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
|
||||||
}.also {
|
|
||||||
if (variable != null) getBuilder().putRevisedVariableForReturnType(variable, it)
|
|
||||||
|
|
||||||
getBuilder().registerVariable(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Context.createTypeVariableForParameterType(
|
private fun Context.createTypeVariableForParameterType(
|
||||||
argument: PostponedAtomWithRevisableExpectedType,
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
index: Int
|
index: Int
|
||||||
): NewTypeVariable {
|
): TypeVariableMarker = with(resolutionTypeSystemContext) {
|
||||||
val expectedType = argument.expectedType
|
val expectedType = argument.expectedType
|
||||||
?: throw IllegalStateException("Postponed argument's expected type must not be null")
|
?: throw IllegalStateException("Postponed argument's expected type must not be null")
|
||||||
|
|
||||||
val variable = getBuilder().currentStorage().allTypeVariables[expectedType.constructor]
|
val variable = getBuilder().currentStorage().allTypeVariables[expectedType.typeConstructor()]
|
||||||
if (variable != null) {
|
if (variable != null) {
|
||||||
val revisedVariableForParameter = getBuilder().getRevisedVariableForParameter(variable, index)
|
val revisedVariableForParameter = getBuilder().getRevisedVariableForParameter(variable, index)
|
||||||
if (revisedVariableForParameter != null) return revisedVariableForParameter as NewTypeVariable
|
if (revisedVariableForParameter != null) return revisedVariableForParameter
|
||||||
}
|
}
|
||||||
|
|
||||||
return when (argument) {
|
return when (argument) {
|
||||||
is LambdaWithTypeVariableAsExpectedTypeAtom -> TypeVariableForLambdaParameterType(
|
is LambdaWithTypeVariableAsExpectedTypeMarker -> createTypeVariableForLambdaParameterType(argument, index)
|
||||||
argument.atom,
|
is PostponedCallableReferenceMarker -> createTypeVariableForCallableReferenceParameterType(argument, index)
|
||||||
index,
|
|
||||||
expectedType.builtIns,
|
|
||||||
TYPE_VARIABLE_NAME_PREFIX_FOR_LAMBDA_PARAMETER_TYPE + (index + 1)
|
|
||||||
)
|
|
||||||
is PostponedCallableReferenceAtom -> TypeVariableForCallableReferenceParameterType(
|
|
||||||
expectedType.builtIns,
|
|
||||||
TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE + (index + 1)
|
|
||||||
)
|
|
||||||
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
||||||
}.also {
|
}.also {
|
||||||
if (variable != null) getBuilder().putRevisedVariableForParameter(variable, index, it)
|
if (variable != null) getBuilder().putRevisedVariableForParameter(variable, index, it)
|
||||||
@@ -213,14 +180,13 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
private fun Context.createTypeVariablesForParameters(
|
private fun Context.createTypeVariablesForParameters(
|
||||||
argument: PostponedAtomWithRevisableExpectedType,
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
parameterTypes: List<List<TypeWithKind?>>
|
parameterTypes: List<List<TypeWithKind?>>
|
||||||
): List<TypeProjection> {
|
): List<TypeArgumentMarker> = with(resolutionTypeSystemContext) {
|
||||||
val atom = argument.atom
|
|
||||||
val csBuilder = getBuilder()
|
val csBuilder = getBuilder()
|
||||||
val allGroupedParameterTypes = parameterTypes.first().indices.map { i -> parameterTypes.map { it.getOrNull(i) } }
|
val allGroupedParameterTypes = parameterTypes.first().indices.map { i -> parameterTypes.map { it.getOrNull(i) } }
|
||||||
|
|
||||||
return allGroupedParameterTypes.mapIndexed { index, types ->
|
return allGroupedParameterTypes.mapIndexed { index, types ->
|
||||||
val parameterTypeVariable = createTypeVariableForParameterType(argument, index)
|
val parameterTypeVariable = createTypeVariableForParameterType(argument, index)
|
||||||
val typeVariableConstructor = parameterTypeVariable.freshTypeConstructor
|
val typeVariableConstructor = parameterTypeVariable.freshTypeConstructor()
|
||||||
|
|
||||||
for (typeWithKind in types) {
|
for (typeWithKind in types) {
|
||||||
if (typeVariableConstructor in fixedTypeVariables) break
|
if (typeVariableConstructor in fixedTypeVariables) break
|
||||||
@@ -228,24 +194,20 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
|
|
||||||
when (typeWithKind.direction) {
|
when (typeWithKind.direction) {
|
||||||
ConstraintKind.EQUALITY -> csBuilder.addEqualityConstraint(
|
ConstraintKind.EQUALITY -> csBuilder.addEqualityConstraint(
|
||||||
parameterTypeVariable.defaultType, typeWithKind.type, ArgumentConstraintPositionImpl(atom)
|
parameterTypeVariable.defaultType(), typeWithKind.type, createArgumentConstraintPosition(argument)
|
||||||
)
|
)
|
||||||
ConstraintKind.UPPER -> csBuilder.addSubtypeConstraint(
|
ConstraintKind.UPPER -> csBuilder.addSubtypeConstraint(
|
||||||
parameterTypeVariable.defaultType, typeWithKind.type, ArgumentConstraintPositionImpl(atom)
|
parameterTypeVariable.defaultType(), typeWithKind.type, createArgumentConstraintPosition(argument)
|
||||||
)
|
)
|
||||||
ConstraintKind.LOWER -> csBuilder.addSubtypeConstraint(
|
ConstraintKind.LOWER -> csBuilder.addSubtypeConstraint(
|
||||||
typeWithKind.type, parameterTypeVariable.defaultType, ArgumentConstraintPositionImpl(atom)
|
typeWithKind.type, parameterTypeVariable.defaultType(), createArgumentConstraintPosition(argument)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val resultType = if (typeVariableConstructor in fixedTypeVariables) {
|
val resultType = fixedTypeVariables[typeVariableConstructor] ?: parameterTypeVariable.defaultType()
|
||||||
fixedTypeVariables[typeVariableConstructor] as KotlinType
|
|
||||||
} else {
|
|
||||||
parameterTypeVariable.defaultType
|
|
||||||
}
|
|
||||||
|
|
||||||
resultType.asTypeProjection()
|
resultType.asTypeArgument()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -254,27 +216,27 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
parametersNumber: Int,
|
parametersNumber: Int,
|
||||||
isSuspend: Boolean,
|
isSuspend: Boolean,
|
||||||
resultTypeResolver: ResultTypeResolver
|
resultTypeResolver: ResultTypeResolver
|
||||||
): TypeConstructor {
|
): TypeConstructorMarker = with(resolutionTypeSystemContext) {
|
||||||
val expectedType = argument.expectedType
|
val expectedType = argument.expectedType
|
||||||
?: throw IllegalStateException("Postponed argument's expected type must not be null")
|
?: throw IllegalStateException("Postponed argument's expected type must not be null")
|
||||||
|
|
||||||
val expectedTypeConstructor = expectedType.constructor
|
val expectedTypeConstructor = expectedType.typeConstructor()
|
||||||
|
|
||||||
return when (argument) {
|
return when (argument) {
|
||||||
is LambdaWithTypeVariableAsExpectedTypeAtom ->
|
is LambdaWithTypeVariableAsExpectedTypeMarker ->
|
||||||
getFunctionDescriptor(expectedTypeConstructor.builtIns, parametersNumber, isSuspend).typeConstructor
|
getFunctionTypeConstructor(parametersNumber, isSuspend)
|
||||||
is PostponedCallableReferenceAtom -> {
|
is PostponedCallableReferenceMarker -> {
|
||||||
val computedResultType = resultTypeResolver.findResultType(
|
val computedResultType = resultTypeResolver.findResultType(
|
||||||
this,
|
this@computeResultingFunctionalConstructor,
|
||||||
notFixedTypeVariables.getValue(expectedTypeConstructor),
|
notFixedTypeVariables.getValue(expectedTypeConstructor),
|
||||||
TypeVariableDirectionCalculator.ResolveDirection.TO_SUPERTYPE
|
TypeVariableDirectionCalculator.ResolveDirection.TO_SUPERTYPE
|
||||||
)
|
)
|
||||||
|
|
||||||
// Avoid KFunction<...>/Function<...> types
|
// Avoid KFunction<...>/Function<...> types
|
||||||
if (computedResultType.isBuiltinFunctionalTypeOrSubtype() && computedResultType.argumentsCount() > 1) {
|
if (computedResultType.isBuiltinFunctionalTypeOrSubtype() && computedResultType.argumentsCount() > 1) {
|
||||||
computedResultType.typeConstructor() as TypeConstructor
|
computedResultType.typeConstructor()
|
||||||
} else {
|
} else {
|
||||||
getKFunctionDescriptor(expectedTypeConstructor.builtIns, parametersNumber, isSuspend).typeConstructor
|
getKFunctionTypeConstructor(parametersNumber, isSuspend)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
||||||
@@ -284,17 +246,16 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
private fun Context.buildNewFunctionalExpectedType(
|
private fun Context.buildNewFunctionalExpectedType(
|
||||||
argument: PostponedAtomWithRevisableExpectedType,
|
argument: PostponedAtomWithRevisableExpectedType,
|
||||||
parameterTypesInfo: ParameterTypesInfo
|
parameterTypesInfo: ParameterTypesInfo
|
||||||
): UnwrappedType? {
|
): KotlinTypeMarker? = with(resolutionTypeSystemContext) {
|
||||||
val expectedType = argument.expectedType
|
val expectedType = argument.expectedType
|
||||||
|
|
||||||
if (expectedType == null || expectedType.constructor !in notFixedTypeVariables)
|
if (expectedType == null || expectedType.typeConstructor() !in notFixedTypeVariables)
|
||||||
return null
|
return null
|
||||||
|
|
||||||
val atom = argument.atom
|
|
||||||
val parametersFromConstraints = parameterTypesInfo.parametersFromConstraints
|
val parametersFromConstraints = parameterTypesInfo.parametersFromConstraints
|
||||||
val parametersFromDeclaration = getDeclaredParametersConsideringExtensionFunctionsPresence(parameterTypesInfo)
|
val parametersFromDeclaration = getDeclaredParametersConsideringExtensionFunctionsPresence(parameterTypesInfo)
|
||||||
val areAllParameterTypesSpecified = !parametersFromDeclaration.isNullOrEmpty() && parametersFromDeclaration.all { it != null }
|
val areAllParameterTypesSpecified = !parametersFromDeclaration.isNullOrEmpty() && parametersFromDeclaration.all { it != null }
|
||||||
val isExtensionFunction = parameterTypesInfo.annotations.hasExtensionFunctionAnnotation()
|
val isExtensionFunction = parameterTypesInfo.isExtensionFunction
|
||||||
val parametersFromDeclarations = parameterTypesInfo.parametersFromDeclarationOfRelatedLambdas.orEmpty() + parametersFromDeclaration
|
val parametersFromDeclarations = parameterTypesInfo.parametersFromDeclarationOfRelatedLambdas.orEmpty() + parametersFromDeclaration
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -306,7 +267,9 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
return null
|
return null
|
||||||
|
|
||||||
val allParameterTypes =
|
val allParameterTypes =
|
||||||
(parametersFromConstraints.orEmpty() + parametersFromDeclarations.map { parameters -> parameters?.map { it.wrapToTypeWithKind() } }).filterNotNull()
|
(parametersFromConstraints.orEmpty() + parametersFromDeclarations.map { parameters ->
|
||||||
|
parameters?.map { it.wrapToTypeWithKind() }
|
||||||
|
}).filterNotNull()
|
||||||
|
|
||||||
if (allParameterTypes.isEmpty())
|
if (allParameterTypes.isEmpty())
|
||||||
return null
|
return null
|
||||||
@@ -320,7 +283,7 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
resultTypeResolver
|
resultTypeResolver
|
||||||
)
|
)
|
||||||
|
|
||||||
val isExtensionFunctionType = parameterTypesInfo.annotations.hasExtensionFunctionAnnotation()
|
val isExtensionFunctionType = parameterTypesInfo.isExtensionFunction
|
||||||
val areParametersNumberInDeclarationAndConstraintsEqual =
|
val areParametersNumberInDeclarationAndConstraintsEqual =
|
||||||
!parametersFromDeclaration.isNullOrEmpty() && !parametersFromConstraints.isNullOrEmpty()
|
!parametersFromDeclaration.isNullOrEmpty() && !parametersFromConstraints.isNullOrEmpty()
|
||||||
&& parametersFromDeclaration.size == parametersFromConstraints.first().size
|
&& parametersFromDeclaration.size == parametersFromConstraints.first().size
|
||||||
@@ -339,27 +302,22 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
*
|
*
|
||||||
* Example: `val x = id(fun String.() = this)`
|
* Example: `val x = id(fun String.() = this)`
|
||||||
*/
|
*/
|
||||||
val shouldAddExtensionFunctionAnnotation = atom is FunctionExpression && atom.receiverType != null
|
|
||||||
|
|
||||||
val annotations = when {
|
val newExpectedType = createSimpleType(
|
||||||
shouldDiscriminateExtensionFunctionAnnotation ->
|
|
||||||
parameterTypesInfo.annotations.withoutExtensionFunctionAnnotation()
|
|
||||||
shouldAddExtensionFunctionAnnotation ->
|
|
||||||
parameterTypesInfo.annotations.withExtensionFunctionAnnotation(expectedType.builtIns)
|
|
||||||
else -> parameterTypesInfo.annotations
|
|
||||||
}
|
|
||||||
|
|
||||||
val newExpectedType = KotlinTypeFactory.simpleType(
|
|
||||||
annotations,
|
|
||||||
functionalConstructor,
|
functionalConstructor,
|
||||||
variablesForParameterTypes + variableForReturnType.defaultType.asTypeProjection(),
|
variablesForParameterTypes + variableForReturnType.defaultType().asTypeArgument(),
|
||||||
parameterTypesInfo.isNullable
|
parameterTypesInfo.isNullable,
|
||||||
|
isExtensionFunction = when {
|
||||||
|
shouldDiscriminateExtensionFunctionAnnotation -> false
|
||||||
|
argument.isFunctionExpressionWithReceiver() -> true
|
||||||
|
else -> parameterTypesInfo.isExtensionFunction
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
getBuilder().addSubtypeConstraint(
|
getBuilder().addSubtypeConstraint(
|
||||||
newExpectedType,
|
newExpectedType,
|
||||||
expectedType,
|
expectedType,
|
||||||
ArgumentConstraintPositionImpl(argument.atom)
|
createArgumentConstraintPosition(argument)
|
||||||
)
|
)
|
||||||
|
|
||||||
return newExpectedType
|
return newExpectedType
|
||||||
@@ -370,12 +328,12 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
postponedArguments: List<PostponedAtomWithRevisableExpectedType>,
|
postponedArguments: List<PostponedAtomWithRevisableExpectedType>,
|
||||||
completionMode: ConstraintSystemCompletionMode,
|
completionMode: ConstraintSystemCompletionMode,
|
||||||
dependencyProvider: TypeVariableDependencyInformationProvider
|
dependencyProvider: TypeVariableDependencyInformationProvider
|
||||||
): Boolean {
|
): Boolean = with(resolutionTypeSystemContext) {
|
||||||
// We can collect parameter types from declaration in any mode, they can't change during completion.
|
// We can collect parameter types from declaration in any mode, they can't change during completion.
|
||||||
for (argument in postponedArguments) {
|
for (argument in postponedArguments) {
|
||||||
if (argument !is LambdaWithTypeVariableAsExpectedTypeAtom) continue
|
if (argument !is LambdaWithTypeVariableAsExpectedTypeMarker) continue
|
||||||
if (argument.parameterTypesFromDeclaration != null) continue
|
if (argument.parameterTypesFromDeclaration != null) continue
|
||||||
argument.parameterTypesFromDeclaration = extractParameterTypesFromDeclaration(argument.atom)
|
argument.updateParameterTypesFromDeclaration(extractParameterTypesFromDeclaration(argument))
|
||||||
}
|
}
|
||||||
|
|
||||||
return postponedArguments.any { argument ->
|
return postponedArguments.any { argument ->
|
||||||
@@ -394,54 +352,34 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
val newExpectedType =
|
val newExpectedType =
|
||||||
c.buildNewFunctionalExpectedType(argument, parameterTypesInfo) ?: return@any false
|
c.buildNewFunctionalExpectedType(argument, parameterTypesInfo) ?: return@any false
|
||||||
|
|
||||||
argument.revisedExpectedType = newExpectedType
|
argument.reviseExpectedType(newExpectedType)
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun transformToAtomWithNewFunctionalExpectedType(
|
private fun Context.getAllDeeplyRelatedTypeVariables(
|
||||||
c: Context,
|
type: KotlinTypeMarker,
|
||||||
argument: PostponedAtomWithRevisableExpectedType,
|
|
||||||
diagnosticsHolder: KotlinDiagnosticsHolder
|
|
||||||
): Boolean {
|
|
||||||
val revisedExpectedType = argument.revisedExpectedType?.takeIf { it.isFunctionOrKFunctionTypeWithAnySuspendability } ?: return false
|
|
||||||
|
|
||||||
when (argument) {
|
|
||||||
is PostponedCallableReferenceAtom ->
|
|
||||||
CallableReferenceWithRevisedExpectedTypeAtom(argument.atom, revisedExpectedType).also {
|
|
||||||
argument.setAnalyzedResults(null, listOf(it))
|
|
||||||
}
|
|
||||||
is LambdaWithTypeVariableAsExpectedTypeAtom ->
|
|
||||||
argument.transformToResolvedLambda(c.getBuilder(), diagnosticsHolder, revisedExpectedType)
|
|
||||||
else -> throw IllegalStateException("Unsupported postponed argument type of $argument")
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getAllDeeplyRelatedTypeVariables(
|
|
||||||
type: KotlinType,
|
|
||||||
variableDependencyProvider: TypeVariableDependencyInformationProvider
|
variableDependencyProvider: TypeVariableDependencyInformationProvider
|
||||||
): List<TypeVariableTypeConstructor> {
|
): List<TypeVariableTypeConstructorMarker> {
|
||||||
val typeConstructor = type.constructor
|
val typeConstructor = type.typeConstructor()
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
typeConstructor is TypeVariableTypeConstructor -> {
|
typeConstructor is TypeVariableTypeConstructorMarker -> {
|
||||||
val relatedVariables = variableDependencyProvider.getDeeplyDependentVariables(typeConstructor).orEmpty()
|
val relatedVariables = variableDependencyProvider.getDeeplyDependentVariables(typeConstructor).orEmpty()
|
||||||
listOf(typeConstructor) + relatedVariables.filterIsInstance<TypeVariableTypeConstructor>()
|
listOf(typeConstructor) + relatedVariables.filterIsInstance<TypeVariableTypeConstructorMarker>()
|
||||||
}
|
}
|
||||||
type.arguments.isNotEmpty() -> {
|
type.argumentsCount() > 0 -> {
|
||||||
type.arguments.flatMap {
|
type.getArguments().flatMap {
|
||||||
if (it.isStarProjection) emptyList() else getAllDeeplyRelatedTypeVariables(it.type, variableDependencyProvider)
|
if (it.isStarProjection()) emptyList() else getAllDeeplyRelatedTypeVariables(it.getType(), variableDependencyProvider)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getDeclaredParametersConsideringExtensionFunctionsPresence(parameterTypesInfo: ParameterTypesInfo): List<UnwrappedType?>? =
|
private fun getDeclaredParametersConsideringExtensionFunctionsPresence(parameterTypesInfo: ParameterTypesInfo): List<KotlinTypeMarker?>? =
|
||||||
with (parameterTypesInfo) {
|
with(parameterTypesInfo) {
|
||||||
|
|
||||||
if (parametersFromConstraints.isNullOrEmpty() || parametersFromDeclaration.isNullOrEmpty())
|
if (parametersFromConstraints.isNullOrEmpty() || parametersFromDeclaration.isNullOrEmpty())
|
||||||
parametersFromDeclaration
|
parametersFromDeclaration
|
||||||
@@ -449,7 +387,7 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
val oneLessParameterInDeclarationThanInConstraints =
|
val oneLessParameterInDeclarationThanInConstraints =
|
||||||
parametersFromConstraints.first().size == parametersFromDeclaration.size + 1
|
parametersFromConstraints.first().size == parametersFromDeclaration.size + 1
|
||||||
|
|
||||||
if (oneLessParameterInDeclarationThanInConstraints && annotations.hasExtensionFunctionAnnotation()) {
|
if (oneLessParameterInDeclarationThanInConstraints && isExtensionFunction) {
|
||||||
listOf(null) + parametersFromDeclaration
|
listOf(null) + parametersFromDeclaration
|
||||||
} else {
|
} else {
|
||||||
parametersFromDeclaration
|
parametersFromDeclaration
|
||||||
@@ -459,23 +397,22 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
|
|
||||||
fun fixNextReadyVariableForParameterTypeIfNeeded(
|
fun fixNextReadyVariableForParameterTypeIfNeeded(
|
||||||
c: Context,
|
c: Context,
|
||||||
argument: PostponedResolvedAtom,
|
argument: PostponedResolvedAtomMarker,
|
||||||
postponedArguments: List<PostponedResolvedAtom>,
|
postponedArguments: List<PostponedResolvedAtomMarker>,
|
||||||
topLevelType: UnwrappedType,
|
topLevelType: KotlinTypeMarker,
|
||||||
topLevelAtoms: List<ResolvedAtom>,
|
|
||||||
dependencyProvider: TypeVariableDependencyInformationProvider,
|
dependencyProvider: TypeVariableDependencyInformationProvider,
|
||||||
): Boolean {
|
resolvedAtomProvider: ResolvedAtomProvider
|
||||||
|
): Boolean = with(resolutionTypeSystemContext) {
|
||||||
val expectedType = argument.run { safeAs<PostponedAtomWithRevisableExpectedType>()?.revisedExpectedType ?: expectedType }
|
val expectedType = argument.run { safeAs<PostponedAtomWithRevisableExpectedType>()?.revisedExpectedType ?: expectedType }
|
||||||
|
|
||||||
if (expectedType != null && expectedType.isFunctionOrKFunctionTypeWithAnySuspendability) {
|
if (expectedType != null && expectedType.isFunctionOrKFunctionTypeWithAnySuspendability()) {
|
||||||
val wasFixedSomeVariable =
|
val wasFixedSomeVariable = c.fixNextReadyVariableForParameterType(
|
||||||
c.fixNextReadyVariableForParameterType(
|
expectedType,
|
||||||
expectedType,
|
postponedArguments,
|
||||||
postponedArguments,
|
topLevelType,
|
||||||
topLevelType,
|
dependencyProvider,
|
||||||
topLevelAtoms,
|
resolvedAtomProvider
|
||||||
dependencyProvider,
|
)
|
||||||
)
|
|
||||||
|
|
||||||
if (wasFixedSomeVariable)
|
if (wasFixedSomeVariable)
|
||||||
return true
|
return true
|
||||||
@@ -485,16 +422,16 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun Context.fixNextReadyVariableForParameterType(
|
private fun Context.fixNextReadyVariableForParameterType(
|
||||||
type: KotlinType,
|
type: KotlinTypeMarker,
|
||||||
postponedArguments: List<PostponedResolvedAtom>,
|
postponedArguments: List<PostponedResolvedAtomMarker>,
|
||||||
topLevelType: UnwrappedType,
|
topLevelType: KotlinTypeMarker,
|
||||||
topLevelAtoms: List<ResolvedAtom>,
|
|
||||||
dependencyProvider: TypeVariableDependencyInformationProvider,
|
dependencyProvider: TypeVariableDependencyInformationProvider,
|
||||||
): Boolean {
|
resolvedAtomByTypeVariableProvider: ResolvedAtomProvider,
|
||||||
val relatedVariables = type.getPureArgumentsForFunctionalTypeOrSubtype()
|
): Boolean = with(resolutionTypeSystemContext) {
|
||||||
|
val relatedVariables = type.extractArgumentsForFunctionalTypeOrSubtype()
|
||||||
.flatMap { getAllDeeplyRelatedTypeVariables(it, dependencyProvider) }
|
.flatMap { getAllDeeplyRelatedTypeVariables(it, dependencyProvider) }
|
||||||
val variableForFixation = variableFixationFinder.findFirstVariableForFixation(
|
val variableForFixation = variableFixationFinder.findFirstVariableForFixation(
|
||||||
this, relatedVariables, postponedArguments, ConstraintSystemCompletionMode.FULL, topLevelType
|
this@fixNextReadyVariableForParameterType, relatedVariables, postponedArguments, ConstraintSystemCompletionMode.FULL, topLevelType
|
||||||
)
|
)
|
||||||
|
|
||||||
if (variableForFixation == null || !variableForFixation.hasProperConstraint)
|
if (variableForFixation == null || !variableForFixation.hasProperConstraint)
|
||||||
@@ -502,24 +439,28 @@ class PostponedArgumentInputTypesResolver(
|
|||||||
|
|
||||||
val variableWithConstraints = notFixedTypeVariables.getValue(variableForFixation.variable)
|
val variableWithConstraints = notFixedTypeVariables.getValue(variableForFixation.variable)
|
||||||
val resultType =
|
val resultType =
|
||||||
resultTypeResolver.findResultType(this, variableWithConstraints, TypeVariableDirectionCalculator.ResolveDirection.UNKNOWN)
|
resultTypeResolver.findResultType(
|
||||||
|
this@fixNextReadyVariableForParameterType,
|
||||||
|
variableWithConstraints,
|
||||||
|
TypeVariableDirectionCalculator.ResolveDirection.UNKNOWN
|
||||||
|
)
|
||||||
val variable = variableWithConstraints.typeVariable
|
val variable = variableWithConstraints.typeVariable
|
||||||
val resolvedAtom = KotlinConstraintSystemCompleter.findResolvedAtomBy(variable, topLevelAtoms)
|
|
||||||
?: topLevelAtoms.firstOrNull()
|
|
||||||
|
|
||||||
fixVariable(variable, resultType, FixVariableConstraintPositionImpl(variable, resolvedAtom))
|
fixVariable(
|
||||||
|
variable,
|
||||||
|
resultType,
|
||||||
|
createFixVariableConstraintPosition(variable, resolvedAtomByTypeVariableProvider(variable))
|
||||||
|
)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KotlinType?.wrapToTypeWithKind() = this?.let { TypeWithKind(it) }
|
private fun KotlinTypeMarker?.wrapToTypeWithKind() = this?.let { TypeWithKind(it) }
|
||||||
|
|
||||||
private fun isAnonymousFunction(argument: PostponedAtomWithRevisableExpectedType) = argument.atom is FunctionExpression
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val TYPE_VARIABLE_NAME_PREFIX_FOR_LAMBDA_PARAMETER_TYPE = "_RP"
|
const val TYPE_VARIABLE_NAME_PREFIX_FOR_LAMBDA_PARAMETER_TYPE = "_RP"
|
||||||
private const val TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE = "_R"
|
const val TYPE_VARIABLE_NAME_FOR_LAMBDA_RETURN_TYPE = "_R"
|
||||||
private const val TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE = "_QP"
|
const val TYPE_VARIABLE_NAME_PREFIX_FOR_CR_PARAMETER_TYPE = "_QP"
|
||||||
private const val TYPE_VARIABLE_NAME_FOR_CR_RETURN_TYPE = "_Q"
|
const val TYPE_VARIABLE_NAME_FOR_CR_RETURN_TYPE = "_Q"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+27
-9
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.types.KotlinType
|
|||||||
import org.jetbrains.kotlin.types.TypeConstructor
|
import org.jetbrains.kotlin.types.TypeConstructor
|
||||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||||
import org.jetbrains.kotlin.types.UnwrappedType
|
import org.jetbrains.kotlin.types.UnwrappedType
|
||||||
|
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
|
||||||
import org.jetbrains.kotlin.types.typeUtil.unCapture
|
import org.jetbrains.kotlin.types.typeUtil.unCapture
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -92,28 +93,36 @@ class ResolvedSubCallArgument(override val atom: SubKotlinCallArgument, resolveI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PostponedAtomWithRevisableExpectedType {
|
|
||||||
var revisedExpectedType: UnwrappedType?
|
|
||||||
val expectedType: UnwrappedType?
|
|
||||||
val atom: PostponableKotlinCallArgument
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class PostponedResolvedAtom : ResolvedAtom(), PostponedResolvedAtomMarker {
|
sealed class PostponedResolvedAtom : ResolvedAtom(), PostponedResolvedAtomMarker {
|
||||||
abstract override val inputTypes: Collection<UnwrappedType>
|
abstract override val inputTypes: Collection<UnwrappedType>
|
||||||
abstract override val outputType: UnwrappedType?
|
abstract override val outputType: UnwrappedType?
|
||||||
abstract val expectedType: UnwrappedType?
|
abstract override val expectedType: UnwrappedType?
|
||||||
}
|
}
|
||||||
|
|
||||||
class LambdaWithTypeVariableAsExpectedTypeAtom(
|
class LambdaWithTypeVariableAsExpectedTypeAtom(
|
||||||
override val atom: LambdaKotlinCallArgument,
|
override val atom: LambdaKotlinCallArgument,
|
||||||
override val expectedType: UnwrappedType
|
override val expectedType: UnwrappedType
|
||||||
) : PostponedResolvedAtom(), PostponedAtomWithRevisableExpectedType {
|
) : PostponedResolvedAtom(), LambdaWithTypeVariableAsExpectedTypeMarker {
|
||||||
override val inputTypes: Collection<UnwrappedType> get() = listOf(expectedType)
|
override val inputTypes: Collection<UnwrappedType> get() = listOf(expectedType)
|
||||||
override val outputType: UnwrappedType? get() = null
|
override val outputType: UnwrappedType? get() = null
|
||||||
|
|
||||||
override var revisedExpectedType: UnwrappedType? = null
|
override var revisedExpectedType: UnwrappedType? = null
|
||||||
|
private set
|
||||||
|
|
||||||
var parameterTypesFromDeclaration: List<UnwrappedType?>? = null
|
override var parameterTypesFromDeclaration: List<UnwrappedType?>? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun updateParameterTypesFromDeclaration(types: List<KotlinTypeMarker?>?) {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
types as List<UnwrappedType?>?
|
||||||
|
parameterTypesFromDeclaration = types
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reviseExpectedType(expectedType: KotlinTypeMarker) {
|
||||||
|
require(expectedType is UnwrappedType)
|
||||||
|
revisedExpectedType = expectedType
|
||||||
|
}
|
||||||
|
|
||||||
fun setAnalyzed(resolvedLambdaAtom: ResolvedLambdaAtom) {
|
fun setAnalyzed(resolvedLambdaAtom: ResolvedLambdaAtom) {
|
||||||
setAnalyzedResults(listOf(resolvedLambdaAtom))
|
setAnalyzedResults(listOf(resolvedLambdaAtom))
|
||||||
@@ -202,8 +211,17 @@ class CallableReferenceWithRevisedExpectedTypeAtom(
|
|||||||
|
|
||||||
class PostponedCallableReferenceAtom(
|
class PostponedCallableReferenceAtom(
|
||||||
eagerCallableReferenceAtom: EagerCallableReferenceAtom
|
eagerCallableReferenceAtom: EagerCallableReferenceAtom
|
||||||
) : AbstractPostponedCallableReferenceAtom(eagerCallableReferenceAtom.atom, eagerCallableReferenceAtom.expectedType), PostponedAtomWithRevisableExpectedType {
|
) : AbstractPostponedCallableReferenceAtom(eagerCallableReferenceAtom.atom, eagerCallableReferenceAtom.expectedType),
|
||||||
|
PostponedCallableReferenceMarker,
|
||||||
|
PostponedAtomWithRevisableExpectedType
|
||||||
|
{
|
||||||
override var revisedExpectedType: UnwrappedType? = null
|
override var revisedExpectedType: UnwrappedType? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
override fun reviseExpectedType(expectedType: KotlinTypeMarker) {
|
||||||
|
require(expectedType is UnwrappedType)
|
||||||
|
revisedExpectedType = expectedType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ResolvedCollectionLiteralAtom(
|
class ResolvedCollectionLiteralAtom(
|
||||||
|
|||||||
@@ -232,6 +232,7 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
|
|||||||
|
|
||||||
fun KotlinTypeMarker.argumentsCount(): Int
|
fun KotlinTypeMarker.argumentsCount(): Int
|
||||||
fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker
|
fun KotlinTypeMarker.getArgument(index: Int): TypeArgumentMarker
|
||||||
|
fun KotlinTypeMarker.getArguments(): List<TypeArgumentMarker>
|
||||||
|
|
||||||
fun SimpleTypeMarker.getArgumentOrNull(index: Int): TypeArgumentMarker? {
|
fun SimpleTypeMarker.getArgumentOrNull(index: Int): TypeArgumentMarker? {
|
||||||
if (index in 0 until argumentsCount()) return getArgument(index)
|
if (index in 0 until argumentsCount()) return getArgument(index)
|
||||||
|
|||||||
@@ -161,6 +161,11 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext, TypeSy
|
|||||||
return this.arguments[index]
|
return this.arguments[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun KotlinTypeMarker.getArguments(): List<TypeArgumentMarker> {
|
||||||
|
require(this is KotlinType, this::errorMessage)
|
||||||
|
return this.arguments
|
||||||
|
}
|
||||||
|
|
||||||
override fun TypeArgumentMarker.isStarProjection(): Boolean {
|
override fun TypeArgumentMarker.isStarProjection(): Boolean {
|
||||||
require(this is TypeProjection, this::errorMessage)
|
require(this is TypeProjection, this::errorMessage)
|
||||||
return this.isStarProjection
|
return this.isStarProjection
|
||||||
|
|||||||
Reference in New Issue
Block a user