Support another one coroutine convention in front-end
- There will be no `coroutine` keyword for builders - They accept a special suspend function type instead (it's return type is straightforward, not Continuation<Unit>) - Instances of these types may be run with special built-in functions - These built-ins functions are parametrized with handleResult/handleException/interceptResume, so these operators become unnecessary (and controllers too) NB: `@Suspend` annotation is subject to replace with the `suspend` modifier on types
This commit is contained in:
committed by
Stanislav Erokhin
parent
66c2333eb5
commit
1ab003c029
@@ -16,90 +16,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.coroutines
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import org.jetbrains.kotlin.types.expressions.FakeCallKind
|
||||
import org.jetbrains.kotlin.types.expressions.FakeCallResolver
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.descriptors.isSuspendFunctionType
|
||||
|
||||
/**
|
||||
* @returns type of first value parameter if function is 'operator handleResult' in coroutines controller
|
||||
*/
|
||||
fun SimpleFunctionDescriptor.getExpectedTypeForCoroutineControllerHandleResult(): KotlinType? {
|
||||
if (!isOperator || name != OperatorNameConventions.COROUTINE_HANDLE_RESULT) return null
|
||||
val CallableDescriptor.isSuspendLambda get() = this is AnonymousFunctionDescriptor && this.isCoroutine
|
||||
|
||||
return valueParameters.getOrNull(0)?.type
|
||||
}
|
||||
|
||||
val CallableDescriptor.controllerTypeIfCoroutine: KotlinType?
|
||||
get() {
|
||||
if (this !is AnonymousFunctionDescriptor || !this.isCoroutine) return null
|
||||
|
||||
return this.extensionReceiverParameter?.returnType
|
||||
}
|
||||
|
||||
fun FakeCallResolver.resolveCoroutineHandleResultCallIfNeeded(
|
||||
callElement: KtExpression,
|
||||
expressionToReturn: KtExpression?,
|
||||
functionDescriptor: FunctionDescriptor,
|
||||
context: ResolutionContext<*>
|
||||
) {
|
||||
functionDescriptor.controllerTypeIfCoroutine ?: return
|
||||
|
||||
val info = if (expressionToReturn != null)
|
||||
context.trace.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expressionToReturn)
|
||||
else
|
||||
null
|
||||
|
||||
val temporaryBindingTrace = TemporaryBindingTrace.create(context.trace, "trace to store fake argument for", "continuation")
|
||||
|
||||
val continuation =
|
||||
ExpressionTypingUtils.createFakeExpressionOfType(
|
||||
callElement.project, temporaryBindingTrace, "continuation",
|
||||
// should be Continuation<Nothing>
|
||||
functionDescriptor.builtIns.nothingType)
|
||||
|
||||
fun tryToResolveCall(firstArgument: KtExpression): Boolean {
|
||||
val resolutionResults = resolveFakeCall(
|
||||
context.replaceBindingTrace(temporaryBindingTrace), functionDescriptor.extensionReceiverParameter!!.value,
|
||||
OperatorNameConventions.COROUTINE_HANDLE_RESULT, callElement, callElement, FakeCallKind.OTHER,
|
||||
listOf(firstArgument, continuation))
|
||||
|
||||
if (resolutionResults.isSuccess && resolutionResults.resultingDescriptor.isOperator) {
|
||||
context.trace.record(BindingContext.RETURN_HANDLE_RESULT_RESOLVED_CALL, callElement, resolutionResults.resultingCall)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
val unitExpression = ExpressionTypingUtils.createFakeExpressionOfType(
|
||||
callElement.project, temporaryBindingTrace, "unit", functionDescriptor.builtIns.unitType)
|
||||
val firstArgument =
|
||||
if (expressionToReturn == null || info != null && info.type != null && KotlinBuiltIns.isUnit(info.type))
|
||||
unitExpression
|
||||
else
|
||||
expressionToReturn
|
||||
|
||||
if (!tryToResolveCall(firstArgument) && firstArgument === expressionToReturn) {
|
||||
tryToResolveCall(unitExpression)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
fun KotlinType.isValidContinuation() =
|
||||
(constructor.declarationDescriptor as? ClassDescriptor)?.fqNameUnsafe == DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME.toUnsafe()
|
||||
val ValueParameterDescriptor.hasSuspendFunctionType get() = returnType?.isSuspendFunctionType == true
|
||||
|
||||
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValue;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.ExplicitSmartCasts;
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.ImplicitSmartCasts;
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
|
||||
import org.jetbrains.kotlin.resolve.coroutine.CoroutineReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics;
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.Qualifier;
|
||||
@@ -136,7 +135,7 @@ public interface BindingContext {
|
||||
WritableSlice<KtExpression, ResolvedCall<FunctionDescriptor>> LOOP_RANGE_NEXT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
WritableSlice<KtExpression, ResolvedCall<FunctionDescriptor>> RETURN_HANDLE_RESULT_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<Call, CoroutineReceiverValue> COROUTINE_RECEIVER_FOR_SUSPENSION_POINT = Slices.createSimpleSlice();
|
||||
WritableSlice<Call, CallableDescriptor> ENCLOSING_SUSPEND_LAMBDA_FOR_SUSPENSION_POINT = Slices.createSimpleSlice();
|
||||
WritableSlice<Call, SimpleFunctionDescriptor> ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<VariableAccessorDescriptor, ResolvedCall<FunctionDescriptor>> DELEGATED_PROPERTY_RESOLVED_CALL = Slices.createSimpleSlice();
|
||||
|
||||
@@ -20,12 +20,8 @@ import kotlin.Unit;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl;
|
||||
import org.jetbrains.kotlin.resolve.coroutine.CoroutineReceiverValue;
|
||||
import org.jetbrains.kotlin.resolve.scopes.*;
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
||||
import org.jetbrains.kotlin.types.*;
|
||||
import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
||||
|
||||
@@ -72,16 +68,6 @@ public class FunctionDescriptorUtil {
|
||||
) {
|
||||
ReceiverParameterDescriptor receiver = descriptor.getExtensionReceiverParameter();
|
||||
|
||||
if (descriptor instanceof AnonymousFunctionDescriptor
|
||||
&& (((AnonymousFunctionDescriptor) descriptor).isCoroutine())
|
||||
&& receiver != null && receiver.getValue() instanceof ExtensionReceiver) {
|
||||
receiver =
|
||||
new ReceiverParameterDescriptorImpl(
|
||||
descriptor,
|
||||
new CoroutineReceiverValue(
|
||||
((ExtensionReceiver) receiver.getValue()).getDeclarationDescriptor(), receiver.getValue().getType()));
|
||||
}
|
||||
|
||||
return new LexicalScopeImpl(outerScope, descriptor, true, receiver, LexicalScopeKind.FUNCTION_INNER_SCOPE, redeclarationChecker,
|
||||
new Function1<LexicalScopeImpl.InitializeHandler, Unit>() {
|
||||
@Override
|
||||
|
||||
@@ -44,8 +44,6 @@ object OperatorModifierChecker {
|
||||
val checkResult = OperatorChecks.check(functionDescriptor)
|
||||
if (checkResult.isSuccess) {
|
||||
when (functionDescriptor.name) {
|
||||
in COROUTINE_OPERATOR_NAMES ->
|
||||
checkSupportsFeature(LanguageFeature.Coroutines, languageVersionSettings, diagnosticHolder, modifier)
|
||||
in REM_TO_MOD_OPERATION_NAMES.keys ->
|
||||
checkSupportsFeature(LanguageFeature.OperatorRem, languageVersionSettings, diagnosticHolder, modifier)
|
||||
OperatorNameConventions.PROVIDE_DELEGATE ->
|
||||
@@ -72,9 +70,3 @@ object OperatorModifierChecker {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val COROUTINE_OPERATOR_NAMES =
|
||||
setOf(OperatorNameConventions.COROUTINE_HANDLE_RESULT,
|
||||
OperatorNameConventions.COROUTINE_HANDLE_EXCEPTION,
|
||||
OperatorNameConventions.COROUTINE_INTERCEPT_RESUME
|
||||
)
|
||||
|
||||
@@ -20,8 +20,6 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.coroutines.controllerTypeIfCoroutine
|
||||
import org.jetbrains.kotlin.coroutines.resolveCoroutineHandleResultCallIfNeeded
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
@@ -100,8 +98,6 @@ class CallCompleter(
|
||||
callChecker.check(resolvedCall, reportOn, callCheckerContext)
|
||||
}
|
||||
}
|
||||
|
||||
resolveHandleResultCallForCoroutineLambdaExpressions(context, resolvedCall)
|
||||
}
|
||||
|
||||
if (results.isSingleResult && results.resultingCall.status.isSuccess) {
|
||||
@@ -110,27 +106,6 @@ class CallCompleter(
|
||||
return results
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> resolveHandleResultCallForCoroutineLambdaExpressions(
|
||||
context: BasicCallResolutionContext,
|
||||
resolvedCall: ResolvedCall<D>
|
||||
) {
|
||||
resolvedCall.valueArguments.values
|
||||
.flatMap { it.arguments.map { it.getArgumentExpression() } }
|
||||
.filterIsInstance<KtLambdaExpression>()
|
||||
.forEach {
|
||||
val function = context.trace.bindingContext[BindingContext.FUNCTION, it.functionLiteral] ?: return@forEach
|
||||
|
||||
function.controllerTypeIfCoroutine ?: return@forEach
|
||||
|
||||
val lastBlockStatement = it.functionLiteral.bodyExpression?.statements?.lastOrNull()
|
||||
|
||||
// Already resolved
|
||||
if (lastBlockStatement is KtReturnExpression) return@forEach
|
||||
|
||||
fakeCallResolver.resolveCoroutineHandleResultCallIfNeeded(it.functionLiteral, lastBlockStatement, function, context)
|
||||
}
|
||||
}
|
||||
|
||||
private fun <D : CallableDescriptor> completeAllCandidates(
|
||||
context: BasicCallResolutionContext,
|
||||
results: OverloadResolutionResultsImpl<D>
|
||||
|
||||
@@ -19,12 +19,8 @@ package org.jetbrains.kotlin.resolve.calls.callResolverUtil
|
||||
import com.google.common.collect.Lists
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
|
||||
import org.jetbrains.kotlin.coroutines.getExpectedTypeForCoroutineControllerHandleResult
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||
import org.jetbrains.kotlin.lexer.KtToken
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -37,7 +33,6 @@ import org.jetbrains.kotlin.resolve.calls.inference.getNestedTypeVariables
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.ResolutionCandidate
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue
|
||||
@@ -46,9 +41,7 @@ import org.jetbrains.kotlin.types.*
|
||||
import org.jetbrains.kotlin.types.TypeUtils.DONT_CARE
|
||||
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
import org.jetbrains.kotlin.types.typeUtil.contains
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
enum class ResolveArgumentsMode {
|
||||
RESOLVE_FUNCTION_ARGUMENTS,
|
||||
@@ -181,30 +174,6 @@ fun getEffectiveExpectedType(parameterDescriptor: ValueParameterDescriptor, argu
|
||||
return varargElementType
|
||||
}
|
||||
|
||||
if (parameterDescriptor.isCoroutine &&
|
||||
argument.getArgumentExpression() is KtLambdaExpression &&
|
||||
parameterDescriptor.type.isExtensionFunctionType
|
||||
) {
|
||||
val receiverType = parameterDescriptor.type.getReceiverTypeFromFunctionType()!!
|
||||
|
||||
val newExpectedLambdaReturnType =
|
||||
receiverType.memberScope
|
||||
.getContributedFunctions(
|
||||
OperatorNameConventions.COROUTINE_HANDLE_RESULT, KotlinLookupLocation(argument.asElement())
|
||||
).mapNotNull {
|
||||
it.getExpectedTypeForCoroutineControllerHandleResult()
|
||||
}.singleOrNull()
|
||||
// If no handleResult function found, then expected return type for lambda is Unit
|
||||
?: parameterDescriptor.module.builtIns.unitType
|
||||
|
||||
// replace return type for lambda with the one we got from single 'handleResult'
|
||||
val newFunctionTypeArguments = parameterDescriptor.type.arguments.toMutableList()
|
||||
newFunctionTypeArguments[newFunctionTypeArguments.lastIndex] = newExpectedLambdaReturnType.asTypeProjection()
|
||||
|
||||
return parameterDescriptor.type.replace(
|
||||
newArguments = newFunctionTypeArguments)
|
||||
}
|
||||
|
||||
return parameterDescriptor.type
|
||||
}
|
||||
|
||||
|
||||
+23
-13
@@ -18,32 +18,40 @@ package org.jetbrains.kotlin.resolve.calls.checkers
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.coroutines.hasSuspendFunctionType
|
||||
import org.jetbrains.kotlin.coroutines.isSuspendLambda
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.coroutine.CoroutineReceiverValue
|
||||
import org.jetbrains.kotlin.resolve.inline.InlineUtil
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
object CoroutineSuspendCallChecker : CallChecker {
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
val descriptor = resolvedCall.candidateDescriptor as? SimpleFunctionDescriptor ?: return
|
||||
if (!descriptor.isSuspend) return
|
||||
|
||||
val closestCoroutineReceiver =
|
||||
context.scope.getImplicitReceiversHierarchy().firstOrNull { it.value is CoroutineReceiverValue }?.value as CoroutineReceiverValue?
|
||||
val (closestSuspendLambdaScope, closestSuspensionLambdaDescriptor) =
|
||||
context.scope
|
||||
.parentsWithSelf.firstOrNull {
|
||||
it is LexicalScope && it.kind == LexicalScopeKind.FUNCTION_INNER_SCOPE &&
|
||||
it.ownerDescriptor.safeAs<CallableDescriptor>()?.isSuspendLambda == true
|
||||
}?.let { it to it.cast<LexicalScope>().ownerDescriptor.cast<CallableDescriptor>() }
|
||||
?: null to null
|
||||
|
||||
val enclosingSuspendFunction =
|
||||
context.scope.parentsWithSelf.filterIsInstance<LexicalScope>().takeWhile {
|
||||
closestCoroutineReceiver == null || it.implicitReceiver?.value != closestCoroutineReceiver
|
||||
}.firstOrNull {
|
||||
(it.ownerDescriptor as? FunctionDescriptor)?.isSuspend == true
|
||||
}?.ownerDescriptor as? SimpleFunctionDescriptor
|
||||
context.scope.parentsWithSelf.filterIsInstance<LexicalScope>().takeWhile { it != closestSuspendLambdaScope }
|
||||
.firstOrNull {
|
||||
(it.ownerDescriptor as? FunctionDescriptor)?.isSuspend == true
|
||||
}?.ownerDescriptor as? SimpleFunctionDescriptor
|
||||
|
||||
when {
|
||||
enclosingSuspendFunction != null -> {
|
||||
@@ -51,14 +59,16 @@ object CoroutineSuspendCallChecker : CallChecker {
|
||||
// Here we only record enclosing function mapping (for backends purposes)
|
||||
context.trace.record(BindingContext.ENCLOSING_SUSPEND_FUNCTION_FOR_SUSPEND_FUNCTION_CALL, resolvedCall.call, enclosingSuspendFunction)
|
||||
}
|
||||
closestCoroutineReceiver != null -> {
|
||||
closestSuspensionLambdaDescriptor != null -> {
|
||||
val callElement = resolvedCall.call.callElement as KtExpression
|
||||
|
||||
if (!InlineUtil.checkNonLocalReturnUsage(closestCoroutineReceiver.declarationDescriptor, callElement, context.resolutionContext)) {
|
||||
if (!InlineUtil.checkNonLocalReturnUsage(closestSuspensionLambdaDescriptor, callElement, context.resolutionContext)) {
|
||||
context.trace.report(Errors.NON_LOCAL_SUSPENSION_POINT.on(reportOn))
|
||||
}
|
||||
|
||||
context.trace.record(BindingContext.COROUTINE_RECEIVER_FOR_SUSPENSION_POINT, resolvedCall.call, closestCoroutineReceiver)
|
||||
context.trace.record(
|
||||
BindingContext.ENCLOSING_SUSPEND_LAMBDA_FOR_SUSPENSION_POINT, resolvedCall.call, closestSuspensionLambdaDescriptor
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
context.trace.report(Errors.ILLEGAL_SUSPEND_FUNCTION_CALL.on(reportOn))
|
||||
@@ -70,7 +80,7 @@ object CoroutineSuspendCallChecker : CallChecker {
|
||||
object BuilderFunctionsCallChecker : CallChecker {
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
val descriptor = resolvedCall.candidateDescriptor as? FunctionDescriptor ?: return
|
||||
if (descriptor.valueParameters.any { it.isCoroutine } &&
|
||||
if (descriptor.valueParameters.any { it.hasSuspendFunctionType } &&
|
||||
!context.languageVersionSettings.supportsFeature(LanguageFeature.Coroutines)) {
|
||||
context.trace.report(Errors.UNSUPPORTED_FEATURE.on(reportOn, LanguageFeature.Coroutines))
|
||||
}
|
||||
|
||||
-4
@@ -22,7 +22,6 @@ import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
|
||||
import org.jetbrains.kotlin.coroutines.CoroutineUtilKt;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.psi.*;
|
||||
import org.jetbrains.kotlin.resolve.BindingContext;
|
||||
@@ -594,9 +593,6 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
|
||||
context.trace.report(RETURN_NOT_ALLOWED.on(expression));
|
||||
resultType = ErrorUtils.createErrorType(RETURN_NOT_ALLOWED_MESSAGE);
|
||||
}
|
||||
|
||||
CoroutineUtilKt.resolveCoroutineHandleResultCallIfNeeded(
|
||||
components.fakeCallResolver, expression, expression.getReturnedExpression(), functionDescriptor, context);
|
||||
}
|
||||
else {
|
||||
context.trace.report(NOT_A_RETURN_LABEL.on(expression, expression.getLabelName()));
|
||||
|
||||
+2
-2
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.isSuspendFunctionType
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||
@@ -33,7 +34,6 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext.EXPECTED_RETURN_TYPE
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.getCorrespondingParameterForFunctionArgument
|
||||
import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker
|
||||
import org.jetbrains.kotlin.resolve.lazy.ForceResolveUtil
|
||||
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope
|
||||
@@ -169,7 +169,7 @@ internal class FunctionsTypingVisitor(facade: ExpressionTypingInternals) : Expre
|
||||
context.scope.ownerDescriptor,
|
||||
components.annotationResolver.resolveAnnotationsWithArguments(context.scope, expression.getAnnotationEntries(), context.trace),
|
||||
CallableMemberDescriptor.Kind.DECLARATION, functionLiteral.toSourceElement(),
|
||||
expression.getCorrespondingParameterForFunctionArgument(context.trace.bindingContext)?.isCoroutine ?: false
|
||||
!noExpectedType(context.expectedType) && context.expectedType.isSuspendFunctionType
|
||||
)
|
||||
components.functionDescriptorResolver.
|
||||
initializeFunctionDescriptorAndExplicitReturnType(context.scope.ownerDescriptor, context.scope, functionLiteral,
|
||||
|
||||
Reference in New Issue
Block a user