From 0a005ca5f8148bf5780af318d2dcf8a93b01d0f2 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Mon, 12 Sep 2011 17:27:31 +0200 Subject: [PATCH] get rid of SyntaxMatchers and MatcherBasedFilter --- .../completion/MatcherBasedFilter.java | 23 -------------- .../PyMethodFirstArgAssignmentInspection.java | 3 +- .../src/com/jetbrains/python/psi/PyUtil.java | 31 +++++++++++++++++++ .../psi/impl/PyQualifiedReferenceImpl.java | 3 +- 4 files changed, 33 insertions(+), 27 deletions(-) delete mode 100644 python/src/com/jetbrains/python/codeInsight/completion/MatcherBasedFilter.java diff --git a/python/src/com/jetbrains/python/codeInsight/completion/MatcherBasedFilter.java b/python/src/com/jetbrains/python/codeInsight/completion/MatcherBasedFilter.java deleted file mode 100644 index 32b77fcfb703..000000000000 --- a/python/src/com/jetbrains/python/codeInsight/completion/MatcherBasedFilter.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.jetbrains.python.codeInsight.completion; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.filters.ElementFilter; -import com.jetbrains.python.psi.patterns.Matcher; - -/** -* Filter that relies on a {@link Matcher}. -* User: dcheryasov -* Date: Dec 3, 2009 11:09:21 AM -*/ -abstract class MatcherBasedFilter implements ElementFilter { - - abstract Matcher getMatcher(); - - public boolean isAcceptable(Object element, PsiElement context) { - return ((element instanceof PsiElement) && getMatcher().search((PsiElement)element) != null); - } - - public boolean isClassAcceptable(Class hintClass) { - return true; - } -} diff --git a/python/src/com/jetbrains/python/inspections/PyMethodFirstArgAssignmentInspection.java b/python/src/com/jetbrains/python/inspections/PyMethodFirstArgAssignmentInspection.java index cc98c2c9508b..695d5a0e332d 100644 --- a/python/src/com/jetbrains/python/inspections/PyMethodFirstArgAssignmentInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyMethodFirstArgAssignmentInspection.java @@ -6,7 +6,6 @@ import com.intellij.psi.PsiElementVisitor; import com.jetbrains.python.PyBundle; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.psi.*; -import com.jetbrains.python.psi.patterns.SyntaxMatchers; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -49,7 +48,7 @@ public class PyMethodFirstArgAssignmentInspection extends PyInspection { @Nullable private static String extractFirstParamName(PyElement node) { // are we a method? - List place = SyntaxMatchers.DEEP_IN_METHOD.search(node); + List place = PyUtil.searchForWrappingMethod(node, true); if (place == null || place.size() < 2) return null; PyFunction method = (PyFunction)place.get(place.size()-2); //PyClass owner = (PyClass)place.get(place.size()-1); diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 6c6f425b28c4..63a0adb91bda 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -543,6 +543,37 @@ public class PyUtil { return false; } + /** + * Searhes for a method wrapping given element. + * @param start element presumably inside a method + * @param deep if true, allow 'start' to be inside functions nested in a method; else, 'start' must be directly inside a method. + * @return if not 'deep', [0] is the method and [1] is the class; if 'deep', first several elements may be the nested functions, + * the last but one is the method, and the last is the class. + */ + @Nullable + public static List searchForWrappingMethod(PsiElement start, boolean deep) { + PsiElement seeker = start; + List ret = new ArrayList(2); + while (seeker != null) { + PyFunction func = PsiTreeUtil.getParentOfType(seeker, PyFunction.class, true, PyClass.class); + if (func != null) { + PyClass cls = func.getContainingClass(); + if (cls != null) { + ret.add(func); + ret.add(cls); + return ret; + } + else if (deep) { + ret.add(func); + seeker = func; + } + else return null; // no immediate class + } + else return null; // no function + } + return null; + } + public static class KnownDecoratorProviderHolder { public static PyKnownDecoratorProvider[] KNOWN_DECORATOR_PROVIDERS = Extensions.getExtensions(PyKnownDecoratorProvider.EP_NAME); diff --git a/python/src/com/jetbrains/python/psi/impl/PyQualifiedReferenceImpl.java b/python/src/com/jetbrains/python/psi/impl/PyQualifiedReferenceImpl.java index 9059fa413899..05632bab9077 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyQualifiedReferenceImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyQualifiedReferenceImpl.java @@ -19,7 +19,6 @@ import com.intellij.util.indexing.FileBasedIndex; import com.jetbrains.python.PyNames; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.psi.*; -import com.jetbrains.python.psi.patterns.SyntaxMatchers; import com.jetbrains.python.psi.resolve.*; import com.jetbrains.python.psi.stubs.PyClassNameIndex; import com.jetbrains.python.psi.stubs.PyClassNameIndexInsensitive; @@ -54,7 +53,7 @@ public class PyQualifiedReferenceImpl extends PyReferenceImpl { PyType qualifierType = myContext.getTypeEvalContext().getType(qualifier); // is it a class-private name qualified by a different class? if (PyUtil.isClassPrivateName(referencedName) && qualifierType instanceof PyClassType) { - final List match = SyntaxMatchers.DEEP_IN_METHOD.search(qualifier); + final List match = PyUtil.searchForWrappingMethod(qualifier, true); if (match == null || (match.size() > 1 && ((PyClassType)qualifierType).getPyClass() != match.get(match.size() - 1))) { return Collections.emptyList(); }