diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index 7538fbae2fd2..fad945b9ef3d 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -20,7 +20,6 @@ import com.intellij.lang.ASTNode; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.NotNullLazyValue; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.search.LocalSearchScope; @@ -237,27 +236,7 @@ public class PyClassImpl extends PyPresentableElementImpl implement @Nullable public String getQualifiedName() { - String name = getName(); - final PyClassStub stub = getStub(); - PsiElement ancestor = stub != null ? stub.getParentStub().getPsi() : getParent(); - while (!(ancestor instanceof PsiFile)) { - if (ancestor == null) return name; // can this happen? - if (ancestor instanceof PyClass) { - name = ((PyClass)ancestor).getName() + "." + name; - } - ancestor = stub != null ? ((StubBasedPsiElement)ancestor).getStub().getParentStub().getPsi() : ancestor.getParent(); - } - - PsiFile psiFile = ((PsiFile)ancestor).getOriginalFile(); - final PyFile builtins = PyBuiltinCache.getInstance(this).getBuiltinsFile(); - if (!psiFile.equals(builtins)) { - VirtualFile vFile = psiFile.getVirtualFile(); - if (vFile != null) { - final String packageName = QualifiedNameFinder.findShortestImportableName(this, vFile); - return packageName + "." + name; - } - } - return name; + return QualifiedNameFinder.getQualifiedName(this); } @Override diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 2531b37bf8b2..246b58d963c3 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -699,21 +699,6 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp @Nullable @Override public String getQualifiedName() { - String name = getName(); - if (name == null) { - return null; - } - PyClass containingClass = getContainingClass(); - if (containingClass != null) { - return containingClass.getQualifiedName() + "." + name; - } - if (PsiTreeUtil.getStubOrPsiParent(this) instanceof PyFile) { - VirtualFile virtualFile = getContainingFile().getVirtualFile(); - if (virtualFile != null) { - final String packageName = QualifiedNameFinder.findShortestImportableName(this, virtualFile); - return packageName + "." + name; - } - } - return null; + return QualifiedNameFinder.getQualifiedName(this); } } diff --git a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java index 97a15da105c3..5dff29010e63 100644 --- a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java +++ b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java @@ -24,10 +24,14 @@ import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.jetbrains.python.PyNames; +import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; +import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.psi.PyClass; +import com.jetbrains.python.psi.PyElement; import com.jetbrains.python.psi.PyFile; import com.jetbrains.python.psi.PyFunction; import com.intellij.psi.util.QualifiedName; +import com.jetbrains.python.psi.impl.PyBuiltinCache; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -156,6 +160,31 @@ public class QualifiedNameFinder { return qname; } + @Nullable + public static String getQualifiedName(@NotNull PyElement element) { + final String name = element.getName(); + if (name != null) { + final ScopeOwner owner = ScopeUtil.getScopeOwner(element); + final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(element); + if (owner instanceof PyClass) { + final String classQName = ((PyClass)owner).getQualifiedName(); + if (classQName != null) { + return classQName + "." + name; + } + } + else if (owner instanceof PyFile && !builtinCache.isBuiltin(element)) { + final VirtualFile virtualFile = ((PyFile)owner).getVirtualFile(); + if (virtualFile != null) { + final String fileQName = findShortestImportableName(element, virtualFile); + if (fileQName != null) { + return fileQName + "." + name; + } + } + } + } + return null; + } + /** * Tries to find roots that contain given vfile, and among them the root that contains at the smallest depth. * For equal depth source root is in preference to library.