diff --git a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java index 45318d295794..7cccb7c31d08 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java +++ b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java @@ -1,6 +1,5 @@ package com.jetbrains.python.psi.impl; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.project.Project; @@ -47,11 +46,6 @@ public class PyBuiltinCache { private PyType STRING_TYPE_PY2 = null; - /** - * Used in cases when a virtual file as absent in test mode; then the project may store its own SDK. - */ - public static final Key TEST_SDK = new Key("test.sdk.instance"); - /** * Returns an instance of builtin cache. Instances differ per module and are cached. * @param reference something to define the module from. @@ -96,10 +90,6 @@ public class PyBuiltinCache { } } } - else if (ApplicationManager.getApplication().isUnitTestMode()) { - // did they store a test SDK for us? - sdk = project.getUserData(TEST_SDK); - } } return sdk; } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java index 386b456e6a69..37b163533252 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFileImpl.java @@ -255,8 +255,8 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression { PsiElement starImportSource = ResolveImportUtil.resolveFromImportStatementSource(statement); if (starImportSource != null) { starImportSource = PyUtil.turnDirIntoInit(starImportSource); - if (starImportSource instanceof PyFile) { - final PsiElement result = ((PyFile)starImportSource).getElementNamed(name); + if (starImportSource instanceof PyFileImpl) { + final PsiElement result = ((PyFileImpl)starImportSource).getElementNamed(name, false); if (result != null) { return result; } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java index 92f50ab36a20..05b5e11807ac 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFromImportStatementImpl.java @@ -137,15 +137,12 @@ public class PyFromImportStatementImpl extends PyBaseElementImpl targets = ResolveImportUtil.resolveImportReference(expr); - for (PsiElement target : targets) { - final PsiElement importedFile = PyUtil.turnDirIntoInit(target); - if (importedFile != null) { - if (!importedFile.processDeclarations(processor, state, null, place)) { - return false; - } + final List targets = ResolveImportUtil.resolveFromOrForeignImport(this, getImportSourceQName()); + for (PsiElement target : targets) { + final PsiElement importedFile = PyUtil.turnDirIntoInit(target); + if (importedFile != null) { + if (!importedFile.processDeclarations(processor, state, null, place)) { + return false; } } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java index 73fcb238216f..4ac10960986a 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java @@ -302,8 +302,8 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere return new PyImportedModuleType((PyImportedModule)target); } if ((target instanceof PyTargetExpression || target instanceof PyNamedParameter) && anchor != null && context.allowDataFlow(anchor)) { - final ScopeOwner scopeOwner = PsiTreeUtil.getParentOfType(anchor, ScopeOwner.class); - if (scopeOwner != null && scopeOwner == PsiTreeUtil.getParentOfType(target, ScopeOwner.class)) { + final ScopeOwner scopeOwner = PsiTreeUtil.getStubOrPsiParentOfType(anchor, ScopeOwner.class); + if (scopeOwner != null && scopeOwner == PsiTreeUtil.getStubOrPsiParentOfType(target, ScopeOwner.class)) { PyAugAssignmentStatement augAssignment = PsiTreeUtil.getParentOfType(anchor, PyAugAssignmentStatement.class); try { final List defs = PyDefUseUtil.getLatestDefs(scopeOwner, (PyElement)target, diff --git a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java index c49dd5d508d2..fac37d090f75 100644 --- a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java +++ b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java @@ -177,19 +177,22 @@ public class ResolveImportUtil { return multiResolveImportElement(import_element, qname); } else if (parent instanceof PyFromImportStatement) { // "from foo import" - PyFromImportStatement from_import_statement = (PyFromImportStatement)parent; - final List results = resolveFromImportStatementSource(from_import_statement, qname); - if (results.isEmpty() && qname != null && qname.getComponentCount() > 0) { - final PyQualifiedName importedQName = PyQualifiedName.fromComponents(qname.getLastComponent()); - final PyQualifiedName containingQName = qname.removeLastComponent(); - final PsiElement result = resolveForeignImport(parent, importedQName, containingQName); - return result != null ? Collections.singletonList(result) : Collections.emptyList(); - } - return results; + return resolveFromOrForeignImport((PyFromImportStatement)parent, qname); } return Collections.emptyList(); } + public static List resolveFromOrForeignImport(PyFromImportStatement fromImportStatement, PyQualifiedName qname) { + final List results = resolveFromImportStatementSource(fromImportStatement, qname); + if (results.isEmpty() && qname != null && qname.getComponentCount() > 0) { + final PyQualifiedName importedQName = PyQualifiedName.fromComponents(qname.getLastComponent()); + final PyQualifiedName containingQName = qname.removeLastComponent(); + final PsiElement result = resolveForeignImport(fromImportStatement, importedQName, containingQName); + return result != null ? Collections.singletonList(result) : Collections.emptyList(); + } + return results; + } + @Nullable public static PsiElement resolveFromImportStatementSource(PyFromImportStatement from_import_statement) { final PyQualifiedName qName = from_import_statement.getImportSourceQName(); @@ -352,7 +355,7 @@ public class ResolveImportUtil { return visitor.resultsAsList(); } else if (foothold != null) { - visitRoots(foothold, visitor); + visitSdkRoots(foothold, visitor); return visitor.resultsAsList(); } else { @@ -460,7 +463,7 @@ public class ResolveImportUtil { // out-of-project file or non-file(e.g. console) - use roots of SDK assigned to project if (orderEntries == null) { - final Sdk sdk = PyBuiltinCache.findSdkForFile(elt_psifile); + final Sdk sdk = ProjectRootManager.getInstance(elt.getProject()).getProjectSdk(); if (sdk != null) { visitSdkRoots(visitor, sdk); } @@ -725,8 +728,9 @@ public class ResolveImportUtil { final PsiElement module = findPyFileInDir(dir, referencedName); if (module != null) return module; - if (isInSdk(dir)) { - PsiDirectory skeletonDir = findSkeletonDir(dir, root); + final Sdk sdk = sdkForDir(dir); + if (sdk != null) { + PsiDirectory skeletonDir = findSkeletonDir(dir, root, sdk); if (skeletonDir != null) { final PsiFile skeletonFile = findPyFileInDir(skeletonDir, referencedName); if (skeletonFile != null) { @@ -756,19 +760,20 @@ public class ResolveImportUtil { return null; } - private static boolean isInSdk(PsiDirectory dir) { + @Nullable + private static Sdk sdkForDir(PsiDirectory dir) { final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(dir.getProject()).getFileIndex(); final List entries = fileIndex.getOrderEntriesForFile(dir.getVirtualFile()); for (OrderEntry entry : entries) { if (entry instanceof JdkOrderEntry) { - return true; + return ((JdkOrderEntry) entry).getJdk(); } } - return false; + return null; } @Nullable - private static PsiDirectory findSkeletonDir(PsiDirectory dir, @Nullable VirtualFile root) { + private static PsiDirectory findSkeletonDir(PsiDirectory dir, @Nullable VirtualFile root, Sdk sdk) { String relativeName = null; if (root != null) { relativeName = VfsUtilCore.getRelativePath(dir.getVirtualFile(), root, '/'); @@ -779,7 +784,7 @@ public class ResolveImportUtil { relativeName = relativeQName.join("/"); } } - VirtualFile skeletonsRoot = findSkeletonsRoot(dir); + VirtualFile skeletonsRoot = PythonSdkType.findSkeletonsDir(sdk); if (skeletonsRoot != null && relativeName != null) { VirtualFile skeletonsVFile = relativeName.length() == 0 ? skeletonsRoot : skeletonsRoot.findFileByRelativePath(relativeName.replace(".", "/")); @@ -790,15 +795,6 @@ public class ResolveImportUtil { return null; } - @Nullable - private static VirtualFile findSkeletonsRoot(PsiFileSystemItem fsItem) { - Sdk sdk = PyBuiltinCache.findSdkForFile(fsItem); - if (sdk != null) { - return PythonSdkType.findSkeletonsDir(sdk); - } - return null; - } - /** * Tries to find roots that contain given vfile, and among them the root that contains at the smallest depth. */