diff --git a/python/psi-api/python-psi-api.iml b/python/psi-api/python-psi-api.iml
index a673d82df7d9..5e3914f028e3 100644
--- a/python/psi-api/python-psi-api.iml
+++ b/python/psi-api/python-psi-api.iml
@@ -10,6 +10,7 @@
+
diff --git a/python/src/com/jetbrains/python/PyNames.java b/python/psi-api/src/com/jetbrains/python/PyNames.java
similarity index 100%
rename from python/src/com/jetbrains/python/PyNames.java
rename to python/psi-api/src/com/jetbrains/python/PyNames.java
diff --git a/python/psi-api/src/com/jetbrains/python/psi/resolve/QualifiedNameResolveContext.java b/python/psi-api/src/com/jetbrains/python/psi/resolve/QualifiedNameResolveContext.java
new file mode 100644
index 000000000000..79c4554cbdfd
--- /dev/null
+++ b/python/psi-api/src/com/jetbrains/python/psi/resolve/QualifiedNameResolveContext.java
@@ -0,0 +1,84 @@
+package com.jetbrains.python.psi.resolve;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.jetbrains.python.PyNames;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public class QualifiedNameResolveContext {
+ @Nullable private Module myModule;
+ private PsiFile myFootholdFile;
+ @NotNull PsiManager myPsiManager;
+ private Sdk mySdk;
+
+ public void copyFrom(QualifiedNameResolveContext context) {
+ myModule = context.getModule();
+ myPsiManager = context.getPsiManager();
+ mySdk = context.getSdk();
+ myFootholdFile = context.getFootholdFile();
+ }
+
+ public void setFromElement(PsiElement foothold) {
+ if (foothold instanceof PsiDirectory) {
+ myFootholdFile = ((PsiDirectory)foothold).findFile(PyNames.INIT_DOT_PY);
+ }
+ else {
+ myFootholdFile = foothold.getContainingFile().getOriginalFile();
+ }
+ myPsiManager = foothold.getManager();
+ myModule = ModuleUtilCore.findModuleForPsiElement(foothold);
+ }
+
+ public void setFromModule(Module module) {
+ myModule = module;
+ myPsiManager = PsiManager.getInstance(module.getProject());
+ }
+
+ public void setFromSdk(Project project, Sdk sdk) {
+ myPsiManager = PsiManager.getInstance(project);
+ mySdk = sdk;
+ }
+
+ public void setSdk(Sdk sdk) {
+ mySdk = sdk;
+ }
+
+ @Nullable
+ public Module getModule() {
+ return myModule;
+ }
+
+ public boolean isValid() {
+ if (myFootholdFile != null) {
+ return myFootholdFile.isValid();
+ }
+ return true;
+ }
+
+ public PsiFile getFootholdFile() {
+ return myFootholdFile;
+ }
+
+ @NotNull
+ public PsiManager getPsiManager() {
+ return myPsiManager;
+ }
+
+ public Project getProject() {
+ return myPsiManager.getProject();
+ }
+
+ public Sdk getSdk() {
+ return mySdk;
+ }
+}
diff --git a/python/psi-api/src/com/jetbrains/python/psi/resolve/QualifiedNameResolver.java b/python/psi-api/src/com/jetbrains/python/psi/resolve/QualifiedNameResolver.java
index d1f111c01348..32e0ad3701c4 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/resolve/QualifiedNameResolver.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/resolve/QualifiedNameResolver.java
@@ -40,4 +40,6 @@ public interface QualifiedNameResolver {
@Nullable
T firstResultOfType(Class clazz);
+
+ QualifiedNameResolver withContext(QualifiedNameResolveContext context);
}
diff --git a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java
index 2ed6f1cb6e19..0d699cf3b050 100644
--- a/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java
+++ b/python/src/com/jetbrains/python/psi/resolve/QualifiedNameResolverImpl.java
@@ -5,14 +5,15 @@ import com.google.common.collect.Sets;
import com.intellij.facet.FacetManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiFileSystemItem;
import com.jetbrains.django.facet.DjangoFacetType;
import com.jetbrains.python.console.PydevConsoleRunner;
-import com.jetbrains.python.psi.PyUtil;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PyQualifiedName;
import com.jetbrains.python.sdk.PythonSdkType;
@@ -31,16 +32,12 @@ import java.util.Set;
*/
public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameResolver {
boolean myCheckForPackage = true;
- @Nullable private Module myModule;
- private PsiFile myFootholdFile;
+ private final QualifiedNameResolveContext myContext = new QualifiedNameResolveContext();
private final @NotNull PyQualifiedName myQualifiedName;
- @NotNull PsiManager myPsiManager;
final Set results = Sets.newLinkedHashSet();
- private boolean myAcceptRootAsTopLevelPackage;
private boolean myVisitAllModules = false;
private int myRelativeLevel = -1;
private boolean myWithoutRoots;
- private Sdk myWithSdk;
public QualifiedNameResolverImpl(@NotNull String qNameString) {
myQualifiedName = PyQualifiedName.fromDottedString(qNameString);
@@ -50,16 +47,15 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
myQualifiedName = qName;
}
+ @Override
+ public QualifiedNameResolver withContext(QualifiedNameResolveContext context) {
+ myContext.copyFrom(context);
+ return this;
+ }
+
@Override
public QualifiedNameResolver fromElement(@NotNull PsiElement foothold) {
- if (foothold instanceof PsiDirectory) {
- myFootholdFile = (PsiFile)PyUtil.turnDirIntoInit(foothold);
- }
- else {
- myFootholdFile = foothold.getContainingFile().getOriginalFile();
- }
- myPsiManager = foothold.getManager();
- setModule(ModuleUtilCore.findModuleForPsiElement(foothold));
+ myContext.setFromElement(foothold);
if (PydevConsoleRunner.isInPydevConsole(foothold)) {
withAllModules();
}
@@ -68,23 +64,19 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
@Override
public QualifiedNameResolver fromModule(@NotNull Module module) {
- setModule(module);
- myPsiManager = PsiManager.getInstance(module.getProject());
+ myContext.setFromModule(module);
return this;
}
@Override
public QualifiedNameResolver fromSdk(@NotNull Project project, @NotNull Sdk sdk) {
- myPsiManager = PsiManager.getInstance(project);
- myWithSdk = sdk;
+ myContext.setFromSdk(project, sdk);
return this;
}
- private void setModule(@Nullable Module module) {
- myModule = module;
- if (module != null && FacetManager.getInstance(module).getFacetByType(DjangoFacetType.ID) != null) {
- myAcceptRootAsTopLevelPackage = true;
- }
+ private boolean isAcceptRootAsTopLevelPackage() {
+ Module module = myContext.getModule();
+ return module != null && FacetManager.getInstance(module).getFacetByType(DjangoFacetType.ID) != null;
}
@Override
@@ -101,7 +93,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
*/
@Override
public QualifiedNameResolver withSdk(Sdk sdk) {
- myWithSdk = sdk;
+ myContext.setSdk(sdk);
return this;
}
@@ -149,7 +141,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
results.add(resolveResult);
}
- if (myAcceptRootAsTopLevelPackage && myQualifiedName.matchesPrefix(PyQualifiedName.fromDottedString(root.getName()))) {
+ if (isAcceptRootAsTopLevelPackage() && myQualifiedName.matchesPrefix(PyQualifiedName.fromDottedString(root.getName()))) {
resolveResult = resolveInRoot(root.getParent());
if (resolveResult != null) {
results.add(resolveResult);
@@ -162,15 +154,16 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
@Override
@NotNull
public List resultsAsList() {
- if (myFootholdFile != null && !myFootholdFile.isValid()) {
+ if (!myContext.isValid()) {
return Collections.emptyList();
}
if (myRelativeLevel >= 0) {
- assert myFootholdFile != null;
- PsiDirectory dir = myFootholdFile.getContainingDirectory();
+ PsiFile footholdFile = myContext.getFootholdFile();
+ assert footholdFile != null;
+ PsiDirectory dir = footholdFile.getContainingDirectory();
if (myRelativeLevel > 0) {
- dir = ResolveImportUtil.stepBackFrom(myFootholdFile, myRelativeLevel);
+ dir = ResolveImportUtil.stepBackFrom(footholdFile, myRelativeLevel);
}
PsiFileSystemItem module = resolveModuleAt(dir);
@@ -196,22 +189,22 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
}
if (myVisitAllModules) {
- for (Module mod : ModuleManager.getInstance(myPsiManager.getProject()).getModules()) {
+ for (Module mod : ModuleManager.getInstance(myContext.getProject()).getModules()) {
RootVisitorHost.visitRoots(mod, false, this);
}
}
- else if (myModule != null) {
+ else if (myContext.getModule() != null) {
final boolean otherSdk = withOtherSdk();
- RootVisitorHost.visitRoots(myModule, otherSdk, this);
+ RootVisitorHost.visitRoots(myContext.getModule(), otherSdk, this);
if (otherSdk) {
- RootVisitorHost.visitSdkRoots(myWithSdk, this);
+ RootVisitorHost.visitSdkRoots(myContext.getSdk(), this);
}
}
- else if (myFootholdFile != null) {
- RootVisitorHost.visitSdkRoots(myFootholdFile, this);
+ else if (myContext.getFootholdFile() != null) {
+ RootVisitorHost.visitSdkRoots(myContext.getFootholdFile(), this);
}
- else if (myWithSdk != null) {
- RootVisitorHost.visitSdkRoots(myWithSdk, this);
+ else if (myContext.getSdk() != null) {
+ RootVisitorHost.visitSdkRoots(myContext.getSdk(), this);
}
else {
throw new IllegalStateException();
@@ -252,7 +245,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
}
private boolean withOtherSdk() {
- return myWithSdk != null && myWithSdk != PythonSdkType.findPythonSdk(myModule);
+ return myContext.getSdk() != null && myContext.getSdk() != PythonSdkType.findPythonSdk(myContext.getModule());
}
@Nullable
@@ -260,13 +253,13 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
if (myVisitAllModules) {
return null;
}
- if (myModule != null) {
- return withOtherSdk() ? null : PythonModulePathCache.getInstance(myModule);
+ if (myContext.getModule() != null) {
+ return withOtherSdk() ? null : PythonModulePathCache.getInstance(myContext.getModule());
}
- if (myFootholdFile != null) {
- final Sdk sdk = PyBuiltinCache.findSdkForNonModuleFile(myFootholdFile);
+ if (myContext.getFootholdFile() != null) {
+ final Sdk sdk = PyBuiltinCache.findSdkForNonModuleFile(myContext.getFootholdFile());
if (sdk != null) {
- return PythonSdkPathCache.getInstance(myPsiManager.getProject(), sdk);
+ return PythonSdkPathCache.getInstance(myContext.getProject(), sdk);
}
}
return null;
@@ -278,7 +271,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
// if we have added a file as a root, it's unlikely that we'll be able to resolve anything under it in 'files only' resolve mode
return null;
}
- return resolveModuleAt(myPsiManager.findDirectory(root));
+ return resolveModuleAt(myContext.getPsiManager().findDirectory(root));
}
/**
@@ -296,7 +289,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
if (name == null) {
return null;
}
- seeker = (PsiFileSystemItem) ResolveImportUtil.resolveChild(seeker, name, myFootholdFile, true, myCheckForPackage);
+ seeker = (PsiFileSystemItem) ResolveImportUtil.resolveChild(seeker, name, myContext.getFootholdFile(), true, myCheckForPackage);
}
return seeker;
}