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