PY-71549 Move async-related check from PyKeywordHighlightingAnnotator to PyAsyncAwaitAnnotatorVisitor

It also caused double highlighting on the frontend as PyKeywordHighlightingAnnotator is currently registered in both frontend and backend.

GitOrigin-RevId: cdf111acfdb8a979613007e12abcf6c7dac9c9dd
This commit is contained in:
Petr
2025-07-15 11:17:13 +00:00
committed by intellij-monorepo-bot
parent efc364c13f
commit 2402957c9d
4 changed files with 16 additions and 11 deletions
@@ -170,6 +170,7 @@ ANN.continue.break.or.return.in.star.except='break', 'continue' and 'return' can
ANN.await.outside.async.function='await' outside async function
ANN.async.with.outside.function='async with' outside async function
ANN.async.for.outside.function='async for' outside async function
ANN.function.cannot.be.async=function \"{0}\" cannot be async
QFIX.convert.into.async.function=Convert to async function
### quick doc generator
@@ -8,12 +8,15 @@ import com.intellij.modcommand.ModPsiUpdater;
import com.intellij.modcommand.PsiUpdateModCommandAction;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.PyPsiBundle;
import com.jetbrains.python.PySyntaxCoreBundle;
import com.jetbrains.python.PyTokenTypes;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
import java.util.Optional;
public final class PyAsyncAwaitAnnotatorVisitor extends PyElementVisitor {
private final @NotNull PyAnnotationHolder myHolder;
@@ -102,6 +105,18 @@ public final class PyAsyncAwaitAnnotatorVisitor extends PyElementVisitor {
checkComprehension(node);
}
@Override
public void visitPyFunction(@NotNull PyFunction node) {
if (!node.isAsyncAllowed()) {
Optional
.ofNullable(node.getNode())
.map(astNode -> astNode.findChildByType(PyTokenTypes.ASYNC_KEYWORD))
.ifPresent(asyncNode -> myHolder.newAnnotation(HighlightSeverity.ERROR,
PyPsiBundle.message("ANN.function.cannot.be.async", node.getName()))
.range(asyncNode).create());
}
}
private static class ConvertIntoAsyncFunctionFix extends PsiUpdateModCommandAction<PyFunction> {
protected ConvertIntoAsyncFunctionFix(@NotNull PyFunction element) {
super(element);
@@ -1,6 +1,3 @@
### Annotators ###
ANN.function.cannot.be.async=function \"{0}\" cannot be async
### Formatter
formatter.panel.dict.alignment.do.not.align=Do not align
formatter.panel.dict.alignment.align.on.colon=Align on colon
@@ -55,14 +55,6 @@ public final class PyKeywordHighlightingAnnotator extends PyAnnotatorBase implem
if (node.isAsyncAllowed()) {
highlightKeyword(node, PyTokenTypes.ASYNC_KEYWORD);
}
else {
Optional
.ofNullable(node.getNode())
.map(astNode -> astNode.findChildByType(PyTokenTypes.ASYNC_KEYWORD))
.ifPresent(asyncNode -> myHolder.newAnnotation(HighlightSeverity.ERROR,
PySyntaxCoreBundle.message("ANN.function.cannot.be.async", node.getName()))
.range(asyncNode).create());
}
}
@Override