diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java index 3c778d28540a..87cbdaf9ab10 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaClassType.java @@ -104,7 +104,7 @@ public class PyJavaClassType implements PyClassLikeType { @Nullable @Override - public PyType getReturnType(@NotNull TypeEvalContext context) { + public PyType getReturnType() { if (myDefinition) { return new PyJavaClassType(myClass, false); } @@ -114,7 +114,7 @@ public class PyJavaClassType implements PyClassLikeType { @Nullable @Override public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { - return getReturnType(context); + return getReturnType(); } @Nullable diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java index 5b496c14a07a..247e5e9ad9b2 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaMethodType.java @@ -52,14 +52,14 @@ public class PyJavaMethodType implements PyCallableType { @Nullable @Override - public PyType getReturnType(@NotNull TypeEvalContext context) { + public PyType getReturnType() { return PyJavaTypeProvider.asPyType(myMethod.getReturnType()); } @Nullable @Override public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { - return getReturnType(context); + return getReturnType(); } @Nullable diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java index 7292391ad4f8..109a20e6c60d 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyCallableType.java @@ -39,7 +39,7 @@ public interface PyCallableType extends PyType { * For example, it may return a generic type. */ @Nullable - PyType getReturnType(@NotNull TypeEvalContext context); + PyType getReturnType(); /** * Returns the type which is the result of calling an instance of this type. diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 26cb36fd9f8f..1f789ba673a8 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -177,6 +177,15 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp @Nullable @Override public PyType getReturnType(@NotNull TypeEvalContext context) { + final PyType type = context.getType(this); + if (type instanceof PyCallableType) { + return ((PyCallableType)type).getReturnType(); + } + return null; + } + + @Nullable + private PyType calculateReturnType(@NotNull TypeEvalContext context) { for (PyTypeProvider typeProvider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) { final PyType returnType = typeProvider.getReturnType(this, context); if (returnType != null) { @@ -399,8 +408,8 @@ public class PyFunctionImpl extends PyPresentableElementImpl imp return type; } } - final PyFunctionType type = new PyFunctionType(this); - if (getDecoratorList() != null) { + final PyFunctionType type = new PyFunctionType(this, calculateReturnType(context)); + if (PyUtil.hasCustomDecorators(this) && !PyUtil.isDecoratedAsAbstract(this) && getProperty() == null) { return PyUnionType.createWeakType(type); } return type; diff --git a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java index 99c50c86123b..f39a88947adb 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyLambdaExpressionImpl.java @@ -21,6 +21,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache; import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.types.PyCallableType; import com.jetbrains.python.psi.types.PyFunctionType; import com.jetbrains.python.psi.types.PyType; import com.jetbrains.python.psi.types.TypeEvalContext; @@ -46,7 +47,7 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp return type; } } - return new PyFunctionType(this); + return new PyFunctionType(this, calculateReturnType(context)); } @NotNull @@ -62,6 +63,15 @@ public class PyLambdaExpressionImpl extends PyElementImpl implements PyLambdaExp @Nullable @Override public PyType getReturnType(@NotNull TypeEvalContext context) { + final PyType type = context.getType(this); + if (type instanceof PyCallableType) { + return ((PyCallableType)type).getReturnType(); + } + return null; + } + + @Nullable + private PyType calculateReturnType(@NotNull TypeEvalContext context) { final PyExpression body = getBody(); return body != null ? context.getType(body) : null; } diff --git a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java index 9c1d2a649263..2c37790558c1 100644 --- a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java @@ -49,8 +49,7 @@ public class PyCallableTypeImpl implements PyCallableType { @Nullable @Override - public PyType getReturnType(@NotNull TypeEvalContext context) { - // TODO: Check that this return type doesn't depend on the call site for all PyCallableTypeImpl objects + public PyType getReturnType() { return myReturnType; } diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index fd1097918dcf..c557c63c9603 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -307,7 +307,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { @Nullable @Override - public PyType getReturnType(@NotNull TypeEvalContext context) { + public PyType getReturnType() { if (isDefinition()) { return new PyClassTypeImpl(getPyClass(), false); } @@ -317,7 +317,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { @Nullable @Override public PyType getCallType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) { - return getReturnType(context); + return getReturnType(); } @Nullable diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java index 6d577721063c..804f19b63b89 100644 --- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java +++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java @@ -34,9 +34,11 @@ import java.util.List; */ public class PyFunctionType implements PyCallableType { @NotNull private final Callable myCallable; + @Nullable private final PyType myReturnType; - public PyFunctionType(@NotNull Callable callable) { + public PyFunctionType(@NotNull Callable callable, @Nullable PyType returnType) { myCallable = callable; + myReturnType = returnType; } @Override @@ -46,9 +48,8 @@ public class PyFunctionType implements PyCallableType { @Nullable @Override - public PyType getReturnType(@NotNull TypeEvalContext context) { - // TODO: Make Callable.getReturnType() call site independent, extract getCallType() - return myCallable.getCallType(context, null); + public PyType getReturnType() { + return myReturnType; } @Nullable diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index 9e6fef3f173d..b698869ea379 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -355,7 +355,7 @@ public class PyTypeChecker { if (init instanceof PyTypedElement) { final PyType initType = context.getType((PyTypedElement)init); if (initType instanceof PyCallableType) { - final PyType initReturnType = ((PyCallableType)initType).getReturnType(context); + final PyType initReturnType = ((PyCallableType)initType).getReturnType(); if (initReturnType != null) { match(initReturnType, qualifierType, context, substitutions); } diff --git a/python/testData/quickdoc/Method.html b/python/testData/quickdoc/Method.html index c99d4b3cbd1b..db6787aadafe 100644 --- a/python/testData/quickdoc/Method.html +++ b/python/testData/quickdoc/Method.html @@ -1 +1 @@ -class Foo

@deco
def meth(self)
Inferred type: (self: Foo) -> None


Doc of meth.
\ No newline at end of file +class Foo

@deco
def meth(self)
Inferred type: (self: Foo) -> unknown


Doc of meth.
\ No newline at end of file