diff --git a/python/src/com/jetbrains/python/psi/PyResolveUtil.java b/python/src/com/jetbrains/python/psi/PyResolveUtil.java index 0fa14a7c4628..a9bdf21a6721 100644 --- a/python/src/com/jetbrains/python/psi/PyResolveUtil.java +++ b/python/src/com/jetbrains/python/psi/PyResolveUtil.java @@ -302,7 +302,7 @@ public class PyResolveUtil { static String _nvl(Object s) { if (s != null) return "'" + s.toString() + "'"; - else return "null"; + else return "null"; // TODO: move to PyNames } public Set getSeen() { @@ -373,21 +373,6 @@ public class PyResolveUtil { } - // NOTE: unused now - /** - * Looks at an element and says if looking at it worthy. - * Used to break circular attempts to resolve names imported into __init__.py inside it again. - * @param element to be analyzed and probably remembered. - * @return true if execute() may be tried with this element; else treeWalkUp and the like should immediately return negative result. - */ - public boolean approve(PsiElement element) { - if ((element instanceof PyFile) && (ResolveImportUtil.INIT_PY.equals(((PyFile)element).getName()))) { - String fname = ((PyFile)element).getUrl(); - if (mySeen.contains(fname)) return false; // already seen it, may not try again - else mySeen.add(fname); - } - return true; - } } public static class MultiResolveProcessor implements PsiScopeProcessor { @@ -432,6 +417,16 @@ public class PyResolveUtil { protected String my_notice; + public VariantsProcessor() { + // empty + } + + public VariantsProcessor(final Filter filter) { + my_filter = filter; + } + + protected Filter my_filter; + public void setNotice(@Nullable String notice) { my_notice = notice; } @@ -457,6 +452,7 @@ public class PyResolveUtil { } public boolean execute(PsiElement element, ResolveState substitutor) { + if (my_filter != null && !my_filter.accept(element)) return true; // skip whatever the filter rejects // TODO: refactor to look saner; much code duplication if (element instanceof PsiNamedElement) { final PsiNamedElement psiNamedElement = (PsiNamedElement)element; @@ -511,4 +507,27 @@ public class PyResolveUtil { public void handleEvent(Event event, Object associated) { } } + + /** + * A simple interface allowing to filter processor results. + */ + public interface Filter { + /** + * @param target the object a processor is currently looking at. + * @return true if the object is acceptable as a processor result. + */ + boolean accept(Object target); + } + + public static class FilterNotInstance implements Filter { + Object instance; + + public FilterNotInstance(Object instance) { + this.instance = instance; + } + + public boolean accept(final Object target) { + return (instance != target); + } + } } diff --git a/python/src/com/jetbrains/python/psi/types/PyClassType.java b/python/src/com/jetbrains/python/psi/types/PyClassType.java index 97c49a3f3255..119f475ca440 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassType.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassType.java @@ -94,7 +94,7 @@ public class PyClassType implements PyType { } public Object[] getCompletionVariants(final PyReferenceExpression referenceExpression) { - final PyResolveUtil.VariantsProcessor processor = new PyResolveUtil.VariantsProcessor(); + final PyResolveUtil.VariantsProcessor processor = new PyResolveUtil.VariantsProcessor(new PyResolveUtil.FilterNotInstance(myClass)); myClass.processDeclarations(processor, ResolveState.initial(), null, referenceExpression); List ret = new ArrayList(); ret.addAll(processor.getResultList());