From 2453928d87b750c8876087fc8511ffca45c2f83c Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Sat, 28 Apr 2012 19:30:43 +0400 Subject: [PATCH] Refactored isTopLevel() function for Python --- .../codeFragment/PyCodeFragmentBuilder.java | 8 +------- .../PyClassNameCompletionContributor.java | 3 ++- .../imports/PythonReferenceImporter.java | 12 +++++------- python/src/com/jetbrains/python/psi/PyClass.java | 7 ------- .../src/com/jetbrains/python/psi/PyFunction.java | 7 ------- .../com/jetbrains/python/psi/impl/PyClassImpl.java | 4 ---- .../jetbrains/python/psi/impl/PyFunctionImpl.java | 4 ---- .../com/jetbrains/python/psi/impl/PyPsiUtils.java | 14 ++++++++++++++ .../move/PyMoveClassOrFunctionDelegate.java | 8 ++------ 9 files changed, 24 insertions(+), 43 deletions(-) diff --git a/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentBuilder.java b/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentBuilder.java index 442722dc9ba9..be24b561b74e 100644 --- a/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentBuilder.java +++ b/python/src/com/jetbrains/python/codeInsight/codeFragment/PyCodeFragmentBuilder.java @@ -7,11 +7,9 @@ import com.intellij.psi.PsiReference; import com.intellij.psi.ResolveResult; import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; -import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyImportStatementNavigator; import com.jetbrains.python.psi.impl.PyPsiUtils; -import org.jetbrains.annotations.NotNull; import java.util.*; @@ -151,7 +149,7 @@ public class PyCodeFragmentBuilder extends PyRecursiveElementVisitor { } } if (modificationSeen) { - if (!isTopLevel(element)) { + if (!PyPsiUtils.isTopLevel(element)) { inElements.add(name); } break; @@ -162,10 +160,6 @@ public class PyCodeFragmentBuilder extends PyRecursiveElementVisitor { } } - private static boolean isTopLevel(@NotNull PyElement element) { - return ScopeUtil.getScopeOwner(element) instanceof PyFile; - } - private void processDeclaration(final PyElement element) { final Position position = CodeFragmentUtil.getPosition(element, startOffset, endOffset); final String name = element.getName(); diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java index 35430c901420..987bf77c8270 100644 --- a/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/completion/PyClassNameCompletionContributor.java @@ -22,6 +22,7 @@ import com.jetbrains.python.codeInsight.imports.AddImportHelper; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyFunction; +import com.jetbrains.python.psi.impl.PyPsiUtils; import com.jetbrains.python.psi.stubs.PyClassNameIndex; import com.jetbrains.python.psi.stubs.PyFunctionNameIndex; import org.jetbrains.annotations.NotNull; @@ -49,7 +50,7 @@ public class PyClassNameCompletionContributor extends CompletionContributor { private static Condition TOPLEVEL_FUNCTION = new Condition() { @Override public boolean value(PyFunction pyFunction) { - return pyFunction.isTopLevel(); + return PyPsiUtils.isTopLevel(pyFunction); } }; diff --git a/python/src/com/jetbrains/python/codeInsight/imports/PythonReferenceImporter.java b/python/src/com/jetbrains/python/codeInsight/imports/PythonReferenceImporter.java index 4dc167d0366d..11bfb09e04c9 100644 --- a/python/src/com/jetbrains/python/codeInsight/imports/PythonReferenceImporter.java +++ b/python/src/com/jetbrains/python/codeInsight/imports/PythonReferenceImporter.java @@ -26,6 +26,7 @@ import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyFileImpl; +import com.jetbrains.python.psi.impl.PyPsiUtils; import com.jetbrains.python.psi.impl.PyQualifiedName; import com.jetbrains.python.psi.resolve.CollectProcessor; import com.jetbrains.python.psi.resolve.PyResolveUtil; @@ -131,7 +132,7 @@ public class PythonReferenceImporter implements ReferenceImporter { } if (symbols.size() > 0) { for (PsiElement symbol : symbols) { - if (isTopLevel(symbol)) { // we only want top-level symbols + if (isIndexableTopLevel(symbol)) { // we only want top-level symbols PsiFileSystemItem srcfile = symbol instanceof PsiFileSystemItem ? ((PsiFileSystemItem)symbol).getParent() : symbol.getContainingFile(); if (srcfile != null && srcfile != existing_import_file && srcfile != node.getContainingFile() && (ImportFromExistingAction.isRoot(project, srcfile) || PyNames.isIdentifier(FileUtil.getNameWithoutExtension(srcfile.getName()))) && @@ -215,15 +216,12 @@ public class PythonReferenceImporter implements ReferenceImporter { return result; } - private static boolean isTopLevel(PsiElement symbol) { + private static boolean isIndexableTopLevel(PsiElement symbol) { if (symbol instanceof PsiFileSystemItem) { return true; } - if (symbol instanceof PyClass) { - return ((PyClass)symbol).isTopLevel(); - } - if (symbol instanceof PyFunction) { - return ((PyFunction)symbol).isTopLevel(); + if (symbol instanceof PyClass || symbol instanceof PyFunction) { + return PyPsiUtils.isTopLevel(symbol); } // only top-level target expressions are included in VariableNameIndex return symbol instanceof PyTargetExpression; diff --git a/python/src/com/jetbrains/python/psi/PyClass.java b/python/src/com/jetbrains/python/psi/PyClass.java index d501b1b8e4cc..7b4d5723b406 100644 --- a/python/src/com/jetbrains/python/psi/PyClass.java +++ b/python/src/com/jetbrains/python/psi/PyClass.java @@ -150,13 +150,6 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine @Nullable String getQualifiedName(); - /** - * Returns true if the class is a top-level class (its parent is its containing file). - * - * @return true if the class is top-level, false otherwise. - */ - boolean isTopLevel(); - /** * Returns the list of names in the class' __slots__ attribute, or null if the class * does not define such an attribute. diff --git a/python/src/com/jetbrains/python/psi/PyFunction.java b/python/src/com/jetbrains/python/psi/PyFunction.java index 87d8689a12ad..2b6a8e666a54 100644 --- a/python/src/com/jetbrains/python/psi/PyFunction.java +++ b/python/src/com/jetbrains/python/psi/PyFunction.java @@ -43,13 +43,6 @@ extends @Nullable PyClass getContainingClass(); - /** - * Returns true if the function is a top-level class (its parent is its containing file). - * - * @return true if the function is top-level, false otherwise. - */ - boolean isTopLevel(); - @Nullable PyType getReturnTypeFromDocString(); diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index 81af6004eb3f..067d957c6d5f 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -227,10 +227,6 @@ public class PyClassImpl extends PyPresentableElementImpl implement return name; } - public boolean isTopLevel() { - return getParentByStub() instanceof PsiFile; - } - @Override public List getSlots() { List slots = getOwnSlots(); diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 4225043f81e7..f8b20e9daa17 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -145,10 +145,6 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp return getStubOrPsiChild(PyElementTypes.DECORATOR_LIST); // PsiTreeUtil.getChildOfType(this, PyDecoratorList.class); } - public boolean isTopLevel() { - return getParentByStub() instanceof PsiFile; - } - @Nullable @Override public PyType getReturnType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { diff --git a/python/src/com/jetbrains/python/psi/impl/PyPsiUtils.java b/python/src/com/jetbrains/python/psi/impl/PyPsiUtils.java index 9aa4e748dc08..c22b5db42900 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyPsiUtils.java +++ b/python/src/com/jetbrains/python/psi/impl/PyPsiUtils.java @@ -13,6 +13,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; import com.jetbrains.python.PyTokenTypes; +import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.psi.*; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -318,6 +319,19 @@ public class PyPsiUtils { return -1; } + public static boolean isTopLevel(@NotNull PsiElement element) { + if (element instanceof StubBasedPsiElement) { + final StubElement stub = ((StubBasedPsiElement)element).getStub(); + if (stub != null) { + final StubElement parentStub = stub.getParentStub(); + if (parentStub != null) { + return parentStub.getPsi() instanceof PsiFile; + } + } + } + return ScopeUtil.getScopeOwner(element) instanceof PsiFile; + } + private static abstract class TopLevelVisitor extends PyRecursiveElementVisitor { public void visitPyElement(final PyElement node) { super.visitPyElement(node); diff --git a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDelegate.java b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDelegate.java index 92051a60425d..182e850b5dac 100644 --- a/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDelegate.java +++ b/python/src/com/jetbrains/python/refactoring/move/PyMoveClassOrFunctionDelegate.java @@ -18,6 +18,7 @@ import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.psi.PyClass; import com.jetbrains.python.psi.PyFile; import com.jetbrains.python.psi.PyFunction; +import com.jetbrains.python.psi.impl.PyPsiUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -71,7 +72,7 @@ public class PyMoveClassOrFunctionDelegate extends MoveHandlerDelegate { @Nullable Editor editor) { final PsiNamedElement e = getElementToMove(element); if (e instanceof PyClass || e instanceof PyFunction) { - if (isTopLevel(e)) { + if (PyPsiUtils.isTopLevel(e)) { doMove(project, new PsiElement[] {e}, null, null); } else { @@ -88,9 +89,4 @@ public class PyMoveClassOrFunctionDelegate extends MoveHandlerDelegate { final ScopeOwner owner = (element instanceof ScopeOwner) ? (ScopeOwner)element : ScopeUtil.getScopeOwner(element); return (owner instanceof PsiNamedElement) ? (PsiNamedElement)owner : null; } - - private static boolean isTopLevel(@NotNull PsiElement element) { - return (element instanceof PyFunction && ((PyFunction)element).isTopLevel()) || - (element instanceof PyClass && ((PyClass)element).isTopLevel()); - } }