Refactoring. Merge Specificity and NullAwareness into Flexibility.

This commit is contained in:
Stanislav Erokhin
2016-04-22 19:09:36 +03:00
parent feec3566a4
commit 8f32eeb663
6 changed files with 39 additions and 44 deletions
@@ -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
}
@@ -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 {