Refactor KotlinBuiltIns#isFunctionType/isExtensionFunctionType
This commit is contained in:
@@ -22,6 +22,7 @@ import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFactory;
|
||||
import org.jetbrains.kotlin.builtins.functions.FunctionClassDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl;
|
||||
@@ -50,8 +51,6 @@ public class KotlinBuiltIns {
|
||||
public static final Name BUILT_INS_PACKAGE_NAME = Name.identifier("kotlin");
|
||||
public static final FqName BUILT_INS_PACKAGE_FQ_NAME = FqName.topLevel(BUILT_INS_PACKAGE_NAME);
|
||||
|
||||
public static final int FUNCTION_TRAIT_COUNT = 23;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private static volatile KotlinBuiltIns instance = null;
|
||||
@@ -164,13 +163,11 @@ public class KotlinBuiltIns {
|
||||
public final FqNameUnsafe array = fqNameUnsafe("Array");
|
||||
|
||||
public final FqNameUnsafe _boolean = fqNameUnsafe("Boolean");
|
||||
|
||||
public final FqNameUnsafe _char = fqNameUnsafe("Char");
|
||||
public final FqNameUnsafe _byte = fqNameUnsafe("Byte");
|
||||
public final FqNameUnsafe _short = fqNameUnsafe("Short");
|
||||
public final FqNameUnsafe _int = fqNameUnsafe("Int");
|
||||
public final FqNameUnsafe _long = fqNameUnsafe("Long");
|
||||
|
||||
public final FqNameUnsafe _float = fqNameUnsafe("Float");
|
||||
public final FqNameUnsafe _double = fqNameUnsafe("Double");
|
||||
|
||||
@@ -195,8 +192,6 @@ public class KotlinBuiltIns {
|
||||
}
|
||||
}
|
||||
|
||||
public final Set<FqNameUnsafe> functionClasses = computeIndexedFqNames("Function", FUNCTION_TRAIT_COUNT);
|
||||
|
||||
@NotNull
|
||||
private static FqNameUnsafe fqNameUnsafe(@NotNull String simpleName) {
|
||||
return fqName(simpleName).toUnsafe();
|
||||
@@ -206,15 +201,6 @@ public class KotlinBuiltIns {
|
||||
private static FqName fqName(@NotNull String simpleName) {
|
||||
return BUILT_INS_PACKAGE_FQ_NAME.child(Name.identifier(simpleName));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<FqNameUnsafe> computeIndexedFqNames(@NotNull String prefix, int count) {
|
||||
Set<FqNameUnsafe> result = new HashSet<FqNameUnsafe>();
|
||||
for (int i = 0; i < count; i++) {
|
||||
result.add(fqNameUnsafe(prefix + i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -764,31 +750,32 @@ public class KotlinBuiltIns {
|
||||
}
|
||||
|
||||
public static boolean isExactFunctionOrExtensionFunctionType(@NotNull JetType type) {
|
||||
return isExactFunctionType(type) || isExactExtensionFunctionType(type);
|
||||
ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
return descriptor != null && isNumberedFunctionClassFqName(getFqName(descriptor));
|
||||
}
|
||||
|
||||
public static boolean isExactFunctionType(@NotNull JetType type) {
|
||||
return isTypeConstructorFqNameInSet(type, FQ_NAMES.functionClasses) && !isTypeAnnotatedWithExtension(type);
|
||||
return isExactFunctionOrExtensionFunctionType(type) && !isTypeAnnotatedWithExtension(type);
|
||||
}
|
||||
|
||||
public static boolean isExactExtensionFunctionType(@NotNull JetType type) {
|
||||
return isTypeConstructorFqNameInSet(type, FQ_NAMES.functionClasses) && isTypeAnnotatedWithExtension(type);
|
||||
return isExactFunctionOrExtensionFunctionType(type) && isTypeAnnotatedWithExtension(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this is an FQ name of a fictitious class representing the function type, e.g. kotlin.Function1
|
||||
* @return true if this is an FQ name of a fictitious class representing the function type,
|
||||
* e.g. kotlin.Function1 (but NOT kotlin.reflect.KFunction1)
|
||||
*/
|
||||
public static boolean isNumberedFunctionClassFqName(@NotNull FqNameUnsafe fqName) {
|
||||
return FQ_NAMES.functionClasses.contains(fqName);
|
||||
}
|
||||
List<Name> segments = fqName.pathSegments();
|
||||
if (segments.size() != 2) return false;
|
||||
|
||||
private static boolean isTypeConstructorFqNameInSet(@NotNull JetType type, @NotNull Set<FqNameUnsafe> classes) {
|
||||
ClassifierDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||
if (!BUILT_INS_PACKAGE_NAME.equals(first(segments))) return false;
|
||||
|
||||
if (declarationDescriptor == null) return false;
|
||||
|
||||
FqNameUnsafe fqName = getFqName(declarationDescriptor);
|
||||
return classes.contains(fqName);
|
||||
return BuiltInFictitiousFunctionClassFactory.parseClassName(
|
||||
last(segments).asString(),
|
||||
FunctionClassDescriptor.Kinds.Functions
|
||||
) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+16
-11
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import kotlin.platform.platformStatic
|
||||
|
||||
/**
|
||||
* Produces descriptors representing the fictitious classes for function types, such as kotlin.Function1 or kotlin.reflect.KMemberFunction0.
|
||||
@@ -36,21 +37,25 @@ public class BuiltInFictitiousFunctionClassFactory(
|
||||
|
||||
private data class KindWithArity(val kind: Kind, val arity: Int)
|
||||
|
||||
private fun parseClassName(className: String, allowedKinds: Set<Kind>): KindWithArity? {
|
||||
for (kind in allowedKinds) {
|
||||
val prefix = kind.classNamePrefix
|
||||
if (!className.startsWith(prefix)) continue
|
||||
companion object {
|
||||
platformStatic public fun parseClassName(className: String, allowedKinds: Set<Kind>): KindWithArity? {
|
||||
for (kind in allowedKinds) {
|
||||
val prefix = kind.classNamePrefix
|
||||
if (!className.startsWith(prefix)) continue
|
||||
|
||||
val arity = try {
|
||||
className.substring(prefix.length()).toInt()
|
||||
val arity = try {
|
||||
className.substring(prefix.length()).toInt()
|
||||
}
|
||||
catch (e: NumberFormatException) {
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO: validate arity, should be <= 255 for functions, <= 254 for members/extensions
|
||||
return KindWithArity(kind, arity)
|
||||
}
|
||||
catch (e: NumberFormatException) { continue }
|
||||
|
||||
// TODO: validate arity, should be <= 255 for functions, <= 254 for members/extensions
|
||||
return KindWithArity(kind, arity)
|
||||
return null
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
override fun createClass(classId: ClassId): ClassDescriptor? {
|
||||
|
||||
Reference in New Issue
Block a user