/** * @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) { List<Name> segments = fqName.pathSegments(); if (segments.size() != 2) return false; if (!BUILT_INS_PACKAGE_NAME.equals(first(segments))) return false; String shortName = last(segments).asString(); return BuiltInFictitiousFunctionClassFactory.parseClassName( shortName, BUILT_INS_PACKAGE_FQ_NAME) != null; }
@NotNull public static List<TypeProjection> getParameterTypeProjectionsFromFunctionType( @NotNull KotlinType type) { assert isFunctionOrExtensionFunctionType(type); List<TypeProjection> arguments = type.getArguments(); int first = isExtensionFunctionType(type) ? 1 : 0; int last = arguments.size() - 2; // TODO: fix bugs associated with this here and in neighboring methods, see KT-9820 assert first <= last + 1 : "Not an exact function type: " + type; List<TypeProjection> parameterTypes = new ArrayList<TypeProjection>(last - first + 1); for (int i = first; i <= last; i++) { parameterTypes.add(arguments.get(i)); } return parameterTypes; }
@NotNull public static List<TypeProjection> getFunctionTypeArgumentProjections( @Nullable KotlinType receiverType, @NotNull List<KotlinType> parameterTypes, @NotNull KotlinType returnType) { List<TypeProjection> arguments = new ArrayList<TypeProjection>(parameterTypes.size() + (receiverType != null ? 1 : 0) + 1); if (receiverType != null) { arguments.add(defaultProjection(receiverType)); } for (KotlinType parameterType : parameterTypes) { arguments.add(defaultProjection(parameterType)); } arguments.add(defaultProjection(returnType)); return arguments; }
@NotNull public static List<ValueParameterDescriptor> getValueParameters( @NotNull FunctionDescriptor functionDescriptor, @NotNull KotlinType type) { assert isFunctionOrExtensionFunctionType(type); List<TypeProjection> parameterTypes = getParameterTypeProjectionsFromFunctionType(type); List<ValueParameterDescriptor> valueParameters = new ArrayList<ValueParameterDescriptor>(parameterTypes.size()); for (int i = 0; i < parameterTypes.size(); i++) { TypeProjection parameterType = parameterTypes.get(i); ValueParameterDescriptorImpl valueParameterDescriptor = new ValueParameterDescriptorImpl( functionDescriptor, null, i, Annotations.Companion.getEMPTY(), Name.identifier("p" + (i + 1)), parameterType.getType(), /* declaresDefaultValue = */ false, /* isCrossinline = */ false, /* isNoinline = */ false, null, SourceElement.NO_SOURCE); valueParameters.add(valueParameterDescriptor); } return valueParameters; }
@NotNull public KotlinType getFunctionType( @NotNull Annotations annotations, @Nullable KotlinType receiverType, @NotNull List<KotlinType> parameterTypes, @NotNull KotlinType returnType) { List<TypeProjection> arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType); int size = parameterTypes.size(); ClassDescriptor classDescriptor = receiverType == null ? getFunction(size) : getExtensionFunction(size); Annotations typeAnnotations = receiverType == null ? annotations : addExtensionFunctionTypeAnnotation(annotations); return KotlinTypeImpl.create(typeAnnotations, classDescriptor, false, arguments); }
@NotNull public static KotlinType getReturnTypeFromFunctionType(@NotNull KotlinType type) { assert isFunctionOrExtensionFunctionType(type); List<TypeProjection> arguments = type.getArguments(); return arguments.get(arguments.size() - 1).getType(); }