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)
}
if (!ReflectionTypes.isKMutablePropertyType(localVariableDescriptorForReference.type)) return
if (!ReflectionTypes.isNumberedKMutablePropertyType(localVariableDescriptorForReference.type)) return
val setterParameters = (getterParameters + arrayOf(OBJECT_TYPE))
generateAccessor(method("set", Type.VOID_TYPE, *setterParameters)) { value ->
@@ -305,7 +305,7 @@ class CodegenAnnotatingVisitor extends KtVisitorVoid {
supertypes = Collections.singleton(
runtimeTypes.getSupertypeForPropertyReference(
(PropertyDescriptor) target,
ReflectionTypes.Companion.isKMutablePropertyType(callableDescriptor.getReturnType()),
ReflectionTypes.Companion.isNumberedKMutablePropertyType(callableDescriptor.getReturnType()),
receiverType != null
)
);
@@ -216,6 +216,9 @@ public abstract class KotlinBuiltIns {
public final FqNameUnsafe kClass = reflect("KClass");
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 kMutableProperty1 = reflect("KMutableProperty1");
public final FqNameUnsafe kMutableProperty2 = reflect("KMutableProperty2");
@@ -120,28 +120,34 @@ class ReflectionTypes(module: ModuleDescriptor) {
fun isCallableType(type: KotlinType): Boolean =
type.isFunctionTypeOrSubtype || isKCallableType(type)
@JvmStatic fun isFunctionalKPropertyType(type: KotlinType): Boolean {
val descriptor = type.constructor.declarationDescriptor ?: return false
val segments = DescriptorUtils.getFqName(descriptor).pathSegments()
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
@JvmStatic
fun isNumberedKPropertyOrKMutablePropertyType(type: KotlinType): Boolean =
isNumberedKPropertyType(type) || isNumberedKMutablePropertyType(type)
private fun isKCallableType(type: KotlinType): Boolean =
hasFqName(type.constructor, KotlinBuiltIns.FQ_NAMES.kCallable) ||
type.constructor.supertypes.any { isKCallableType(it) }
fun isKMutablePropertyType(type: KotlinType): Boolean {
val typeConstructor = type.constructor
return hasFqName(typeConstructor, KotlinBuiltIns.FQ_NAMES.kMutableProperty0) ||
hasFqName(typeConstructor, KotlinBuiltIns.FQ_NAMES.kMutableProperty1) ||
hasFqName(typeConstructor, KotlinBuiltIns.FQ_NAMES.kMutableProperty2)
fun isNumberedKMutablePropertyType(type: KotlinType): Boolean {
val descriptor = type.constructor.declarationDescriptor as? ClassDescriptor ?: return false
return hasFqName(descriptor, KotlinBuiltIns.FQ_NAMES.kMutableProperty0) ||
hasFqName(descriptor, KotlinBuiltIns.FQ_NAMES.kMutableProperty1) ||
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 {
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
}
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.KtNodeTypes;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.PrimitiveType;
import org.jetbrains.kotlin.builtins.ReflectionTypes;
import org.jetbrains.kotlin.builtins.ReflectionTypesKt;
import org.jetbrains.kotlin.descriptors.CallableDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
@@ -183,7 +182,7 @@ public final class PatternTranslator extends AbstractTranslator {
private JsExpression getIsTypeCheckCallableForBuiltin(@NotNull KotlinType type) {
if (isAnyOrNullableAny(type)) return namer().isAny();
if (isFunctionTypeOrSubtype(type) && !ReflectionTypes.isFunctionalKPropertyType(type)) {
if (isFunctionTypeOrSubtype(type) && !ReflectionTypes.isNumberedKPropertyOrKMutablePropertyType(type)) {
return namer().isTypeOf(program().getStringLiteral("function"));
}