python.colors.parameters.self.parameter=Parameters//'self' parameter
python.colors.parameters.parameter=Parameters//Parameter
python.colors.functions.method.call=Functions//Method call
+python.colors.functions.nested.function.definition=Functions//Nested function definition
python.colors.functions.function.call=Functions//Function call
python.colors.functions.function.definition=Functions//Function definition
python.colors.braces.and.operators.dot=Braces and Operators//Dot
public static final TextAttributesKey PY_FUNC_DEFINITION = TextAttributesKey.createTextAttributesKey("PY.FUNC_DEFINITION", FUNCTION_DECLARATION);
+ public static final TextAttributesKey PY_NESTED_FUNC_DEFINITION = TextAttributesKey.createTextAttributesKey("PY.NESTED_FUNC_DEFINITION", PY_FUNC_DEFINITION);
+
public static final TextAttributesKey PY_PREDEFINED_DEFINITION = TextAttributesKey.createTextAttributesKey("PY.PREDEFINED_DEFINITION", PREDEFINED_SYMBOL);
public static final TextAttributesKey PY_PREDEFINED_USAGE = TextAttributesKey.createTextAttributesKey("PY.PREDEFINED_USAGE", PREDEFINED_SYMBOL);
new AttributesDescriptor(PyBundle.message("python.colors.braces.and.operators.dot"), PyHighlighter.PY_DOT),
new AttributesDescriptor(PyBundle.message("python.colors.functions.function.definition"), PyHighlighter.PY_FUNC_DEFINITION),
+ new AttributesDescriptor(PyBundle.message("python.colors.functions.nested.function.definition"), PyHighlighter.PY_NESTED_FUNC_DEFINITION),
new AttributesDescriptor(PyBundle.message("python.colors.functions.function.call"), PyHighlighter.PY_FUNCTION_CALL),
new AttributesDescriptor(PyBundle.message("python.colors.functions.method.call"), PyHighlighter.PY_METHOD_CALL),
.put("predefined", PyHighlighter.PY_PREDEFINED_DEFINITION)
.put("predefinedUsage", PyHighlighter.PY_PREDEFINED_USAGE)
.put("funcDef", PyHighlighter.PY_FUNC_DEFINITION)
+ .put("nestedFuncDef", PyHighlighter.PY_NESTED_FUNC_DEFINITION)
.put("classDef", PyHighlighter.PY_CLASS_DEFINITION)
.put("builtin", PyHighlighter.PY_BUILTIN_NAME)
.put("self", PyHighlighter.PY_SELF_PARAMETER)
"" +
RainbowHighlighter.generatePaletteExample("\n ") + "\n" +
" \"\"\"</docComment>\n" +
+ " def <nestedFuncDef>nested_func</nestedFuncDef>(<param>y</param>):\n" +
+ " <call>print</call>(<param>y</param> + 1)\n" +
" <localVar>s</localVar> = (\"Test\", 2+3, {'a': 'b'}, f'{<param>x</param>!s:{\"^10\"}}') # Comment\n" +
" <call>f</call>(<localVar>s</localVar>[0].<mcall>lower()</mcall>)\n" +
+ " <call>nested_func(42)</call>" +
"\n" +
"class <classDef>Foo</classDef>:\n" +
" tags: <annotation>List[<builtin>str</builtin>]</annotation>\n" +
" def <predefined>__init__</predefined>(<self>self</self>: <annotation>Foo</annotation>):\n" +
" <localVar>byte_string</localVar>: <annotation><builtin>bytes</builtin></annotation> = b'newline:\\n also newline:\\x0a'\n" +
" <localVar>text_string</localVar> = u\"Cyrillic Я is \\u042f. Oops: \\u042g\"\n" +
- " <self>self</self>.<mcall>makeSense</mcall>(<kwarg>whatever</kwarg>=1)\n" +
+ " <self>self</self>.<mcall>make_sense</mcall>(<kwarg>whatever</kwarg>=1)\n" +
" \n" +
- " def <funcDef>makeSense</funcDef>(<self>self</self>, <param>whatever</param>):\n" +
+ " def <funcDef>make_sense</funcDef>(<self>self</self>, <param>whatever</param>):\n" +
" <self>self</self>.sense = <param>whatever</param>\n" +
"\n" +
"<localVar>x</localVar> = <builtin>len</builtin>('abc')\n" +
import com.intellij.lang.ASTNode;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.python.PyNames;
+import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
+import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.highlighting.PyHighlighter;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
@Override
public void visitPyFunction(PyFunction node) {
- ASTNode name_node = node.getNameNode();
- if (name_node != null) {
+ ASTNode nameNode = node.getNameNode();
+ if (nameNode != null) {
final String name = node.getName();
LanguageLevel languageLevel = LanguageLevel.forElement(node);
if (PyNames.UNDERSCORED_ATTRIBUTES.contains(name) || PyNames.getBuiltinMethods(languageLevel).containsKey(name)) {
catch (IndexNotReadyException ignored) {
}
if (new_style_class) {
- addHighlightingAnnotation(name_node, PyHighlighter.PY_PREDEFINED_DEFINITION);
+ addHighlightingAnnotation(nameNode, PyHighlighter.PY_PREDEFINED_DEFINITION);
}
}
else {
- addHighlightingAnnotation(name_node, PyHighlighter.PY_PREDEFINED_DEFINITION);
+ addHighlightingAnnotation(nameNode, PyHighlighter.PY_PREDEFINED_DEFINITION);
}
}
else {
- addHighlightingAnnotation(name_node, PyHighlighter.PY_FUNC_DEFINITION);
+ if (ScopeUtil.getScopeOwner(node) instanceof PyFunction) {
+ addHighlightingAnnotation(nameNode, PyHighlighter.PY_NESTED_FUNC_DEFINITION);
+ }
+ else {
+ addHighlightingAnnotation(nameNode, PyHighlighter.PY_FUNC_DEFINITION);
+ }
}
}
}
<error descr="Indent expected">d</error>ef <info descr="PY.FUNC_DEFINITION">regular</info>(<info descr="PY.PARAMETER">xs</info>):
- <info descr="null">async</info> def <info descr="PY.FUNC_DEFINITION">quux</info>():
+ <info descr="null">async</info> def <info descr="PY.NESTED_FUNC_DEFINITION">quux</info>():
<info descr="null">async</info> for x in xs:
pass
--- /dev/null
+# func declarations are red
+def <info descr="PY.FUNC_DEFINITION" foreground="0xff0000" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">foo</info>():
+ def <info descr="PY.NESTED_FUNC_DEFINITION" foreground="0x00ff00" background="0x0000ff" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">nested</info>():
+ return 42
+ return <info descr="PY.BUILTIN_NAME">False</info>
+
+
+def <info descr="PY.FUNC_DEFINITION" foreground="0xff0000" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">bar</info>():
+ class <info descr="PY.CLASS_DEFINITION" type="INFORMATION" foreground="0x0000ff" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">Clzz</info>:
+ def <info descr="PY.FUNC_DEFINITION" foreground="0xff0000" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">baz</info>():
+ return 42
+ return <info descr="PY.BUILTIN_NAME">False</info>
# func declarations are red
def <info descr="PY.FUNC_DEFINITION" foreground="0xff0000" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">foo</info>():
- def <info descr="PY.FUNC_DEFINITION" foreground="0xff0000" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">a</info>():
+ def <info descr="PY.NESTED_FUNC_DEFINITION" foreground="0xff0000" background="0x000000" effectcolor="0xffffff" effecttype="BOXED" fonttype="1">a</info>():
yield 1
return <info descr="PY.BUILTIN_NAME">False</info>
doTest();
}
+ // PY-33235
+ public void testNestedFunction() {
+ EditorColorsScheme scheme = createTemporaryColorScheme();
+
+ TextAttributesKey xKey = TextAttributesKey.find("PY.CLASS_DEFINITION");
+ TextAttributes xAttributes = new TextAttributes(Color.blue, Color.black, Color.white, EffectType.BOXED, Font.BOLD);
+ scheme.setAttributes(xKey, xAttributes);
+
+ xKey = TextAttributesKey.find("PY.FUNC_DEFINITION");
+ xAttributes = new TextAttributes(Color.red, Color.black, Color.white, EffectType.BOXED, Font.BOLD);
+ scheme.setAttributes(xKey, xAttributes);
+
+ xKey = TextAttributesKey.find("PY.NESTED_FUNC_DEFINITION");
+ xAttributes = new TextAttributes(Color.green, Color.blue, Color.white, EffectType.BOXED, Font.BOLD);
+ scheme.setAttributes(xKey, xAttributes);
+
+ doTest();
+ }
+
public void testAsync() {
doTest(LanguageLevel.PYTHON35, true, true);
}