[PSI, FE] Support functional types
This commit is contained in:
committed by
TeamCityServer
parent
e53cee77a3
commit
e3f987459c
@@ -346,7 +346,12 @@ class TypeResolver(
|
||||
|
||||
override fun visitFunctionType(type: KtFunctionType) {
|
||||
val receiverTypeRef = type.receiverTypeReference
|
||||
val receiverType = if (receiverTypeRef == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
|
||||
val receiverType = if (receiverTypeRef?.typeElement == null) null else resolveType(c.noBareTypes(), receiverTypeRef)
|
||||
|
||||
val contextReceiversTypeRefs = type.contextReceiversTypeReferences
|
||||
val contextReceiversTypes = contextReceiversTypeRefs?.mapNotNull {
|
||||
resolveType(c.noBareTypes(), it)
|
||||
} ?: emptyList()
|
||||
|
||||
val parameterDescriptors = resolveParametersOfFunctionType(type.parameters)
|
||||
checkParametersOfFunctionType(parameterDescriptors)
|
||||
@@ -362,7 +367,7 @@ class TypeResolver(
|
||||
|
||||
result = type(
|
||||
createFunctionType(
|
||||
moduleDescriptor.builtIns, annotations, receiverType,
|
||||
moduleDescriptor.builtIns, annotations, receiverType, contextReceiversTypes,
|
||||
parameterDescriptors.map { it.type },
|
||||
parameterDescriptors.map { it.name },
|
||||
returnType,
|
||||
|
||||
@@ -44,6 +44,7 @@ import javax.inject.Inject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.jetbrains.kotlin.psi.KtPsiUtil.getLastElementDeparenthesized;
|
||||
import static org.jetbrains.kotlin.resolve.BindingContextUtils.getRecordedTypeInfo;
|
||||
@@ -334,7 +335,7 @@ public class ArgumentTypeResolver {
|
||||
}
|
||||
|
||||
return FunctionTypesKt.createFunctionType(
|
||||
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), null, TypeUtils.DONT_CARE
|
||||
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), Collections.emptyList(), null, TypeUtils.DONT_CARE
|
||||
);
|
||||
}
|
||||
|
||||
@@ -372,7 +373,7 @@ public class ArgumentTypeResolver {
|
||||
return expectedTypeIsUnknown
|
||||
? functionPlaceholders.createFunctionPlaceholderType(Collections.emptyList(), /* hasDeclaredArguments = */ false)
|
||||
: FunctionTypesKt.createFunctionType(
|
||||
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), null, DONT_CARE
|
||||
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), Collections.emptyList(), null, DONT_CARE
|
||||
);
|
||||
}
|
||||
List<KtParameter> valueParameters = function.getValueParameters();
|
||||
@@ -391,11 +392,14 @@ public class ArgumentTypeResolver {
|
||||
KotlinType returnType = resolveTypeRefWithDefault(function.getTypeReference(), scope, temporaryTrace, DONT_CARE);
|
||||
assert returnType != null;
|
||||
KotlinType receiverType = resolveTypeRefWithDefault(function.getReceiverTypeReference(), scope, temporaryTrace, null);
|
||||
List<KotlinType> contextReceiversTypes = function.getContextReceivers().stream().map(contextReceiver ->
|
||||
resolveTypeRefWithDefault(contextReceiver.typeReference(), scope, temporaryTrace, null)
|
||||
).collect(Collectors.toList());
|
||||
|
||||
return expectedTypeIsUnknown && isFunctionLiteral
|
||||
? functionPlaceholders.createFunctionPlaceholderType(parameterTypes, /* hasDeclaredArguments = */ true)
|
||||
: FunctionTypesKt.createFunctionType(
|
||||
builtIns, Annotations.Companion.getEMPTY(), receiverType, parameterTypes, parameterNames, returnType, suspendFunctionTypeExpected
|
||||
builtIns, Annotations.Companion.getEMPTY(), receiverType, contextReceiversTypes, parameterTypes, parameterNames, returnType, suspendFunctionTypeExpected
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -357,7 +357,7 @@ public class CallResolver {
|
||||
parameterTypes.add(NO_EXPECTED_TYPE);
|
||||
}
|
||||
expectedType = FunctionTypesKt.createFunctionType(
|
||||
builtIns, Annotations.Companion.getEMPTY(), null, parameterTypes, null, context.expectedType
|
||||
builtIns, Annotations.Companion.getEMPTY(), null, Collections.emptyList(), parameterTypes, null, context.expectedType
|
||||
);
|
||||
}
|
||||
KotlinType calleeType = expressionTypingServices.safeGetType(
|
||||
|
||||
+1
-1
@@ -177,7 +177,7 @@ class BuilderInferenceSupport(
|
||||
approximationSubstitutor.buildSubstitutor().substitute(lambdaExpectedType, Variance.IN_VARIANCE) ?: return
|
||||
|
||||
val newExpectedType = createFunctionType(
|
||||
newReceiverType.builtIns, approximatedLambdaType.annotations, newReceiverType,
|
||||
newReceiverType.builtIns, approximatedLambdaType.annotations, newReceiverType, emptyList(), // TODO: Context receivers?
|
||||
approximatedLambdaType.getValueParameterTypesFromFunctionType().map(TypeProjection::getType),
|
||||
parameterNames = null, // TODO: parameterNames
|
||||
returnType = approximatedLambdaType.getReturnTypeFromFunctionType(),
|
||||
|
||||
+3
-4
@@ -16,9 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.calls.inference
|
||||
|
||||
import org.jetbrains.kotlin.builtins.createFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinExtensionFunctionalType
|
||||
import org.jetbrains.kotlin.builtins.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.builtins.*
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilderImpl.ConstraintKind.EQUAL
|
||||
@@ -471,8 +469,9 @@ internal fun createTypeForFunctionPlaceholder(
|
||||
functionPlaceholderTypeConstructor.argumentTypes
|
||||
}
|
||||
val receiverType = if (isExtension) DONT_CARE else null
|
||||
val contextReceiverTypes = (0 until expectedType.contextFunctionTypeParamsCount()).map { DONT_CARE }
|
||||
return createFunctionType(
|
||||
functionPlaceholder.builtIns, Annotations.EMPTY, receiverType, newArgumentTypes, null, DONT_CARE,
|
||||
functionPlaceholder.builtIns, Annotations.EMPTY, receiverType, contextReceiverTypes, newArgumentTypes, null, DONT_CARE,
|
||||
suspendFunction = expectedType.isSuspendFunctionType
|
||||
)
|
||||
}
|
||||
|
||||
@@ -186,9 +186,11 @@ class DynamicCallableDescriptors(private val storageManager: StorageManager, bui
|
||||
val funLiteral = funLiteralExpr.functionLiteral
|
||||
|
||||
val receiverType = funLiteral.receiverTypeReference?.let { dynamicType }
|
||||
val contextReceiversTypes = funLiteral.contextReceivers.map { dynamicType }
|
||||
|
||||
val parameterTypes = funLiteral.valueParameters.map { dynamicType }
|
||||
|
||||
return createFunctionType(owner.builtIns, Annotations.EMPTY, receiverType, parameterTypes, null, dynamicType)
|
||||
return createFunctionType(owner.builtIns, Annotations.EMPTY, receiverType, contextReceiversTypes, parameterTypes, null, dynamicType)
|
||||
}
|
||||
|
||||
for (arg in call.valueArguments) {
|
||||
|
||||
+2
-1
@@ -171,8 +171,9 @@ class KotlinResolutionCallbacksImpl(
|
||||
@OptIn(TypeRefinement::class) callComponents.kotlinTypeChecker.kotlinTypeRefiner.refineType(it)
|
||||
}
|
||||
|
||||
// TODO: Context receivers?
|
||||
val expectedType = createFunctionType(
|
||||
builtIns, annotations, refinedReceiverType, parameters, null,
|
||||
builtIns, annotations, refinedReceiverType, emptyList(), parameters, null,
|
||||
lambdaInfo.expectedType, isSuspend
|
||||
)
|
||||
|
||||
|
||||
+1
@@ -334,6 +334,7 @@ class ResolvedAtomCompleter(
|
||||
builtIns,
|
||||
existingLambdaType.annotations,
|
||||
substitutedLambdaTypes.receiverType?.substitutedType,
|
||||
emptyList(),
|
||||
substitutedLambdaTypes.parameterTypes.map { it.substitutedType },
|
||||
null, // parameter names transforms to special annotations, so they are already taken from parameter types
|
||||
substitutedLambdaTypes.returnType.substitutedType,
|
||||
|
||||
+5
-1
@@ -830,6 +830,9 @@ class DoubleColonExpressionResolver(
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun contextReceiverTypesFor(descriptor: CallableDescriptor): List<KotlinType> =
|
||||
descriptor.contextReceiverParameters.map { it.type }
|
||||
|
||||
private fun receiverTypeFor(descriptor: CallableDescriptor, lhs: DoubleColonLHS?): KotlinType? =
|
||||
(descriptor.extensionReceiverParameter ?: descriptor.dispatchReceiverParameter)?.let { (lhs as? DoubleColonLHS.Type)?.type }
|
||||
|
||||
@@ -849,6 +852,7 @@ class DoubleColonExpressionResolver(
|
||||
reflectionTypes: ReflectionTypes,
|
||||
scopeOwnerDescriptor: DeclarationDescriptor
|
||||
): KotlinType? {
|
||||
val contextReceiverTypes = contextReceiverTypesFor(descriptor)
|
||||
val receiverType = receiverTypeFor(descriptor, lhs)
|
||||
return when (descriptor) {
|
||||
is FunctionDescriptor -> {
|
||||
@@ -857,7 +861,7 @@ class DoubleColonExpressionResolver(
|
||||
val parametersNames = descriptor.valueParameters.map { it.name }
|
||||
return reflectionTypes.getKFunctionType(
|
||||
Annotations.EMPTY, receiverType,
|
||||
parametersTypes, parametersNames, returnType, descriptor.builtIns, descriptor.isSuspend
|
||||
contextReceiverTypes, parametersTypes, parametersNames, returnType, descriptor.builtIns, descriptor.isSuspend
|
||||
)
|
||||
}
|
||||
is PropertyDescriptor -> {
|
||||
|
||||
@@ -397,6 +397,7 @@ fun SimpleFunctionDescriptor.createFunctionType(
|
||||
builtIns,
|
||||
Annotations.EMPTY,
|
||||
extensionReceiverParameter?.type,
|
||||
contextReceiverParameters.map { it.type },
|
||||
if (shouldUseVarargType) valueParameters.map { it.varargElementType ?: it.type } else valueParameters.map { it.type },
|
||||
null,
|
||||
returnType ?: return null,
|
||||
|
||||
Reference in New Issue
Block a user