Abstract FlatSignature from kotlin types

This commit is contained in:
Simon Ogorodnik
2019-04-04 17:50:18 +03:00
parent 8e595f015e
commit fe2e5b7301
7 changed files with 42 additions and 28 deletions
@@ -11,10 +11,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstituto
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.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.inference.model.NewTypeVariable
import org.jetbrains.kotlin.types.StubType import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext import org.jetbrains.kotlin.types.checker.ClassicTypeSystemContext
import org.jetbrains.kotlin.types.checker.NewCapturedType import org.jetbrains.kotlin.types.checker.NewCapturedType
import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor import org.jetbrains.kotlin.types.checker.NewCapturedTypeConstructor
@@ -61,9 +58,12 @@ class ClassicTypeSystemContextForCS(override val builtIns: KotlinBuiltIns) : Typ
} }
override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker {
require(type is UnwrappedType, this::errorMessage) require(type is UnwrappedType, type::errorMessage)
require(this is NewTypeSubstitutor, this::errorMessage) return when (this) {
return this.safeSubstitute(type) is NewTypeSubstitutor -> safeSubstitute(type)
is TypeSubstitutor -> safeSubstitute(type, Variance.INVARIANT)
else -> error(this.errorMessage())
}
} }
override fun createStubType(typeVariable: TypeVariableMarker): StubTypeMarker { override fun createStubType(typeVariable: TypeVariableMarker): StubTypeMarker {
@@ -26,10 +26,9 @@ import org.jetbrains.kotlin.resolve.calls.inference.substitute
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
import org.jetbrains.kotlin.types.TypeConstructorSubstitution import org.jetbrains.kotlin.types.TypeConstructorSubstitution
import org.jetbrains.kotlin.types.checker.requireOrDescribe import org.jetbrains.kotlin.types.checker.requireOrDescribe
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.model.KotlinTypeMarker import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeParameterMarker import org.jetbrains.kotlin.types.model.TypeParameterMarker
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
@@ -38,7 +37,7 @@ class SimpleConstraintSystemImpl(constraintInjector: ConstraintInjector, builtIn
val csBuilder: ConstraintSystemBuilder = val csBuilder: ConstraintSystemBuilder =
system.getBuilder() system.getBuilder()
override fun registerTypeVariables(typeParameters: Collection<TypeParameterMarker>): TypeSubstitutor { override fun registerTypeVariables(typeParameters: Collection<TypeParameterMarker>): TypeSubstitutorMarker {
val substitutionMap = typeParameters.associate { val substitutionMap = typeParameters.associate {
requireOrDescribe(it is TypeParameterDescriptor, it) requireOrDescribe(it is TypeParameterDescriptor, it)
@@ -58,8 +57,6 @@ class SimpleConstraintSystemImpl(constraintInjector: ConstraintInjector, builtIn
} }
override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker) { override fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker) {
require(subType is UnwrappedType)
require(superType is UnwrappedType)
csBuilder.addSubtypeConstraint( csBuilder.addSubtypeConstraint(
subType, subType,
superType, superType,
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor import org.jetbrains.kotlin.descriptors.synthetic.SyntheticMemberDescriptor
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.captureFromExpression import org.jetbrains.kotlin.types.model.*
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeParameterMarker
import org.jetbrains.kotlin.types.model.TypeSystemInferenceExtensionContext
interface SpecificityComparisonCallbacks { interface SpecificityComparisonCallbacks {
fun isNonSubtypeNotLessSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean fun isNonSubtypeNotLessSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean
@@ -114,7 +111,7 @@ class FlatSignature<out T> constructor(
interface SimpleConstraintSystem { interface SimpleConstraintSystem {
fun registerTypeVariables(typeParameters: Collection<TypeParameterMarker>): TypeSubstitutor fun registerTypeVariables(typeParameters: Collection<TypeParameterMarker>): TypeSubstitutorMarker
fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker) fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker)
fun hasContradiction(): Boolean fun hasContradiction(): Boolean
@@ -134,6 +131,7 @@ fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific(
if (specific.valueParameterTypes.size != general.valueParameterTypes.size) return false if (specific.valueParameterTypes.size != general.valueParameterTypes.size) return false
val typeParameters = general.typeParameters val typeParameters = general.typeParameters
val typeSubstitutor = registerTypeVariables(typeParameters)
for ((specificType, generalType) in specific.valueParameterTypes.zip(general.valueParameterTypes)) { for ((specificType, generalType) in specific.valueParameterTypes.zip(general.valueParameterTypes)) {
if (specificType == null || generalType == null) continue if (specificType == null || generalType == null) continue
@@ -142,18 +140,14 @@ fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific(
return false return false
} }
if (typeParameters.isEmpty() /*|| !TypeUtils.dependsOnTypeParameters(generalType, typeParameters)*/) { if (typeParameters.isEmpty() || !generalType.dependsOnTypeParameters(context, typeParameters)) {
if (!AbstractTypeChecker.isSubtypeOf(context, specificType, generalType)) { if (!AbstractTypeChecker.isSubtypeOf(context, specificType, generalType)) {
if (!callbacks.isNonSubtypeNotLessSpecific(specificType, generalType)) { if (!callbacks.isNonSubtypeNotLessSpecific(specificType, generalType)) {
return false return false
} }
} }
} else { } else {
val typeSubstitutor = registerTypeVariables(typeParameters) val substitutedGeneralType = typeSubstitutor.safeSubstitute(context, generalType)
require(generalType is KotlinType) { TODO("not supported") }
require(specificType is KotlinType) { TODO("not supported") }
val substitutedGeneralType = typeSubstitutor.safeSubstitute(generalType, Variance.INVARIANT)
/** /**
* Example: * Example:
@@ -162,8 +156,9 @@ fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific(
* Here, when we try solve this CS(Y is variables) then Array<out X> <: Array<out Y> and this system impossible to solve, * Here, when we try solve this CS(Y is variables) then Array<out X> <: Array<out Y> and this system impossible to solve,
* so we capture types from receiver and value parameters. * so we capture types from receiver and value parameters.
*/ */
val specificCapturedType = specificType.unwrap().let { if (captureFromArgument) captureFromExpression(it) ?: it else it } val specificCapturedType =
addSubtypeConstraint(specificCapturedType, substitutedGeneralType.unwrap()) context.prepareType(specificType).let { if (captureFromArgument) context.captureFromExpression(it) ?: it else it }
addSubtypeConstraint(specificCapturedType, substitutedGeneralType)
} }
} }
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations;
import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations; import org.jetbrains.kotlin.descriptors.annotations.FilteredAnnotations;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructorKt; import org.jetbrains.kotlin.resolve.calls.inference.CapturedTypeConstructorKt;
import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker;
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt; import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt; import org.jetbrains.kotlin.types.typesApproximation.CapturedTypeApproximationKt;
import org.jetbrains.kotlin.utils.ExceptionUtilsKt; import org.jetbrains.kotlin.utils.ExceptionUtilsKt;
@@ -34,7 +35,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
public class TypeSubstitutor { public class TypeSubstitutor implements TypeSubstitutorMarker {
private static final int MAX_RECURSION_DEPTH = 100; private static final int MAX_RECURSION_DEPTH = 100;
@@ -444,7 +444,9 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext {
} }
override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker { override fun TypeSubstitutorMarker.safeSubstitute(type: KotlinTypeMarker): KotlinTypeMarker {
errorSupportedOnlyInTypeInference() require(type is UnwrappedType, type::errorMessage)
require(this is TypeSubstitutor, this::errorMessage)
return safeSubstitute(type, Variance.INVARIANT)
} }
override fun TypeVariableMarker.defaultType(): SimpleTypeMarker { override fun TypeVariableMarker.defaultType(): SimpleTypeMarker {
@@ -470,8 +472,14 @@ interface ClassicTypeSystemContext : TypeSystemInferenceExtensionContext {
require(this is KotlinType, this::errorMessage) require(this is KotlinType, this::errorMessage)
return KotlinBuiltIns.isPrimitiveType(this) return KotlinBuiltIns.isPrimitiveType(this)
} }
override fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker? {
return captureFromExpressionInternal(type as UnwrappedType)
}
} }
private fun captureFromExpressionInternal(type: UnwrappedType) = captureFromExpression(type)
private fun hasNoInferInternal(type: UnwrappedType): Boolean { private fun hasNoInferInternal(type: UnwrappedType): Boolean {
return type.hasNoInferAnnotation() return type.hasNoInferAnnotation()
} }
@@ -12,3 +12,14 @@ fun TypeSubstitutorMarker.safeSubstitute(
) = with(c) { safeSubstitute(type) } ) = with(c) { safeSubstitute(type) }
fun TypeVariableMarker.defaultType(c: TypeSystemInferenceExtensionContext) = with(c) { defaultType() } fun TypeVariableMarker.defaultType(c: TypeSystemInferenceExtensionContext) = with(c) { defaultType() }
fun KotlinTypeMarker.dependsOnTypeConstructor(c: TypeSystemInferenceExtensionContext, typeConstructors: Set<TypeConstructorMarker>) =
with(c) {
contains { it.typeConstructor() in typeConstructors }
}
fun KotlinTypeMarker.dependsOnTypeParameters(c: TypeSystemInferenceExtensionContext, typeParameters: Collection<TypeParameterMarker>) =
with(c) {
val typeConstructors = typeParameters.mapTo(mutableSetOf()) { it.getTypeConstructor() }
dependsOnTypeConstructor(c, typeConstructors)
}
@@ -223,6 +223,8 @@ interface TypeSystemContext : TypeSystemOptimizationContext {
status: CaptureStatus status: CaptureStatus
): SimpleTypeMarker? ): SimpleTypeMarker?
fun captureFromExpression(type: KotlinTypeMarker): KotlinTypeMarker?
fun SimpleTypeMarker.asArgumentList(): TypeArgumentListMarker fun SimpleTypeMarker.asArgumentList(): TypeArgumentListMarker
operator fun TypeArgumentListMarker.get(index: Int): TypeArgumentMarker { operator fun TypeArgumentListMarker.get(index: Int): TypeArgumentMarker {