diff --git a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java index 76b59b4ade92..b06a549f2f69 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java +++ b/python/src/com/jetbrains/python/codeInsight/PyDunderAllReference.java @@ -1,13 +1,21 @@ package com.jetbrains.python.codeInsight; +import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiNamedElement; import com.intellij.psi.PsiReferenceBase; +import com.intellij.psi.ResolveState; +import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.util.ArrayUtil; import com.jetbrains.python.psi.PyFile; import com.jetbrains.python.psi.PyStringLiteralExpression; +import com.jetbrains.python.psi.PyUtil; +import com.jetbrains.python.psi.impl.LightNamedElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; import java.util.List; /** @@ -33,6 +41,30 @@ public class PyDunderAllReference extends PsiReferenceBase result = new ArrayList(); + PyFile containingFile = (PyFile) getElement().getContainingFile().getOriginalFile(); + final List dunderAll = containingFile.getDunderAll(); + containingFile.processDeclarations(new PsiScopeProcessor() { + @Override + public boolean execute(PsiElement element, ResolveState state) { + if (element instanceof PsiNamedElement && !(element instanceof LightNamedElement)) { + final String name = ((PsiNamedElement)element).getName(); + if (name != null && PyUtil.getInitialUnderscores(name) == 0 && (dunderAll == null || !dunderAll.contains(name))) { + result.add(element); + } + } + return true; + } + + @Override + public T getHint(Key hintKey) { + return null; + } + + @Override + public void handleEvent(Event event, @Nullable Object associated) { + } + }, ResolveState.initial(), null, containingFile); + return ArrayUtil.toObjectArray(result); } } diff --git a/python/testData/completion/dunderAllReference.after.py b/python/testData/completion/dunderAllReference.after.py new file mode 100644 index 000000000000..a22fb0ad80ad --- /dev/null +++ b/python/testData/completion/dunderAllReference.after.py @@ -0,0 +1,4 @@ +__all__ = ['xyzzy'] + +def xyzzy(): + pass \ No newline at end of file diff --git a/python/testData/completion/dunderAllReference.py b/python/testData/completion/dunderAllReference.py new file mode 100644 index 000000000000..c35270431971 --- /dev/null +++ b/python/testData/completion/dunderAllReference.py @@ -0,0 +1,4 @@ +__all__ = ['xy'] + +def xyzzy(): + pass \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java index 23e628062221..d11717b76b48 100644 --- a/python/testSrc/com/jetbrains/python/PythonCompletionTest.java +++ b/python/testSrc/com/jetbrains/python/PythonCompletionTest.java @@ -512,4 +512,8 @@ public class PythonCompletionTest extends PyTestCase { final List strings = myFixture.getLookupElementStrings(); assertFalse(strings.contains("mro")); } + + public void testDunderAllReference() { // PY-5502 + doTest(); + } }