Introduce SimpleConstraintSystem for OverloadChecker and OverloadingConflictResolver

This commit is contained in:
Stanislav Erokhin
2016-08-23 18:31:10 +03:00
parent 5ad0e4e9b8
commit f31493f80f
4 changed files with 40 additions and 23 deletions
@@ -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)
}
@@ -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()
}
}
}
}
@@ -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}
@@ -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 =