get rid of SyntaxMatchers and MatcherBasedFilter

This commit is contained in:
Dmitry Jemerov
2011-09-12 18:20:06 +02:00
parent ab7329d8d3
commit 0a005ca5f8
4 changed files with 33 additions and 27 deletions
@@ -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;
}
}
@@ -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<? extends PsiElement> place = SyntaxMatchers.DEEP_IN_METHOD.search(node);
List<? extends PsiElement> 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);
@@ -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<PsiElement> searchForWrappingMethod(PsiElement start, boolean deep) {
PsiElement seeker = start;
List<PsiElement> ret = new ArrayList<PsiElement>(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);
@@ -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<? extends PsiElement> match = SyntaxMatchers.DEEP_IN_METHOD.search(qualifier);
final List<? extends PsiElement> match = PyUtil.searchForWrappingMethod(qualifier, true);
if (match == null || (match.size() > 1 && ((PyClassType)qualifierType).getPyClass() != match.get(match.size() - 1))) {
return Collections.emptyList();
}