Introduce SimpleConstraintSystem for OverloadChecker and OverloadingConflictResolver
This commit is contained in:
@@ -21,7 +21,11 @@ import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqNameUnsafe
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.calls.results.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.results.FlatSignature
|
||||
import org.jetbrains.kotlin.resolve.calls.results.SpecificityComparisonCallbacks
|
||||
import org.jetbrains.kotlin.resolve.calls.results.TypeSpecificityComparator
|
||||
import org.jetbrains.kotlin.resolve.calls.results.isSignatureNotLessSpecific
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.getTypeAliasConstructors
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasLowPriorityInOverloadResolution
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.varargParameterPosition
|
||||
@@ -63,8 +67,8 @@ class OverloadChecker(val specificityComparator: TypeSpecificityComparator) {
|
||||
val aSignature = FlatSignature.createFromCallableDescriptor(a)
|
||||
val bSignature = FlatSignature.createFromCallableDescriptor(b)
|
||||
|
||||
val aIsNotLessSpecificThanB = isSignatureNotLessSpecific(aSignature, bSignature, OverloadabilitySpecificityCallbacks, specificityComparator)
|
||||
val bIsNotLessSpecificThanA = isSignatureNotLessSpecific(bSignature, aSignature, OverloadabilitySpecificityCallbacks, specificityComparator)
|
||||
val aIsNotLessSpecificThanB = ConstraintSystemBuilderImpl.forSpecificity().isSignatureNotLessSpecific (aSignature, bSignature, OverloadabilitySpecificityCallbacks, specificityComparator)
|
||||
val bIsNotLessSpecificThanA = ConstraintSystemBuilderImpl.forSpecificity().isSignatureNotLessSpecific(bSignature, aSignature, OverloadabilitySpecificityCallbacks, specificityComparator)
|
||||
|
||||
return !(aIsNotLessSpecificThanB && bIsNotLessSpecificThanA)
|
||||
}
|
||||
|
||||
+16
-2
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.BoundKind.*
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.TYPE_BOUND_POSITION
|
||||
import org.jetbrains.kotlin.resolve.calls.results.SimpleConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.util.createFunctionType
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasExactAnnotation
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasNoInferAnnotation
|
||||
@@ -38,7 +39,7 @@ import org.jetbrains.kotlin.types.typeUtil.defaultProjections
|
||||
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
|
||||
import java.util.*
|
||||
|
||||
class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystemBuilderImpl.Mode.INFERENCE) : ConstraintSystem.Builder {
|
||||
open class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystemBuilderImpl.Mode.INFERENCE) : ConstraintSystem.Builder {
|
||||
enum class Mode {
|
||||
INFERENCE,
|
||||
SPECIFICITY
|
||||
@@ -409,7 +410,20 @@ class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystemBuild
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun forSpecificity() = ConstraintSystemBuilderImpl(Mode.SPECIFICITY)
|
||||
fun forSpecificity(): SimpleConstraintSystem = object : ConstraintSystemBuilderImpl(Mode.SPECIFICITY), SimpleConstraintSystem {
|
||||
var counter = 0
|
||||
|
||||
override fun registerTypeVariables(typeParameters: Collection<TypeParameterDescriptor>) =
|
||||
registerTypeVariables(CallHandle.NONE, typeParameters)
|
||||
|
||||
override fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType) =
|
||||
addSubtypeConstraint(subType, superType, ConstraintPositionKind.VALUE_PARAMETER_POSITION.position(counter++))
|
||||
|
||||
override fun hasContradiction(): Boolean {
|
||||
fixVariables()
|
||||
return build().status.hasContradiction()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-16
@@ -17,21 +17,17 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.results
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CallHandle
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.valueParameterPosition
|
||||
import org.jetbrains.kotlin.resolve.calls.model.DefaultValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.model.MutableResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCallImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.results.FlatSignature.Companion.argumentValueType
|
||||
import org.jetbrains.kotlin.resolve.calls.results.FlatSignature.Companion.extensionReceiverTypeOrEmpty
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import java.util.*
|
||||
|
||||
@@ -47,21 +43,24 @@ interface TypeSpecificityComparator {
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> isSignatureNotLessSpecific(
|
||||
interface SimpleConstraintSystem {
|
||||
fun registerTypeVariables(typeParameters: Collection<TypeParameterDescriptor>): TypeSubstitutor
|
||||
fun addSubtypeConstraint(subType: UnwrappedType, superType: UnwrappedType)
|
||||
fun hasContradiction(): Boolean
|
||||
}
|
||||
|
||||
fun <T> SimpleConstraintSystem.isSignatureNotLessSpecific(
|
||||
specific: FlatSignature<T>,
|
||||
general: FlatSignature<T>,
|
||||
callbacks: SpecificityComparisonCallbacks,
|
||||
specificityComparator: TypeSpecificityComparator,
|
||||
callHandle: CallHandle = CallHandle.NONE
|
||||
specificityComparator: TypeSpecificityComparator
|
||||
): Boolean {
|
||||
if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return false
|
||||
if (specific.valueParameterTypes.size != general.valueParameterTypes.size) return false
|
||||
|
||||
val typeParameters = general.typeParameters
|
||||
val constraintSystemBuilder: ConstraintSystem.Builder = ConstraintSystemBuilderImpl.forSpecificity()
|
||||
val typeSubstitutor = constraintSystemBuilder.registerTypeVariables(callHandle, typeParameters)
|
||||
val typeSubstitutor = registerTypeVariables(typeParameters)
|
||||
|
||||
var numConstraints = 0
|
||||
for ((specificType, generalType) in specific.valueParameterTypes.zip(general.valueParameterTypes)) {
|
||||
if (specificType == null || generalType == null) continue
|
||||
|
||||
@@ -78,13 +77,11 @@ fun <T> isSignatureNotLessSpecific(
|
||||
}
|
||||
else {
|
||||
val substitutedGeneralType = typeSubstitutor.safeSubstitute(generalType, Variance.INVARIANT)
|
||||
constraintSystemBuilder.addSubtypeConstraint(specificType, substitutedGeneralType, valueParameterPosition(numConstraints++))
|
||||
addSubtypeConstraint(specificType.unwrap(), substitutedGeneralType.unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
constraintSystemBuilder.fixVariables()
|
||||
val constraintSystem = constraintSystemBuilder.build()
|
||||
return !constraintSystem.status.hasContradiction()
|
||||
return !hasContradiction()
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +120,7 @@ fun createOverloadingConflictResolver(
|
||||
builtIns,
|
||||
specificityComparator,
|
||||
MutableResolvedCall<*>::getResultingDescriptor,
|
||||
ConstraintSystemBuilderImpl.Companion::forSpecificity,
|
||||
MutableResolvedCall<*>::createFlatSignature,
|
||||
{ (it as? VariableAsFunctionResolvedCallImpl)?.variableCall },
|
||||
{ DescriptorToSourceUtils.descriptorToDeclaration(it) != null}
|
||||
|
||||
+3
-2
@@ -34,6 +34,7 @@ class OverloadingConflictResolver<C : Any>(
|
||||
private val builtIns: KotlinBuiltIns,
|
||||
private val specificityComparator: TypeSpecificityComparator,
|
||||
private val getResultingDescriptor: (C) -> CallableDescriptor,
|
||||
private val createEmptyConstraintSystem: () -> SimpleConstraintSystem,
|
||||
private val createFlatSignature: (C) -> FlatSignature<C>,
|
||||
private val getVariableCandidates: (C) -> C?, // vor variable WithInvoke
|
||||
private val isFromSources: (CallableDescriptor) -> Boolean
|
||||
@@ -235,7 +236,7 @@ class OverloadingConflictResolver<C : Any>(
|
||||
if (isGeneric1 && isGeneric2) return false
|
||||
}
|
||||
|
||||
return isSignatureNotLessSpecific(call1, call2, SpecificityComparisonWithNumerics, specificityComparator)
|
||||
return createEmptyConstraintSystem().isSignatureNotLessSpecific(call1, call2, SpecificityComparisonWithNumerics, specificityComparator)
|
||||
}
|
||||
|
||||
private val SpecificityComparisonWithNumerics = object : SpecificityComparisonCallbacks {
|
||||
@@ -321,7 +322,7 @@ class OverloadingConflictResolver<C : Any>(
|
||||
|
||||
val fSignature = FlatSignature.createFromCallableDescriptor(f)
|
||||
val gSignature = FlatSignature.createFromCallableDescriptor(g)
|
||||
return isSignatureNotLessSpecific(fSignature, gSignature, SpecificityComparisonWithNumerics, specificityComparator)
|
||||
return createEmptyConstraintSystem().isSignatureNotLessSpecific(fSignature, gSignature, SpecificityComparisonWithNumerics, specificityComparator)
|
||||
}
|
||||
|
||||
private fun isNotLessSpecificCallableReference(f: CallableDescriptor, g: CallableDescriptor): Boolean =
|
||||
|
||||
Reference in New Issue
Block a user