Switched to @NotNull call site in Callable.getCallType() and PyCallableType.getCallType()

Changed some usages of getCallType() to getReturnType() and fixed
handling of functions with custom decorators.
This commit is contained in:
Andrey Vlasovskikh
2014-03-03 15:39:47 +04:00
parent eb0b14f04f
commit e77d5bb8b7
16 changed files with 40 additions and 28 deletions
@@ -113,7 +113,7 @@ public class PyJavaClassType implements PyClassLikeType {
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
return getReturnType();
}
@@ -58,7 +58,7 @@ public class PyJavaMethodType implements PyCallableType {
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
return getReturnType();
}
@@ -45,7 +45,7 @@ public interface Callable extends PyTypedElement, PyQualifiedNameOwner {
* Returns the type of the call to the callable.
*/
@Nullable
PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite);
PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite);
/**
* Returns the type of the call to the callable where the call site is specified by the optional receiver and the arguments to parameters
@@ -45,7 +45,7 @@ public interface PyCallableType extends PyType {
* Returns the type which is the result of calling an instance of this type.
*/
@Nullable
PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite);
PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite);
/**
* Returns the list of parameter types.
@@ -95,7 +95,7 @@ public class PyNamedTupleType extends PyClassTypeImpl implements PyCallableType
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
if (myDefinitionLevel > 0) {
return new PyNamedTupleType(myClass, myDeclaration, myName, myFields, myDefinitionLevel-1);
}
@@ -226,7 +226,7 @@ public class PyTypeModelBuilder {
parameterModels.add(new ParamType(parameter.getName(), build(parameter.getType(myContext), true)));
}
}
final PyType ret = type.getCallType(myContext, null);
final PyType ret = type.getReturnType();
final TypeModel returnType = build(ret, true);
return new FunctionType(returnType, parameterModels);
}
@@ -301,7 +301,9 @@ public class PyPropertyDefinitionInspection extends PyInspection {
}
else {
PyReferenceExpression callSite = being_checked instanceof PyReferenceExpression ? (PyReferenceExpression) being_checked : null;
hasReturns = !(callable.getCallType(myTypeEvalContext, callSite) instanceof PyNoneType);
final PyType type = callSite != null ? callable.getCallType(myTypeEvalContext, callSite)
: callable.getReturnType(myTypeEvalContext);
hasReturns = !(type instanceof PyNoneType);
}
if (allowed ^ hasReturns) {
if (allowed && callable instanceof PyFunction) {
@@ -463,8 +463,14 @@ public class PyCallExpressionHelper {
else {
final PyType type = context.getType(callee);
if (type instanceof PyCallableType) {
final PyCallableType callableType = (PyCallableType)type;
final PyQualifiedExpression callSite = callee instanceof PyQualifiedExpression ? (PyQualifiedExpression)callee : null;
return ((PyCallableType) type).getCallType(context, callSite);
if (callSite != null) {
return callableType.getCallType(context, callSite);
}
else {
return callableType.getReturnType();
}
}
return null;
}
@@ -176,7 +176,11 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
@Nullable
@Override
public PyType getReturnType(@NotNull TypeEvalContext context) {
final PyType type = context.getType(this);
PyType type = context.getType(this);
if (type instanceof PyUnionType) {
final PyUnionType unionType = (PyUnionType)type;
type = unionType.excludeNull();
}
if (type instanceof PyCallableType) {
return ((PyCallableType)type).getReturnType();
}
@@ -218,7 +222,7 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
PyType type = null;
for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
type = typeProvider.getCallType(this, callSite, context);
@@ -230,9 +234,6 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
if (type == null) {
type = getReturnType(context);
}
if (callSite == null) {
return type;
}
final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, context);
if (results != null) {
return analyzeCallType(type, results.getReceiver(), results.getArguments(), context);
@@ -249,8 +250,10 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
}
@Nullable
private PyType analyzeCallType(@Nullable PyType type, @Nullable PyExpression receiver,
@NotNull Map<PyExpression, PyNamedParameter> parameters, @NotNull TypeEvalContext context) {
private PyType analyzeCallType(@Nullable PyType type,
@Nullable PyExpression receiver,
@NotNull Map<PyExpression, PyNamedParameter> parameters,
@NotNull TypeEvalContext context) {
if (PyTypeChecker.hasGenerics(type, context)) {
final Map<PyGenericType, PyType> substitutions = PyTypeChecker.unifyGenericCall(receiver, parameters, context);
if (substitutions != null) {
@@ -400,8 +403,10 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
return type;
}
}
final PyFunctionType type = new PyFunctionType(this, calculateReturnType(context));
if (PyUtil.hasCustomDecorators(this) && !PyUtil.isDecoratedAsAbstract(this) && getProperty() == null) {
final boolean hasCustomDecorators = PyUtil.hasCustomDecorators(this) && !PyUtil.isDecoratedAsAbstract(this) && getProperty() == null;
final PyType returnType = calculateReturnType(context);
final PyFunctionType type = new PyFunctionType(this, hasCustomDecorators ? PyUnionType.createWeakType(returnType) : returnType);
if (hasCustomDecorators) {
return PyUnionType.createWeakType(type);
}
return type;
@@ -80,7 +80,7 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
return getReturnType(context);
}
@@ -55,7 +55,7 @@ public class PyCallableTypeImpl implements PyCallableType {
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
return myReturnType;
}
@@ -316,7 +316,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
return getReturnType();
}
@@ -54,7 +54,7 @@ public class PyFunctionType implements PyCallableType {
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyQualifiedExpression callSite) {
return myCallable.getCallType(context, callSite);
}
@@ -171,8 +171,7 @@ public class PyTypeChecker {
}
}
}
if (!match(expectedCallable.getCallType(context, null), actualCallable.getCallType(context, null), context, substitutions,
recursive)) {
if (!match(expectedCallable.getReturnType(), actualCallable.getReturnType(), context, substitutions, recursive)) {
return false;
}
return true;
@@ -258,7 +257,7 @@ public class PyTypeChecker {
}
}
}
collectGenerics(callable.getCallType(context, null), context, collected, visited);
collectGenerics(callable.getReturnType(), context, collected, visited);
}
}
@@ -308,7 +307,7 @@ public class PyTypeChecker {
substParams.add(subst);
}
}
final PyType substResult = substitute(callable.getCallType(context, null), substitutions, context);
final PyType substResult = substitute(callable.getReturnType(), substitutions, context);
return new PyCallableTypeImpl(substParams, substResult);
}
}
+1 -1
View File
@@ -1 +1 @@
<html><body><code><small>class <a href="psi_element://#class#">Foo</a></small><br><br>@<i>deco</i><br>def <b>meth</b>(self)<br>Inferred&nbsp;type:&nbsp;(self:&nbsp;<a href="psi_element://#typename#Foo">Foo</a>)&nbsp;-&gt;&nbsp;unknown<br><br><br>Doc&nbsp;of&nbsp;meth.<br></code></body></html>
<html><body><code><small>class <a href="psi_element://#class#">Foo</a></small><br><br>@<i>deco</i><br>def <b>meth</b>(self)<br>Inferred&nbsp;type:&nbsp;(self:&nbsp;<a href="psi_element://#typename#Foo">Foo</a>)&nbsp;-&gt;&nbsp;None<br><br><br>Doc&nbsp;of&nbsp;meth.<br></code></body></html>
@@ -252,7 +252,7 @@ public class PyTypeParserTest extends PyTestCase {
final PyCallableType callableType = (PyCallableType)type;
assertNotNull(callableType);
final TypeEvalContext context = getTypeEvalContext();
final PyType returnType = callableType.getCallType(context, null);
final PyType returnType = callableType.getReturnType();
assertInstanceOf(returnType, PyGenericType.class);
final List<PyCallableParameter> parameterTypes = callableType.getParameters(context);
assertNotNull(parameterTypes);
@@ -271,7 +271,7 @@ public class PyTypeParserTest extends PyTestCase {
assertInstanceOf(type, PyCallableType.class);
final PyCallableType callableType = (PyCallableType)type;
assertNotNull(callableType);
final PyType returnType = callableType.getCallType(getTypeEvalContext(), null);
final PyType returnType = callableType.getReturnType();
assertNotNull(returnType);
assertEquals("int", returnType.getName());
final List<PyCallableParameter> parameterTypes = callableType.getParameters(getTypeEvalContext());