FIR: introduce builtin suspend related diagnostics
This commit is contained in:
committed by
teamcityserver
parent
391c4db87c
commit
229dfd3f5f
+2
@@ -1192,6 +1192,8 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
}
|
}
|
||||||
val NON_LOCAL_SUSPENSION_POINT by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
val NON_LOCAL_SUSPENSION_POINT by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
val ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
val NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -612,5 +612,7 @@ object FirErrors {
|
|||||||
val ILLEGAL_SUSPEND_PROPERTY_ACCESS by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val ILLEGAL_SUSPEND_PROPERTY_ACCESS by error1<PsiElement, FirBasedSymbol<*>>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val NON_LOCAL_SUSPENSION_POINT by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val NON_LOCAL_SUSPENSION_POINT by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
val ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
val ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
val NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
val MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+56
-4
@@ -5,17 +5,17 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
package org.jetbrains.kotlin.fir.analysis.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.getChild
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
import org.jetbrains.kotlin.fir.declarations.utils.isSuspend
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirExpression
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirThisReceiverExpression
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedCallableReference
|
||||||
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
|
||||||
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_1_2_20_FQ_NAME
|
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_1_2_20_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_1_2_30_FQ_NAME
|
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_1_2_30_FQ_NAME
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_1_3_FQ_NAME
|
import org.jetbrains.kotlin.resolve.calls.checkers.COROUTINE_CONTEXT_1_3_FQ_NAME
|
||||||
|
import org.jetbrains.kotlin.serialization.deserialization.KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
|
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
|
||||||
|
|
||||||
object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||||
@@ -44,13 +45,20 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
|||||||
private val RESTRICTS_SUSPENSION_CLASS_ID =
|
private val RESTRICTS_SUSPENSION_CLASS_ID =
|
||||||
ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE, Name.identifier("RestrictsSuspension"))
|
ClassId(StandardNames.COROUTINES_PACKAGE_FQ_NAME_RELEASE, Name.identifier("RestrictsSuspension"))
|
||||||
|
|
||||||
|
private val BUILTIN_SUSPEND_NAME = KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME.shortName()
|
||||||
|
|
||||||
@OptIn(SymbolInternals::class)
|
@OptIn(SymbolInternals::class)
|
||||||
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(expression: FirQualifiedAccessExpression, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
val reference = expression.calleeReference as? FirResolvedNamedReference ?: return
|
val reference = expression.calleeReference as? FirResolvedNamedReference ?: return
|
||||||
if (reference is FirResolvedCallableReference) return
|
|
||||||
val symbol = reference.resolvedSymbol as? FirCallableSymbol ?: return
|
val symbol = reference.resolvedSymbol as? FirCallableSymbol ?: return
|
||||||
symbol.ensureResolved(FirResolvePhase.STATUS)
|
symbol.ensureResolved(FirResolvePhase.STATUS)
|
||||||
val fir = symbol.fir as? FirCallableDeclaration ?: return
|
val fir = symbol.fir as? FirCallableDeclaration ?: return
|
||||||
|
if (reference.name == BUILTIN_SUSPEND_NAME ||
|
||||||
|
fir is FirSimpleFunction && fir.name == BUILTIN_SUSPEND_NAME
|
||||||
|
) {
|
||||||
|
checkSuspendModifierForm(expression, reference, symbol, context, reporter)
|
||||||
|
}
|
||||||
|
if (reference is FirResolvedCallableReference) return
|
||||||
when (fir) {
|
when (fir) {
|
||||||
is FirSimpleFunction -> if (!fir.isSuspend) return
|
is FirSimpleFunction -> if (!fir.isSuspend) return
|
||||||
is FirProperty -> if (symbol.callableId.asSingleFqName() !in SUSPEND_PROPERTIES_FQ_NAMES) return
|
is FirProperty -> if (symbol.callableId.asSingleFqName() !in SUSPEND_PROPERTIES_FQ_NAMES) return
|
||||||
@@ -74,6 +82,50 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkSuspendModifierForm(
|
||||||
|
expression: FirQualifiedAccessExpression,
|
||||||
|
reference: FirResolvedNamedReference,
|
||||||
|
symbol: FirCallableSymbol<*>,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
if (symbol.callableId.asSingleFqName() == KOTLIN_SUSPEND_BUILT_IN_FUNCTION_FQ_NAME) {
|
||||||
|
if (reference.name != BUILTIN_SUSPEND_NAME ||
|
||||||
|
expression.explicitReceiver != null ||
|
||||||
|
!expression.hasFormOfSuspendModifierForLambda()
|
||||||
|
) {
|
||||||
|
reporter.reportOn(expression.source, FirErrors.NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND, context)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (reference.name == BUILTIN_SUSPEND_NAME && expression.hasFormOfSuspendModifierForLambda()) {
|
||||||
|
reporter.reportOn(expression.source, FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirQualifiedAccessExpression.hasFormOfSuspendModifierForLambda(): Boolean {
|
||||||
|
if (this !is FirFunctionCall) return false
|
||||||
|
val reference = this.calleeReference
|
||||||
|
if (reference is FirResolvedCallableReference) return false
|
||||||
|
if (typeArguments.any { it.source != null }) return false
|
||||||
|
if (arguments.singleOrNull() is FirLambdaArgumentExpression) {
|
||||||
|
// No brackets should be in a selector call
|
||||||
|
val callExpressionSource =
|
||||||
|
if (explicitReceiver == null) source
|
||||||
|
else source?.getChild(KtNodeTypes.CALL_EXPRESSION, index = 1, depth = 1)
|
||||||
|
if (callExpressionSource?.getChild(KtNodeTypes.VALUE_ARGUMENT_LIST, depth = 1) == null) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (source?.elementType == KtNodeTypes.BINARY_EXPRESSION) {
|
||||||
|
val lastArgument = arguments.lastOrNull()
|
||||||
|
if (lastArgument is FirAnonymousFunctionExpression && source?.getChild(KtNodeTypes.PARENTHESIZED, depth = 1) == null) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
private fun findEnclosingSuspendFunction(context: CheckerContext): FirFunction? {
|
private fun findEnclosingSuspendFunction(context: CheckerContext): FirFunction? {
|
||||||
return context.containingDeclarations.lastOrNull {
|
return context.containingDeclarations.lastOrNull {
|
||||||
when (it) {
|
when (it) {
|
||||||
|
|||||||
+10
@@ -247,6 +247,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MANY_LAMBDA_EXPRE
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.METHOD_OF_ANY_IMPLEMENTED_IN_INTERFACE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISPLACED_TYPE_PARAMETER_CONSTRAINTS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISPLACED_TYPE_PARAMETER_CONSTRAINTS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MISSING_VAL_ON_ANNOTATION_PARAMETER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MULTIPLE_VARARG_PARAMETERS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.MUST_BE_INITIALIZED_OR_BE_ABSTRACT
|
||||||
@@ -264,6 +265,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_LOCAL_RETURN_NOT_ALLOWED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_LOCAL_SUSPENSION_POINT
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_LOCAL_SUSPENSION_POINT
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_MEMBER_FUNCTION_NO_BODY
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_MEMBER_FUNCTION_NO_BODY
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_ENUM
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_CONSTRUCTOR_IN_ENUM
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PRIVATE_OR_PROTECTED_CONSTRUCTOR_IN_SEALED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_PUBLIC_CALL_FROM_PUBLIC_INLINE
|
||||||
@@ -1497,6 +1499,14 @@ class FirDefaultErrorMessages {
|
|||||||
ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL,
|
ILLEGAL_RESTRICTED_SUSPENDING_FUNCTION_CALL,
|
||||||
"Restricted suspending functions can only invoke member or extension suspending functions on their restricted coroutine scope"
|
"Restricted suspending functions can only invoke member or extension suspending functions on their restricted coroutine scope"
|
||||||
)
|
)
|
||||||
|
map.put(
|
||||||
|
NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND,
|
||||||
|
"''suspend'' function can only be called in a form of modifier of a lambda: suspend { ... }"
|
||||||
|
)
|
||||||
|
map.put(
|
||||||
|
MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND,
|
||||||
|
"Calls having a form of ''suspend {}'' are deprecated because ''suspend'' in the context will have a meaning of a modifier. Add empty argument list to the call: ''suspend() { ... }''"
|
||||||
|
)
|
||||||
|
|
||||||
// Extended checkers group
|
// Extended checkers group
|
||||||
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
|
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
|
||||||
|
|||||||
Vendored
-76
@@ -1,76 +0,0 @@
|
|||||||
// !LANGUAGE: +ReleaseCoroutines
|
|
||||||
// SKIP_TXT
|
|
||||||
|
|
||||||
fun <R> suspend(block: suspend () -> R): suspend () -> R = block
|
|
||||||
|
|
||||||
class A {
|
|
||||||
infix fun <R> suspend(block: suspend () -> R): suspend () -> R = block
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.EXPRESSION)
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
annotation class Ann
|
|
||||||
|
|
||||||
fun bar() {
|
|
||||||
suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Ann suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend @Ann {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend() {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend({ println() })
|
|
||||||
|
|
||||||
suspend<Unit> {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
val w: (suspend () -> Int) -> Any? = ::suspend
|
|
||||||
|
|
||||||
A().suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
A().suspend() {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
A().suspend({ println() })
|
|
||||||
|
|
||||||
A().suspend<Unit> {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
with(A()) {
|
|
||||||
suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend() {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend({ println() })
|
|
||||||
|
|
||||||
suspend<Unit> {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
A() suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
A() suspend ({
|
|
||||||
println()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
Vendored
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +ReleaseCoroutines
|
// !LANGUAGE: +ReleaseCoroutines
|
||||||
// SKIP_TXT
|
// SKIP_TXT
|
||||||
|
|
||||||
|
|||||||
-84
@@ -1,84 +0,0 @@
|
|||||||
// !LANGUAGE: +ReleaseCoroutines
|
|
||||||
// SKIP_TXT
|
|
||||||
|
|
||||||
fun <R> suspend(block: R) = block
|
|
||||||
|
|
||||||
class A {
|
|
||||||
infix fun <R> suspend(block: R) = block
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.EXPRESSION)
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
annotation class Ann
|
|
||||||
|
|
||||||
fun bar() {
|
|
||||||
suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Ann suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend @Ann {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend() {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend({ println() })
|
|
||||||
|
|
||||||
suspend<suspend () -> Unit> {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend<Nothing?>(null)
|
|
||||||
|
|
||||||
val w: (Any?) -> Any? = ::suspend
|
|
||||||
|
|
||||||
A().suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
A().suspend() {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
A().suspend({ println() })
|
|
||||||
|
|
||||||
A().suspend<suspend () -> Unit> {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
A().suspend<Nothing?>(null)
|
|
||||||
|
|
||||||
with(A()) {
|
|
||||||
suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend() {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend({ println() })
|
|
||||||
|
|
||||||
suspend<suspend () -> Unit> {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend<Nothing?>(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
A() suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
A() suspend ({
|
|
||||||
println()
|
|
||||||
})
|
|
||||||
|
|
||||||
A() suspend ""
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +ReleaseCoroutines
|
// !LANGUAGE: +ReleaseCoroutines
|
||||||
// SKIP_TXT
|
// SKIP_TXT
|
||||||
|
|
||||||
|
|||||||
-45
@@ -1,45 +0,0 @@
|
|||||||
// !LANGUAGE: +ReleaseCoroutines
|
|
||||||
// SKIP_TXT
|
|
||||||
|
|
||||||
fun bar() {
|
|
||||||
suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Ann suspend {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend @Ann {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin.suspend {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend() {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend({ println() })
|
|
||||||
|
|
||||||
suspend<Unit> {
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
val w: (suspend () -> Int) -> Any? = ::suspend
|
|
||||||
}
|
|
||||||
|
|
||||||
@Target(AnnotationTarget.EXPRESSION)
|
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
|
||||||
annotation class Ann
|
|
||||||
|
|
||||||
fun main(suspend: WLambdaInvoke) {
|
|
||||||
|
|
||||||
suspend {}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WLambdaInvoke {
|
|
||||||
operator fun invoke(l: () -> Unit) {}
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !LANGUAGE: +ReleaseCoroutines
|
// !LANGUAGE: +ReleaseCoroutines
|
||||||
// SKIP_TXT
|
// SKIP_TXT
|
||||||
|
|
||||||
|
|||||||
+6
-6
@@ -8,23 +8,23 @@ fun bar() {
|
|||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin.suspend {
|
kotlin.<!NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND!>suspend<!> {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspendLambda {
|
<!NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND!>suspendLambda<!> {
|
||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspendLambda() {
|
<!NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND!>suspendLambda<!>() {
|
||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
|
|
||||||
suspendLambda({ println() })
|
<!NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND!>suspendLambda<!>({ println() })
|
||||||
|
|
||||||
suspendLambda<Unit> {
|
<!NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND!>suspendLambda<!><Unit> {
|
||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
|
|
||||||
val w: (suspend () -> Int) -> Any? = ::suspendLambda
|
val w: (suspend () -> Int) -> Any? = ::<!NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND!>suspendLambda<!>
|
||||||
}
|
}
|
||||||
|
|||||||
+12
@@ -3168,6 +3168,18 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.NON_MODIFIER_FORM_FOR_BUILT_IN_SUSPEND) { firDiagnostic ->
|
||||||
|
NonModifierFormForBuiltInSuspendImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
add(FirErrors.MODIFIER_FORM_FOR_NON_BUILT_IN_SUSPEND) { firDiagnostic ->
|
||||||
|
ModifierFormForNonBuiltInSuspendImpl(
|
||||||
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirJvmErrors.CONFLICTING_JVM_DECLARATIONS) { firDiagnostic ->
|
add(FirJvmErrors.CONFLICTING_JVM_DECLARATIONS) { firDiagnostic ->
|
||||||
ConflictingJvmDeclarationsImpl(
|
ConflictingJvmDeclarationsImpl(
|
||||||
firDiagnostic as FirPsiDiagnostic,
|
firDiagnostic as FirPsiDiagnostic,
|
||||||
|
|||||||
+8
@@ -2215,6 +2215,14 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
override val diagnosticClass get() = IllegalRestrictedSuspendingFunctionCall::class
|
override val diagnosticClass get() = IllegalRestrictedSuspendingFunctionCall::class
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class NonModifierFormForBuiltInSuspend : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = NonModifierFormForBuiltInSuspend::class
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class ModifierFormForNonBuiltInSuspend : KtFirDiagnostic<PsiElement>() {
|
||||||
|
override val diagnosticClass get() = ModifierFormForNonBuiltInSuspend::class
|
||||||
|
}
|
||||||
|
|
||||||
abstract class ConflictingJvmDeclarations : KtFirDiagnostic<PsiElement>() {
|
abstract class ConflictingJvmDeclarations : KtFirDiagnostic<PsiElement>() {
|
||||||
override val diagnosticClass get() = ConflictingJvmDeclarations::class
|
override val diagnosticClass get() = ConflictingJvmDeclarations::class
|
||||||
}
|
}
|
||||||
|
|||||||
+14
@@ -3575,6 +3575,20 @@ internal class IllegalRestrictedSuspendingFunctionCallImpl(
|
|||||||
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class NonModifierFormForBuiltInSuspendImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.NonModifierFormForBuiltInSuspend(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class ModifierFormForNonBuiltInSuspendImpl(
|
||||||
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
|
override val token: ValidityToken,
|
||||||
|
) : KtFirDiagnostic.ModifierFormForNonBuiltInSuspend(), KtAbstractFirDiagnostic<PsiElement> {
|
||||||
|
override val firDiagnostic: FirPsiDiagnostic by weakRef(firDiagnostic)
|
||||||
|
}
|
||||||
|
|
||||||
internal class ConflictingJvmDeclarationsImpl(
|
internal class ConflictingJvmDeclarationsImpl(
|
||||||
firDiagnostic: FirPsiDiagnostic,
|
firDiagnostic: FirPsiDiagnostic,
|
||||||
override val token: ValidityToken,
|
override val token: ValidityToken,
|
||||||
|
|||||||
Reference in New Issue
Block a user