when doing stub-based resolve, resolve names into except block if there's no declaration elsewhere (PY-2302)

This commit is contained in:
Dmitry Jemerov
2010-11-23 18:43:09 +03:00
parent bf7670e3cb
commit ff67211797
4 changed files with 95 additions and 53 deletions
@@ -41,6 +41,7 @@ public class PyDynamicMember {
@NotNull final String type,
final Function<PsiElement, PyType> typeCallback) {
myName = name;
myResolveToInstance = false;
myTypeName = type;
@@ -22,6 +22,7 @@ import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.PyResolveUtil;
import com.jetbrains.python.psi.resolve.ResolveImportUtil;
import com.jetbrains.python.psi.resolve.ResolveProcessor;
import com.jetbrains.python.psi.stubs.PyExceptPartStub;
import com.jetbrains.python.psi.stubs.PyFileStub;
import com.jetbrains.python.psi.stubs.PyFromImportStatementStub;
import com.jetbrains.python.psi.stubs.PyImportStatementStub;
@@ -190,67 +191,32 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
final StubElement stub = getStub();
if (stub != null) {
final List children = stub.getChildrenStubs();
final List<PyExceptPartStub> exceptParts = new ArrayList<PyExceptPartStub>();
for (int i=children.size()-1; i >= 0; i--) {
Object child = children.get(i);
if (child instanceof NamedStub && name.equals(((NamedStub)child).getName())) {
return ((NamedStub) child).getPsi();
}
else if (child instanceof PyFromImportStatementStub) {
if (((PyFromImportStatementStub)child).isStarImport()) {
final PyFromImportStatement statement = ((PyFromImportStatementStub)child).getPsi();
PsiElement starImportSource = ResolveImportUtil.resolveFromImportStatementSource(statement);
if (starImportSource != null) {
starImportSource = PyUtil.turnDirIntoInit(starImportSource);
if (starImportSource instanceof PyFile) {
final PsiElement result = ((PyFile)starImportSource).getElementNamed(name);
if (result != null) {
return result;
}
}
}
}
else {
final List<StubElement> importElements = ((StubElement)child).getChildrenStubs();
for (StubElement importElement : importElements) {
final PsiElement psi = importElement.getPsi();
if (psi instanceof PyImportElement && name.equals(((PyImportElement)psi).getVisibleName())) {
final PsiElement resolved = ((PyImportElement) psi).getElementNamed(name);
if (resolved != null) {
return resolved;
}
}
}
}
return findNameInFromImportStatementStub(name, (PyFromImportStatementStub) child);
}
else if (child instanceof PyImportStatementStub) {
final List<StubElement> importElements = ((StubElement)child).getChildrenStubs();
for (StubElement importElementStub : importElements) {
final PsiElement psi = importElementStub.getPsi();
if (psi instanceof PyImportElement) {
final PyImportElement importElement = (PyImportElement)psi;
final String asName = importElement.getAsName();
if (asName != null && asName.equals(name)) {
final PsiElement resolved = importElement.getElementNamed(name);
if (resolved != null) {
return resolved;
}
}
final PyQualifiedName qName = importElement.getImportedQName();
if (qName != null && qName.getComponentCount() > 0) {
if (qName.getComponents().get(0).equals(name)) {
if (qName.getComponentCount() == 1) {
return psi;
}
return new PyImportedModule(this, PyQualifiedName.fromComponents(name));
}
if (name.equals(((PyImportElement)psi).getVisibleName())) {
final PsiElement resolved = importElement.getElementNamed(name);
if (resolved != null) {
return resolved;
}
}
}
}
final PsiElement result = findNameInImportStatementStub(name, (PyImportStatementStub)child);
if (result != null) {
return result;
}
}
else if (child instanceof PyExceptPartStub) {
exceptParts.add((PyExceptPartStub) child);
}
}
for (int i = exceptParts.size() - 1; i >= 0; i--) {
PyExceptPartStub part = exceptParts.get(i);
final List<StubElement> exceptChildren = part.getChildrenStubs();
for (int j = exceptChildren.size() - 1; j >= 0; j--) {
Object child = exceptChildren.get(j);
if (child instanceof NamedStub && name.equals(((NamedStub)child).getName())) {
return ((NamedStub) child).getPsi();
}
}
}
@@ -274,6 +240,70 @@ public class PyFileImpl extends PsiFileBase implements PyFile, PyExpression {
}
}
@Nullable
private static PsiElement findNameInFromImportStatementStub(String name, PyFromImportStatementStub child) {
if (child.isStarImport()) {
final PyFromImportStatement statement = child.getPsi();
PsiElement starImportSource = ResolveImportUtil.resolveFromImportStatementSource(statement);
if (starImportSource != null) {
starImportSource = PyUtil.turnDirIntoInit(starImportSource);
if (starImportSource instanceof PyFile) {
final PsiElement result = ((PyFile)starImportSource).getElementNamed(name);
if (result != null) {
return result;
}
}
}
}
else {
final List<StubElement> importElements = child.getChildrenStubs();
for (StubElement importElement : importElements) {
final PsiElement psi = importElement.getPsi();
if (psi instanceof PyImportElement && name.equals(((PyImportElement)psi).getVisibleName())) {
final PsiElement resolved = ((PyImportElement) psi).getElementNamed(name);
if (resolved != null) {
return resolved;
}
}
}
}
return null;
}
@Nullable
private PsiElement findNameInImportStatementStub(String name, PyImportStatementStub child) {
final List<StubElement> importElements = child.getChildrenStubs();
for (StubElement importElementStub : importElements) {
final PsiElement psi = importElementStub.getPsi();
if (psi instanceof PyImportElement) {
final PyImportElement importElement = (PyImportElement)psi;
final String asName = importElement.getAsName();
if (asName != null && asName.equals(name)) {
final PsiElement resolved = importElement.getElementNamed(name);
if (resolved != null) {
return resolved;
}
}
final PyQualifiedName qName = importElement.getImportedQName();
if (qName != null && qName.getComponentCount() > 0) {
if (qName.getComponents().get(0).equals(name)) {
if (qName.getComponentCount() == 1) {
return psi;
}
return new PyImportedModule(this, PyQualifiedName.fromComponents(name));
}
if (name.equals(((PyImportElement)psi).getVisibleName())) {
final PsiElement resolved = importElement.getElementNamed(name);
if (resolved != null) {
return resolved;
}
}
}
}
}
return null;
}
@Nullable
public PsiElement getElementNamed(String name) {
return getElementNamed(name, true);
+4
View File
@@ -0,0 +1,4 @@
try:
pass
except:
md5 = ""
@@ -255,6 +255,13 @@ public class PyStubsTest extends PyLightFixtureTestCase {
assertNotParsed(file);
}
public void testNameInExcept() {
final PyFileImpl file = (PyFileImpl) getTestFile();
final PsiElement element = file.findExportedName("md5");
assertTrue(element != null ? element.toString() : "null", element instanceof PyTargetExpression);
assertNotParsed(file);
}
private PyFile getTestFile() {
return getTestFile(getTestName(false) + ".py");
}