Merge remote-tracking branch 'origin/master'

This commit is contained in:
Andrey Vlasovskikh
2011-12-09 21:53:38 +04:00
5 changed files with 33 additions and 50 deletions
@@ -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<Sdk> TEST_SDK = new Key<Sdk>("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;
}
@@ -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;
}
@@ -137,15 +137,12 @@ public class PyFromImportStatementImpl extends PyBaseElementImpl<PyFromImportSta
return true;
}
if (isStarImport()) {
PyReferenceExpression expr = getImportSource();
if (expr != null) {
final List<PsiElement> 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<PsiElement> 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;
}
}
}
@@ -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<ReadWriteInstruction> defs = PyDefUseUtil.getLatestDefs(scopeOwner, (PyElement)target,
@@ -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<PsiElement> 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.<PsiElement>emptyList();
}
return results;
return resolveFromOrForeignImport((PyFromImportStatement)parent, qname);
}
return Collections.emptyList();
}
public static List<PsiElement> resolveFromOrForeignImport(PyFromImportStatement fromImportStatement, PyQualifiedName qname) {
final List<PsiElement> 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.<PsiElement>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<OrderEntry> 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.
*/