Fixed type inference for type() calls (PY-7058)

This commit is contained in:
Andrey Vlasovskikh
2012-07-26 21:54:15 +04:00
parent 614c51ae1a
commit 036e056b21
2 changed files with 53 additions and 0 deletions
@@ -110,6 +110,25 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
return superCallType.value();
}
}
if ("type".equals(callee.getText())) {
final PyExpression[] args = getArguments();
if (args.length == 1) {
final PyExpression arg = args[0];
final PyType argType = arg.getType(context);
if (argType instanceof PyClassType) {
final PyClassType classType = (PyClassType)argType;
if (!classType.isDefinition()) {
final PyClass cls = classType.getPyClass();
if (cls != null) {
return cls.getType(context);
}
}
}
else {
return null;
}
}
}
// normal cases
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
ResolveResult[] targets = ((PyReferenceExpression)callee).getReference(resolveContext).multiResolve(false);
@@ -385,6 +385,40 @@ public class PyTypeTest extends PyTestCase {
assertNull(actual);
}
// PY-7058
public void testReturnTypeOfTypeForInstance() {
PyExpression expr = parseExpr("class C(object):\n" +
" pass\n" +
"\n" +
"x = C()\n" +
"expr = type(x)\n");
TypeEvalContext context = TypeEvalContext.slow().withTracing();
PyType type = expr.getType(context);
assertInstanceOf(type, PyClassType.class);
assertTrue("Got instance type instead of class type", ((PyClassType)type).isDefinition());
}
// PY-7058
public void testReturnTypeOfTypeForClass() {
PyExpression expr = parseExpr("class C(object):\n" +
" pass\n" +
"\n" +
"expr = type(C)\n");
TypeEvalContext context = TypeEvalContext.slow().withTracing();
PyType type = expr.getType(context);
assertInstanceOf(type, PyClassType.class);
assertEquals(type.getName(), "type");
}
// PY-7058
public void testReturnTypeOfTypeForUnknown() {
PyExpression expr = parseExpr("def f(x):\n" +
" expr = type(x)\n");
TypeEvalContext context = TypeEvalContext.slow().withTracing();
PyType type = expr.getType(context);
assertNull(type);
}
private PyExpression parseExpr(String text) {
myFixture.configureByText(PythonFileType.INSTANCE, text);
return myFixture.findElementByText("expr", PyExpression.class);