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 fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? {
if (capabilityClass.isAssignableFrom(javaClass<Impl>()))
[suppress("UNCHECKED_CAST")]
return Impl(flexibility) as T
else return null
@suppress("UNCHECKED_CAST")
return when (capabilityClass) {
javaClass<CustomTypeVariable>(), javaClass<Specificity>() -> Impl(flexibility) as T
else -> null
}
}
@@ -16,11 +16,12 @@
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.annotations.Annotations
import org.jetbrains.kotlin.types.Variance.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.Variance.IN_VARIANCE
import org.jetbrains.kotlin.types.Variance.OUT_VARIANCE
public class CapturedTypeConstructor(
public val typeProjection: TypeProjection
@@ -64,6 +65,12 @@ public class CapturedType(
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
get() = representative(OUT_VARIANCE, KotlinBuiltIns.getInstance().getNullableAnyType())
@@ -29,10 +29,6 @@ public abstract class AbstractJetType implements JetType {
@Nullable
@Override
public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
if (capabilityClass.isInstance(this)) {
//noinspection unchecked
return (T) this;
}
return null;
}
@@ -64,10 +64,6 @@ public abstract class DelegatingType implements JetType {
@Override
@Nullable
public <T extends TypeCapability> T getCapability(@NotNull Class<T> capabilityClass) {
if (capabilityClass.isInstance(this)) {
//noinspection unchecked
return (T) this;
}
return getDelegate().getCapability(capabilityClass);
}
@@ -17,7 +17,6 @@
package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import kotlin.platform.platformStatic
open class DynamicTypesSettings {
open val dynamicTypesAllowed: Boolean
@@ -29,7 +28,7 @@ class DynamicTypesAllowed: DynamicTypesSettings() {
get() = true
}
trait Dynamicity : TypeCapability
interface Dynamicity : TypeCapability
// Object is created only for convenience here. Dynamic types may occur in the form of DelegatingFlexibleTypes,
// which are produced by substitutions
@@ -45,14 +44,20 @@ public object DynamicTypeCapabilities : FlexibleTypeCapabilities {
override val id: String get() = "kotlin.DynamicType"
override fun <T : TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T? {
if (capabilityClass.isAssignableFrom(javaClass<Impl>()))
[suppress("UNCHECKED_CAST")]
return Impl(flexibility) as T
else return null
@suppress("UNCHECKED_CAST")
return if (capabilityClass in Impl.capabilityClasses) Impl(flexibility) as T else null
}
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 fun getSpecificityRelationTo(otherType: JetType): Specificity.Relation {
@@ -16,11 +16,10 @@
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.FqName
import org.jetbrains.kotlin.types.checker.JetTypeChecker
import kotlin.platform.platformStatic
public trait FlexibleTypeCapabilities {
fun <T: TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T?
@@ -142,12 +141,20 @@ trait FlexibleTypeDelegation : TypeCapability {
public val delegateType: JetType
}
public open class DelegatingFlexibleType protected (
public open class DelegatingFlexibleType protected constructor(
override val lowerBound: JetType,
override val upperBound: JetType,
override val extraCapabilities: FlexibleTypeCapabilities
) : DelegatingType(), NullAwareness, Flexibility, FlexibleTypeDelegation, Approximation {
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 {
if (lowerBound == upperBound) return lowerBound
return DelegatingFlexibleType(lowerBound, upperBound, extraCapabilities)
@@ -166,7 +173,13 @@ public open class DelegatingFlexibleType protected (
}
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 {