Allow suspend extensions for specially annotated controllers
This commit is contained in:
@@ -83,7 +83,7 @@ object ModifierCheckerCore {
|
||||
NOINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER),
|
||||
COROUTINE_KEYWORD to EnumSet.of(VALUE_PARAMETER),
|
||||
TAILREC_KEYWORD to EnumSet.of(FUNCTION),
|
||||
SUSPEND_KEYWORD to EnumSet.of(MEMBER_FUNCTION),
|
||||
SUSPEND_KEYWORD to EnumSet.of(FUNCTION),
|
||||
EXTERNAL_KEYWORD to EnumSet.of(FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER),
|
||||
ANNOTATION_KEYWORD to EnumSet.of(ANNOTATION_CLASS),
|
||||
CROSSINLINE_KEYWORD to EnumSet.of(VALUE_PARAMETER),
|
||||
|
||||
@@ -20,12 +20,14 @@ import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isExtensionFunctionType
|
||||
import org.jetbrains.kotlin.coroutines.isValidContinuation
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.KotlinLookupLocation
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
@@ -33,6 +35,8 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
|
||||
object SuspendModifierChecker : SimpleDeclarationChecker {
|
||||
private val ALLOW_SUSPEND_EXTENSIONS_ANNOTATION_FQ_NAME = FqName("kotlin.coroutines.AllowSuspendExtensions")
|
||||
|
||||
override fun check(
|
||||
declaration: KtDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
@@ -47,6 +51,25 @@ object SuspendModifierChecker : SimpleDeclarationChecker {
|
||||
diagnosticHolder.report(Errors.INAPPLICABLE_MODIFIER.on(suspendModifierElement, KtTokens.SUSPEND_KEYWORD, message))
|
||||
}
|
||||
|
||||
if (functionDescriptor.dispatchReceiverParameter == null) {
|
||||
if (functionDescriptor.extensionReceiverParameter == null) {
|
||||
report("function must be either a class member or an extension")
|
||||
return
|
||||
}
|
||||
|
||||
val classDescriptor =
|
||||
functionDescriptor.extensionReceiverParameter!!.type.constructor.declarationDescriptor as? ClassDescriptor
|
||||
if (classDescriptor == null) {
|
||||
report("function must be an extension to class")
|
||||
return
|
||||
}
|
||||
|
||||
if (!classDescriptor.annotations.hasAnnotation(ALLOW_SUSPEND_EXTENSIONS_ANNOTATION_FQ_NAME)) {
|
||||
report("controller class must be annotated with AllowSuspendExtensions annotation")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val isValidContinuation = functionDescriptor.valueParameters.lastOrNull()?.type?.isValidContinuation() ?: false
|
||||
if (!isValidContinuation) {
|
||||
report("last parameter of suspend function should have a type of Continuation<T>")
|
||||
|
||||
Reference in New Issue
Block a user