Do not ignore import element completely if qualifier was resolved to namespace package

Consider the case when we are trying to invoke auto completion in
"import foo.bar.<caret>". Previously (mistakenly) type of
qualifier "foo.bar" was PyImportedModuleType(bar), which could not be
successfully resolved unless there is some other top-level "bar" module
under project roots. Now it's correct PyImportModuleType(foo.bar).
This commit is contained in:
Mikhail Golubev
2014-11-11 18:34:07 +03:00
parent b89ea3103c
commit f5b93393fc
7 changed files with 29 additions and 3 deletions
@@ -37,6 +37,13 @@ public class PyImportedModule extends LightElement implements NameDefiner {
@NotNull private final PyFile myContainingFile;
@NotNull private final QualifiedName myImportedPrefix;
/**
* @param importElement parental import element, may be {@code null} if we're resolving {@code module} part in {@code from module import ...} statement
* @param containingFile file to be used as anchor e.g. to determine relative import position
* @param importedPrefix qualified name to resolve
*
* @see com.jetbrains.python.psi.resolve.ResolveImportUtil
*/
public PyImportedModule(@Nullable PyImportElement importElement, @NotNull PyFile containingFile, @NotNull QualifiedName importedPrefix) {
super(containingFile.getManager(), PythonLanguage.getInstance());
myImportElement = importElement;
@@ -36,7 +36,10 @@ import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.references.PyImportReference;
import com.jetbrains.python.psi.impl.references.PyQualifiedReference;
import com.jetbrains.python.psi.impl.references.PyReferenceImpl;
import com.jetbrains.python.psi.resolve.*;
import com.jetbrains.python.psi.resolve.ImplicitResolveResult;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.QualifiedResolveResult;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import com.jetbrains.python.psi.types.*;
import com.jetbrains.python.refactoring.PyDefUseUtil;
import org.jetbrains.annotations.NotNull;
@@ -382,8 +385,18 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
if (PyUtil.isPackage(dir, anchor)) {
final PsiFile containingFile = anchor.getContainingFile();
if (containingFile instanceof PyFile) {
final QualifiedName qualifiedName = QualifiedName.fromComponents(dir.getName());
final PyImportedModule module = new PyImportedModule(null, (PyFile)containingFile, qualifiedName);
final PyImportElement importElement = PsiTreeUtil.getParentOfType(anchor, PyImportElement.class);
final QualifiedName qualifiedName;
if (importElement != null) {
qualifiedName = anchor.asQualifiedName();
}
else {
qualifiedName = QualifiedName.fromComponents(dir.getName());
}
if (qualifiedName == null) {
return null;
}
final PyImportedModule module = new PyImportedModule(importElement, (PyFile)containingFile, qualifiedName);
return new PyImportedModuleType(module);
}
}
@@ -0,0 +1 @@
import nspkg1.nspkg2.foo
@@ -0,0 +1 @@
import nspkg1.nspkg2.f<caret>
@@ -115,4 +115,8 @@ public class Py3CompletionTest extends PyTestCase {
public void testFromQualifiedNamespacePackageImport() {
doMultiFileTest();
}
public void testImportNestedQualifiedNamespacePackage() {
doMultiFileTest();
}
}