[NI] Added isSuspend for lambdas.

This commit is contained in:
Stanislav Erokhin
2017-05-18 12:41:04 +03:00
committed by Mikhail Zarechenskiy
parent 29e2a26ad6
commit acc6e48172
5 changed files with 15 additions and 13 deletions
@@ -59,6 +59,7 @@ class KotlinResolutionCallbacksImpl(
override fun analyzeAndGetLambdaResultArguments(
topLevelCall: KotlinCall,
lambdaArgument: LambdaKotlinCallArgument,
isSuspend: Boolean,
receiverType: UnwrappedType?,
parameters: List<UnwrappedType>,
expectedReturnType: UnwrappedType?
@@ -71,7 +72,7 @@ class KotlinResolutionCallbacksImpl(
val builtIns = outerCallContext.scope.ownerDescriptor.builtIns
val expectedType = createFunctionType(builtIns, Annotations.EMPTY, receiverType, parameters, null,
expectedReturnType ?: TypeUtils.NO_EXPECTED_TYPE)
expectedReturnType ?: TypeUtils.NO_EXPECTED_TYPE, isSuspend)
val approximatesExpectedType = typeApproximator.approximateToSubType(expectedType, TypeApproximatorConfiguration.LocalDeclaration) ?: expectedType
@@ -16,10 +16,7 @@
package org.jetbrains.kotlin.resolve.calls.components
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.builtins.getValueParameterTypesFromFunctionType
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
import org.jetbrains.kotlin.builtins.isFunctionType
import org.jetbrains.kotlin.builtins.*
import org.jetbrains.kotlin.descriptors.ClassifierDescriptorWithTypeParameters
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
@@ -92,7 +89,7 @@ internal object CheckArguments : ResolutionPart {
): List<UnwrappedType> {
argument.parametersTypes?.map { it ?: createFreshType() } ?.let { return it }
if (expectedType.isFunctionType) {
if (expectedType.isBuiltinFunctionalType) {
return expectedType.getValueParameterTypesFromFunctionType().map { createFreshType() }
}
@@ -107,7 +104,7 @@ internal object CheckArguments : ResolutionPart {
) : UnwrappedType? {
if (argument is FunctionExpression) return argument.receiverType
if (expectedType.isExtensionFunctionType) return createFreshType()
if (expectedType.isBuiltinExtensionFunctionalType) return createFreshType()
return null
}
@@ -128,7 +125,7 @@ internal object CheckArguments : ResolutionPart {
expectedType: UnwrappedType
): KotlinCallDiagnostic? {
// initial checks
if (expectedType.isFunctionType) {
if (expectedType.isBuiltinFunctionalType) {
val expectedParameterCount = expectedType.getValueParameterTypesFromFunctionType().size
argument.parametersTypes?.size?.let {
@@ -136,8 +133,8 @@ internal object CheckArguments : ResolutionPart {
}
if (argument is FunctionExpression) {
if (argument.receiverType != null && !expectedType.isExtensionFunctionType) return UnexpectedReceiver(argument)
if (argument.receiverType == null && expectedType.isExtensionFunctionType) return MissingReceiver(argument)
if (argument.receiverType != null && !expectedType.isBuiltinExtensionFunctionalType) return UnexpectedReceiver(argument)
if (argument.receiverType == null && expectedType.isBuiltinExtensionFunctionalType) return MissingReceiver(argument)
}
}
@@ -155,7 +152,8 @@ internal object CheckArguments : ResolutionPart {
LambdaTypeVariable(argument, LambdaTypeVariable.Kind.RETURN_TYPE, builtIns).apply { freshVariables.add(this) }.defaultType
}
val resolvedArgument = ResolvedLambdaArgument(kotlinCall, argument, freshVariables, receiver, parameters, returnType)
val isSuspend = expectedType.isSuspendFunctionType
val resolvedArgument = ResolvedLambdaArgument(kotlinCall, argument, freshVariables, isSuspend, receiver, parameters, returnType)
freshVariables.forEach(csBuilder::registerVariable)
csBuilder.addSubtypeConstraint(resolvedArgument.type, expectedType, ArgumentConstraintPosition(argument))
@@ -28,6 +28,7 @@ interface KotlinResolutionCallbacks {
fun analyzeAndGetLambdaResultArguments(
topLevelCall: KotlinCall,
lambdaArgument: LambdaKotlinCallArgument,
isSuspend: Boolean,
receiverType: UnwrappedType?,
parameters: List<UnwrappedType>,
expectedReturnType: UnwrappedType? // null means, that return type is not proper i.e. it depends on some type variables
@@ -67,6 +67,7 @@ class KotlinCallCompleter(
fun transformWhenAmbiguity(candidate: KotlinResolutionCandidate, resolutionCallbacks: KotlinResolutionCallbacks): ResolvedKotlinCall =
toCompletedBaseResolvedCall(candidate.lastCall.constraintSystem.asCallCompleterContext(), candidate, resolutionCallbacks)
// todo investigate variable+function calls
fun completeCallIfNecessary(
candidate: KotlinResolutionCandidate,
expectedType: UnwrappedType?,
@@ -259,7 +260,7 @@ class KotlinCallCompleter(
val parameters = lambda.parameters.map(::substitute)
val expectedType = lambda.returnType.takeIf { c.canBeProper(it) }?.let(::substitute)
lambda.analyzed = true
lambda.resultArguments = resolutionCallbacks.analyzeAndGetLambdaResultArguments(topLevelCall, lambda.argument, receiver, parameters, expectedType)
lambda.resultArguments = resolutionCallbacks.analyzeAndGetLambdaResultArguments(topLevelCall, lambda.argument, lambda.isSuspend, receiver, parameters, expectedType)
for (innerCall in lambda.resultArguments) {
// todo strange code -- why top-level kotlinCall? may be it isn't right outer call
@@ -41,11 +41,12 @@ class ResolvedLambdaArgument(
override val outerCall: KotlinCall,
override val argument: LambdaKotlinCallArgument,
override val myTypeVariables: Collection<LambdaTypeVariable>,
val isSuspend: Boolean,
val receiver: UnwrappedType?,
val parameters: List<UnwrappedType>,
val returnType: UnwrappedType
) : ArgumentWithPostponeResolution() {
val type: SimpleType = createFunctionType(returnType.builtIns, Annotations.EMPTY, receiver, parameters, null, returnType) // todo support annotations
val type: SimpleType = createFunctionType(returnType.builtIns, Annotations.EMPTY, receiver, parameters, null, returnType, isSuspend) // todo support annotations
override val inputType: Collection<UnwrappedType> get() = receiver?.let { parameters + it } ?: parameters
override val outputType: UnwrappedType get() = returnType