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();