Cleanup constraint system, convert functions to properties, delete unused
This commit is contained in:
@@ -152,7 +152,7 @@ public object Renderers {
|
||||
public fun renderConflictingSubstitutionsInferenceError(
|
||||
inferenceErrorData: InferenceErrorData, result: TabledDescriptorRenderer
|
||||
): TabledDescriptorRenderer {
|
||||
LOG.assertTrue(inferenceErrorData.constraintSystem.getStatus().hasConflictingConstraints(),
|
||||
LOG.assertTrue(inferenceErrorData.constraintSystem.status.hasConflictingConstraints(),
|
||||
renderDebugMessage("Conflicting substitutions inference error renderer is applied for incorrect status", inferenceErrorData))
|
||||
|
||||
val substitutedDescriptors = Lists.newArrayList<CallableDescriptor>()
|
||||
@@ -207,7 +207,7 @@ public object Renderers {
|
||||
public fun renderParameterConstraintError(
|
||||
inferenceErrorData: InferenceErrorData, renderer: TabledDescriptorRenderer
|
||||
): TabledDescriptorRenderer {
|
||||
val constraintErrors = inferenceErrorData.constraintSystem.getStatus().constraintErrors
|
||||
val constraintErrors = inferenceErrorData.constraintSystem.status.constraintErrors
|
||||
val errorPositions = constraintErrors.filter { it is ParameterConstraintError }.map { it.constraintPosition }
|
||||
return renderer.table(
|
||||
TabledDescriptorRenderer
|
||||
@@ -225,7 +225,7 @@ public object Renderers {
|
||||
inferenceErrorData: InferenceErrorData, result: TabledDescriptorRenderer
|
||||
): TabledDescriptorRenderer {
|
||||
var firstUnknownParameter: TypeParameterDescriptor? = null
|
||||
for (typeParameter in inferenceErrorData.constraintSystem.getTypeVariables()) {
|
||||
for (typeParameter in inferenceErrorData.constraintSystem.typeVariables) {
|
||||
if (inferenceErrorData.constraintSystem.getTypeBounds(typeParameter).values.isEmpty()) {
|
||||
firstUnknownParameter = typeParameter
|
||||
break
|
||||
@@ -250,12 +250,12 @@ public object Renderers {
|
||||
inferenceErrorData: InferenceErrorData, result: TabledDescriptorRenderer
|
||||
): TabledDescriptorRenderer {
|
||||
val constraintSystem = inferenceErrorData.constraintSystem
|
||||
val status = constraintSystem.getStatus()
|
||||
val status = constraintSystem.status
|
||||
LOG.assertTrue(status.hasViolatedUpperBound(),
|
||||
renderDebugMessage("Upper bound violated renderer is applied for incorrect status", inferenceErrorData))
|
||||
|
||||
val systemWithoutWeakConstraints = constraintSystem.filterConstraintsOut(ConstraintPositionKind.TYPE_BOUND_POSITION)
|
||||
val typeParameterDescriptor = inferenceErrorData.descriptor.getTypeParameters().firstOrNull {
|
||||
val typeParameterDescriptor = inferenceErrorData.descriptor.typeParameters.firstOrNull {
|
||||
!ConstraintsUtil.checkUpperBoundIsSatisfied(systemWithoutWeakConstraints, it, true)
|
||||
}
|
||||
if (typeParameterDescriptor == null && status.hasConflictingConstraints()) {
|
||||
@@ -282,7 +282,7 @@ public object Renderers {
|
||||
|
||||
var violatedUpperBound: KotlinType? = null
|
||||
for (upperBound in typeParameterDescriptor.getUpperBounds()) {
|
||||
val upperBoundWithSubstitutedInferredTypes = systemWithoutWeakConstraints.getResultingSubstitutor().substitute(upperBound, Variance.INVARIANT)
|
||||
val upperBoundWithSubstitutedInferredTypes = systemWithoutWeakConstraints.resultingSubstitutor.substitute(upperBound, Variance.INVARIANT)
|
||||
if (upperBoundWithSubstitutedInferredTypes != null
|
||||
&& !KotlinTypeChecker.DEFAULT.isSubtypeOf(inferredValueForTypeParameter, upperBoundWithSubstitutedInferredTypes)) {
|
||||
violatedUpperBound = upperBoundWithSubstitutedInferredTypes
|
||||
@@ -309,7 +309,7 @@ public object Renderers {
|
||||
inferenceErrorData: InferenceErrorData, result: TabledDescriptorRenderer
|
||||
): TabledDescriptorRenderer {
|
||||
val constraintSystem = inferenceErrorData.constraintSystem
|
||||
val errors = constraintSystem.getStatus().constraintErrors
|
||||
val errors = constraintSystem.status.constraintErrors
|
||||
val typeParameterWithCapturedConstraint = (errors.firstOrNull { it is CannotCapture } as? CannotCapture)?.typeVariable
|
||||
if (typeParameterWithCapturedConstraint == null) {
|
||||
LOG.error(renderDebugMessage("An error 'cannot capture type parameter' is not found in errors", inferenceErrorData))
|
||||
@@ -362,14 +362,14 @@ public object Renderers {
|
||||
public val RENDER_COLLECTION_OF_TYPES: Renderer<Collection<KotlinType>> = Renderer { renderTypes(it) }
|
||||
|
||||
private fun renderConstraintSystem(constraintSystem: ConstraintSystem, renderTypeBounds: Renderer<TypeBounds>): String {
|
||||
val typeVariables = constraintSystem.getTypeVariables()
|
||||
val typeBounds = Sets.newLinkedHashSet<TypeBounds>()
|
||||
val typeVariables = constraintSystem.typeVariables
|
||||
val typeBounds = linkedSetOf<TypeBounds>()
|
||||
for (variable in typeVariables) {
|
||||
typeBounds.add(constraintSystem.getTypeBounds(variable))
|
||||
}
|
||||
return "type parameter bounds:\n" +
|
||||
StringUtil.join(typeBounds, { renderTypeBounds.render(it) }, "\n") + "\n\n" + "status:\n" +
|
||||
ConstraintsUtil.getDebugMessageForStatus(constraintSystem.getStatus())
|
||||
ConstraintsUtil.getDebugMessageForStatus(constraintSystem.status)
|
||||
}
|
||||
|
||||
public val RENDER_CONSTRAINT_SYSTEM: Renderer<ConstraintSystem> = Renderer { renderConstraintSystem(it, RENDER_TYPE_BOUNDS) }
|
||||
|
||||
@@ -162,7 +162,7 @@ public class CallCompleter(
|
||||
updateSystemIfNeeded { builder ->
|
||||
constraintSystemCompleter.completeConstraintSystem(builder, this)
|
||||
val system = builder.build()
|
||||
val status = system.filterConstraintsOut(TYPE_BOUND_POSITION).getStatus()
|
||||
val status = system.filterConstraintsOut(TYPE_BOUND_POSITION).status
|
||||
if (status.hasOnlyErrorsDerivedFrom(FROM_COMPLETER)) null else system
|
||||
}
|
||||
}
|
||||
@@ -171,7 +171,7 @@ public class CallCompleter(
|
||||
updateSystemIfNeeded { builder ->
|
||||
builder.addSupertypeConstraint(builtIns.getUnitType(), returnType, EXPECTED_TYPE_POSITION.position())
|
||||
val system = builder.build()
|
||||
if (system.getStatus().isSuccessful()) system else null
|
||||
if (system.status.isSuccessful()) system else null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +181,7 @@ public class CallCompleter(
|
||||
val system = builder.build()
|
||||
setConstraintSystem(system)
|
||||
|
||||
setResultingSubstitutor(system.getResultingSubstitutor())
|
||||
setResultingSubstitutor(system.resultingSubstitutor)
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> MutableResolvedCall<D>.updateResolutionStatusFromConstraintSystem(
|
||||
@@ -192,7 +192,7 @@ public class CallCompleter(
|
||||
val valueArgumentsCheckingResult = candidateResolver.checkAllValueArguments(contextWithResolvedCall, RESOLVE_FUNCTION_ARGUMENTS)
|
||||
|
||||
val status = getStatus()
|
||||
if (getConstraintSystem()!!.getStatus().isSuccessful()) {
|
||||
if (getConstraintSystem()!!.status.isSuccessful()) {
|
||||
if (status == ResolutionStatus.UNKNOWN_STATUS || status == ResolutionStatus.INCOMPLETE_TYPE_INFERENCE) {
|
||||
setStatusToSuccess()
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public fun CallableDescriptor.hasInferredReturnType(constraintSystem: Constraint
|
||||
if (hasReturnTypeDependentOnUninferredParams(constraintSystem)) return false
|
||||
|
||||
// Expected type mismatch was reported before as 'TYPE_INFERENCE_EXPECTED_TYPE_MISMATCH'
|
||||
if (constraintSystem.getStatus().hasOnlyErrorsDerivedFrom(EXPECTED_TYPE_POSITION)) return false
|
||||
if (constraintSystem.status.hasOnlyErrorsDerivedFrom(EXPECTED_TYPE_POSITION)) return false
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -104,7 +104,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
||||
candidateCall.setConstraintSystem(constraintSystem)
|
||||
|
||||
// Solution
|
||||
val hasContradiction = constraintSystem.getStatus().hasContradiction()
|
||||
val hasContradiction = constraintSystem.status.hasContradiction()
|
||||
if (!hasContradiction) {
|
||||
return INCOMPLETE_TYPE_INFERENCE
|
||||
}
|
||||
@@ -209,7 +209,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
||||
}
|
||||
val resultingSystem = constraintSystem.build()
|
||||
resolvedCall.setConstraintSystem(resultingSystem)
|
||||
resolvedCall.setResultingSubstitutor(resultingSystem.getResultingSubstitutor())
|
||||
resolvedCall.setResultingSubstitutor(resultingSystem.resultingSubstitutor)
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> addConstraintForFunctionLiteral(
|
||||
@@ -222,7 +222,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
||||
val argumentExpression = valueArgument.getArgumentExpression() ?: return
|
||||
|
||||
val effectiveExpectedType = getEffectiveExpectedType(valueParameterDescriptor, valueArgument)
|
||||
var expectedType = constraintSystem.build().getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT)
|
||||
var expectedType = constraintSystem.build().currentSubstitutor.substitute(effectiveExpectedType, Variance.INVARIANT)
|
||||
if (expectedType == null || TypeUtils.isDontCarePlaceholder(expectedType)) {
|
||||
expectedType = argumentTypeResolver.getShapeTypeOfFunctionLiteral(functionLiteral, context.scope, context.trace, false)
|
||||
}
|
||||
@@ -284,7 +284,7 @@ class GenericCandidateResolver(private val argumentTypeResolver: ArgumentTypeRes
|
||||
context: CallCandidateResolutionContext<D>,
|
||||
effectiveExpectedType: KotlinType
|
||||
): KotlinType? {
|
||||
val substitutedType = constraintSystem.build().getCurrentSubstitutor().substitute(effectiveExpectedType, Variance.INVARIANT)
|
||||
val substitutedType = constraintSystem.build().currentSubstitutor.substitute(effectiveExpectedType, Variance.INVARIANT)
|
||||
if (substitutedType != null && !TypeUtils.isDontCarePlaceholder(substitutedType))
|
||||
return substitutedType
|
||||
|
||||
|
||||
-1
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.inference.constraintPosition
|
||||
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.*
|
||||
import java.util.*
|
||||
|
||||
public enum class ConstraintPositionKind {
|
||||
RECEIVER_POSITION,
|
||||
|
||||
+5
-5
@@ -27,9 +27,9 @@ interface ConstraintSystem {
|
||||
/**
|
||||
* Returns a set of all non-external registered type variables.
|
||||
*/
|
||||
fun getTypeVariables(): Set<TypeParameterDescriptor>
|
||||
val typeVariables: Set<TypeParameterDescriptor>
|
||||
|
||||
fun getStatus(): ConstraintSystemStatus
|
||||
val status: ConstraintSystemStatus
|
||||
|
||||
/**
|
||||
* Returns the resulting type constraints of solving the constraint system for specific type variable.
|
||||
@@ -46,18 +46,18 @@ interface ConstraintSystem {
|
||||
* If the addition of the 'expected type' constraint made the system fail,
|
||||
* this constraint is not included in the resulting substitution.
|
||||
*/
|
||||
fun getResultingSubstitutor(): TypeSubstitutor
|
||||
val resultingSubstitutor: TypeSubstitutor
|
||||
|
||||
/**
|
||||
* Returns the current result of solving the constraint system (mapping from the type variable to the resulting type projection).
|
||||
* If there is no information for type parameter, returns type projection for DONT_CARE type.
|
||||
*/
|
||||
fun getCurrentSubstitutor(): TypeSubstitutor
|
||||
val currentSubstitutor: TypeSubstitutor
|
||||
|
||||
/**
|
||||
* Returns the substitution only for type parameters that have result values, otherwise returns the type parameter itself.
|
||||
*/
|
||||
fun getPartialSubstitutor(): TypeSubstitutor
|
||||
val partialSubstitutor: TypeSubstitutor
|
||||
|
||||
fun getNestedTypeVariables(type: KotlinType): List<TypeParameterDescriptor>
|
||||
|
||||
|
||||
+15
-17
@@ -79,9 +79,9 @@ public class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
variablesToOriginal[typeVariable] = original
|
||||
}
|
||||
for ((typeVariable, typeBounds) in allTypeParameterBounds) {
|
||||
for (declaredUpperBound in typeVariable.getUpperBounds()) {
|
||||
for (declaredUpperBound in typeVariable.upperBounds) {
|
||||
if (declaredUpperBound.isDefaultBound()) continue //todo remove this line (?)
|
||||
val context = ConstraintContext(TYPE_BOUND_POSITION.position(typeVariable.getIndex()))
|
||||
val context = ConstraintContext(TYPE_BOUND_POSITION.position(typeVariable.index))
|
||||
addBound(typeVariable, declaredUpperBound, UPPER_BOUND, context)
|
||||
}
|
||||
}
|
||||
@@ -89,11 +89,11 @@ public class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
|
||||
val TypeParameterDescriptor.correspondingType: KotlinType
|
||||
get() = cachedTypeForVariable.getOrPut(this) {
|
||||
KotlinTypeImpl.create(Annotations.EMPTY, this.getTypeConstructor(), false, listOf(), MemberScope.Empty)
|
||||
KotlinTypeImpl.create(Annotations.EMPTY, typeConstructor, false, listOf(), MemberScope.Empty)
|
||||
}
|
||||
|
||||
fun KotlinType.isProper() = !TypeUtils.containsSpecialType(this) {
|
||||
type -> type.getConstructor().getDeclarationDescriptor() in getAllTypeVariables()
|
||||
type -> type.constructor.declarationDescriptor.let { it is TypeParameterDescriptor && it in getAllTypeVariables() }
|
||||
}
|
||||
|
||||
fun getNestedTypeVariables(type: KotlinType, original: Boolean): List<TypeParameterDescriptor> {
|
||||
@@ -147,7 +147,7 @@ public class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
}
|
||||
|
||||
override fun capture(typeVariable: KotlinType, typeProjection: TypeProjection): Boolean {
|
||||
if (isMyTypeVariable(typeProjection.getType())) return false
|
||||
if (isMyTypeVariable(typeProjection.type)) return false
|
||||
val myTypeVariable = getMyTypeVariable(typeVariable)
|
||||
|
||||
if (myTypeVariable != null && constraintPosition.isParameter()) {
|
||||
@@ -173,7 +173,7 @@ public class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
return true
|
||||
}
|
||||
|
||||
if (type == null || (type.isError() && !type.isFunctionPlaceholder)) {
|
||||
if (type == null || (type.isError && !type.isFunctionPlaceholder)) {
|
||||
errors.add(ErrorInConstrainingType(constraintPosition))
|
||||
return true
|
||||
}
|
||||
@@ -195,9 +195,7 @@ public class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
return doAddConstraint(EQUAL, subType, superType, constraintContext, typeCheckingProcedure)
|
||||
}
|
||||
|
||||
assert(!superType.isFunctionPlaceholder) {
|
||||
"The type for " + constraintPosition + " shouldn't be a placeholder for function type"
|
||||
}
|
||||
assert(!superType.isFunctionPlaceholder) { "The type for $constraintPosition shouldn't be a placeholder for function type" }
|
||||
|
||||
// function literal { x -> ... } goes without declaring receiver type
|
||||
// and can be considered as extension function if one is expected
|
||||
@@ -290,7 +288,7 @@ public class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
}
|
||||
}
|
||||
|
||||
if (!parameterType.isMarkedNullable() || !TypeUtils.isNullableType(newConstrainingType)) {
|
||||
if (!parameterType.isMarkedNullable || !TypeUtils.isNullableType(newConstrainingType)) {
|
||||
addBound(typeVariable, newConstrainingType, boundKind, constraintContext)
|
||||
return
|
||||
}
|
||||
@@ -329,7 +327,7 @@ public class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
addBound(typeVariable, capturedType, EXACT_BOUND, constraintContext)
|
||||
}
|
||||
|
||||
fun getAllTypeVariables() = allTypeParameterBounds.keySet()
|
||||
fun getAllTypeVariables() = allTypeParameterBounds.keys
|
||||
|
||||
fun getBoundsUsedIn(typeVariable: TypeParameterDescriptor): List<Bound> = usedInBounds[typeVariable] ?: emptyList()
|
||||
|
||||
@@ -349,7 +347,7 @@ public class ConstraintSystemBuilderImpl : ConstraintSystem.Builder {
|
||||
fun isMyTypeVariable(type: KotlinType): Boolean = getMyTypeVariable(type) != null
|
||||
|
||||
fun getMyTypeVariable(type: KotlinType): TypeParameterDescriptor? {
|
||||
val typeParameterDescriptor = type.getConstructor().getDeclarationDescriptor() as? TypeParameterDescriptor
|
||||
val typeParameterDescriptor = type.constructor.declarationDescriptor as? TypeParameterDescriptor
|
||||
return if (typeParameterDescriptor != null && isMyTypeVariable(typeParameterDescriptor)) typeParameterDescriptor else null
|
||||
}
|
||||
|
||||
@@ -389,11 +387,11 @@ fun createTypeForFunctionPlaceholder(
|
||||
): KotlinType {
|
||||
if (!functionPlaceholder.isFunctionPlaceholder) return functionPlaceholder
|
||||
|
||||
val functionPlaceholderTypeConstructor = functionPlaceholder.getConstructor() as FunctionPlaceholderTypeConstructor
|
||||
val functionPlaceholderTypeConstructor = functionPlaceholder.constructor as FunctionPlaceholderTypeConstructor
|
||||
|
||||
val isExtension = KotlinBuiltIns.isExtensionFunctionType(expectedType)
|
||||
val newArgumentTypes = if (!functionPlaceholderTypeConstructor.hasDeclaredArguments) {
|
||||
val typeParamSize = expectedType.getConstructor().getParameters().size()
|
||||
val typeParamSize = expectedType.constructor.parameters.size
|
||||
// the first parameter is receiver (if present), the last one is return type,
|
||||
// the remaining are function arguments
|
||||
val functionArgumentsSize = if (isExtension) typeParamSize - 2 else typeParamSize - 1
|
||||
@@ -409,7 +407,7 @@ fun createTypeForFunctionPlaceholder(
|
||||
}
|
||||
|
||||
internal fun TypeSubstitutor.setApproximateCapturedTypes(): TypeSubstitutor {
|
||||
return TypeSubstitutor.create(SubstitutionWithCapturedTypeApproximation(getSubstitution()))
|
||||
return TypeSubstitutor.create(SubstitutionWithCapturedTypeApproximation(substitution))
|
||||
}
|
||||
|
||||
private class SubstitutionWithCapturedTypeApproximation(substitution: TypeSubstitution) : DelegatedTypeSubstitution(substitution) {
|
||||
@@ -426,11 +424,11 @@ class SubstitutionFilteringInternalResolveAnnotations(substitution: TypeSubstitu
|
||||
public fun createTypeSubstitutor(conversion: (TypeParameterDescriptor) -> TypeParameterDescriptor?): TypeSubstitutor {
|
||||
return TypeSubstitutor.create(object : TypeConstructorSubstitution() {
|
||||
override fun get(key: TypeConstructor): TypeProjection? {
|
||||
val descriptor = key.getDeclarationDescriptor()
|
||||
val descriptor = key.declarationDescriptor
|
||||
if (descriptor !is TypeParameterDescriptor) return null
|
||||
val typeParameterDescriptor = conversion(descriptor) ?: return null
|
||||
|
||||
val type = KotlinTypeImpl.create(Annotations.EMPTY, typeParameterDescriptor.getTypeConstructor(), false, listOf(), MemberScope.Empty)
|
||||
val type = KotlinTypeImpl.create(Annotations.EMPTY, typeParameterDescriptor.typeConstructor, false, listOf(), MemberScope.Empty)
|
||||
return TypeProjectionImpl(type)
|
||||
}
|
||||
})
|
||||
|
||||
+14
-15
@@ -46,7 +46,7 @@ class ConstraintSystemImpl(
|
||||
get() = if (externalTypeParameters.isEmpty()) allTypeParameterBounds
|
||||
else allTypeParameterBounds.filter { !externalTypeParameters.contains(it.key) }
|
||||
|
||||
private val constraintSystemStatus = object : ConstraintSystemStatus {
|
||||
override val status = object : ConstraintSystemStatus {
|
||||
// for debug ConstraintsUtil.getDebugMessageForStatus might be used
|
||||
|
||||
override fun isSuccessful() = !hasContradiction() && !hasUnknownParameters()
|
||||
@@ -54,7 +54,7 @@ class ConstraintSystemImpl(
|
||||
override fun hasContradiction() = hasParameterConstraintError() || hasConflictingConstraints()
|
||||
|| hasCannotCaptureTypesError() || hasTypeInferenceIncorporationError()
|
||||
|
||||
override fun hasViolatedUpperBound() = !isSuccessful() && filterConstraintsOut(TYPE_BOUND_POSITION).getStatus().isSuccessful()
|
||||
override fun hasViolatedUpperBound() = !isSuccessful() && filterConstraintsOut(TYPE_BOUND_POSITION).status.isSuccessful()
|
||||
|
||||
override fun hasConflictingConstraints() = localTypeParameterBounds.values.any { it.values.size > 1 }
|
||||
|
||||
@@ -65,7 +65,7 @@ class ConstraintSystemImpl(
|
||||
|
||||
override fun hasOnlyErrorsDerivedFrom(kind: ConstraintPositionKind): Boolean {
|
||||
if (isSuccessful()) return false
|
||||
if (filterConstraintsOut(kind).getStatus().isSuccessful()) return true
|
||||
if (filterConstraintsOut(kind).status.isSuccessful()) return true
|
||||
return errors.isNotEmpty() && errors.all { it.constraintPosition.derivedFrom(kind) }
|
||||
}
|
||||
|
||||
@@ -112,15 +112,14 @@ class ConstraintSystemImpl(
|
||||
return SubstitutionFilteringInternalResolveAnnotations(substitution).buildSubstitutor()
|
||||
}
|
||||
|
||||
override fun getStatus(): ConstraintSystemStatus = constraintSystemStatus
|
||||
|
||||
override fun getNestedTypeVariables(type: KotlinType): List<TypeParameterDescriptor> {
|
||||
return type.getNestedArguments().map { typeProjection ->
|
||||
typeProjection.type.constructor.declarationDescriptor as? TypeParameterDescriptor
|
||||
}.filterNotNull().filter { it in getTypeVariables() }
|
||||
}.filterNotNull().filter { it in typeVariables }
|
||||
}
|
||||
|
||||
override fun getTypeVariables() = originalToVariables.keys
|
||||
override val typeVariables: Set<TypeParameterDescriptor>
|
||||
get() = originalToVariables.keys
|
||||
|
||||
override fun getTypeBounds(typeVariable: TypeParameterDescriptor): TypeBoundsImpl {
|
||||
val variableForOriginal = originalToVariables[typeVariable]
|
||||
@@ -131,16 +130,16 @@ class ConstraintSystemImpl(
|
||||
throw IllegalArgumentException("TypeParameterDescriptor is not a type variable for constraint system: $typeVariable")
|
||||
}
|
||||
|
||||
override fun getResultingSubstitutor() =
|
||||
getSubstitutor(substituteOriginal = true) { TypeProjectionImpl(ErrorUtils.createUninferredParameterType(it)) }
|
||||
override val resultingSubstitutor: TypeSubstitutor
|
||||
get() = getSubstitutor(substituteOriginal = true) { TypeProjectionImpl(ErrorUtils.createUninferredParameterType(it)) }
|
||||
|
||||
override fun getCurrentSubstitutor() =
|
||||
getSubstitutor(substituteOriginal = true) { TypeProjectionImpl(TypeUtils.DONT_CARE) }
|
||||
override val currentSubstitutor: TypeSubstitutor
|
||||
get() = getSubstitutor(substituteOriginal = true) { TypeProjectionImpl(TypeUtils.DONT_CARE) }
|
||||
|
||||
override fun getPartialSubstitutor() =
|
||||
getSubstitutor(substituteOriginal = true) {
|
||||
TypeProjectionImpl(KotlinTypeImpl.create(Annotations.EMPTY, it.typeConstructor, false, listOf(), KtScope.Empty))
|
||||
}
|
||||
override val partialSubstitutor: TypeSubstitutor
|
||||
get() = getSubstitutor(substituteOriginal = true) {
|
||||
TypeProjectionImpl(KotlinTypeImpl.create(Annotations.EMPTY, it.typeConstructor, false, listOf(), KtScope.Empty))
|
||||
}
|
||||
|
||||
private fun getSubstitutor(substituteOriginal: Boolean, getDefaultValue: (TypeParameterDescriptor) -> TypeProjection) =
|
||||
replaceUninferredBy(getDefaultValue, substituteOriginal).setApproximateCapturedTypes()
|
||||
|
||||
-51
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.inference;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
|
||||
/**
|
||||
* A specific type for subtype constraint of types.
|
||||
*/
|
||||
public enum ConstraintType implements Comparable<ConstraintType> {
|
||||
// The order of these constants DOES matter
|
||||
// they are compared according to ordinal() values
|
||||
// First element has the highest priority
|
||||
RECEIVER("{0} is not a subtype of the expected receiver type {1}"),
|
||||
VALUE_ARGUMENT("Type mismatch: argument type is {0}, but {1} was expected"),
|
||||
EXPECTED_TYPE("Resulting type is {0} but {1} was expected"),
|
||||
PARAMETER_BOUND("Type parameter bound is not satisfied: {0} is not a subtype of {1}");
|
||||
|
||||
private final String errorMessageTemplate; // {0} is subtype, {1} is supertype
|
||||
|
||||
private ConstraintType(@NotNull String errorMessageTemplate) {
|
||||
this.errorMessageTemplate = errorMessageTemplate;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SubtypingConstraint assertSubtyping(@NotNull KotlinType subtype, @NotNull KotlinType supertype) {
|
||||
return new SubtypingConstraint(this, subtype, supertype);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String makeErrorMessage(@NotNull SubtypingConstraint constraint) {
|
||||
return MessageFormat.format(errorMessageTemplate, constraint.getSubtype(), constraint.getSupertype());
|
||||
}
|
||||
}
|
||||
-12
@@ -101,18 +101,6 @@ public class ConstraintsUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean checkBoundsAreSatisfied(
|
||||
@NotNull ConstraintSystem constraintSystem,
|
||||
boolean substituteOtherTypeParametersInBounds
|
||||
) {
|
||||
for (TypeParameterDescriptor typeVariable : constraintSystem.getTypeVariables()) {
|
||||
if (!checkUpperBoundIsSatisfied(constraintSystem, typeVariable, substituteOtherTypeParametersInBounds)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static String getDebugMessageForStatus(@NotNull ConstraintSystemStatus status) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
List<Method> interestingMethods = Lists.newArrayList();
|
||||
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.inference;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
public class SubtypingConstraint {
|
||||
private final ConstraintType type;
|
||||
private final KotlinType subtype;
|
||||
private final KotlinType supertype;
|
||||
|
||||
public SubtypingConstraint(@NotNull ConstraintType type, @NotNull KotlinType subtype, @NotNull KotlinType supertype) {
|
||||
this.type = type;
|
||||
this.subtype = subtype;
|
||||
this.supertype = supertype;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public KotlinType getSubtype() {
|
||||
return subtype;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public KotlinType getSupertype() {
|
||||
return supertype;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ConstraintType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getErrorMessage() {
|
||||
return type.makeErrorMessage(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getSubtype() + " :< " + getSupertype();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -43,7 +43,7 @@ public class TypeBoundsImpl(override val typeVariable: TypeParameterDescriptor)
|
||||
public fun addBound(bound: Bound) {
|
||||
resultValues = null
|
||||
assert(bound.typeVariable == typeVariable) {
|
||||
"$bound is added for incorrect type variable ${bound.typeVariable.getName()}. Expected: ${typeVariable.getName()}"
|
||||
"$bound is added for incorrect type variable ${bound.typeVariable.name}. Expected: ${typeVariable.name}"
|
||||
}
|
||||
bounds.add(bound)
|
||||
}
|
||||
|
||||
+4
-4
@@ -75,8 +75,8 @@ private fun ConstraintSystemBuilderImpl.addConstraintFromBounds(old: Bound, new:
|
||||
val context = ConstraintContext(CompoundConstraintPosition(old.position, new.position), old.derivedFrom + new.derivedFrom)
|
||||
|
||||
when {
|
||||
old.kind.ordinal() < new.kind.ordinal() -> addConstraint(SUB_TYPE, oldType, newType, context)
|
||||
old.kind.ordinal() > new.kind.ordinal() -> addConstraint(SUB_TYPE, newType, oldType, context)
|
||||
old.kind.ordinal < new.kind.ordinal -> addConstraint(SUB_TYPE, oldType, newType, context)
|
||||
old.kind.ordinal > new.kind.ordinal -> addConstraint(SUB_TYPE, newType, oldType, context)
|
||||
old.kind == new.kind && old.kind == EXACT_BOUND -> addConstraint(EQUAL, oldType, newType, context)
|
||||
}
|
||||
}
|
||||
@@ -93,7 +93,7 @@ private fun ConstraintSystemBuilderImpl.generateNewBound(bound: Bound, substitut
|
||||
}
|
||||
|
||||
val newTypeProjection = TypeProjectionImpl(substitutedType)
|
||||
val substitutor = TypeSubstitutor.create(mapOf(substitution.typeVariable.getTypeConstructor() to newTypeProjection))
|
||||
val substitutor = TypeSubstitutor.create(mapOf(substitution.typeVariable.typeConstructor to newTypeProjection))
|
||||
val type = substitutor.substitute(bound.constrainingType, INVARIANT) ?: return
|
||||
|
||||
val position = CompoundConstraintPosition(bound.position, substitution.position)
|
||||
@@ -120,7 +120,7 @@ private fun ConstraintSystemBuilderImpl.generateNewBound(bound: Bound, substitut
|
||||
// if we allow non-trivial type projections, we bump into errors like
|
||||
// "Empty intersection for types [MutableCollection<in ('Int'..'Int?')>, MutableCollection<out Any?>, MutableCollection<in Int>]"
|
||||
fun KotlinType.containsConstrainingTypeWithoutProjection() = this.getNestedArguments().any {
|
||||
it.getType().getConstructor() == substitution.constrainingType.getConstructor() && it.getProjectionKind() == Variance.INVARIANT
|
||||
it.type.constructor == substitution.constrainingType.constructor && it.projectionKind == Variance.INVARIANT
|
||||
}
|
||||
if (approximationBounds.upper.containsConstrainingTypeWithoutProjection() && bound.kind != LOWER_BOUND) {
|
||||
addNewBound(approximationBounds.upper, UPPER_BOUND)
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ abstract public class AbstractConstraintSystemTest() : KotlinLiteFixture() {
|
||||
|
||||
val resultingStatus = Renderers.RENDER_CONSTRAINT_SYSTEM_SHORT.render(system)
|
||||
|
||||
val resultingSubstitutor = system.getResultingSubstitutor()
|
||||
val resultingSubstitutor = system.resultingSubstitutor
|
||||
val result = typeParameterDescriptors.map {
|
||||
val parameterType = testDeclarations.getType(it.getName().asString())
|
||||
val resultType = resultingSubstitutor.substitute(parameterType, Variance.INVARIANT)
|
||||
|
||||
@@ -129,15 +129,15 @@ class FuzzyType(
|
||||
|
||||
val constraintSystem = builder.build()
|
||||
|
||||
if (constraintSystem.getStatus().hasContradiction()) return null
|
||||
if (constraintSystem.status.hasContradiction()) return null
|
||||
|
||||
// currently ConstraintSystem return successful status in case there are problems with nullability
|
||||
// that's why we have to check subtyping manually
|
||||
val substitutor = constraintSystem.getResultingSubstitutor()
|
||||
val substitutor = constraintSystem.resultingSubstitutor
|
||||
val substitutedType = substitutor.substitute(type, Variance.INVARIANT) ?: return null
|
||||
if (substitutedType.isError) return null
|
||||
val otherSubstitutedType = substitutor.substitute(otherType.type, Variance.INVARIANT) ?: return null
|
||||
if (otherSubstitutedType.isError) return null
|
||||
return if (substitutedType.checkInheritance(otherSubstitutedType)) constraintSystem.getPartialSubstitutor() else null
|
||||
return if (substitutedType.checkInheritance(otherSubstitutedType)) constraintSystem.partialSubstitutor else null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,9 +79,9 @@ public class AddGenericUpperBoundFix(
|
||||
private fun createActionsByInferenceData(inferenceData: InferenceErrorData): List<IntentionAction> {
|
||||
val successfulConstraintSystem = inferenceData.constraintSystem.filterConstraintsOut(ConstraintPositionKind.TYPE_BOUND_POSITION)
|
||||
|
||||
if (!successfulConstraintSystem.getStatus().isSuccessful()) return emptyList()
|
||||
if (!successfulConstraintSystem.status.isSuccessful()) return emptyList()
|
||||
|
||||
val resultingSubstitutor = successfulConstraintSystem.getResultingSubstitutor()
|
||||
val resultingSubstitutor = successfulConstraintSystem.resultingSubstitutor
|
||||
|
||||
return inferenceData.descriptor.typeParameters.map factory@{
|
||||
typeParameterDescriptor ->
|
||||
|
||||
Reference in New Issue
Block a user