FIR: introduce NON_LOCAL_SUSPENSION_POINT diagnostic
This commit is contained in:
committed by
teamcityserver
parent
8f1d07084b
commit
2397650c24
+1
@@ -1190,6 +1190,7 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
||||
val ILLEGAL_SUSPEND_PROPERTY_ACCESS by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
|
||||
parameter<Symbol>("suspendCallable")
|
||||
}
|
||||
val NON_LOCAL_SUSPENSION_POINT by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -610,5 +610,6 @@ object FirErrors {
|
||||
// Suspend errors
|
||||
val ILLEGAL_SUSPEND_FUNCTION_CALL 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)
|
||||
|
||||
}
|
||||
|
||||
+14
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.types.coneType
|
||||
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_3_FQ_NAME
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
|
||||
|
||||
object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||
private val SUSPEND_PROPERTIES_FQ_NAMES = setOf(
|
||||
@@ -48,6 +49,10 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||
else -> {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!checkNonLocalReturnUsage(enclosingSuspendFunction, context)) {
|
||||
reporter.reportOn(expression.source, FirErrors.NON_LOCAL_SUSPENSION_POINT, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,4 +65,13 @@ object FirSuspendCallChecker : FirQualifiedAccessExpressionChecker() {
|
||||
}
|
||||
} as? FirFunction
|
||||
}
|
||||
|
||||
private fun checkNonLocalReturnUsage(enclosingSuspendFunction: FirFunction, context: CheckerContext): Boolean {
|
||||
val containingFunction = context.containingDeclarations.lastIsInstanceOrNull<FirFunction>() ?: return false
|
||||
return if (containingFunction is FirAnonymousFunction && enclosingSuspendFunction !== containingFunction) {
|
||||
containingFunction.inlineStatus.returnAllowed
|
||||
} else {
|
||||
enclosingSuspendFunction === containingFunction
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -261,6 +261,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_EXHAUSTIVE_WH
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_FINAL_CLASS
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.NON_FINAL_MEMBER_IN_OBJECT
|
||||
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_MEMBER_FUNCTION_NO_BODY
|
||||
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
|
||||
@@ -1490,6 +1491,7 @@ class FirDefaultErrorMessages {
|
||||
"Suspend property ''{0}'' should be accessed only from a coroutine or suspend function",
|
||||
SYMBOL
|
||||
)
|
||||
map.put(NON_LOCAL_SUSPENSION_POINT, "Suspension functions can be called only within coroutine body")
|
||||
|
||||
// Extended checkers group
|
||||
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
|
||||
|
||||
Reference in New Issue
Block a user