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,
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -NOTHING_TO_INLINE
|
||||
class Controller
|
||||
|
||||
class A(coroutine c: Controller.() -> Continuation<Unit>, y: Int) {
|
||||
var x: String = ""
|
||||
set(<!INAPPLICABLE_MODIFIER!>coroutine<!> x) {
|
||||
|
||||
}
|
||||
|
||||
constructor(coroutine c: Controller.() -> Continuation<Unit>) : this(c, 1)
|
||||
constructor(<!INAPPLICABLE_MODIFIER!>coroutine<!> c: Controller.() -> Continuation<Nothing>, y: String) : <!NONE_APPLICABLE!>this<!>(c, 2)
|
||||
}
|
||||
|
||||
fun valid(coroutine c: Controller.() -> Continuation<Unit>) {
|
||||
|
||||
}
|
||||
|
||||
fun noFunctionType(<!INAPPLICABLE_MODIFIER!>coroutine<!> c: Unit) {
|
||||
|
||||
}
|
||||
|
||||
fun noExtensionFunction(<!INAPPLICABLE_MODIFIER!>coroutine<!> c: (Controller) -> Continuation<Unit>) {
|
||||
|
||||
}
|
||||
|
||||
fun nullableReturnType(<!INAPPLICABLE_MODIFIER!>coroutine<!> c: Controller.() -> Continuation<Unit>?) {
|
||||
|
||||
}
|
||||
|
||||
fun wrongReturnType(<!INAPPLICABLE_MODIFIER!>coroutine<!> c: Controller.() -> Collection<Unit>) {
|
||||
|
||||
}
|
||||
|
||||
fun notUnitContinuation(<!INAPPLICABLE_MODIFIER!>coroutine<!> c: Controller.() -> Continuation<Int>) {
|
||||
|
||||
}
|
||||
|
||||
inline fun inlineBuilder(<!INAPPLICABLE_MODIFIER!>coroutine<!> c: Controller.() -> Continuation<Unit>) {
|
||||
|
||||
}
|
||||
|
||||
inline fun inlineBuilderNoInlineCoroutine(coroutine noinline c: Controller.() -> Continuation<Unit>) {
|
||||
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
package
|
||||
|
||||
public inline fun inlineBuilder(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public inline fun inlineBuilderNoInlineCoroutine(/*0*/ noinline coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public fun noExtensionFunction(/*0*/ coroutine c: (Controller) -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public fun noFunctionType(/*0*/ coroutine c: kotlin.Unit): kotlin.Unit
|
||||
public fun notUnitContinuation(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Int>): kotlin.Unit
|
||||
public fun nullableReturnType(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>?): kotlin.Unit
|
||||
public fun valid(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public fun wrongReturnType(/*0*/ coroutine c: Controller.() -> kotlin.collections.Collection<kotlin.Unit>): kotlin.Unit
|
||||
|
||||
public final class A {
|
||||
public constructor A(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Nothing>, /*1*/ y: kotlin.String)
|
||||
public constructor A(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>)
|
||||
public constructor A(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>, /*1*/ y: kotlin.Int)
|
||||
public final var x: kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class Controller {
|
||||
public constructor Controller()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class A1 {
|
||||
operator fun interceptResume(x: () -> Unit) {}
|
||||
}
|
||||
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun A1.interceptResume(x: () -> Unit) {}
|
||||
|
||||
class A2 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun interceptResume(x: () -> Unit, w: Int) {}
|
||||
}
|
||||
|
||||
class A3 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun interceptResume(x: String.() -> Unit) = 1
|
||||
}
|
||||
|
||||
class A4 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun interceptResume(x: (String) -> Unit) {}
|
||||
}
|
||||
|
||||
class A5 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun interceptResume(x: () -> Int) {}
|
||||
}
|
||||
|
||||
class A6 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T> interceptResume(x: () -> Unit) {}
|
||||
}
|
||||
|
||||
class A7 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun interceptResume(x: () -> Unit = {}) {}
|
||||
}
|
||||
|
||||
class A8 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun interceptResume(vararg x: () -> Unit) {}
|
||||
}
|
||||
|
||||
class A9 {
|
||||
inline operator fun interceptResume(x: () -> Unit) {}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package
|
||||
|
||||
public operator fun A1.interceptResume(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
|
||||
|
||||
public final class A1 {
|
||||
public constructor A1()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun interceptResume(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A2 {
|
||||
public constructor A2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun interceptResume(/*0*/ x: () -> kotlin.Unit, /*1*/ w: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A3 {
|
||||
public constructor A3()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun interceptResume(/*0*/ x: kotlin.String.() -> kotlin.Unit): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A4 {
|
||||
public constructor A4()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun interceptResume(/*0*/ x: (kotlin.String) -> kotlin.Unit): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A5 {
|
||||
public constructor A5()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun interceptResume(/*0*/ x: () -> kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A6 {
|
||||
public constructor A6()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun </*0*/ T> interceptResume(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A7 {
|
||||
public constructor A7()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun interceptResume(/*0*/ x: () -> kotlin.Unit = ...): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A8 {
|
||||
public constructor A8()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun interceptResume(/*0*/ vararg x: () -> kotlin.Unit /*kotlin.Array<out () -> kotlin.Unit>*/): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A9 {
|
||||
public constructor A9()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator inline fun interceptResume(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ class A {
|
||||
suspend fun suspendHere(a: Int) = 1
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {}
|
||||
fun builder(c: @Suspend() (Controller.() -> Unit)) {}
|
||||
|
||||
fun test() {
|
||||
builder {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package
|
||||
|
||||
public fun builder(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public fun builder(/*0*/ c: @kotlin.coroutines.Suspend() (Controller.() -> kotlin.Unit)): kotlin.Unit
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public final class A {
|
||||
|
||||
@@ -1,56 +1,43 @@
|
||||
// !CHECK_TYPE
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_VARIABLE
|
||||
class IntController {
|
||||
operator fun handleResult(x: Int, c: Continuation<Nothing>) { }
|
||||
}
|
||||
|
||||
class GenericController<T> {
|
||||
operator fun handleResult(x: T, c: Continuation<Nothing>) { }
|
||||
}
|
||||
|
||||
class UnitController {
|
||||
operator fun handleResult(x: Unit, c: Continuation<Nothing>) { }
|
||||
}
|
||||
|
||||
class EmptyController
|
||||
|
||||
fun builder(coroutine c: IntController.() -> Continuation<Unit>) = 1
|
||||
fun <T> genericBuilder(coroutine c: GenericController<T>.() -> Continuation<Unit>): T = null!!
|
||||
fun unitBuilder(coroutine c: UnitController.() -> Continuation<Unit>) = 1
|
||||
fun emptyBuilder(coroutine c: EmptyController.() -> Continuation<Unit>) = 1
|
||||
fun builder(c: @Suspend() (() -> Int)) = 1
|
||||
fun <T> genericBuilder(c: @Suspend() (() -> T)): T = null!!
|
||||
fun unitBuilder(c: @Suspend() (() -> Unit)) = 1
|
||||
fun emptyBuilder(c: @Suspend() (() -> Unit)) = 1
|
||||
|
||||
fun <T> manyArgumentsBuilder(
|
||||
coroutine c1: UnitController.() -> Continuation<Unit>,
|
||||
coroutine c2: GenericController<T>.() -> Continuation<Unit>,
|
||||
coroutine c3: IntController.() -> Continuation<Unit>
|
||||
c1: @Suspend() (() -> Unit),
|
||||
c2: @Suspend() (() -> T),
|
||||
c3: @Suspend() (() -> Int)
|
||||
):T = null!!
|
||||
|
||||
fun severalParamsInLambda(coroutine c: UnitController.(String, Int) -> Continuation<Unit>) {}
|
||||
fun severalParamsInLambda(c: @Suspend() ((String, Int) -> Unit)) {}
|
||||
|
||||
fun foo() {
|
||||
builder({ 1 })
|
||||
builder { 1 }
|
||||
|
||||
val x = { 1 }
|
||||
builder(<!TYPE_MISMATCH!>x<!>)
|
||||
builder(<!UNCHECKED_CAST!>{1} as (IntController.() -> Continuation<Unit>)<!>)
|
||||
builder(x)
|
||||
builder({1} <!USELESS_CAST!>as (@Suspend() (() -> Int))<!>)
|
||||
|
||||
var i: Int = 1
|
||||
i = genericBuilder({ 1 })
|
||||
i = genericBuilder { 1 }
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>genericBuilder<!> { 1 }
|
||||
genericBuilder { 1 }
|
||||
genericBuilder<Int> { 1 }
|
||||
genericBuilder<Int> { <!TYPE_MISMATCH!>""<!> }
|
||||
|
||||
val y = { 1 }
|
||||
<!TYPE_INFERENCE_PARAMETER_CONSTRAINT_ERROR!>genericBuilder<!>(<!TYPE_MISMATCH!>y<!>)
|
||||
genericBuilder(y)
|
||||
|
||||
unitBuilder {}
|
||||
unitBuilder { <!UNUSED_EXPRESSION!>1<!> }
|
||||
unitBuilder({})
|
||||
unitBuilder({ <!UNUSED_EXPRESSION!>1<!> })
|
||||
|
||||
<!TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER!>manyArgumentsBuilder<!>({}, { "" }) { 1 }
|
||||
manyArgumentsBuilder({}, { "" }) { 1 }
|
||||
|
||||
val s: String = manyArgumentsBuilder({}, { "" }) { 1 }
|
||||
|
||||
|
||||
@@ -1,40 +1,9 @@
|
||||
package
|
||||
|
||||
public fun builder(/*0*/ coroutine c: IntController.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Int
|
||||
public fun emptyBuilder(/*0*/ coroutine c: EmptyController.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Int
|
||||
public fun builder(/*0*/ c: @kotlin.coroutines.Suspend () -> kotlin.Int): kotlin.Int
|
||||
public fun emptyBuilder(/*0*/ c: @kotlin.coroutines.Suspend () -> kotlin.Unit): kotlin.Int
|
||||
public fun foo(): kotlin.Unit
|
||||
public fun </*0*/ T> genericBuilder(/*0*/ coroutine c: GenericController<T>.() -> kotlin.coroutines.Continuation<kotlin.Unit>): T
|
||||
public fun </*0*/ T> manyArgumentsBuilder(/*0*/ coroutine c1: UnitController.() -> kotlin.coroutines.Continuation<kotlin.Unit>, /*1*/ coroutine c2: GenericController<T>.() -> kotlin.coroutines.Continuation<kotlin.Unit>, /*2*/ coroutine c3: IntController.() -> kotlin.coroutines.Continuation<kotlin.Unit>): T
|
||||
public fun severalParamsInLambda(/*0*/ coroutine c: UnitController.(kotlin.String, kotlin.Int) -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public fun unitBuilder(/*0*/ coroutine c: UnitController.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Int
|
||||
|
||||
public final class EmptyController {
|
||||
public constructor EmptyController()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class GenericController</*0*/ T> {
|
||||
public constructor GenericController</*0*/ T>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: T, /*1*/ c: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class IntController {
|
||||
public constructor IntController()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.Int, /*1*/ c: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class UnitController {
|
||||
public constructor UnitController()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.Unit, /*1*/ c: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public fun </*0*/ T> genericBuilder(/*0*/ c: @kotlin.coroutines.Suspend () -> T): T
|
||||
public fun </*0*/ T> manyArgumentsBuilder(/*0*/ c1: @kotlin.coroutines.Suspend () -> kotlin.Unit, /*1*/ c2: @kotlin.coroutines.Suspend () -> T, /*2*/ c3: @kotlin.coroutines.Suspend () -> kotlin.Int): T
|
||||
public fun severalParamsInLambda(/*0*/ c: @kotlin.coroutines.Suspend (kotlin.String, kotlin.Int) -> kotlin.Unit): kotlin.Unit
|
||||
public fun unitBuilder(/*0*/ c: @kotlin.coroutines.Suspend () -> kotlin.Unit): kotlin.Int
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
interface A {
|
||||
operator fun handleResult(x: Int, y: Continuation<Nothing>) {}
|
||||
}
|
||||
|
||||
interface B {
|
||||
operator fun handleResult(x: String, y: Continuation<Nothing>) {}
|
||||
}
|
||||
|
||||
class C : A, B {
|
||||
// multiple handleResults
|
||||
}
|
||||
|
||||
fun builder1(coroutine c: A.() -> Continuation<Unit>) {}
|
||||
fun builder2(coroutine c: B.() -> Continuation<Unit>) {}
|
||||
fun builder3(<!INAPPLICABLE_MODIFIER!>coroutine<!> c: C.() -> Continuation<Unit>) {}
|
||||
@@ -1,28 +0,0 @@
|
||||
package
|
||||
|
||||
public fun builder1(/*0*/ coroutine c: A.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public fun builder2(/*0*/ coroutine c: B.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public fun builder3(/*0*/ coroutine c: C.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
|
||||
public interface A {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open operator fun handleResult(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public interface B {
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open operator fun handleResult(/*0*/ x: kotlin.String, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class C : A, B {
|
||||
public constructor C()
|
||||
public open override /*2*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun handleResult(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun handleResult(/*0*/ x: kotlin.String, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*2*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*2*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -1,12 +1,9 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
|
||||
class Controller<T> {
|
||||
suspend fun suspendHere() = 1
|
||||
suspend fun suspendHere() = 1
|
||||
suspend fun <T> another(a: T) = 1
|
||||
|
||||
suspend fun another(a: T) = 1
|
||||
}
|
||||
|
||||
fun <T> builder(coroutine c: Controller<T>.() -> Continuation<Unit>) { }
|
||||
fun <T> builder(c: @Suspend() (() -> Unit)) { }
|
||||
|
||||
inline fun run(x: () -> Unit) {}
|
||||
|
||||
@@ -19,7 +16,7 @@ fun foo() {
|
||||
builder<String> {
|
||||
suspendHere()
|
||||
another("")
|
||||
another(<!CONSTANT_EXPECTED_TYPE_MISMATCH!>1<!>)
|
||||
another(1)
|
||||
|
||||
result += suspendHere()
|
||||
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
package
|
||||
|
||||
public fun </*0*/ T> builder(/*0*/ coroutine c: Controller<T>.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public suspend fun </*0*/ T> another(/*0*/ a: T): kotlin.Int
|
||||
public fun </*0*/ T> builder(/*0*/ c: @kotlin.coroutines.Suspend () -> kotlin.Unit): kotlin.Unit
|
||||
public fun foo(): kotlin.Unit
|
||||
public fun noinline(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
|
||||
public inline fun run(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
|
||||
public inline fun runCross(/*0*/ crossinline x: () -> kotlin.Unit): kotlin.Unit
|
||||
|
||||
public final class Controller</*0*/ T> {
|
||||
public constructor Controller</*0*/ T>()
|
||||
public final suspend fun another(/*0*/ a: T): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final suspend fun suspendHere(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public suspend fun suspendHere(): kotlin.Int
|
||||
|
||||
+5
-11
@@ -1,24 +1,21 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// !CHECK_TYPE
|
||||
class Controller
|
||||
|
||||
suspend fun noParams() {
|
||||
|
||||
}
|
||||
|
||||
suspend fun yieldString(value: String) {}
|
||||
|
||||
suspend fun <V> await(f: () -> V) = f()
|
||||
|
||||
suspend fun <V> Controller.await(f: Int): V = null!!
|
||||
suspend fun <V> await(f: Int): V = null!!
|
||||
|
||||
suspend fun Controller.severalParams(x: String, y: Int) = 1.0
|
||||
suspend fun severalParams(x: String, y: Int) = 1.0
|
||||
|
||||
suspend fun String.stringReceiver(y: Int) = 1.0
|
||||
|
||||
suspend fun Any.anyReceiver(y: Int) = 1.0
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {}
|
||||
fun builder(c: @Suspend() (() -> Unit)) {}
|
||||
|
||||
fun test() {
|
||||
builder {
|
||||
@@ -39,15 +36,12 @@ fun test() {
|
||||
severalParams("", 89) checkType { _<Double>() }
|
||||
// TODO: should we allow somehow to call with passing continuation explicitly?
|
||||
severalParams("", 89, <!TOO_MANY_ARGUMENTS!>6.9<!>) checkType { <!TYPE_MISMATCH!>_<!><Unit>() }
|
||||
severalParams("", 89, <!TOO_MANY_ARGUMENTS!>this <!CAST_NEVER_SUCCEEDS!>as<!> Continuation<Double><!>) checkType { <!TYPE_MISMATCH!>_<!><Unit>() }
|
||||
|
||||
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>stringReceiver<!>(1)
|
||||
"".stringReceiver(1)
|
||||
Any().anyReceiver(1)
|
||||
|
||||
with("") {
|
||||
stringReceiver(2)
|
||||
}
|
||||
|
||||
// Though such calls are allowed declarations with not-annotated receiver should be prohibited
|
||||
anyReceiver(3)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-10
@@ -1,18 +1,11 @@
|
||||
package
|
||||
|
||||
public suspend fun </*0*/ V> await(/*0*/ f: () -> V): V
|
||||
public fun builder(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public suspend fun </*0*/ V> await(/*0*/ f: kotlin.Int): V
|
||||
public fun builder(/*0*/ c: @kotlin.coroutines.Suspend () -> kotlin.Unit): kotlin.Unit
|
||||
public suspend fun noParams(): kotlin.Unit
|
||||
public suspend fun severalParams(/*0*/ x: kotlin.String, /*1*/ y: kotlin.Int): kotlin.Double
|
||||
public fun test(): kotlin.Unit
|
||||
public suspend fun yieldString(/*0*/ value: kotlin.String): kotlin.Unit
|
||||
public suspend fun kotlin.Any.anyReceiver(/*0*/ y: kotlin.Int): kotlin.Double
|
||||
public suspend fun </*0*/ V> Controller.await(/*0*/ f: kotlin.Int): V
|
||||
public suspend fun Controller.severalParams(/*0*/ x: kotlin.String, /*1*/ y: kotlin.Int): kotlin.Double
|
||||
public suspend fun kotlin.String.stringReceiver(/*0*/ y: kotlin.Int): kotlin.Double
|
||||
|
||||
public final class Controller {
|
||||
public constructor Controller()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ class Controller {
|
||||
suspend fun severalParams(x: String, y: Int) = 1.0
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {}
|
||||
fun builder(c: @Suspend() (Controller.() -> Unit)) {}
|
||||
|
||||
fun test() {
|
||||
builder {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package
|
||||
|
||||
public fun builder(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public fun builder(/*0*/ c: @kotlin.coroutines.Suspend() (Controller.() -> kotlin.Unit)): kotlin.Unit
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public final class Controller {
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@
|
||||
// !CHECK_TYPE
|
||||
class Controller {
|
||||
suspend fun noParams(): Unit = suspendWithCurrentContinuation {
|
||||
if (hashCode() % 2 == 0) {
|
||||
if (hashCode() <!DEPRECATED_BINARY_MOD_AS_REM!>%<!> 2 == 0) {
|
||||
it.resume(Unit)
|
||||
Suspend
|
||||
}
|
||||
@@ -21,7 +21,7 @@ class Controller {
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(coroutine c: Controller.() -> Continuation<Unit>) {}
|
||||
fun builder(c: @Suspend() (Controller.() -> Unit)) {}
|
||||
|
||||
fun test() {
|
||||
builder {
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
package
|
||||
|
||||
public fun builder(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
public fun builder(/*0*/ c: @kotlin.coroutines.Suspend() (Controller.() -> kotlin.Unit)): kotlin.Unit
|
||||
public fun test(): kotlin.Unit
|
||||
|
||||
public final class Controller {
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
// Tail calls are not allowed to be Nothing typed. See KT-15051
|
||||
suspend fun suspendLogAndThrow(exception: Throwable): Nothing = <!SUSPENSION_CALL_MUST_BE_USED_AS_RETURN_VALUE!>suspendWithCurrentContinuation { c ->
|
||||
c.resumeWithException(exception)
|
||||
Suspend
|
||||
SUSPENDED
|
||||
}<!>
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER -ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE -UNUSED_VALUE -UNUSED_VARIABLE
|
||||
class GenericController<T> {
|
||||
operator fun handleResult(x: T, c: Continuation<Nothing>) { }
|
||||
suspend fun <V> await(f: V): V = f
|
||||
}
|
||||
suspend fun <V> await(f: V): V = f
|
||||
|
||||
fun <T> genericBuilder(coroutine c: GenericController<T>.() -> Continuation<Unit>): T = null!!
|
||||
fun <T> genericBuilder(c: @Suspend() (() -> T)): T = null!!
|
||||
|
||||
fun foo() {
|
||||
var result = ""
|
||||
|
||||
@@ -1,13 +1,5 @@
|
||||
package
|
||||
|
||||
public suspend fun </*0*/ V> await(/*0*/ f: V): V
|
||||
public fun foo(): kotlin.Unit
|
||||
public fun </*0*/ T> genericBuilder(/*0*/ coroutine c: GenericController<T>.() -> kotlin.coroutines.Continuation<kotlin.Unit>): T
|
||||
|
||||
public final class GenericController</*0*/ T> {
|
||||
public constructor GenericController</*0*/ T>()
|
||||
public final suspend fun </*0*/ V> await(/*0*/ f: V): V
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: T, /*1*/ c: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public fun </*0*/ T> genericBuilder(/*0*/ c: @kotlin.coroutines.Suspend () -> T): T
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// !LANGUAGE: -Coroutines
|
||||
|
||||
class Controller {
|
||||
<!UNSUPPORTED_FEATURE!>suspend<!> fun suspendHere(): String = "OK"
|
||||
<!UNSUPPORTED_FEATURE!>suspend<!> fun suspendHere(): String = "OK"
|
||||
|
||||
<!UNSUPPORTED_FEATURE!>operator<!> fun handleResult(x: String, y: Continuation<Nothing>) {}
|
||||
fun builder(c: @Suspend() (() -> Unit)) {
|
||||
|
||||
<!UNSUPPORTED_FEATURE!>operator<!> fun handleException(x: Throwable, y: Continuation<Nothing>) {
|
||||
}
|
||||
|
||||
<!UNSUPPORTED_FEATURE!>operator<!> fun interceptResume(x: () -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
fun builder(<!UNSUPPORTED_FEATURE!>coroutine<!> c: Controller.() -> Continuation<Unit>) {
|
||||
c(Controller()).resume(Unit)
|
||||
}
|
||||
|
||||
fun box(): String {
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
package
|
||||
|
||||
public fun box(): kotlin.String
|
||||
public fun builder(/*0*/ coroutine c: Controller.() -> kotlin.coroutines.Continuation<kotlin.Unit>): kotlin.Unit
|
||||
|
||||
public final class Controller {
|
||||
public constructor Controller()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleException(/*0*/ x: kotlin.Throwable, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.String, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public final operator fun interceptResume(/*0*/ x: () -> kotlin.Unit): kotlin.Unit
|
||||
public final suspend fun suspendHere(): kotlin.String
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
public fun builder(/*0*/ c: @kotlin.coroutines.Suspend () -> kotlin.Unit): kotlin.Unit
|
||||
public suspend fun suspendHere(): kotlin.String
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class A1 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleException(x: Throwable) {
|
||||
}
|
||||
}
|
||||
|
||||
class A2 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleException(x: Throwable, y: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
class A3 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleException(x: Throwable, y: Continuation<Any>) {
|
||||
}
|
||||
}
|
||||
|
||||
class A4 {
|
||||
operator fun handleException(x: Throwable, y: Continuation<Nothing>) {
|
||||
}
|
||||
}
|
||||
|
||||
class A5 {
|
||||
// TODO: Allow?
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleException(x: Throwable, y: Continuation<Nothing>): Int = 1
|
||||
}
|
||||
|
||||
class A6 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleException(x: Throwable = Exception(), y: Continuation<Nothing>) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleException(x: Throwable, vararg y: Continuation<Nothing>) {}
|
||||
}
|
||||
|
||||
class A7 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T> handleException(x: Throwable, y: Continuation<Nothing>) {
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
package
|
||||
|
||||
public final class A1 {
|
||||
public constructor A1()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleException(/*0*/ x: kotlin.Throwable): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A2 {
|
||||
public constructor A2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleException(/*0*/ x: kotlin.Throwable, /*1*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A3 {
|
||||
public constructor A3()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleException(/*0*/ x: kotlin.Throwable, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Any>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A4 {
|
||||
public constructor A4()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleException(/*0*/ x: kotlin.Throwable, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A5 {
|
||||
public constructor A5()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleException(/*0*/ x: kotlin.Throwable, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A6 {
|
||||
public constructor A6()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleException(/*0*/ x: kotlin.Throwable, /*1*/ vararg y: kotlin.coroutines.Continuation<kotlin.Nothing> /*kotlin.Array<out kotlin.coroutines.Continuation<kotlin.Nothing>>*/): kotlin.Unit
|
||||
public final operator fun handleException(/*0*/ x: kotlin.Throwable = ..., /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A7 {
|
||||
public constructor A7()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun </*0*/ T> handleException(/*0*/ x: kotlin.Throwable, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
class A1 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleResult(x: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
class A2 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleResult(x: Int, y: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
class A3 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleResult(x: Int, y: Continuation<Any>) {
|
||||
}
|
||||
}
|
||||
|
||||
class A4 {
|
||||
operator fun handleResult(x: Int, y: Continuation<Nothing>) {
|
||||
}
|
||||
}
|
||||
|
||||
class A5 {
|
||||
// TODO: Allow?
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleResult(x: Int, y: Continuation<Nothing>): Int = 1
|
||||
}
|
||||
|
||||
class A6 {
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun <T> handleResult(x: Int, y: Continuation<Nothing>) {
|
||||
}
|
||||
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleResult(x: String = "", y: Continuation<Nothing>) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleResult(x: Double = 1.0, vararg y: Continuation<Nothing>) {}
|
||||
<!INAPPLICABLE_OPERATOR_MODIFIER!>operator<!> fun handleResult(x: Double = 1.0, z: Int, y: Continuation<Nothing>) {}
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
package
|
||||
|
||||
public final class A1 {
|
||||
public constructor A1()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A2 {
|
||||
public constructor A2()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.Int): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A3 {
|
||||
public constructor A3()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Any>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A4 {
|
||||
public constructor A4()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A5 {
|
||||
public constructor A5()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class A6 {
|
||||
public constructor A6()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.Double = ..., /*1*/ vararg y: kotlin.coroutines.Continuation<kotlin.Nothing> /*kotlin.Array<out kotlin.coroutines.Continuation<kotlin.Nothing>>*/): kotlin.Unit
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.Double = ..., /*1*/ z: kotlin.Int, /*2*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public final operator fun </*0*/ T> handleResult(/*0*/ x: kotlin.Int, /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public final operator fun handleResult(/*0*/ x: kotlin.String = ..., /*1*/ y: kotlin.coroutines.Continuation<kotlin.Nothing>): kotlin.Unit
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -4258,24 +4258,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/tests/coroutines"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("coroutineApplicability.kt")
|
||||
public void testCoroutineApplicability() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/coroutineApplicability.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("illegalSuspendCalls.kt")
|
||||
public void testIllegalSuspendCalls() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/illegalSuspendCalls.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("interceptResume.kt")
|
||||
public void testInterceptResume() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/interceptResume.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("irrelevantSuspendDeclarations.kt")
|
||||
public void testIrrelevantSuspendDeclarations() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/irrelevantSuspendDeclarations.kt");
|
||||
@@ -4288,12 +4276,6 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("manyHandleResults.kt")
|
||||
public void testManyHandleResults() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/manyHandleResults.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("nonLocalSuspension.kt")
|
||||
public void testNonLocalSuspension() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/nonLocalSuspension.kt");
|
||||
@@ -4336,18 +4318,6 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongHandleException.kt")
|
||||
public void testWrongHandleException() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/wrongHandleException.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("wrongHandleResult.kt")
|
||||
public void testWrongHandleResult() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/coroutines/wrongHandleResult.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/coroutines/tailCalls")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -16,8 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.isFunctionType
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
fun ModuleDescriptor.resolveClassByFqName(fqName: FqName, lookupLocation: LookupLocation): ClassDescriptor? {
|
||||
if (fqName.isRoot) return null
|
||||
@@ -29,3 +33,7 @@ fun ModuleDescriptor.resolveClassByFqName(fqName: FqName, lookupLocation: Lookup
|
||||
?.unsubstitutedInnerClassesScope
|
||||
?.getContributedClassifier(fqName.shortName(), lookupLocation) as? ClassDescriptor
|
||||
}
|
||||
|
||||
val KotlinType.isSuspendFunctionType get() = isFunctionType && annotations.hasAnnotation(DescriptorUtils.SUSPEND_ANNOTATION_FQ_NAME)
|
||||
|
||||
val KotlinBuiltIns.continuationClassDescriptor get() = getBuiltInClassByFqName(DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME)
|
||||
|
||||
@@ -54,6 +54,9 @@ public class DescriptorUtils {
|
||||
public static final FqName CONTINUATION_INTERFACE_FQ_NAME =
|
||||
KotlinBuiltIns.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("Continuation"));
|
||||
|
||||
public static final FqName SUSPEND_ANNOTATION_FQ_NAME =
|
||||
KotlinBuiltIns.COROUTINES_PACKAGE_FQ_NAME.child(Name.identifier("Suspend"));
|
||||
|
||||
private DescriptorUtils() {
|
||||
}
|
||||
|
||||
|
||||
@@ -59,9 +59,6 @@ object OperatorNameConventions {
|
||||
@JvmField val REM_ASSIGN = Name.identifier("remAssign")
|
||||
@JvmField val PLUS_ASSIGN = Name.identifier("plusAssign")
|
||||
@JvmField val MINUS_ASSIGN = Name.identifier("minusAssign")
|
||||
@JvmField val COROUTINE_HANDLE_RESULT = Name.identifier("handleResult")
|
||||
@JvmField val COROUTINE_HANDLE_EXCEPTION = Name.identifier("handleException")
|
||||
@JvmField val COROUTINE_INTERCEPT_RESUME = Name.identifier("interceptResume")
|
||||
|
||||
// If you add new unary, binary or assignment operators, add it to OperatorConventions as well
|
||||
|
||||
|
||||
@@ -16,17 +16,18 @@
|
||||
|
||||
package org.jetbrains.kotlin.util
|
||||
|
||||
import org.jetbrains.kotlin.builtins.*
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.ReflectionTypes
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.*
|
||||
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
|
||||
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
|
||||
import org.jetbrains.kotlin.util.MemberKindCheck.Member
|
||||
import org.jetbrains.kotlin.util.MemberKindCheck.MemberOrExtension
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.ASSIGNMENT_OPERATIONS
|
||||
@@ -34,9 +35,6 @@ import org.jetbrains.kotlin.util.OperatorNameConventions.BINARY_OPERATION_NAMES
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.COMPARE_TO
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.COMPONENT_REGEX
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.CONTAINS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.COROUTINE_HANDLE_EXCEPTION
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.COROUTINE_HANDLE_RESULT
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.COROUTINE_INTERCEPT_RESUME
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.DEC
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.EQUALS
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions.GET
|
||||
@@ -206,38 +204,8 @@ object OperatorChecks : AbstractModifierChecks() {
|
||||
}
|
||||
},
|
||||
Checks(ASSIGNMENT_OPERATIONS, MemberOrExtension, ReturnsUnit, SingleValueParameter, NoDefaultAndVarargsCheck),
|
||||
Checks(COMPONENT_REGEX, MemberOrExtension, NoValueParameters),
|
||||
Checks(COROUTINE_HANDLE_RESULT, Member, ValueParameterCountCheck.Equals(2), ReturnsUnit, NoDefaultAndVarargsCheck,
|
||||
NoTypeParametersCheck) {
|
||||
checkHandleSecondParameter()
|
||||
},
|
||||
Checks(COROUTINE_HANDLE_EXCEPTION, Member, ValueParameterCountCheck.Equals(2), ReturnsUnit, NoDefaultAndVarargsCheck,
|
||||
NoTypeParametersCheck) {
|
||||
checkHandleSecondParameter()
|
||||
?: ensure(valueParameters[0].type.isThrowable()) {
|
||||
"First parameter should be 'Throwable'"
|
||||
}
|
||||
},
|
||||
Checks(COROUTINE_INTERCEPT_RESUME, Member, ValueParameterCountCheck.Equals(1), ReturnsUnit, NoDefaultAndVarargsCheck,
|
||||
NoTypeParametersCheck
|
||||
) {
|
||||
val parameterType = valueParameters.single().type
|
||||
ensure(parameterType.isNonExtensionFunctionType && parameterType.getValueParameterTypesFromFunctionType().isEmpty() &&
|
||||
parameterType.getReturnTypeFromFunctionType().isUnit()
|
||||
) { "Value parameter must have a functional type '() -> Unit'" }
|
||||
}
|
||||
)
|
||||
|
||||
private fun FunctionDescriptor.checkHandleSecondParameter(): String? {
|
||||
val secondParameter = valueParameters[1]
|
||||
return ensure(
|
||||
secondParameter.type.isConstructedFromClassWithGivenFqName(DescriptorUtils.CONTINUATION_INTERFACE_FQ_NAME)
|
||||
&& secondParameter.type.arguments[0].type.isNothing()
|
||||
) {
|
||||
"Second parameter should be Continuation<Nothing>"
|
||||
}
|
||||
}
|
||||
}
|
||||
Checks(COMPONENT_REGEX, MemberOrExtension, NoValueParameters)
|
||||
) }
|
||||
|
||||
object InfixChecks : AbstractModifierChecks() {
|
||||
override val checks = listOf(
|
||||
|
||||
Reference in New Issue
Block a user