Refactoring. Merge Specificity and NullAwareness into Flexibility.
This commit is contained in:
+10
-3
@@ -20,7 +20,11 @@ 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.types.*
|
||||
import org.jetbrains.kotlin.types.Flexibility
|
||||
import org.jetbrains.kotlin.types.Flexibility.SpecificityRelation
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import org.jetbrains.kotlin.types.Variance
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
|
||||
interface SpecificityComparisonCallbacks {
|
||||
@@ -66,9 +70,12 @@ fun <T> isSignatureNotLessSpecific(
|
||||
return !constraintSystem.status.hasContradiction()
|
||||
}
|
||||
|
||||
private fun KotlinType.getSpecificityRelationTo(otherType: KotlinType) =
|
||||
this.getCapability(Flexibility::class.java)?.getSpecificityRelationTo(otherType) ?: Flexibility.SpecificityRelation.DONT_KNOW
|
||||
|
||||
private fun isDefinitelyLessSpecificByTypeSpecificity(specific: KotlinType, general: KotlinType): Boolean {
|
||||
val sThanG = specific.getSpecificityRelationTo(general)
|
||||
val gThanS = general.getSpecificityRelationTo(specific)
|
||||
return sThanG == Specificity.Relation.LESS_SPECIFIC &&
|
||||
gThanS != Specificity.Relation.LESS_SPECIFIC
|
||||
return sThanG == SpecificityRelation.LESS_SPECIFIC &&
|
||||
gThanS != SpecificityRelation.LESS_SPECIFIC
|
||||
}
|
||||
+6
-5
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.load.java.structure.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||
import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.Flexibility.SpecificityRelation
|
||||
import org.jetbrains.kotlin.types.Variance.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.createProjection
|
||||
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
|
||||
@@ -313,20 +314,20 @@ class LazyJavaTypeResolver(
|
||||
else create(replacement, TypeUtils.makeNullable(replacement))
|
||||
}
|
||||
|
||||
override fun getSpecificityRelationTo(otherType: KotlinType): Specificity.Relation {
|
||||
override fun getSpecificityRelationTo(otherType: KotlinType): SpecificityRelation {
|
||||
// For primitive types we have to take care of the case when there are two overloaded methods like
|
||||
// foo(int) and foo(Integer)
|
||||
// if we do not discriminate one of them, any call to foo(kotlin.Int) will result in overload resolution ambiguity
|
||||
// so, for such cases, we discriminate Integer in favour of int
|
||||
if (!KotlinBuiltIns.isPrimitiveType(otherType) || !KotlinBuiltIns.isPrimitiveType(lowerBound)) {
|
||||
return Specificity.Relation.DONT_KNOW
|
||||
return SpecificityRelation.DONT_KNOW
|
||||
}
|
||||
// Int! >< Int?
|
||||
if (otherType.isFlexible()) return Specificity.Relation.DONT_KNOW
|
||||
if (otherType.isFlexible()) return SpecificityRelation.DONT_KNOW
|
||||
// Int? >< Int!
|
||||
if (otherType.isMarkedNullable) return Specificity.Relation.DONT_KNOW
|
||||
if (otherType.isMarkedNullable) return SpecificityRelation.DONT_KNOW
|
||||
// Int! lessSpecific Int
|
||||
return Specificity.Relation.LESS_SPECIFIC
|
||||
return SpecificityRelation.LESS_SPECIFIC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 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.
|
||||
@@ -49,19 +49,6 @@ fun <T : TypeCapability> TypeCapabilities.addCapability(clazz: Class<T>, typeCap
|
||||
|
||||
inline fun <reified T : TypeCapability> KotlinType.getCapability(): T? = getCapability(T::class.java)
|
||||
|
||||
interface Specificity : TypeCapability {
|
||||
|
||||
enum class Relation {
|
||||
LESS_SPECIFIC,
|
||||
MORE_SPECIFIC,
|
||||
DONT_KNOW
|
||||
}
|
||||
|
||||
fun getSpecificityRelationTo(otherType: KotlinType): Relation
|
||||
}
|
||||
|
||||
fun KotlinType.getSpecificityRelationTo(otherType: KotlinType) =
|
||||
this.getCapability(Specificity::class.java)?.getSpecificityRelationTo(otherType) ?: Specificity.Relation.DONT_KNOW
|
||||
|
||||
// To facilitate laziness, any KotlinType implementation may inherit from this trait,
|
||||
// even if it turns out that the type an instance represents is not actually a type variable
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2015 JetBrains s.r.o.
|
||||
* Copyright 2010-2016 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.
|
||||
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType;
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstructor;
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||
@@ -126,9 +125,9 @@ public class TypeUtils {
|
||||
|
||||
@NotNull
|
||||
public static KotlinType makeNullableAsSpecified(@NotNull KotlinType type, boolean nullable) {
|
||||
NullAwareness nullAwareness = type.getCapability(NullAwareness.class);
|
||||
if (nullAwareness != null) {
|
||||
return nullAwareness.makeNullableAsSpecified(nullable);
|
||||
Flexibility flexibility = type.getCapability(Flexibility.class);
|
||||
if (flexibility != null) {
|
||||
return flexibility.makeNullableAsSpecified(nullable);
|
||||
}
|
||||
|
||||
// Wrapping serves two purposes here
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.types
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.types.Flexibility.SpecificityRelation
|
||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||
|
||||
open class DynamicTypesSettings {
|
||||
@@ -55,8 +56,8 @@ object DynamicTypeFactory : FlexibleTypeFactory {
|
||||
|
||||
override val delegateType: KotlinType get() = upperBound
|
||||
|
||||
override fun getSpecificityRelationTo(otherType: KotlinType): Specificity.Relation {
|
||||
return if (!otherType.isDynamic()) Specificity.Relation.LESS_SPECIFIC else Specificity.Relation.DONT_KNOW
|
||||
override fun getSpecificityRelationTo(otherType: KotlinType): SpecificityRelation {
|
||||
return if (!otherType.isDynamic()) SpecificityRelation.LESS_SPECIFIC else SpecificityRelation.DONT_KNOW
|
||||
}
|
||||
|
||||
override fun makeNullableAsSpecified(nullable: Boolean): KotlinType {
|
||||
|
||||
@@ -38,6 +38,16 @@ interface Flexibility : TypeCapability, SubtypingRepresentatives {
|
||||
get() = upperBound
|
||||
|
||||
override fun sameTypeConstructor(type: KotlinType) = false
|
||||
|
||||
fun makeNullableAsSpecified(nullable: Boolean): KotlinType
|
||||
|
||||
enum class SpecificityRelation {
|
||||
LESS_SPECIFIC,
|
||||
MORE_SPECIFIC,
|
||||
DONT_KNOW
|
||||
}
|
||||
|
||||
fun getSpecificityRelationTo(otherType: KotlinType): SpecificityRelation
|
||||
}
|
||||
|
||||
fun KotlinType.isFlexible(): Boolean = this.getCapability(Flexibility::class.java) != null
|
||||
@@ -85,23 +95,12 @@ fun Collection<TypeProjection>.singleBestRepresentative(): TypeProjection? {
|
||||
fun KotlinType.lowerIfFlexible(): KotlinType = if (this.isFlexible()) this.flexibility().lowerBound else this
|
||||
fun KotlinType.upperIfFlexible(): KotlinType = if (this.isFlexible()) this.flexibility().upperBound else this
|
||||
|
||||
interface NullAwareness : TypeCapability {
|
||||
fun makeNullableAsSpecified(nullable: Boolean): KotlinType
|
||||
}
|
||||
|
||||
abstract class DelegatingFlexibleType protected constructor(
|
||||
override val lowerBound: KotlinType,
|
||||
override val upperBound: KotlinType,
|
||||
override val factory: FlexibleTypeFactory
|
||||
) : DelegatingType(), NullAwareness, Flexibility, Specificity {
|
||||
) : DelegatingType(), Flexibility {
|
||||
companion object {
|
||||
internal val capabilityClasses = hashSetOf(
|
||||
NullAwareness::class.java,
|
||||
Flexibility::class.java,
|
||||
SubtypingRepresentatives::class.java,
|
||||
Specificity::class.java
|
||||
)
|
||||
|
||||
@JvmField
|
||||
var RUN_SLOW_ASSERTIONS = false
|
||||
}
|
||||
@@ -130,9 +129,10 @@ abstract class DelegatingFlexibleType protected constructor(
|
||||
|
||||
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>): T? {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
if (capabilityClass in capabilityClasses) return this as T
|
||||
|
||||
return super<DelegatingType>.getCapability(capabilityClass)
|
||||
return when(capabilityClass) {
|
||||
Flexibility::class.java, SubtypingRepresentatives::class.java -> this as T
|
||||
else -> super<DelegatingType>.getCapability(capabilityClass)
|
||||
}
|
||||
}
|
||||
|
||||
override fun makeNullableAsSpecified(nullable: Boolean): KotlinType {
|
||||
|
||||
Reference in New Issue
Block a user