QualifiedNameResolver and ResolveImportUtil is back from resolving PsiFileSystemItems to PsiElements

This commit is contained in:
Dmitry Jemerov
2012-08-13 13:39:12 +02:00
parent 1123c7b0d8
commit 4455bd8ea5
7 changed files with 40 additions and 42 deletions
@@ -1,7 +1,6 @@
package com.jetbrains.python.psi;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.StubBasedPsiElement;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import com.jetbrains.python.psi.stubs.PyFromImportStatementStub;
@@ -63,7 +62,7 @@ public interface PyFromImportStatement extends PyImportStatementBase, StubBasedP
* @return the resolved import source (file or directory containing __init__.py), or null if the import is unresolved.
*/
@Nullable
PsiFileSystemItem resolveImportSource();
PsiElement resolveImportSource();
/**
* Resolves the import source qualified name to a number of possible files or directories. Note: performs a Python only resolve,
@@ -72,5 +71,5 @@ public interface PyFromImportStatement extends PyImportStatementBase, StubBasedP
* @return possible candidates the resolved import source (file or directory containing __init__.py), or an empty list if the import is unresolved.
*/
@NotNull
List<PsiFileSystemItem> resolveImportSourceCandidates();
List<PsiElement> resolveImportSourceCandidates();
}
@@ -4,7 +4,6 @@ import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -31,10 +30,10 @@ public interface QualifiedNameResolver {
QualifiedNameResolver withPlainDirectories();
@NotNull
List<PsiFileSystemItem> resultsAsList();
List<PsiElement> resultsAsList();
@Nullable
PsiFileSystemItem firstResult();
PsiElement firstResult();
@NotNull
<T extends PsiElement> List<T> resultsOfType(Class<T> clazz);
@@ -786,7 +786,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
continue;
}
}
PsiFileSystemItem importedElement;
PsiElement importedElement;
if (unusedImport instanceof PyImportElement) {
final PyImportElement importElement = (PyImportElement)unusedImport;
final PsiElement element = ResolveImportUtil.resolveImportElement(importElement);
@@ -806,7 +806,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
}
}
if (packageQName != null && importedElement instanceof PsiFileSystemItem) {
final PyQualifiedName importedQName = QualifiedNameFinder.findShortestImportableQName(importedElement);
final PyQualifiedName importedQName = QualifiedNameFinder.findShortestImportableQName((PsiFileSystemItem)importedElement);
if (importedQName != null && importedQName.matchesPrefix(packageQName)) {
continue;
}
@@ -189,20 +189,20 @@ public class PyFromImportStatementImpl extends PyBaseElementImpl<PyFromImportSta
}
@Nullable
public PsiFileSystemItem resolveImportSource() {
final List<PsiFileSystemItem> candidates = resolveImportSourceCandidates();
public PsiElement resolveImportSource() {
final List<PsiElement> candidates = resolveImportSourceCandidates();
return candidates.size() > 0 ? candidates.get(0) : null;
}
@NotNull
@Override
public List<PsiFileSystemItem> resolveImportSourceCandidates() {
public List<PsiElement> resolveImportSourceCandidates() {
final PyQualifiedName qName = getImportSourceQName();
if (qName == null) {
final int level = getRelativeLevel();
if (level > 0) {
final PsiDirectory upper = ResolveImportUtil.stepBackFrom(getContainingFile().getOriginalFile(), level);
return upper == null ? Collections.<PsiFileSystemItem>emptyList() : Collections.<PsiFileSystemItem>singletonList(upper);
return upper == null ? Collections.<PsiElement>emptyList() : Collections.<PsiElement>singletonList(upper);
}
}
return ResolveImportUtil.resolveFromOrForeignImportStatementSource(this, qName);
@@ -1,7 +1,7 @@
package com.jetbrains.python.psi.resolve;
import com.intellij.openapi.vfs.*;
import com.intellij.psi.PsiFileSystemItem;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import java.util.HashMap;
@@ -12,7 +12,7 @@ import java.util.Map;
* @author yole
*/
public abstract class PythonPathCache {
private final Map<PyQualifiedName, List<PsiFileSystemItem>> myCache = new HashMap<PyQualifiedName, List<PsiFileSystemItem>>();
private final Map<PyQualifiedName, List<PsiElement>> myCache = new HashMap<PyQualifiedName, List<PsiElement>>();
private final Map<VirtualFile, PyQualifiedName> myQNameCache = new HashMap<VirtualFile, PyQualifiedName>();
protected void clearCache() {
@@ -20,11 +20,11 @@ public abstract class PythonPathCache {
myQNameCache.clear();
}
public synchronized List<PsiFileSystemItem> get(PyQualifiedName qualifiedName) {
public synchronized List<PsiElement> get(PyQualifiedName qualifiedName) {
return myCache.get(qualifiedName);
}
public synchronized void put(PyQualifiedName qualifiedName, List<PsiFileSystemItem> results) {
public synchronized void put(PyQualifiedName qualifiedName, List<PsiElement> results) {
myCache.put(qualifiedName, results);
}
@@ -35,7 +35,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
private PsiFile myFootholdFile;
private final @NotNull PyQualifiedName myQualifiedName;
@NotNull PsiManager myPsiManager;
final Set<PsiFileSystemItem> results = Sets.newLinkedHashSet();
final Set<PsiElement> results = Sets.newLinkedHashSet();
private boolean myAcceptRootAsTopLevelPackage;
private boolean myVisitAllModules = false;
private int myRelativeLevel = -1;
@@ -161,7 +161,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
@Override
@NotNull
public List<PsiFileSystemItem> resultsAsList() {
public List<PsiElement> resultsAsList() {
if (myFootholdFile != null && !myFootholdFile.isValid()) {
return Collections.emptyList();
}
@@ -186,10 +186,10 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
return Lists.newArrayList(results);
}
private List<PsiFileSystemItem> resolveInRoots() {
private List<PsiElement> resolveInRoots() {
PythonPathCache cache = findMyCache();
if (cache != null) {
final List<PsiFileSystemItem> cachedResults = cache.get(myQualifiedName);
final List<PsiElement> cachedResults = cache.get(myQualifiedName);
if (cachedResults != null) {
return cachedResults;
}
@@ -217,7 +217,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
throw new IllegalStateException();
}
final ArrayList<PsiFileSystemItem> resultList = Lists.newArrayList(results);
final ArrayList<PsiElement> resultList = Lists.newArrayList(results);
if (cache != null) {
cache.put(myQualifiedName, resultList);
}
@@ -226,8 +226,8 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
@Override
@Nullable
public PsiFileSystemItem firstResult() {
final List<PsiFileSystemItem> results = resultsAsList();
public PsiElement firstResult() {
final List<PsiElement> results = resultsAsList();
return results.size() > 0 ? results.get(0) : null;
}
@@ -106,8 +106,8 @@ public class ResolveImportUtil {
return Collections.emptyList();
}
final PsiFile file = importElement.getContainingFile().getOriginalFile();
boolean absolute_import_enabled = isAbsoluteImportEnabledFor(importElement);
final List<PsiFileSystemItem> modules = resolveModule(qName, file, absolute_import_enabled, 0);
boolean absoluteImportEnabled = isAbsoluteImportEnabledFor(importElement);
final List<PsiElement> modules = resolveModule(qName, file, absoluteImportEnabled, 0);
if (modules.size() > 0) {
return rateResults(modules);
}
@@ -125,7 +125,7 @@ public class ResolveImportUtil {
PsiFile file = importElement.getContainingFile().getOriginalFile();
String name = qName.getComponents().get(0);
final List<PsiFileSystemItem> candidates = importStatement.resolveImportSourceCandidates();
final List<PsiElement> candidates = importStatement.resolveImportSourceCandidates();
List<PsiElement> resultList = new ArrayList<PsiElement>();
for (PsiElement candidate : candidates) {
if (!candidate.isValid()) {
@@ -152,7 +152,7 @@ public class ResolveImportUtil {
@NotNull
public static List<PsiElement> resolveFromOrForeignImport(PyFromImportStatement fromImportStatement, PyQualifiedName qname) {
final List<PsiFileSystemItem> results = resolveFromImportStatementSource(fromImportStatement, 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();
@@ -163,27 +163,27 @@ public class ResolveImportUtil {
}
@NotNull
public static List<PsiFileSystemItem> resolveFromImportStatementSource(PyFromImportStatement from_import_statement, PyQualifiedName qName) {
boolean absolute_import_enabled = isAbsoluteImportEnabledFor(from_import_statement);
public static List<PsiElement> resolveFromImportStatementSource(PyFromImportStatement from_import_statement, PyQualifiedName qName) {
boolean absoluteImportEnabled = isAbsoluteImportEnabledFor(from_import_statement);
PsiFile file = from_import_statement.getContainingFile();
return resolveModule(qName, file, absolute_import_enabled, from_import_statement.getRelativeLevel());
return resolveModule(qName, file, absoluteImportEnabled, from_import_statement.getRelativeLevel());
}
@NotNull
public static List<PsiFileSystemItem> resolveFromOrForeignImportStatementSource(@NotNull PyFromImportStatement fromImportStatement,
@Nullable PyQualifiedName qName) {
final List<PsiFileSystemItem> results = resolveFromImportStatementSource(fromImportStatement, qName);
public static List<PsiElement> resolveFromOrForeignImportStatementSource(@NotNull PyFromImportStatement fromImportStatement,
@Nullable PyQualifiedName qName) {
final List<PsiElement> results = resolveFromImportStatementSource(fromImportStatement, qName);
if (!results.isEmpty()) {
return results;
}
final PsiElement result = qName != null ? resolveForeignImport(fromImportStatement, qName, null) : null;
return result instanceof PsiFileSystemItem ? Collections.singletonList((PsiFileSystemItem)result)
: Collections.<PsiFileSystemItem>emptyList();
return result != null ? Collections.singletonList(result) : Collections.<PsiElement>emptyList();
}
/**
* Resolves a module reference in a general case.
*
*
* @param qualifiedName qualified name of the module reference to resolve
* @param sourceFile where that reference resides; serves as PSI foothold to determine module, project, etc.
* @param importIsAbsolute if false, try old python 2.x's "relative first, absolute next" approach.
@@ -191,8 +191,8 @@ public class ResolveImportUtil {
* @return list of possible candidates
*/
@NotNull
public static List<PsiFileSystemItem> resolveModule(@Nullable PyQualifiedName qualifiedName, PsiFile sourceFile,
boolean importIsAbsolute, int relativeLevel) {
public static List<PsiElement> resolveModule(@Nullable PyQualifiedName qualifiedName, PsiFile sourceFile,
boolean importIsAbsolute, int relativeLevel) {
if (qualifiedName == null || sourceFile == null) {
return Collections.emptyList();
}
@@ -214,7 +214,7 @@ public class ResolveImportUtil {
visitor.withRelative(0);
}
}
List<PsiFileSystemItem> results = visitor.resultsAsList();
List<PsiElement> results = visitor.resultsAsList();
if (results.isEmpty() && relativeLevel == 0 && !importIsAbsolute) {
results = resolveRelativeImportAsAbsolute(sourceFile, qualifiedName);
}
@@ -235,8 +235,8 @@ public class ResolveImportUtil {
* @return list of resolved elements.
*/
@NotNull
private static List<PsiFileSystemItem> resolveRelativeImportAsAbsolute(@NotNull PsiFile foothold,
@NotNull PyQualifiedName qualifiedName) {
private static List<PsiElement> resolveRelativeImportAsAbsolute(@NotNull PsiFile foothold,
@NotNull PyQualifiedName qualifiedName) {
final PsiDirectory containingDirectory = foothold.getContainingDirectory();
if (containingDirectory != null) {
final PyQualifiedName containingPath = QualifiedNameFinder.findCanonicalImportPath(containingDirectory, null);
@@ -343,8 +343,8 @@ public class ResolveImportUtil {
return result;
}
if (parent instanceof PsiFile) {
final List<PsiFileSystemItem> items = resolveRelativeImportAsAbsolute((PsiFile)parent,
PyQualifiedName.fromComponents(referencedName));
final List<PsiElement> items = resolveRelativeImportAsAbsolute((PsiFile)parent,
PyQualifiedName.fromComponents(referencedName));
if (!items.isEmpty()) {
return items.get(0);
}