From 680a841d5a01935392db68faa3b65a0f15076907 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Fri, 1 Mar 2013 09:50:47 +0100 Subject: [PATCH] correctly highlight __nonzero__ and __bool__ depending on language level (PY-9023) --- .../src/com/jetbrains/python/PyNames.java | 18 ++++++++++++++++-- ...pecialMethodNamesCompletionContributor.java | 7 ++++--- .../PySuperMethodCompletionContributor.java | 4 +++- .../python/validation/PyBuiltinAnnotator.java | 3 ++- .../validation/PyDefinitionsAnnotator.java | 8 +++----- 5 files changed, 28 insertions(+), 12 deletions(-) diff --git a/python/psi-api/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java index 0e7ef7181afe..5b1eb98bf5d4 100644 --- a/python/psi-api/src/com/jetbrains/python/PyNames.java +++ b/python/psi-api/src/com/jetbrains/python/PyNames.java @@ -2,6 +2,7 @@ package com.jetbrains.python; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import com.jetbrains.python.psi.LanguageLevel; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -187,7 +188,7 @@ public class PyNames { private static final BuiltinDescription _self_item_descr = new BuiltinDescription("(self, item)"); private static final BuiltinDescription _self_key_descr = new BuiltinDescription("(self, key)"); - public static final ImmutableMap BuiltinMethods = ImmutableMap.builder() + private static final ImmutableMap BuiltinMethods = ImmutableMap.builder() .put("__abs__", _only_self_descr) .put("__add__", _self_other_descr) .put("__and__", _self_other_descr) @@ -260,7 +261,6 @@ public class PyNames { .put("__ne__", _self_other_descr) .put("__neg__", _only_self_descr) .put(NEW, new BuiltinDescription("(cls, *args, **kwargs)")) - .put("__nonzero__", _only_self_descr) .put("__oct__", _only_self_descr) .put("__or__", _self_other_descr) //_BuiltinMethods.put("__path__", _only_self_descr); @@ -297,6 +297,20 @@ public class PyNames { .put("__xor__", _self_other_descr) .build(); + public static ImmutableMap PY2_BUILTIN_METHODS = ImmutableMap.builder() + .putAll(BuiltinMethods) + .put("__nonzero__", _only_self_descr) + .build(); + + public static ImmutableMap PY3_BUILTIN_METHODS = ImmutableMap.builder() + .putAll(BuiltinMethods) + .put("__bool__", _only_self_descr) + .build(); + + public static ImmutableMap getBuiltinMethods(LanguageLevel level) { + return level.isPy3K() ? PY3_BUILTIN_METHODS : PY2_BUILTIN_METHODS; + } + // canonical names, not forced by interpreter public static final String CANONICAL_SELF = "self"; public static final String BASESTRING = "basestring"; diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PySpecialMethodNamesCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PySpecialMethodNamesCompletionContributor.java index 130306020fd8..5275c072f9d6 100644 --- a/python/src/com/jetbrains/python/codeInsight/completion/PySpecialMethodNamesCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/completion/PySpecialMethodNamesCompletionContributor.java @@ -8,6 +8,7 @@ import com.intellij.codeInsight.lookup.TailTypeDecorator; import com.intellij.util.ProcessingContext; import com.jetbrains.python.PyNames; import com.jetbrains.python.PythonLanguage; +import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyFunction; import icons.PythonIcons; @@ -45,9 +46,9 @@ public class PySpecialMethodNamesCompletionContributor extends CompletionContrib protected void addCompletions( @NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result ) { - for (Map.Entry entry: PyNames.BuiltinMethods.entrySet()) { - LookupElementBuilder item; - item = LookupElementBuilder + LanguageLevel languageLevel = LanguageLevel.forElement(parameters.getOriginalFile()); + for (Map.Entry entry: PyNames.getBuiltinMethods(languageLevel).entrySet()) { + LookupElementBuilder item = LookupElementBuilder .create(entry.getKey() + entry.getValue().getSignature()) .bold() .withTypeText("predefined") diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java index 8a4032b80631..197220f10607 100644 --- a/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java @@ -10,6 +10,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ProcessingContext; import com.jetbrains.python.PyNames; import com.jetbrains.python.PyTokenTypes; +import com.jetbrains.python.psi.LanguageLevel; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyFunction; import org.jetbrains.annotations.NotNull; @@ -44,7 +45,8 @@ public class PySuperMethodCompletionContributor extends CompletionContributor { for (PyFunction function : containingClass.getMethods()) { seenNames.add(function.getName()); } - seenNames.addAll(PyNames.BuiltinMethods.keySet()); + LanguageLevel languageLevel = LanguageLevel.forElement(parameters.getOriginalFile()); + seenNames.addAll(PyNames.getBuiltinMethods(languageLevel).keySet()); for (PyClass ancestor : containingClass.iterateAncestorClasses()) { for (PyFunction superMethod : ancestor.getMethods()) { if (!seenNames.contains(superMethod.getName())) { diff --git a/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java b/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java index e7572433420b..b952ef67f01e 100644 --- a/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java +++ b/python/src/com/jetbrains/python/validation/PyBuiltinAnnotator.java @@ -52,7 +52,8 @@ public class PyBuiltinAnnotator extends PyAnnotator { * @return true iff the node was highlighted. */ private boolean highlightAsAttribute(PyQualifiedExpression node, String name) { - if (PyNames.UnderscoredAttributes.contains(name) || PyNames.BuiltinMethods.containsKey(name)) { + LanguageLevel languageLevel = LanguageLevel.forElement(node); + if (PyNames.UnderscoredAttributes.contains(name) || PyNames.getBuiltinMethods(languageLevel).containsKey(name)) { // things like __len__ if ( (node.getQualifier() != null) // foo.__len__ diff --git a/python/src/com/jetbrains/python/validation/PyDefinitionsAnnotator.java b/python/src/com/jetbrains/python/validation/PyDefinitionsAnnotator.java index 53fded84244e..7893c8f52c27 100644 --- a/python/src/com/jetbrains/python/validation/PyDefinitionsAnnotator.java +++ b/python/src/com/jetbrains/python/validation/PyDefinitionsAnnotator.java @@ -6,10 +6,7 @@ import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.psi.PsiElement; import com.jetbrains.python.highlighting.PyHighlighter; import com.jetbrains.python.PyNames; -import com.jetbrains.python.psi.PyClass; -import com.jetbrains.python.psi.PyDecorator; -import com.jetbrains.python.psi.PyDecoratorList; -import com.jetbrains.python.psi.PyFunction; +import com.jetbrains.python.psi.*; /** * Highlights class definitions, functrion definitions, and decorators. @@ -33,7 +30,8 @@ public class PyDefinitionsAnnotator extends PyAnnotator { if (name_node != null) { Annotation ann = getHolder().createInfoAnnotation(name_node, null); final String name = node.getName(); - if (PyNames.UnderscoredAttributes.contains(name) || PyNames.BuiltinMethods.containsKey(name)) { + LanguageLevel languageLevel = LanguageLevel.forElement(node); + if (PyNames.UnderscoredAttributes.contains(name) || PyNames.getBuiltinMethods(languageLevel).containsKey(name)) { PyClass cls = node.getContainingClass(); if (PyNames.NEW.equals(name)) { boolean new_style_class = false;