diff --git a/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java b/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java index 4bcad0638a27..e1959e6d6bb4 100644 --- a/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java +++ b/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java @@ -16,8 +16,6 @@ package com.jetbrains.python.validation; import com.intellij.lang.ASTNode; -import com.intellij.lang.annotation.Annotation; -import com.intellij.psi.PsiElement; import com.jetbrains.python.PyNames; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; @@ -40,16 +38,8 @@ public class PyBuiltinAnnotator extends PyAnnotator { if (highlightedAsAttribute) { return; } - if (PyBuiltinCache.isInBuiltins(node) || PyUtil.isPy2ReservedWord(node)) { - final Annotation ann; - final PsiElement parent = node.getParent(); - if (parent instanceof PyDecorator) { - // don't mark the entire decorator, only mark the "@", else we'll conflict with deco annotator - addHighlightingAnnotation(parent.getFirstChild(), PyHighlighter.PY_BUILTIN_NAME); - } - else { - addHighlightingAnnotation(node, PyHighlighter.PY_BUILTIN_NAME); - } + if ((PyBuiltinCache.isInBuiltins(node) || PyUtil.isPy2ReservedWord(node)) && !(node.getParent() instanceof PyDecorator)) { + addHighlightingAnnotation(node, PyHighlighter.PY_BUILTIN_NAME); } } diff --git a/python/src/com/jetbrains/python/validation/PyDefinitionsAnnotator.java b/python/src/com/jetbrains/python/validation/PyDefinitionsAnnotator.java index cc7bf004789d..e3cfd4aba0c7 100644 --- a/python/src/com/jetbrains/python/validation/PyDefinitionsAnnotator.java +++ b/python/src/com/jetbrains/python/validation/PyDefinitionsAnnotator.java @@ -40,7 +40,7 @@ public class PyDefinitionsAnnotator extends PyAnnotator { @Override public void visitPyFunction(PyFunction node) { - ASTNode name_node = node.getNameNode(); + ASTNode name_node = node.getNameNode(); if (name_node != null) { final String name = node.getName(); LanguageLevel languageLevel = LanguageLevel.forElement(node); @@ -61,7 +61,9 @@ public class PyDefinitionsAnnotator extends PyAnnotator { addHighlightingAnnotation(name_node, PyHighlighter.PY_PREDEFINED_DEFINITION); } } - else addHighlightingAnnotation(name_node, PyHighlighter.PY_FUNC_DEFINITION); + else { + addHighlightingAnnotation(name_node, PyHighlighter.PY_FUNC_DEFINITION); + } } } @@ -69,7 +71,7 @@ public class PyDefinitionsAnnotator extends PyAnnotator { public void visitPyDecoratorList(PyDecoratorList node) { PyDecorator[] decos = node.getDecorators(); for (PyDecorator deco : decos) { - highlightDecorator(deco); + highlightDecorator(deco); } } diff --git a/python/testData/highlighting/builtinDecorator.py b/python/testData/highlighting/builtinDecorator.py new file mode 100644 index 000000000000..64ba47831ef1 --- /dev/null +++ b/python/testData/highlighting/builtinDecorator.py @@ -0,0 +1,13 @@ +@ foo +def f(): + pass + + +class C: + @ f + def bar(self): + pass + + @staticmethod + def bar(): + pass \ No newline at end of file diff --git a/python/testData/highlighting/builtins.py b/python/testData/highlighting/builtins.py index 36aa74f6fe8c..b152bdd128b1 100644 --- a/python/testData/highlighting/builtins.py +++ b/python/testData/highlighting/builtins.py @@ -12,7 +12,7 @@ len # no highlight class A(object): __metaclass__ = M # assignment target - @classmethod + @classmethod def foo(cls): pass diff --git a/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java b/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java index 72de2e84c24f..92552803d508 100644 --- a/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java +++ b/python/testSrc/com/jetbrains/python/PythonHighlightingTest.java @@ -346,6 +346,11 @@ public class PythonHighlightingTest extends PyTestCase { doTest(true, true); } + // PY-25381 + public void testBuiltinDecorator() { + doTest(true, true); + } + // PY-11418 public void testFunctionCalls() { doTest();