type inference for isinstance() should not touch resolve logic (PY-1133)

This commit is contained in:
Dmitry Jemerov
2010-06-24 15:23:52 +04:00
parent d9b6502e20
commit 8b9b16b1eb
11 changed files with 49 additions and 27 deletions
@@ -252,7 +252,7 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
if (target instanceof PyImportedModule) {
return new PyImportedModuleType((PyImportedModule)target);
}
if ((target instanceof PyTargetExpression | target instanceof PyNamedParameter) && context.allowDataFlow() && anchor != null) {
if ((target instanceof PyTargetExpression || target instanceof PyNamedParameter) && context.allowDataFlow() && anchor != null) {
final ScopeOwner scopeOwner = PsiTreeUtil.getParentOfType(anchor, ScopeOwner.class);
if (scopeOwner != null && scopeOwner == PsiTreeUtil.getParentOfType(target, ScopeOwner.class)) {
PyAugAssignmentStatement augAssignment = PsiTreeUtil.getParentOfType(anchor, PyAugAssignmentStatement.class);
@@ -15,14 +15,12 @@ import com.intellij.util.Icons;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.SortedList;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.*;
import com.jetbrains.python.psi.search.PySuperMethodsSearch;
import com.jetbrains.python.psi.types.PyModuleType;
import com.jetbrains.python.psi.types.PyType;
import com.jetbrains.python.psi.types.TypeEvalContext;
import com.jetbrains.python.refactoring.PyDefUseUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -179,26 +177,6 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
}
if (roof == null) roof = realContext.getContainingFile();
PsiElement uexpr = PyResolveUtil.treeCrawlUp(processor, false, realContext, roof);
if (uexpr != null) {
//add possible inferred types
if ((uexpr instanceof PyTargetExpression || uexpr instanceof PyNamedParameter) && myElement != null) {
final ScopeOwner scopeOwner = PsiTreeUtil.getParentOfType(myElement, ScopeOwner.class);
if (scopeOwner != null && scopeOwner == PsiTreeUtil.getStubOrPsiParentOfType(uexpr, ScopeOwner.class)) {
PyAugAssignmentStatement augAssignment = PsiTreeUtil.getParentOfType(myElement, PyAugAssignmentStatement.class);
try {
final PyElement[] defs = PyDefUseUtil.getLatestDefs(scopeOwner, (PyElement)uexpr,
augAssignment != null ? augAssignment : myElement);
for (PyElement e : defs) {
ret.add(new RatedResolveResult(RatedResolveResult.RATE_NORMAL + 1, e));
}
}
catch (PyDefUseUtil.InstructionNotFoundException e) {
// ignore
}
}
}
}
if ((uexpr != null)) {
if ((uexpr instanceof PyClass)) {
// is it a case of the bizarre "class Foo(Foo)" construct?
@@ -0,0 +1,6 @@
class Foo:
def xyzzy(self): pass
def x(p):
if isinstance(p, Foo):
p.xyzzy()
+6
View File
@@ -0,0 +1,6 @@
class Foo:
def xyzzy(self): pass
def x(p):
if isinstance(p, Foo):
p.xy<caret>
@@ -0,0 +1,8 @@
class Foo:
def xyzzy(self): pass
def bar(): pass
f = bar()
assert isinstance(f, Foo)
f.xyzzy()
@@ -0,0 +1,8 @@
class Foo:
def xyzzy(self): pass
def bar(): pass
f = bar()
assert isinstance(f, Foo)
f.xy<caret>
+3
View File
@@ -0,0 +1,3 @@
def my_func(my_arg):
assert isinstance(my_arg, basestring)
print my<ref>_arg
@@ -26,7 +26,7 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
private void doTest() throws Exception {
final String testName = getTestName(false).toLowerCase();
configureByFile(testName + ".py");
final ControlFlow flow = ((PyFile)myFile).getControlFlow();
final ControlFlow flow = ((PyFile)myFile).getControlFlow();
final String fullPath = getTestDataPath() + testName + ".txt";
check(fullPath, flow);
}
@@ -38,7 +38,7 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
public void testFile() throws Exception {
doTest();
}
public void testIf() throws Exception {
doTest();
}
@@ -152,7 +152,7 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
check(fullPath, flow);
}
private void check(final String fullPath, final ControlFlow flow) throws IOException {
private static void check(final String fullPath, final ControlFlow flow) throws IOException {
final StringBuffer buffer = new StringBuffer();
final Instruction[] instructions = flow.getInstructions();
for (Instruction instruction : instructions) {
@@ -309,4 +309,9 @@ public class PyResolveTest extends PyResolveTestCase {
ImportedResolveResult result = (ImportedResolveResult) results [0];
assertNull(result.getElement());
}
public void testIsInstance() { // PY-1133
PsiElement targetElement = resolve();
assertInstanceOf(targetElement, PyNamedParameter.class);
}
}
@@ -99,6 +99,14 @@ public class PythonCompletionTest extends PyLightFixtureTestCase {
doTest();
}
public void testIsInstance() throws Exception {
doTest();
}
public void testIsInstanceAssert() throws Exception {
doTest();
}
public void testImportModule() throws Exception {
final String testName = "completion/" + getTestName(true);
myFixture.configureByFiles(testName + ".py", "completion/someModule.py");
@@ -37,7 +37,7 @@ public abstract class LightMarkedTestCase extends PyLightFixtureTestCase {
* @return a mapping of markers to PSI elements
* @throws Exception
*/
protected Map<String, PsiElement> configureByFile(@NonNls String filePath) throws Exception {
protected Map<String, PsiElement> configureByFile(@TestDataFile @NonNls String filePath) throws Exception {
return configureByFile(filePath, MARKER);
}