Minor, refactor "is KProperty" checks in ReflectionTypes

This commit is contained in:
Alexander Udalov
2016-06-22 15:55:41 +03:00
parent e68de436bb
commit cf630e01db
5 changed files with 26 additions and 18 deletions
@@ -179,7 +179,7 @@ class PropertyReferenceCodegen(
value.put(OBJECT_TYPE, this) value.put(OBJECT_TYPE, this)
} }
if (!ReflectionTypes.isKMutablePropertyType(localVariableDescriptorForReference.type)) return if (!ReflectionTypes.isNumberedKMutablePropertyType(localVariableDescriptorForReference.type)) return
val setterParameters = (getterParameters + arrayOf(OBJECT_TYPE)) val setterParameters = (getterParameters + arrayOf(OBJECT_TYPE))
generateAccessor(method("set", Type.VOID_TYPE, *setterParameters)) { value -> generateAccessor(method("set", Type.VOID_TYPE, *setterParameters)) { value ->
@@ -305,7 +305,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
supertypes = Collections.singleton( supertypes = Collections.singleton(
runtimeTypes.getSupertypeForPropertyReference( runtimeTypes.getSupertypeForPropertyReference(
(PropertyDescriptor) target, (PropertyDescriptor) target,
ReflectionTypes.Companion.isKMutablePropertyType(callableDescriptor.getReturnType()), ReflectionTypes.Companion.isNumberedKMutablePropertyType(callableDescriptor.getReturnType()),
receiverType != null receiverType != null
) )
); );
@@ -216,6 +216,9 @@ public abstract class KotlinBuiltIns {
public final FqNameUnsafe kClass = reflect("KClass"); public final FqNameUnsafe kClass = reflect("KClass");
public final FqNameUnsafe kCallable = reflect("KCallable"); public final FqNameUnsafe kCallable = reflect("KCallable");
public final FqNameUnsafe kProperty0 = reflect("KProperty0");
public final FqNameUnsafe kProperty1 = reflect("KProperty1");
public final FqNameUnsafe kProperty2 = reflect("KProperty2");
public final FqNameUnsafe kMutableProperty0 = reflect("KMutableProperty0"); public final FqNameUnsafe kMutableProperty0 = reflect("KMutableProperty0");
public final FqNameUnsafe kMutableProperty1 = reflect("KMutableProperty1"); public final FqNameUnsafe kMutableProperty1 = reflect("KMutableProperty1");
public final FqNameUnsafe kMutableProperty2 = reflect("KMutableProperty2"); public final FqNameUnsafe kMutableProperty2 = reflect("KMutableProperty2");
@@ -120,28 +120,34 @@ class ReflectionTypes(module: ModuleDescriptor) {
fun isCallableType(type: KotlinType): Boolean = fun isCallableType(type: KotlinType): Boolean =
type.isFunctionTypeOrSubtype || isKCallableType(type) type.isFunctionTypeOrSubtype || isKCallableType(type)
@JvmStatic fun isFunctionalKPropertyType(type: KotlinType): Boolean { @JvmStatic
val descriptor = type.constructor.declarationDescriptor ?: return false fun isNumberedKPropertyOrKMutablePropertyType(type: KotlinType): Boolean =
val segments = DescriptorUtils.getFqName(descriptor).pathSegments() isNumberedKPropertyType(type) || isNumberedKMutablePropertyType(type)
return segments.size == 3 && segments.subList(0, 2) == KOTLIN_REFLECT_FQ_NAME.pathSegments() &&
segments.last().let { it.isProperty("KProperty") || it.isProperty("KMutableProperty") }
}
private fun Name.isProperty(baseName: String) = asString().startsWith(baseName) && asString() != baseName
private fun isKCallableType(type: KotlinType): Boolean = private fun isKCallableType(type: KotlinType): Boolean =
hasFqName(type.constructor, KotlinBuiltIns.FQ_NAMES.kCallable) || hasFqName(type.constructor, KotlinBuiltIns.FQ_NAMES.kCallable) ||
type.constructor.supertypes.any { isKCallableType(it) } type.constructor.supertypes.any { isKCallableType(it) }
fun isKMutablePropertyType(type: KotlinType): Boolean { fun isNumberedKMutablePropertyType(type: KotlinType): Boolean {
val typeConstructor = type.constructor val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
return hasFqName(typeConstructor, KotlinBuiltIns.FQ_NAMES.kMutableProperty0) || return hasFqName(descriptor, KotlinBuiltIns.FQ_NAMES.kMutableProperty0) ||
hasFqName(typeConstructor, KotlinBuiltIns.FQ_NAMES.kMutableProperty1) || hasFqName(descriptor, KotlinBuiltIns.FQ_NAMES.kMutableProperty1) ||
hasFqName(typeConstructor, KotlinBuiltIns.FQ_NAMES.kMutableProperty2) hasFqName(descriptor, KotlinBuiltIns.FQ_NAMES.kMutableProperty2)
}
fun isNumberedKPropertyType(type: KotlinType): Boolean {
val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
return hasFqName(descriptor, KotlinBuiltIns.FQ_NAMES.kProperty0) ||
hasFqName(descriptor, KotlinBuiltIns.FQ_NAMES.kProperty1) ||
hasFqName(descriptor, KotlinBuiltIns.FQ_NAMES.kProperty2)
} }
private fun hasFqName(typeConstructor: TypeConstructor, fqName: FqNameUnsafe): Boolean { private fun hasFqName(typeConstructor: TypeConstructor, fqName: FqNameUnsafe): Boolean {
val descriptor = typeConstructor.declarationDescriptor as? ClassDescriptor ?: return false val descriptor = typeConstructor.declarationDescriptor
return descriptor is ClassDescriptor && hasFqName(descriptor, fqName)
}
private fun hasFqName(descriptor: ClassDescriptor, fqName: FqNameUnsafe): Boolean {
return descriptor.name == fqName.shortName() && DescriptorUtils.getFqName(descriptor) == fqName return descriptor.name == fqName.shortName() && DescriptorUtils.getFqName(descriptor) == fqName
} }
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.KtNodeTypes;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType; import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.builtins.ReflectionTypes; import org.jetbrains.kotlin.builtins.ReflectionTypes;
import org.jetbrains.kotlin.builtins.ReflectionTypesKt;
import org.jetbrains.kotlin.descriptors.CallableDescriptor; import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
@@ -183,7 +182,7 @@ public final class PatternTranslator extends AbstractTranslator {
private JsExpression getIsTypeCheckCallableForBuiltin(@NotNull KotlinType type) { private JsExpression getIsTypeCheckCallableForBuiltin(@NotNull KotlinType type) {
if (isAnyOrNullableAny(type)) return namer().isAny(); if (isAnyOrNullableAny(type)) return namer().isAny();
if (isFunctionTypeOrSubtype(type) && !ReflectionTypes.isFunctionalKPropertyType(type)) { if (isFunctionTypeOrSubtype(type) && !ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(type)) {
return namer().isTypeOf(program().getStringLiteral("function")); return namer().isTypeOf(program().getStringLiteral("function"));
} }