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:
Denis Zharkov
2016-12-14 20:15:55 +03:00
committed by Stanislav Erokhin
parent 66c2333eb5
commit 1ab003c029
41 changed files with 97 additions and 809 deletions
@@ -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
}
@@ -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))
}
@@ -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()));
@@ -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
}
@@ -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,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
@@ -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)
}
}
@@ -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,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,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,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(