diff --git a/python/src/com/jetbrains/python/PyNames.java b/python/src/com/jetbrains/python/PyNames.java index f1c93ab8b0c9..9b7c3c85fb72 100644 --- a/python/src/com/jetbrains/python/PyNames.java +++ b/python/src/com/jetbrains/python/PyNames.java @@ -60,6 +60,8 @@ public class PyNames { public static final String DEPRECATION_WARNING = "DeprecationWarning"; public static final String PENDING_DEPRECATION_WARNING = "PendingDeprecationWarning"; + public static final String NAME = "__name__"; + /** * Contains all known predefined names of "__foo__" form. */ diff --git a/python/src/com/jetbrains/python/psi/PyFileElementType.java b/python/src/com/jetbrains/python/psi/PyFileElementType.java index d09cae9afe8a..a08e015b04de 100644 --- a/python/src/com/jetbrains/python/psi/PyFileElementType.java +++ b/python/src/com/jetbrains/python/psi/PyFileElementType.java @@ -43,7 +43,7 @@ public class PyFileElementType extends IStubFileElementType { @Override public int getStubVersion() { - return 34; + return 35; } @Override diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 011d3bc522c7..2af5450416d5 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -506,6 +506,28 @@ public class PyUtil { return null; } + public static boolean isIfNameEqualsMain(PyIfStatement ifStatement) { + final PyExpression condition = ifStatement.getIfPart().getCondition(); + return isNameEqualsMain(condition); + } + + private static boolean isNameEqualsMain(PyExpression condition) { + if (condition instanceof PyParenthesizedExpression) { + return isNameEqualsMain(((PyParenthesizedExpression) condition).getContainedExpression()); + } + if (condition instanceof PyBinaryExpression) { + PyBinaryExpression binaryExpression = (PyBinaryExpression)condition; + if (binaryExpression.getOperator() == PyTokenTypes.OR_KEYWORD) { + return isNameEqualsMain(binaryExpression.getLeftExpression()) || isNameEqualsMain(binaryExpression.getRightExpression()); + } + final PyExpression rhs = binaryExpression.getRightExpression(); + return binaryExpression.getOperator() == PyTokenTypes.EQEQ && + binaryExpression.getLeftExpression().getText().equals(PyNames.NAME) && + rhs != null && rhs.getText().contains("__main__"); + } + return false; + } + 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/stubs/PyFileStubBuilder.java b/python/src/com/jetbrains/python/psi/impl/stubs/PyFileStubBuilder.java index aa49a84a43e6..dbbd8ce73b0a 100644 --- a/python/src/com/jetbrains/python/psi/impl/stubs/PyFileStubBuilder.java +++ b/python/src/com/jetbrains/python/psi/impl/stubs/PyFileStubBuilder.java @@ -1,9 +1,12 @@ package com.jetbrains.python.psi.impl.stubs; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.stubs.DefaultStubBuilder; import com.intellij.psi.stubs.StubElement; import com.jetbrains.python.psi.PyFile; +import com.jetbrains.python.psi.PyIfStatement; +import com.jetbrains.python.psi.PyUtil; /** * @author yole @@ -17,4 +20,12 @@ public class PyFileStubBuilder extends DefaultStubBuilder { return super.createStubForFile(file); } + + @Override + protected boolean skipChildProcessingWhenBuildingStubs(PsiElement element, PsiElement child) { + if (element instanceof PyIfStatement) { + return PyUtil.isIfNameEqualsMain((PyIfStatement)element); + } + return false; + } } diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestRunnableScriptFilter.java b/python/src/com/jetbrains/python/testing/PythonUnitTestRunnableScriptFilter.java index 88e6e14f4884..5c2108ceb2c0 100644 --- a/python/src/com/jetbrains/python/testing/PythonUnitTestRunnableScriptFilter.java +++ b/python/src/com/jetbrains/python/testing/PythonUnitTestRunnableScriptFilter.java @@ -5,11 +5,7 @@ import com.intellij.openapi.module.Module; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; -import com.jetbrains.python.PyTokenTypes; -import com.jetbrains.python.psi.PyBinaryExpression; -import com.jetbrains.python.psi.PyExpression; -import com.jetbrains.python.psi.PyFile; -import com.jetbrains.python.psi.PyIfStatement; +import com.jetbrains.python.psi.*; import com.jetbrains.python.run.RunnableScriptFilter; import org.jetbrains.annotations.NotNull; @@ -32,14 +28,7 @@ public class PythonUnitTestRunnableScriptFilter implements RunnableScriptFilter } if (element instanceof PyIfStatement) { PyIfStatement ifStatement = (PyIfStatement)element; - final PyExpression condition = ifStatement.getIfPart().getCondition(); - if (condition instanceof PyBinaryExpression) { - PyBinaryExpression binaryExpression = (PyBinaryExpression)condition; - final PyExpression rhs = binaryExpression.getRightExpression(); - return binaryExpression.getOperator() == PyTokenTypes.EQEQ && - binaryExpression.getLeftExpression().getText().equals("__name__") && - rhs != null && rhs.getText().contains("__main__"); - } + return PyUtil.isIfNameEqualsMain(ifStatement); } return false; } diff --git a/python/testData/stubs/IfNameMain.py b/python/testData/stubs/IfNameMain.py new file mode 100644 index 000000000000..8f5d89eecafa --- /dev/null +++ b/python/testData/stubs/IfNameMain.py @@ -0,0 +1,2 @@ +if __name__ == '__main__': + xyzzy = None diff --git a/python/testSrc/com/jetbrains/python/PyStubsTest.java b/python/testSrc/com/jetbrains/python/PyStubsTest.java index 0832f25a2e8e..1bfb7b07e970 100644 --- a/python/testSrc/com/jetbrains/python/PyStubsTest.java +++ b/python/testSrc/com/jetbrains/python/PyStubsTest.java @@ -315,6 +315,13 @@ public class PyStubsTest extends PyLightFixtureTestCase { assertNotParsed(file); } + public void testIfNameMain() { // PY-4008 + getTestFile(); + GlobalSearchScope scope = GlobalSearchScope.allScope(myFixture.getProject()); + Collection result = PyVariableNameIndex.find("xyzzy", myFixture.getProject(), scope); + assertEquals(0, result.size()); + } + // --- private PyFile getTestFile() {