Don't use reflection in JetType.getCapability

This commit is contained in:
Alexander Udalov
2015-06-05 19:07:24 +03:00
parent d4c18b3d55
commit 5394abc83e
6 changed files with 46 additions and 28 deletions
@@ -300,10 +300,11 @@ class LazyJavaTypeResolver(
override val id: String get() = "kotlin.jvm.PlatformType" override val id: String get() = "kotlin.jvm.PlatformType"
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? { override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? {
if (capabilityClass.isAssignableFrom(javaClass<Impl>())) @suppress("UNCHECKED_CAST")
[suppress("UNCHECKED_CAST")] return when (capabilityClass) {
return Impl(flexibility) as T javaClass<CustomTypeVariable>(), javaClass<Specificity>() -> Impl(flexibility) as T
else return null else -> null
}
} }
@@ -16,11 +16,12 @@
package org.jetbrains.kotlin.resolve.calls.inference package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.builtins.KotlinBuiltIns
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.types.Variance.* import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.types.Variance.IN_VARIANCE
import org.jetbrains.kotlin.types.Variance.OUT_VARIANCE
public class CapturedTypeConstructor( public class CapturedTypeConstructor(
public val typeProjection: TypeProjection public val typeProjection: TypeProjection
@@ -64,6 +65,12 @@ public class CapturedType(
override fun getDelegate(): JetType = delegateType override fun getDelegate(): JetType = delegateType
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>): T? {
@suppress("UNCHECKED_CAST")
return if (capabilityClass == javaClass<SubtypingRepresentatives>()) this as T
else super<DelegatingType>.getCapability(capabilityClass)
}
override val subTypeRepresentative: JetType override val subTypeRepresentative: JetType
get() = representative(OUT_VARIANCE, KotlinBuiltIns.getInstance().getNullableAnyType()) get() = representative(OUT_VARIANCE, KotlinBuiltIns.getInstance().getNullableAnyType())
@@ -29,10 +29,6 @@ public abstract class AbstractJetType implements JetType {
@Nullable @Nullable
@Override @Override
public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) { public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
if (capabilityClass.isInstance(this)) {
//noinspection unchecked
return (T) this;
}
return null; return null;
} }
@@ -64,10 +64,6 @@ public abstract class DelegatingType implements JetType {
@Override @Override
@Nullable @Nullable
public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) { public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
if (capabilityClass.isInstance(this)) {
//noinspection unchecked
return (T) this;
}
return getDelegate().getCapability(capabilityClass); return getDelegate().getCapability(capabilityClass);
} }
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.types package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import kotlin.platform.platformStatic
open class DynamicTypesSettings { open class DynamicTypesSettings {
open val dynamicTypesAllowed: Boolean open val dynamicTypesAllowed: Boolean
@@ -29,7 +28,7 @@ class DynamicTypesAllowed: DynamicTypesSettings() {
get() = true get() = true
} }
trait Dynamicity : TypeCapability interface Dynamicity : TypeCapability
// Object is created only for convenience here. Dynamic types may occur in the form of DelegatingFlexibleTypes, // Object is created only for convenience here. Dynamic types may occur in the form of DelegatingFlexibleTypes,
// which are produced by substitutions // which are produced by substitutions
@@ -45,14 +44,20 @@ public object DynamicTypeCapabilities : FlexibleTypeCapabilities {
override val id: String get() = "kotlin.DynamicType" override val id: String get() = "kotlin.DynamicType"
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? { override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? {
if (capabilityClass.isAssignableFrom(javaClass<Impl>())) @suppress("UNCHECKED_CAST")
[suppress("UNCHECKED_CAST")] return if (capabilityClass in Impl.capabilityClasses) Impl(flexibility) as T else null
return Impl(flexibility) as T
else return null
} }
private class Impl(flexibility: Flexibility) : Dynamicity, Specificity, NullAwareness, FlexibleTypeDelegation { private class Impl(flexibility: Flexibility) : Dynamicity, Specificity, NullAwareness, FlexibleTypeDelegation {
companion object {
internal val capabilityClasses = hashSetOf(
javaClass<Dynamicity>(),
javaClass<Specificity>(),
javaClass<NullAwareness>(),
javaClass<FlexibleTypeDelegation>()
)
}
override val delegateType: JetType = flexibility.upperBound override val delegateType: JetType = flexibility.upperBound
override fun getSpecificityRelationTo(otherType: JetType): Specificity.Relation { override fun getSpecificityRelationTo(otherType: JetType): Specificity.Relation {
@@ -16,11 +16,10 @@
package org.jetbrains.kotlin.types package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import org.jetbrains.kotlin.types.Approximation.DataFlowExtras
import org.jetbrains.kotlin.name.FqName
import kotlin.platform.platformStatic
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import kotlin.platform.platformStatic
public trait FlexibleTypeCapabilities { public trait FlexibleTypeCapabilities {
fun <T: TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? fun <T: TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T?
@@ -142,12 +141,20 @@ trait FlexibleTypeDelegation : TypeCapability {
public val delegateType: JetType public val delegateType: JetType
} }
public open class DelegatingFlexibleType protected ( public open class DelegatingFlexibleType protected constructor(
override val lowerBound: JetType, override val lowerBound: JetType,
override val upperBound: JetType, override val upperBound: JetType,
override val extraCapabilities: FlexibleTypeCapabilities override val extraCapabilities: FlexibleTypeCapabilities
) : DelegatingType(), NullAwareness, Flexibility, FlexibleTypeDelegation, Approximation { ) : DelegatingType(), NullAwareness, Flexibility, FlexibleTypeDelegation, Approximation {
companion object { companion object {
internal val capabilityClasses = hashSetOf(
javaClass<NullAwareness>(),
javaClass<Flexibility>(),
javaClass<SubtypingRepresentatives>(),
javaClass<FlexibleTypeDelegation>(),
javaClass<Approximation>()
)
platformStatic fun create(lowerBound: JetType, upperBound: JetType, extraCapabilities: FlexibleTypeCapabilities): JetType { platformStatic fun create(lowerBound: JetType, upperBound: JetType, extraCapabilities: FlexibleTypeCapabilities): JetType {
if (lowerBound == upperBound) return lowerBound if (lowerBound == upperBound) return lowerBound
return DelegatingFlexibleType(lowerBound, upperBound, extraCapabilities) return DelegatingFlexibleType(lowerBound, upperBound, extraCapabilities)
@@ -166,7 +173,13 @@ public open class DelegatingFlexibleType protected (
} }
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>): T? { override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>): T? {
return extraCapabilities.getCapability(capabilityClass, this, this) ?: super<DelegatingType>.getCapability(capabilityClass) val extra = extraCapabilities.getCapability(capabilityClass, this, this)
if (extra != null) return extra
@suppress("UNCHECKED_CAST")
if (capabilityClass in capabilityClasses) return this as T
return super<DelegatingType>.getCapability(capabilityClass)
} }
override fun makeNullableAsSpecified(nullable: Boolean): JetType { override fun makeNullableAsSpecified(nullable: Boolean): JetType {