Supported obtaining function type parameter names from KotlinType

This commit is contained in:
Valentin Kipyatkov
2016-09-13 12:07:59 +03:00
parent 8d7b59777c
commit 147d1da1ed
12 changed files with 86 additions and 17 deletions
@@ -16,6 +16,8 @@
package org.jetbrains.kotlin.codegen;
import kotlin.collections.CollectionsKt;
import kotlin.jvm.functions.Function1;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.coroutines.CoroutineUtilKt;
import org.jetbrains.kotlin.descriptors.*;
@@ -101,11 +103,18 @@ public class JvmRuntimeTypes {
ReceiverParameterDescriptor receiverParameter = descriptor.getExtensionReceiverParameter();
//noinspection ConstantConditions
List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
KotlinType functionType = FunctionTypeResolveUtilsKt.createFunctionType(
DescriptorUtilsKt.getBuiltIns(descriptor),
Annotations.Companion.getEMPTY(),
receiverParameter == null ? null : receiverParameter.getType(),
ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
ExpressionTypingUtils.getValueParametersTypes(parameters),
CollectionsKt.map(parameters, new Function1<ValueParameterDescriptor, Name>() {
@Override
public Name invoke(ValueParameterDescriptor descriptor) {
return descriptor.getName();
}
}),
descriptor.getReturnType()
);
@@ -128,11 +137,18 @@ public class JvmRuntimeTypes {
extensionReceiver != null ? extensionReceiver.getType() : dispatchReceiver != null ? dispatchReceiver.getType() : null;
//noinspection ConstantConditions
List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
KotlinType functionType = FunctionTypeResolveUtilsKt.createFunctionType(
DescriptorUtilsKt.getBuiltIns(descriptor),
Annotations.Companion.getEMPTY(),
isBound ? null : receiverType,
ExpressionTypingUtils.getValueParametersTypes(descriptor.getValueParameters()),
ExpressionTypingUtils.getValueParametersTypes(parameters),
CollectionsKt.map(parameters, new Function1<ValueParameterDescriptor, Name>() {
@Override
public Name invoke(ValueParameterDescriptor descriptor) {
return descriptor.getName();
}
}),
descriptor.getReturnType()
);
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl;
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
import org.jetbrains.kotlin.load.java.descriptors.*;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.resolve.DescriptorUtils;
import org.jetbrains.kotlin.resolve.calls.util.FunctionTypeResolveUtilsKt;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
@@ -101,11 +102,13 @@ public class SingleAbstractMethodUtils {
assert returnType != null : "function is not initialized: " + function;
List<ValueParameterDescriptor> valueParameters = function.getValueParameters();
List<KotlinType> parameterTypes = new ArrayList<KotlinType>(valueParameters.size());
List<Name> parameterNames = new ArrayList<Name>(valueParameters.size());
for (ValueParameterDescriptor parameter : valueParameters) {
parameterTypes.add(parameter.getType());
parameterNames.add(function.hasSynthesizedParameterNames() ? SpecialNames.NO_NAME_PROVIDED : parameter.getName());
}
return FunctionTypeResolveUtilsKt.createFunctionType(
DescriptorUtilsKt.getBuiltIns(function), Annotations.Companion.getEMPTY(), null, parameterTypes, returnType
DescriptorUtilsKt.getBuiltIns(function), Annotations.Companion.getEMPTY(), null, parameterTypes, parameterNames, returnType
);
}
@@ -213,7 +213,10 @@ class TypeResolver(
else moduleDescriptor.builtIns.unitType
result = type(createFunctionType(
moduleDescriptor.builtIns, annotations, receiverType, parameterDescriptors.map { it.type }, returnType
moduleDescriptor.builtIns, annotations, receiverType,
parameterDescriptors.map { it.type },
parameterDescriptors.map { it.name },
returnType
))
}
@@ -24,6 +24,8 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.builtins.ReflectionTypes;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.BindingTrace;
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace;
@@ -270,7 +272,7 @@ public class ArgumentTypeResolver {
}
return FunctionTypeResolveUtilsKt.createFunctionType(
builtIns, Annotations.Companion.getEMPTY(), null, Collections.<KotlinType>emptyList(), TypeUtils.DONT_CARE
builtIns, Annotations.Companion.getEMPTY(), null, Collections.<KotlinType>emptyList(), Collections.<Name>emptyList(), TypeUtils.DONT_CARE
);
}
@@ -301,15 +303,21 @@ public class ArgumentTypeResolver {
? functionPlaceholders
.createFunctionPlaceholderType(Collections.<KotlinType>emptyList(), /* hasDeclaredArguments = */ false)
: FunctionTypeResolveUtilsKt.createFunctionType(
builtIns, Annotations.Companion.getEMPTY(), null, Collections.<KotlinType>emptyList(), DONT_CARE
builtIns, Annotations.Companion.getEMPTY(), null, Collections.<KotlinType>emptyList(), Collections.<Name>emptyList(), DONT_CARE
);
}
List<KtParameter> valueParameters = function.getValueParameters();
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(
trace, "trace to resolve function literal parameter types");
List<KotlinType> parameterTypes = Lists.newArrayList();
List<Name> parameterNames = Lists.newArrayList();
for (KtParameter parameter : valueParameters) {
parameterTypes.add(resolveTypeRefWithDefault(parameter.getTypeReference(), scope, temporaryTrace, DONT_CARE));
Name name = parameter.getNameAsName();
if (name == null) {
name = SpecialNames.NO_NAME_PROVIDED;
}
parameterNames.add(name);
}
KotlinType returnType = resolveTypeRefWithDefault(function.getTypeReference(), scope, temporaryTrace, DONT_CARE);
assert returnType != null;
@@ -318,7 +326,7 @@ public class ArgumentTypeResolver {
return expectedTypeIsUnknown && isFunctionLiteral
? functionPlaceholders.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true)
: FunctionTypeResolveUtilsKt.createFunctionType(
builtIns, Annotations.Companion.getEMPTY(), receiverType, parameterTypes, returnType
builtIns, Annotations.Companion.getEMPTY(), receiverType, parameterTypes, parameterNames, returnType
);
}
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.name.SpecialNames;
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
@@ -290,11 +291,13 @@ public class CallResolver {
if (calleeExpression instanceof KtLambdaExpression) {
int parameterNumber = ((KtLambdaExpression) calleeExpression).getValueParameters().size();
List<KotlinType> parameterTypes = new ArrayList<KotlinType>(parameterNumber);
List<Name> parameterNames = new ArrayList<Name>(parameterNumber);
for (int i = 0; i < parameterNumber; i++) {
parameterTypes.add(NO_EXPECTED_TYPE);
parameterNames.add(SpecialNames.NO_NAME_PROVIDED);
}
expectedType = FunctionTypeResolveUtilsKt.createFunctionType(
builtIns, Annotations.Companion.getEMPTY(), null, parameterTypes, context.expectedType
builtIns, Annotations.Companion.getEMPTY(), null, parameterTypes, parameterNames, context.expectedType
);
}
KotlinType calleeType = expressionTypingServices.safeGetType(
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.calls.inference
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.EQUAL
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.SUB_TYPE
import org.jetbrains.kotlin.resolve.calls.inference.TypeBounds.Bound
@@ -37,6 +38,8 @@ import org.jetbrains.kotlin.types.checker.TypeCheckingProcedureCallbacks
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.types.typeUtil.defaultProjections
import org.jetbrains.kotlin.types.typeUtil.isDefaultBound
import java.lang.IllegalArgumentException
import java.lang.IllegalStateException
import java.util.*
open class ConstraintSystemBuilderImpl(private val mode: Mode = ConstraintSystemBuilderImpl.Mode.INFERENCE) : ConstraintSystem.Builder {
@@ -446,5 +449,6 @@ internal fun createTypeForFunctionPlaceholder(
functionPlaceholderTypeConstructor.argumentTypes
}
val receiverType = if (isExtension) DONT_CARE else null
return createFunctionType(functionPlaceholder.builtIns, Annotations.EMPTY, receiverType, newArgumentTypes, DONT_CARE)
val parameterNames = newArgumentTypes.map { SpecialNames.NO_NAME_PROVIDED }
return createFunctionType(functionPlaceholder.builtIns, Annotations.EMPTY, receiverType, newArgumentTypes, parameterNames, DONT_CARE)
}
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.impl.*
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.calls.util.createFunctionType
@@ -175,8 +176,9 @@ class DynamicCallableDescriptors(builtIns: KotlinBuiltIns) {
val receiverType = funLiteral.receiverTypeReference?.let { dynamicType }
val parameterTypes = funLiteral.valueParameters.map { dynamicType }
val parameterNames = funLiteral.valueParameters.map { it.nameAsName ?: SpecialNames.NO_NAME_PROVIDED }
return createFunctionType(owner.builtIns, Annotations.EMPTY, receiverType, parameterTypes, dynamicType)
return createFunctionType(owner.builtIns, Annotations.EMPTY, receiverType, parameterTypes, parameterNames, dynamicType)
}
for (arg in call.valueArguments) {
@@ -132,6 +132,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
Annotations.EMPTY,
extensionReceiverParameter?.type,
valueParameters.map { it.type },
valueParameters.map { it.name },
returnType ?: return null
)
}
@@ -28,10 +28,7 @@ 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.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.KotlinTypeFactory
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeProjection
import org.jetbrains.kotlin.types.*
fun createValueParametersForInvokeInFunctionType(
functionDescriptor: FunctionDescriptor, parameterTypes: List<TypeProjection>
@@ -54,8 +51,9 @@ fun createFunctionType(
annotations: Annotations,
receiverType: KotlinType?,
parameterTypes: List<KotlinType>,
parameterNames: List<Name>,
returnType: KotlinType
): SimpleType {
): FunctionType {
val arguments = getFunctionTypeArgumentProjections(receiverType, parameterTypes, returnType)
val size = parameterTypes.size
val classDescriptor = builtIns.getFunction(if (receiverType == null) size else size + 1)
@@ -74,7 +72,7 @@ fun createFunctionType(
AnnotationsImpl(annotations + extensionFunctionAnnotation)
}
return KotlinTypeFactory.simpleNotNullType(typeAnnotations, classDescriptor, arguments)
return KotlinTypeFactory.functionType(typeAnnotations, classDescriptor, arguments, parameterNames)
}
fun getValueParametersCountFromFunctionType(type: KotlinType): Int {
@@ -20,7 +20,9 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import java.lang.IllegalStateException
object KotlinTypeFactory {
private fun computeMemberScope(constructor: TypeConstructor, arguments: List<TypeProjection>): MemberScope {
@@ -49,6 +51,14 @@ object KotlinTypeFactory {
arguments: List<TypeProjection>
): SimpleType = SimpleTypeImpl(annotations, descriptor.typeConstructor, arguments, false, descriptor.getMemberScope(arguments))
@JvmStatic
fun functionType(
annotations: Annotations,
descriptor: ClassDescriptor,
arguments: List<TypeProjection>,
parameterNames: List<Name>
): FunctionType = FunctionType(simpleNotNullType(annotations, descriptor, arguments), parameterNames)
@JvmStatic
fun simpleType(
baseType: SimpleType,
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.types
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager
@@ -42,13 +43,31 @@ class AbbreviatedType(override val delegate: SimpleType, val abbreviation: Simpl
override val isError: Boolean get() = false
}
fun KotlinType.getAbbreviatedType(): AbbreviatedType? = (unwrap() as? AbbreviatedType)
fun KotlinType.getAbbreviatedType(): AbbreviatedType? = unwrap() as? AbbreviatedType
fun SimpleType.withAbbreviation(abbreviatedType: SimpleType): SimpleType {
if (isError) return this
return AbbreviatedType(this, abbreviatedType)
}
class FunctionType(
override val delegate: SimpleType,
/**
* SpecialNames.NO_NAME_PROVIDED if no parameter name specified
*/
val parameterNames: List<Name>
) : DelegatingSimpleType() {
override fun replaceAnnotations(newAnnotations: Annotations)
= FunctionType(delegate.replaceAnnotations(newAnnotations), parameterNames)
override fun makeNullableAsSpecified(newNullability: Boolean)
= FunctionType(delegate.makeNullableAsSpecified(newNullability), parameterNames)
override val isError: Boolean get() = false
}
fun KotlinType.getFunctionTypeParameterNames(): List<Name>? = (unwrap() as? FunctionType)?.parameterNames
class LazyWrappedType(storageManager: StorageManager, computation: () -> KotlinType): WrappedType() {
private val lazyValue = storageManager.createLazyValue(computation)
@@ -53,6 +53,7 @@ import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
import org.jetbrains.kotlin.types.CommonSupertypes
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import java.lang.AssertionError
import java.util.*
internal class ParametersInfo {
@@ -303,6 +304,7 @@ private fun suggestParameterType(
Annotations.EMPTY,
originalDescriptor.extensionReceiverParameter?.type,
originalDescriptor.valueParameters.map { it.type },
originalDescriptor.valueParameters.map { it.name },
originalDescriptor.returnType ?: builtIns.defaultReturnType
)
}