Rename KotlinBuiltIns.getFunctionType -> createFunctionType, move to functionTypes.kt

This commit is contained in:
Alexander Udalov
2016-03-14 13:40:38 +03:00
parent fd344561fc
commit 2ce661af98
13 changed files with 98 additions and 100 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.codegen; package org.jetbrains.kotlin.codegen;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
@@ -76,7 +77,8 @@ public class JvmRuntimeTypes {
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter(); ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
//noinspection ConstantConditions //noinspection ConstantConditions
KotlinType functionType = DescriptorUtilsKt.getBuiltIns(descriptor).getFunctionType( KotlinType functionType = FunctionTypesKt.createFunctionType(
DescriptorUtilsKt.getBuiltIns(descriptor),
Annotations.Companion.getEMPTY(), Annotations.Companion.getEMPTY(),
receiverParameter == null ? null : receiverParameter.getType(), receiverParameter == null ? null : receiverParameter.getType(),
ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()), ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
@@ -95,7 +97,8 @@ public class JvmRuntimeTypes {
extensionReceiver != null ? extensionReceiver.getType() : dispatchReceiver != null ? dispatchReceiver.getType() : null; extensionReceiver != null ? extensionReceiver.getType() : dispatchReceiver != null ? dispatchReceiver.getType() : null;
//noinspection ConstantConditions //noinspection ConstantConditions
KotlinType functionType = DescriptorUtilsKt.getBuiltIns(descriptor).getFunctionType( KotlinType functionType = FunctionTypesKt.createFunctionType(
DescriptorUtilsKt.getBuiltIns(descriptor),
Annotations.Companion.getEMPTY(), Annotations.Companion.getEMPTY(),
receiverType, receiverType,
ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()), ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.java.sam;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
@@ -31,7 +32,7 @@ import org.jetbrains.kotlin.resolve.jvm.JavaResolverUtils;
import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -89,7 +90,9 @@ public class SingleAbstractMethodUtils {
for (ValueParameterDescriptor parameter : valueParameters) { for (ValueParameterDescriptor parameter : valueParameters) {
parameterTypes.add(parameter.getType()); parameterTypes.add(parameter.getType());
} }
return DescriptorUtilsKt.getBuiltIns(function).getFunctionType(Annotations.Companion.getEMPTY(), null, parameterTypes, returnType); return FunctionTypesKt.createFunctionType(
DescriptorUtilsKt.getBuiltIns(function), Annotations.Companion.getEMPTY(), null, parameterTypes, returnType
);
} }
@Nullable @Nullable
@@ -142,7 +145,7 @@ public class SingleAbstractMethodUtils {
null, null,
null, null,
typeParameters.descriptors, typeParameters.descriptors,
Arrays.asList(parameter), Collections.singletonList(parameter),
returnType, returnType,
Modality.FINAL, Modality.FINAL,
samInterface.getVisibility() samInterface.getVisibility()
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import com.intellij.util.SmartList import com.intellij.util.SmartList
import org.jetbrains.kotlin.builtins.createFunctionType
import org.jetbrains.kotlin.context.TypeLazinessToken import org.jetbrains.kotlin.context.TypeLazinessToken
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -206,11 +207,9 @@ class TypeResolver(
val returnType = if (returnTypeRef != null) resolveType(c.noBareTypes(), returnTypeRef) val returnType = if (returnTypeRef != null) resolveType(c.noBareTypes(), returnTypeRef)
else moduleDescriptor.builtIns.unitType else moduleDescriptor.builtIns.unitType
result = type( result = type(createFunctionType(
moduleDescriptor.builtIns.getFunctionType( moduleDescriptor.builtIns, annotations, receiverType, parameterDescriptors.map { it.type }, returnType
annotations, receiverType, parameterDescriptors.map { it.type }, returnType ))
)
)
} }
private fun resolveParametersOfFunctionType(parameters: List<KtParameter>): List<VariableDescriptor> { private fun resolveParametersOfFunctionType(parameters: List<KtParameter>): List<VariableDescriptor> {
@@ -319,5 +319,5 @@ fun getResolvedCallableReferenceShapeType(
expectedTypeUnknown /* && overload resolution was ambiguous */ -> expectedTypeUnknown /* && overload resolution was ambiguous */ ->
functionPlaceholders.createFunctionPlaceholderType(emptyList(), false) functionPlaceholders.createFunctionPlaceholderType(emptyList(), false)
else -> else ->
builtIns.getFunctionType(Annotations.EMPTY, null, emptyList(), TypeUtils.DONT_CARE) createFunctionType(builtIns, Annotations.EMPTY, null, emptyList(), TypeUtils.DONT_CARE)
} }
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.ReflectionTypes; import org.jetbrains.kotlin.builtins.ReflectionTypes;
import org.jetbrains.kotlin.descriptors.CallableDescriptor; import org.jetbrains.kotlin.descriptors.CallableDescriptor;
@@ -245,7 +246,8 @@ public class ArgumentTypeResolver {
callResolver); callResolver);
return CallableReferencesResolutionUtilsKt.getResolvedCallableReferenceShapeType( return CallableReferencesResolutionUtilsKt.getResolvedCallableReferenceShapeType(
callableReferenceExpression, receiverType, overloadResolutionResults, context, expectedTypeIsUnknown, callableReferenceExpression, receiverType, overloadResolutionResults, context, expectedTypeIsUnknown,
reflectionTypes, builtIns, functionPlaceholders); reflectionTypes, builtIns, functionPlaceholders
);
} }
@NotNull @NotNull
@@ -274,7 +276,9 @@ public class ArgumentTypeResolver {
return expectedTypeIsUnknown return expectedTypeIsUnknown
? functionPlaceholders ? functionPlaceholders
.createFunctionPlaceholderType(Collections.<KotlinType>emptyList(), /* hasDeclaredArguments = */ false) .createFunctionPlaceholderType(Collections.<KotlinType>emptyList(), /* hasDeclaredArguments = */ false)
: builtIns.getFunctionType(Annotations.Companion.getEMPTY(), null, Collections.<KotlinType>emptyList(), DONT_CARE); : FunctionTypesKt.createFunctionType(
builtIns, Annotations.Companion.getEMPTY(), null, Collections.<KotlinType>emptyList(), DONT_CARE
);
} }
List<KtParameter> valueParameters = function.getValueParameters(); List<KtParameter> valueParameters = function.getValueParameters();
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create( TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(
@@ -289,7 +293,7 @@ public class ArgumentTypeResolver {
return expectedTypeIsUnknown && isFunctionLiteral return expectedTypeIsUnknown && isFunctionLiteral
? functionPlaceholders.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true) ? functionPlaceholders.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true)
: builtIns.getFunctionType(Annotations.Companion.getEMPTY(), receiverType, parameterTypes, returnType); : FunctionTypesKt.createFunctionType(builtIns, Annotations.Companion.getEMPTY(), receiverType, parameterTypes, returnType);
} }
@Nullable @Nullable
@@ -21,6 +21,7 @@ import kotlin.Pair;
import kotlin.jvm.functions.Function0; import kotlin.jvm.functions.Function0;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.builtins.FunctionTypesKt;
import org.jetbrains.kotlin.builtins.KotlinBuiltIns; import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.annotations.Annotations;
@@ -288,7 +289,9 @@ public class CallResolver {
for (int i = 0; i < parameterNumber; i++) { for (int i = 0; i < parameterNumber; i++) {
parameterTypes.add(NO_EXPECTED_TYPE); parameterTypes.add(NO_EXPECTED_TYPE);
} }
expectedType = builtIns.getFunctionType(Annotations.Companion.getEMPTY(), null, parameterTypes, context.expectedType); expectedType = FunctionTypesKt.createFunctionType(
builtIns, Annotations.Companion.getEMPTY(), null, parameterTypes, context.expectedType
);
} }
KotlinType calleeType = expressionTypingServices.safeGetType( KotlinType calleeType = expressionTypingServices.safeGetType(
context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.trace); context.scope, calleeExpression, expectedType, context.dataFlowInfo, context.trace);
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.resolve.calls.inference package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.builtins.createFunctionType
import org.jetbrains.kotlin.builtins.isExtensionFunctionType import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
@@ -433,5 +434,5 @@ internal fun createTypeForFunctionPlaceholder(
functionPlaceholderTypeConstructor.argumentTypes functionPlaceholderTypeConstructor.argumentTypes
} }
val receiverType = if (isExtension) DONT_CARE else null val receiverType = if (isExtension) DONT_CARE else null
return functionPlaceholder.builtIns.getFunctionType(Annotations.EMPTY, receiverType, newArgumentTypes, DONT_CARE) return createFunctionType(functionPlaceholder.builtIns, Annotations.EMPTY, receiverType, newArgumentTypes, DONT_CARE)
} }
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.calls.tasks package org.jetbrains.kotlin.resolve.calls.tasks
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.createFunctionType
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.* import org.jetbrains.kotlin.descriptors.impl.*
@@ -174,7 +175,7 @@ class DynamicCallableDescriptors(private val builtIns: KotlinBuiltIns) {
val receiverType = funLiteral.receiverTypeReference?.let { dynamicType } val receiverType = funLiteral.receiverTypeReference?.let { dynamicType }
val parameterTypes = funLiteral.valueParameters.map { dynamicType } val parameterTypes = funLiteral.valueParameters.map { dynamicType }
return owner.builtIns.getFunctionType(Annotations.EMPTY, receiverType, parameterTypes, dynamicType) return createFunctionType(owner.builtIns, Annotations.EMPTY, receiverType, parameterTypes, dynamicType)
} }
for (arg in call.valueArguments) { for (arg in call.valueArguments) {
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.types.expressions
import com.google.common.collect.Lists import com.google.common.collect.Lists
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.builtins.createFunctionType
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
import org.jetbrains.kotlin.builtins.isFunctionOrExtensionFunctionType import org.jetbrains.kotlin.builtins.isFunctionOrExtensionFunctionType
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
@@ -119,23 +120,18 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
return createTypeInfo(components.dataFlowAnalyzer.checkStatementType(function, context), context) return createTypeInfo(components.dataFlowAnalyzer.checkStatementType(function, context), context)
} }
else { else {
return components.dataFlowAnalyzer.createCheckedTypeInfo(createFunctionType(functionDescriptor), context, function) return components.dataFlowAnalyzer.createCheckedTypeInfo(functionDescriptor.createFunctionType(), context, function)
} }
} }
private fun createFunctionType(functionDescriptor: SimpleFunctionDescriptor): KotlinType? { private fun SimpleFunctionDescriptor.createFunctionType(): KotlinType? {
val receiverType = functionDescriptor.extensionReceiverParameter?.type return createFunctionType(
components.builtIns,
val returnType = functionDescriptor.returnType Annotations.EMPTY,
if (returnType == null) { extensionReceiverParameter?.type,
return null valueParameters.map { it.type },
} returnType ?: return null
)
val parameters = functionDescriptor.valueParameters.map {
it.type
}
return components.builtIns.getFunctionType(Annotations.EMPTY, receiverType, parameters, returnType)
} }
override fun visitLambdaExpression(expression: KtLambdaExpression, context: ExpressionTypingContext): KotlinTypeInfo? { override fun visitLambdaExpression(expression: KtLambdaExpression, context: ExpressionTypingContext): KotlinTypeInfo? {
@@ -154,7 +150,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
val safeReturnType = computeReturnType(expression, context, functionDescriptor, functionTypeExpected) val safeReturnType = computeReturnType(expression, context, functionDescriptor, functionTypeExpected)
functionDescriptor.setReturnType(safeReturnType) functionDescriptor.setReturnType(safeReturnType)
val resultType = createFunctionType(functionDescriptor)!! val resultType = functionDescriptor.createFunctionType()!!
if (functionTypeExpected) { if (functionTypeExpected) {
// all checks were done before // all checks were done before
return createTypeInfo(resultType, context) return createTypeInfo(resultType, context)
@@ -24,14 +24,12 @@ import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFac
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.*; import org.jetbrains.kotlin.descriptors.annotations.*;
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation; import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.ClassId;
import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.FqName;
import org.jetbrains.kotlin.name.FqNameUnsafe; import org.jetbrains.kotlin.name.FqNameUnsafe;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorUtils; import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.constants.ConstantValue;
import org.jetbrains.kotlin.resolve.scopes.MemberScope; import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.serialization.deserialization.AdditionalSupertypes; import org.jetbrains.kotlin.serialization.deserialization.AdditionalSupertypes;
import org.jetbrains.kotlin.storage.LockBasedStorageManager; import org.jetbrains.kotlin.storage.LockBasedStorageManager;
@@ -41,7 +39,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
import java.io.InputStream; import java.io.InputStream;
import java.util.*; import java.util.*;
import static kotlin.collections.CollectionsKt.*; import static kotlin.collections.CollectionsKt.single;
import static kotlin.collections.SetsKt.setOf; import static kotlin.collections.SetsKt.setOf;
import static org.jetbrains.kotlin.builtins.PrimitiveType.*; import static org.jetbrains.kotlin.builtins.PrimitiveType.*;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName; import static org.jetbrains.kotlin.resolve.DescriptorUtils.getFqName;
@@ -809,63 +807,6 @@ public abstract class KotlinBuiltIns {
return getAnnotation().getDefaultType(); return getAnnotation().getDefaultType();
} }
@NotNull
private AnnotationDescriptor createExtensionFunctionTypeAnnotation() {
return new AnnotationDescriptorImpl(getBuiltInClassByName(FQ_NAMES.extensionFunctionType.shortName()).getDefaultType(),
Collections.<ValueParameterDescriptor, ConstantValue<?>>emptyMap(), SourceElement.NO_SOURCE);
}
@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
private Annotations addExtensionFunctionTypeAnnotation(@NotNull Annotations annotations) {
if (annotations.findAnnotation(FQ_NAMES.extensionFunctionType) != null) return annotations;
// TODO: preserve laziness of given annotations
return new AnnotationsImpl(plus(annotations, listOf(createExtensionFunctionTypeAnnotation())));
}
@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;
}
private static TypeProjection defaultProjection(KotlinType returnType) {
return new TypeProjectionImpl(Variance.INVARIANT, returnType);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// IS TYPE
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static boolean isArray(@NotNull KotlinType type) { public static boolean isArray(@NotNull KotlinType type) {
return isConstructedFromGivenClass(type, FQ_NAMES.array); return isConstructedFromGivenClass(type, FQ_NAMES.array);
} }
@@ -74,7 +74,7 @@ class ReflectionTypes(private val module: ModuleDescriptor) {
parameterTypes: List<KotlinType>, parameterTypes: List<KotlinType>,
returnType: KotlinType returnType: KotlinType
): KotlinType { ): KotlinType {
val arguments = KotlinBuiltIns.getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType) val arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
val classDescriptor = getKFunction(arguments.size - 1 /* return type */) val classDescriptor = getKFunction(arguments.size - 1 /* return type */)
@@ -20,13 +20,14 @@ import org.jetbrains.kotlin.builtins.functions.BuiltInFictitiousFunctionClassFac
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptorImpl
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.FqNameUnsafe
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.TypeProjection
import java.util.* import java.util.*
val KotlinType.isFunctionOrExtensionFunctionType: Boolean val KotlinType.isFunctionOrExtensionFunctionType: Boolean
@@ -108,3 +109,45 @@ fun getParameterTypeProjectionsFromFunctionType(type: KotlinType): List<TypeProj
} }
return parameterTypes return parameterTypes
} }
fun createFunctionType(
builtIns: KotlinBuiltIns,
annotations: Annotations,
receiverType: KotlinType?,
parameterTypes: List<KotlinType>,
returnType: KotlinType
): KotlinType {
val arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
val size = parameterTypes.size
val classDescriptor = builtIns.getFunction(if (receiverType == null) size else size + 1)
val typeAnnotations =
if (receiverType == null || annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.extensionFunctionType) != null) {
annotations
}
else {
val extensionFunctionAnnotation = AnnotationDescriptorImpl(
builtIns.getBuiltInClassByName(KotlinBuiltIns.FQ_NAMES.extensionFunctionType.shortName()).defaultType,
emptyMap(), SourceElement.NO_SOURCE
)
// TODO: preserve laziness of given annotations
AnnotationsImpl(annotations + extensionFunctionAnnotation)
}
return KotlinTypeImpl.create(typeAnnotations, classDescriptor, false, arguments)
}
internal fun getFunctionTypeArgumentProjections(
receiverType: KotlinType?,
parameterTypes: List<KotlinType>,
returnType: KotlinType
): List<TypeProjection> {
fun KotlinType.defaultProjection() = TypeProjectionImpl(Variance.INVARIANT, this)
val arguments = ArrayList<TypeProjection>(parameterTypes.size + (if (receiverType != null) 1 else 0) + 1)
receiverType?.let { arguments.add(it.defaultProjection()) }
parameterTypes.mapTo(arguments, KotlinType::defaultProjection)
arguments.add(returnType.defaultProjection())
return arguments
}
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.util.containers.MultiMap import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.builtins.createFunctionType
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
import org.jetbrains.kotlin.cfg.pseudocode.SingleType import org.jetbrains.kotlin.cfg.pseudocode.SingleType
import org.jetbrains.kotlin.cfg.pseudocode.getElementValuesRecursively import org.jetbrains.kotlin.cfg.pseudocode.getElementValuesRecursively
@@ -297,10 +298,13 @@ private fun suggestParameterType(
return when { return when {
extractFunctionRef -> { extractFunctionRef -> {
originalDescriptor as FunctionDescriptor originalDescriptor as FunctionDescriptor
builtIns.getFunctionType(Annotations.EMPTY, createFunctionType(
originalDescriptor.extensionReceiverParameter?.type, builtIns,
originalDescriptor.valueParameters.map { it.type }, Annotations.EMPTY,
originalDescriptor.returnType ?: builtIns.defaultReturnType) originalDescriptor.extensionReceiverParameter?.type,
originalDescriptor.valueParameters.map { it.type },
originalDescriptor.returnType ?: builtIns.defaultReturnType
)
} }
parameterExpression != null -> parameterExpression != null ->