mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Moved annotation-based type inference to PyTypingTypeProvider
We couldn't do check for 'typing.Any' inside PyTypingTypeProvider, so we had to put some 'typing' knowlegde into PyFunctionImpl and PyParameterImpl which wasn't elegant. Also we couldn't combine type information from annotations and default arguments that was required for Optional[T] for 'x: T = None'. Now we can implement it.
This commit is contained in:
@@ -22,7 +22,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public interface PyAnnotation extends PyTypedElement, StubBasedPsiElement<PyAnnotationStub> {
|
||||
public interface PyAnnotation extends PyElement, StubBasedPsiElement<PyAnnotationStub> {
|
||||
@Nullable
|
||||
PyExpression getValue();
|
||||
}
|
||||
|
||||
@@ -172,6 +172,10 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
if (genericType != null) {
|
||||
return genericType;
|
||||
}
|
||||
final Ref<PyType> classType = getClassType(expression, context);
|
||||
if (classType != null) {
|
||||
return classType.get();
|
||||
}
|
||||
final PyType stringBasedType = getStringBasedType(expression, context);
|
||||
if (stringBasedType != null) {
|
||||
return stringBasedType;
|
||||
@@ -179,6 +183,25 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Ref<PyType> getClassType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
|
||||
final PyType type = context.getType(expression);
|
||||
if (type != null && isAny(type)) {
|
||||
return Ref.create();
|
||||
}
|
||||
if (type instanceof PyClassLikeType) {
|
||||
final PyClassLikeType classType = (PyClassLikeType)type;
|
||||
if (classType.isDefinition()) {
|
||||
final PyType instanceType = classType.toInstance();
|
||||
return Ref.create(instanceType);
|
||||
}
|
||||
}
|
||||
else if (type instanceof PyNoneType) {
|
||||
return Ref.create(type);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Ref<PyType> getOptionalType(@NotNull PyExpression expression, @NotNull TypeEvalContext context) {
|
||||
if (expression instanceof PySubscriptionExpression) {
|
||||
|
||||
@@ -20,11 +20,6 @@ import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.psi.PyAnnotation;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.stubs.PyAnnotationStub;
|
||||
import com.jetbrains.python.psi.types.PyClassLikeType;
|
||||
import com.jetbrains.python.psi.types.PyNoneType;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -44,23 +39,4 @@ public class PyAnnotationImpl extends PyBaseElementImpl<PyAnnotationStub> implem
|
||||
public PyExpression getValue() {
|
||||
return findChildByClass(PyExpression.class);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) {
|
||||
final PyExpression value = getValue();
|
||||
if (value != null) {
|
||||
final PyType type = context.getType(value);
|
||||
if (type instanceof PyClassLikeType) {
|
||||
final PyClassLikeType classType = (PyClassLikeType)type;
|
||||
if (classType.isDefinition()) {
|
||||
return classType.toInstance();
|
||||
}
|
||||
}
|
||||
else if (type instanceof PyNoneType) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ import com.intellij.util.PlatformIcons;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.codeInsight.PyTypingTypeProvider;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
@@ -193,18 +192,6 @@ public class PyFunctionImpl extends PyBaseElementImpl<PyFunctionStub> implements
|
||||
return returnType;
|
||||
}
|
||||
}
|
||||
if (context.maySwitchToAST(this) && LanguageLevel.forElement(this).isAtLeast(LanguageLevel.PYTHON30)) {
|
||||
final PyAnnotation annotation = getAnnotation();
|
||||
if (annotation != null) {
|
||||
final PyType type = context.getType(annotation);
|
||||
if (type != null) {
|
||||
if (PyTypingTypeProvider.isAny(type)) {
|
||||
return null;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
}
|
||||
final PyType docStringType = getReturnTypeFromDocString();
|
||||
if (docStringType != null) {
|
||||
docStringType.assertValid("from docstring");
|
||||
|
||||
@@ -33,7 +33,6 @@ import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonDialectsTokenSetProvider;
|
||||
import com.jetbrains.python.codeInsight.PyTypingTypeProvider;
|
||||
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
|
||||
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
|
||||
import com.jetbrains.python.psi.*;
|
||||
@@ -229,16 +228,6 @@ public class PyNamedParameterImpl extends PyBaseElementImpl<PyNamedParameterStub
|
||||
return resultRef.get();
|
||||
}
|
||||
}
|
||||
final PyAnnotation annotation = getAnnotation();
|
||||
if (annotation != null) {
|
||||
final PyType type = context.getType(annotation);
|
||||
if (type != null) {
|
||||
if (PyTypingTypeProvider.isAny(type)) {
|
||||
return null;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
}
|
||||
if (context.maySwitchToAST(this)) {
|
||||
final PyExpression defaultValue = getDefaultValue();
|
||||
if (defaultValue != null) {
|
||||
|
||||
Reference in New Issue
Block a user