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.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.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
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||||
|
|
||||||
interface SpecificityComparisonCallbacks {
|
interface SpecificityComparisonCallbacks {
|
||||||
@@ -66,9 +70,12 @@ fun <T> isSignatureNotLessSpecific(
|
|||||||
return !constraintSystem.status.hasContradiction()
|
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 {
|
private fun isDefinitelyLessSpecificByTypeSpecificity(specific: KotlinType, general: KotlinType): Boolean {
|
||||||
val sThanG = specific.getSpecificityRelationTo(general)
|
val sThanG = specific.getSpecificityRelationTo(general)
|
||||||
val gThanS = general.getSpecificityRelationTo(specific)
|
val gThanS = general.getSpecificityRelationTo(specific)
|
||||||
return sThanG == Specificity.Relation.LESS_SPECIFIC &&
|
return sThanG == SpecificityRelation.LESS_SPECIFIC &&
|
||||||
gThanS != Specificity.Relation.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.name.FqName
|
||||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
|
import org.jetbrains.kotlin.types.Flexibility.SpecificityRelation
|
||||||
import org.jetbrains.kotlin.types.Variance.*
|
import org.jetbrains.kotlin.types.Variance.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.createProjection
|
import org.jetbrains.kotlin.types.typeUtil.createProjection
|
||||||
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
|
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
|
||||||
@@ -313,20 +314,20 @@ class LazyJavaTypeResolver(
|
|||||||
else create(replacement, TypeUtils.makeNullable(replacement))
|
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
|
// For primitive types we have to take care of the case when there are two overloaded methods like
|
||||||
// foo(int) and foo(Integer)
|
// 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
|
// 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
|
// so, for such cases, we discriminate Integer in favour of int
|
||||||
if (!KotlinBuiltIns.isPrimitiveType(otherType) || !KotlinBuiltIns.isPrimitiveType(lowerBound)) {
|
if (!KotlinBuiltIns.isPrimitiveType(otherType) || !KotlinBuiltIns.isPrimitiveType(lowerBound)) {
|
||||||
return Specificity.Relation.DONT_KNOW
|
return SpecificityRelation.DONT_KNOW
|
||||||
}
|
}
|
||||||
// Int! >< Int?
|
// Int! >< Int?
|
||||||
if (otherType.isFlexible()) return Specificity.Relation.DONT_KNOW
|
if (otherType.isFlexible()) return SpecificityRelation.DONT_KNOW
|
||||||
// Int? >< Int!
|
// Int? >< Int!
|
||||||
if (otherType.isMarkedNullable) return Specificity.Relation.DONT_KNOW
|
if (otherType.isMarkedNullable) return SpecificityRelation.DONT_KNOW
|
||||||
// Int! lessSpecific Int
|
// 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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)
|
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,
|
// 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
|
// 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.DeclarationDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor;
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
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.constants.IntegerValueTypeConstructor;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
|
||||||
@@ -126,9 +125,9 @@ public class TypeUtils {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static KotlinType makeNullableAsSpecified(@NotNull KotlinType type, boolean nullable) {
|
public static KotlinType makeNullableAsSpecified(@NotNull KotlinType type, boolean nullable) {
|
||||||
NullAwareness nullAwareness = type.getCapability(NullAwareness.class);
|
Flexibility flexibility = type.getCapability(Flexibility.class);
|
||||||
if (nullAwareness != null) {
|
if (flexibility != null) {
|
||||||
return nullAwareness.makeNullableAsSpecified(nullable);
|
return flexibility.makeNullableAsSpecified(nullable);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrapping serves two purposes here
|
// Wrapping serves two purposes here
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package org.jetbrains.kotlin.types
|
package org.jetbrains.kotlin.types
|
||||||
|
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.types.Flexibility.SpecificityRelation
|
||||||
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
import org.jetbrains.kotlin.types.typeUtil.builtIns
|
||||||
|
|
||||||
open class DynamicTypesSettings {
|
open class DynamicTypesSettings {
|
||||||
@@ -55,8 +56,8 @@ object DynamicTypeFactory : FlexibleTypeFactory {
|
|||||||
|
|
||||||
override val delegateType: KotlinType get() = upperBound
|
override val delegateType: KotlinType get() = upperBound
|
||||||
|
|
||||||
override fun getSpecificityRelationTo(otherType: KotlinType): Specificity.Relation {
|
override fun getSpecificityRelationTo(otherType: KotlinType): SpecificityRelation {
|
||||||
return if (!otherType.isDynamic()) Specificity.Relation.LESS_SPECIFIC else Specificity.Relation.DONT_KNOW
|
return if (!otherType.isDynamic()) SpecificityRelation.LESS_SPECIFIC else SpecificityRelation.DONT_KNOW
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun makeNullableAsSpecified(nullable: Boolean): KotlinType {
|
override fun makeNullableAsSpecified(nullable: Boolean): KotlinType {
|
||||||
|
|||||||
@@ -38,6 +38,16 @@ interface Flexibility : TypeCapability, SubtypingRepresentatives {
|
|||||||
get() = upperBound
|
get() = upperBound
|
||||||
|
|
||||||
override fun sameTypeConstructor(type: KotlinType) = false
|
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
|
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.lowerIfFlexible(): KotlinType = if (this.isFlexible()) this.flexibility().lowerBound else this
|
||||||
fun KotlinType.upperIfFlexible(): KotlinType = if (this.isFlexible()) this.flexibility().upperBound 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(
|
abstract class DelegatingFlexibleType protected constructor(
|
||||||
override val lowerBound: KotlinType,
|
override val lowerBound: KotlinType,
|
||||||
override val upperBound: KotlinType,
|
override val upperBound: KotlinType,
|
||||||
override val factory: FlexibleTypeFactory
|
override val factory: FlexibleTypeFactory
|
||||||
) : DelegatingType(), NullAwareness, Flexibility, Specificity {
|
) : DelegatingType(), Flexibility {
|
||||||
companion object {
|
companion object {
|
||||||
internal val capabilityClasses = hashSetOf(
|
|
||||||
NullAwareness::class.java,
|
|
||||||
Flexibility::class.java,
|
|
||||||
SubtypingRepresentatives::class.java,
|
|
||||||
Specificity::class.java
|
|
||||||
)
|
|
||||||
|
|
||||||
@JvmField
|
@JvmField
|
||||||
var RUN_SLOW_ASSERTIONS = false
|
var RUN_SLOW_ASSERTIONS = false
|
||||||
}
|
}
|
||||||
@@ -130,9 +129,10 @@ abstract class DelegatingFlexibleType protected constructor(
|
|||||||
|
|
||||||
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>): T? {
|
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>): T? {
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
if (capabilityClass in capabilityClasses) return this as T
|
return when(capabilityClass) {
|
||||||
|
Flexibility::class.java, SubtypingRepresentatives::class.java -> this as T
|
||||||
return super<DelegatingType>.getCapability(capabilityClass)
|
else -> super<DelegatingType>.getCapability(capabilityClass)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun makeNullableAsSpecified(nullable: Boolean): KotlinType {
|
override fun makeNullableAsSpecified(nullable: Boolean): KotlinType {
|
||||||
|
|||||||
Reference in New Issue
Block a user