honor fileOnly flag correctly when resolving import references (PY-1896)

This commit is contained in:
Dmitry Jemerov
2011-12-14 14:55:19 +01:00
parent 5c866def18
commit 21d063d58e
8 changed files with 32 additions and 23 deletions
@@ -323,7 +323,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
}
private void registerUnresolvedReferenceProblem(final PyElement node, final PsiReference reference, HighlightSeverity severity) {
final StringBuilder description_buf = new StringBuilder(""); // TODO: clear description_buf logic. maybe a flag is needed instead.
final StringBuilder descriptionBuf = new StringBuilder(""); // TODO: clear descriptionBuf logic. maybe a flag is needed instead.
final String text = reference.getElement().getText();
final String ref_text = reference.getRangeInElement().substring(text); // text of the part we're working with
final PsiElement element = reference.getElement();
@@ -393,7 +393,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
)) {
severity = HighlightSeverity.WEAK_WARNING;
String errmsg = PyBundle.message("INSP.module.$0.not.found", ref_text);
description_buf.append(errmsg);
descriptionBuf.append(errmsg);
// TODO: mark the node so that future references pointing to it won't result in a error, but in a warning
}
}
@@ -401,11 +401,11 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
if (myIgnoredIdentifiers.contains(reference.getCanonicalText()))
return;
}
if (reference instanceof PsiReferenceEx) {
if (reference instanceof PsiReferenceEx && descriptionBuf.length() == 0) {
final String s = ((PsiReferenceEx)reference).getUnresolvedDescription();
if (s != null) description_buf.append(s);
if (s != null) descriptionBuf.append(s);
}
if (description_buf.length() == 0) {
if (descriptionBuf.length() == 0) {
boolean marked_qualified = false;
if (element instanceof PyQualifiedExpression) {
final PyQualifiedExpression qexpr = (PyQualifiedExpression)element;
@@ -441,12 +441,12 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
}
}
if (reference instanceof PyOperatorReferenceImpl) {
description_buf.append(PyBundle.message("INSP.unresolved.operator.ref",
descriptionBuf.append(PyBundle.message("INSP.unresolved.operator.ref",
qtype.getName(), refname,
((PyOperatorReferenceImpl)reference).getReadableOperatorName()));
}
else {
description_buf.append(PyBundle.message("INSP.unresolved.ref.$0.for.class.$1", ref_text, qtype.getName()));
descriptionBuf.append(PyBundle.message("INSP.unresolved.ref.$0.for.class.$1", ref_text, qtype.getName()));
}
marked_qualified = true;
}
@@ -461,14 +461,14 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
return;
}
else {
description_buf.append(PyBundle.message("INSP.cannot.find.$0.in.$1", ref_text, qtype.getName()));
descriptionBuf.append(PyBundle.message("INSP.cannot.find.$0.in.$1", ref_text, qtype.getName()));
marked_qualified = true;
}
}
}
}
if (! marked_qualified) {
description_buf.append(PyBundle.message("INSP.unresolved.ref.$0", ref_text));
descriptionBuf.append(PyBundle.message("INSP.unresolved.ref.$0", ref_text));
if (ref_text.equals("true") || ref_text.equals("false"))
actions.add(new UnresolvedRefTrueFalseQuickFix(element));
@@ -509,7 +509,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
}
}
}
String description = description_buf.toString();
String description = descriptionBuf.toString();
ProblemHighlightType hl_type;
if (severity == HighlightSeverity.WARNING) {
hl_type = ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
@@ -37,6 +37,16 @@ public class PyImportReferenceImpl extends PyReferenceImpl {
myElement = element;
}
@Override
public String getUnresolvedDescription() {
final PyImportStatement importStatement = PsiTreeUtil.getParentOfType(myElement, PyImportStatement.class);
if (importStatement != null) {
return "No module named " + myElement.getReferencedName();
}
return super.getUnresolvedDescription();
}
@NotNull
@Override
protected List<RatedResolveResult> resolveInner() {
@@ -615,7 +615,7 @@ public class ResolveImportUtil {
module = null;
break;
}
module = resolveChild(module, component, foothold_file, root, false, checkForPackage); // only files, we want a module
module = resolveChild(module, component, foothold_file, root, true, checkForPackage); // only files, we want a module
}
return module;
}
@@ -685,7 +685,10 @@ public class ResolveImportUtil {
// OTOH, quite often a module named foo exports a class or function named foo, which is used as a fallback
// by a module one level higher (e.g. curses.set_key). Prefer it to submodule if possible.
ret = ((PyFileImpl)parent).getElementNamed(referencedName, false);
PsiElement elementNamed = ((PyFileImpl)parent).getElementNamed(referencedName, false);
if (!fileOnly || PyUtil.instanceOf(elementNamed, PsiFile.class, PsiDirectory.class)) {
ret = elementNamed;
}
if (ret != null && !PyUtil.instanceOf(ret, PsiFile.class, PsiDirectory.class) &&
PsiTreeUtil.getStubOrPsiParentOfType(ret, PyExceptPart.class) == null) {
return ret;
@@ -0,0 +1 @@
import collections.<warning descr="No module named OrderedDict">OrderedDict</warning>
@@ -1 +1 @@
import <warning descr="Unresolved reference 'wurm'">wurm</warning>
import <warning descr="No module named wurm">wurm</warning>
@@ -1,2 +1,2 @@
import <warning descr="Unresolved reference 'deliverance'">deliverance</warning>.proxycommand
import <warning descr="No module named deliverance">deliverance</warning>.proxycommand
deliverance.proxycommand.main()
@@ -1,7 +1,6 @@
package com.jetbrains.python;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileFilter;
import com.intellij.psi.*;
@@ -210,14 +209,6 @@ public class PyMultiFileResolveTest extends PyResolveTestCase {
assertResolvesTo(PyTargetExpression.class, "__all__");
}
public void testDunderAllImport() {
assertResolvesTo(PyTargetExpression.class, "__all__");
}
public void testDunderAllImportResolve() {
assertResolvesTo(PyTargetExpression.class, "__all__");
}
public void testDunderAllConflict() {
assertResolvesTo(PyFunction.class, "do_stuff", "/src/mypackage1.py");
}
@@ -73,6 +73,10 @@ public class PyUnresolvedReferencesInspectionTest extends PyTestCase {
doTest();
}
public void testImportFunction() { // PY-1896
doTest();
}
public void testImportToContainingFile() { // PY-4372
myFixture.copyFileToProject("inspections/PyUnresolvedReferencesInspection/__init__.py", "PyUnresolvedReferencesInspection/__init__.py");
myFixture.copyFileToProject("inspections/PyUnresolvedReferencesInspection/importToContainingFile.py", "PyUnresolvedReferencesInspection/importToContainingFile.py");