From dd328f3a607939b5f7877ead001f56d90918c1ce Mon Sep 17 00:00:00 2001 From: Daniil Kalinin Date: Thu, 29 Aug 2024 12:01:34 +0200 Subject: [PATCH] PY-71002 PEP-696: Adapt the interfaces and implementations of Type Parameter types for the support of defaults In particular: - Add getters and setters for default types of Type Parameters - Change the type of declaration elements for Type Parameters from hardcoded PyTargetExpression to PyQualifiedNameOwner to make it possible to set new-style Type Parameters as declaration elements - Correctly calculate the qualified names of the new-style type alias statements as now they will be used in declaration elements of Type Parameters GitOrigin-RevId: 5185d85c1a75052dfcb3f97c0eee17b52540d24b --- .../jetbrains/python/psi/PyTypeParameter.java | 2 +- .../python/psi/types/PyTypeParameterType.java | 5 +++ .../python/psi/impl/PyTypeParameterImpl.java | 7 +++- .../psi/resolve/QualifiedNameFinder.java | 6 +++ .../python/psi/types/PyGenericType.java | 34 +++++++++++------ .../python/psi/types/PyParamSpecType.java | 38 ++++++++++++------- .../psi/types/PyTypeVarTupleTypeImpl.java | 33 ++++++++++++---- .../python/psi/types/PyTypeVarTypeImpl.java | 3 ++ 8 files changed, 94 insertions(+), 34 deletions(-) diff --git a/python/python-psi-api/src/com/jetbrains/python/psi/PyTypeParameter.java b/python/python-psi-api/src/com/jetbrains/python/psi/PyTypeParameter.java index 67fe4fca90df..9b00bc792e6c 100644 --- a/python/python-psi-api/src/com/jetbrains/python/psi/PyTypeParameter.java +++ b/python/python-psi-api/src/com/jetbrains/python/psi/PyTypeParameter.java @@ -11,7 +11,7 @@ import org.jetbrains.annotations.Nullable; * Represents a Type Parameter that can be a part of {@link PyTypeParameterList}
* For more information see PEP 695 */ -public interface PyTypeParameter extends PyAstTypeParameter, PyElement, PsiNameIdentifierOwner, PyTypedElement, StubBasedPsiElement { +public interface PyTypeParameter extends PyAstTypeParameter, PyElement, PsiNameIdentifierOwner, PyTypedElement, PyQualifiedNameOwner, StubBasedPsiElement { @Override @Nullable diff --git a/python/python-psi-api/src/com/jetbrains/python/psi/types/PyTypeParameterType.java b/python/python-psi-api/src/com/jetbrains/python/psi/types/PyTypeParameterType.java index 9bde566a1aa5..6e36b92b0114 100644 --- a/python/python-psi-api/src/com/jetbrains/python/psi/types/PyTypeParameterType.java +++ b/python/python-psi-api/src/com/jetbrains/python/psi/types/PyTypeParameterType.java @@ -79,4 +79,9 @@ public interface PyTypeParameterType extends PyType { * Results of {@code getScopeOwner()} and {@link #getName()} constitute unique "coordinates" of a given type parameter. */ @Nullable PyQualifiedNameOwner getScopeOwner(); + + @Nullable + default PyType getDefaultType() { + return null; + } } diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/impl/PyTypeParameterImpl.java b/python/python-psi-impl/src/com/jetbrains/python/psi/impl/PyTypeParameterImpl.java index 27c6d4302712..f83cafbdc66e 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/psi/impl/PyTypeParameterImpl.java +++ b/python/python-psi-impl/src/com/jetbrains/python/psi/impl/PyTypeParameterImpl.java @@ -4,10 +4,10 @@ import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; import com.intellij.psi.stubs.IStubElementType; import com.intellij.util.IncorrectOperationException; -import com.jetbrains.python.PyElementTypes; import com.jetbrains.python.PyStubElementTypes; import com.jetbrains.python.codeInsight.typing.PyTypingTypeProvider; import com.jetbrains.python.psi.*; +import com.jetbrains.python.psi.resolve.QualifiedNameFinder; import com.jetbrains.python.psi.stubs.PyTypeParameterStub; import com.jetbrains.python.psi.types.PyClassTypeImpl; import com.jetbrains.python.psi.types.PyType; @@ -108,4 +108,9 @@ public class PyTypeParameterImpl extends PyBaseElementImpl } return null; } + + @Override + public @Nullable String getQualifiedName() { + return QualifiedNameFinder.getQualifiedName(this); + } } diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java b/python/python-psi-impl/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java index 7bded3919257..add7e4891b2d 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java +++ b/python/python-psi-impl/src/com/jetbrains/python/psi/resolve/QualifiedNameFinder.java @@ -216,6 +216,12 @@ public final class QualifiedNameFinder { return classQName + "." + name; } } + if (owner instanceof PyTypeAliasStatement typeAliasStatement) { + final String typeQName = typeAliasStatement.getQualifiedName(); + if (typeQName != null) { + return typeQName + "." + name; + } + } else if (owner instanceof PyFile) { if (builtinCache.isBuiltin(element)) { return name; diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyGenericType.java b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyGenericType.java index b08ea1612e44..e9b938bfbb75 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyGenericType.java +++ b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyGenericType.java @@ -25,38 +25,45 @@ import java.util.Objects; public class PyGenericType implements PyTypeVarType { @NotNull private final String myName; @Nullable private final PyType myBound; + @Nullable private final PyType myDefaultType; private final boolean myIsDefinition; - @Nullable private final PyTargetExpression myTargetExpression; + @Nullable private final PyQualifiedNameOwner myDeclarationElement; @Nullable private PyQualifiedNameOwner myScopeOwner; public PyGenericType(@NotNull String name, @Nullable PyType bound) { this(name, bound, false); } + public PyGenericType(@NotNull String name, @Nullable PyType bound, @Nullable PyType defaultType) { + this(name, bound, defaultType, false, null, null); + } + public PyGenericType(@NotNull String name, @Nullable PyType bound, boolean isDefinition) { this(name, bound, isDefinition, null); } private PyGenericType(@NotNull String name, @Nullable PyType bound, boolean isDefinition, @Nullable PyTargetExpression target) { - this(name, bound, isDefinition, target, null); + this(name, bound, null, isDefinition, target, null); } private PyGenericType(@NotNull String name, @Nullable PyType bound, + @Nullable PyType defaultType, boolean isDefinition, - @Nullable PyTargetExpression target, + @Nullable PyQualifiedNameOwner declarationElement, @Nullable PyQualifiedNameOwner scopeOwner) { myName = name; myBound = bound; + myDefaultType = defaultType; myIsDefinition = isDefinition; - myTargetExpression = target; + myDeclarationElement = declarationElement; myScopeOwner = scopeOwner; } @Nullable @Override - public PyTargetExpression getDeclarationElement() { - return myTargetExpression; + public PyQualifiedNameOwner getDeclarationElement() { + return myDeclarationElement; } @Nullable @@ -136,6 +143,11 @@ public class PyGenericType implements PyTypeVarType { return myBound; } + @Override + public PyType getDefaultType() { + return myDefaultType; + } + @Override public boolean isDefinition() { return myIsDefinition; @@ -148,12 +160,12 @@ public class PyGenericType implements PyTypeVarType { @NotNull public PyGenericType withScopeOwner(@Nullable PyQualifiedNameOwner scopeOwner) { - return new PyGenericType(getName(), getBound(), isDefinition(), getDeclarationElement(), scopeOwner); + return new PyGenericType(getName(), getBound(), getDefaultType(), isDefinition(), getDeclarationElement(), scopeOwner); } @NotNull - public PyGenericType withTargetExpression(@Nullable PyTargetExpression targetExpression) { - return new PyGenericType(getName(), getBound(), isDefinition(), targetExpression, getScopeOwner()); + public PyGenericType withDeclarationElement(@Nullable PyQualifiedNameOwner declarationElement) { + return new PyGenericType(getName(), getBound(), getDefaultType(), isDefinition(), declarationElement, getScopeOwner()); } @ApiStatus.Internal @@ -167,12 +179,12 @@ public class PyGenericType implements PyTypeVarType { @NotNull @Override public PyGenericType toInstance() { - return myIsDefinition ? new PyGenericType(myName, myBound, false, myTargetExpression, myScopeOwner) : this; + return myIsDefinition ? new PyGenericType(myName, myBound, myDefaultType, false, myDeclarationElement, myScopeOwner) : this; } @NotNull @Override public PyGenericType toClass() { - return myIsDefinition ? this : new PyGenericType(myName, myBound, true, myTargetExpression, myScopeOwner); + return myIsDefinition ? this : new PyGenericType(myName, myBound, myDefaultType, true, myDeclarationElement, myScopeOwner); } } diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyParamSpecType.java b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyParamSpecType.java index 2dde52171868..de3355883d57 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyParamSpecType.java +++ b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyParamSpecType.java @@ -9,7 +9,6 @@ import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.AccessDirection; import com.jetbrains.python.psi.PyExpression; import com.jetbrains.python.psi.PyQualifiedNameOwner; -import com.jetbrains.python.psi.PyTargetExpression; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.resolve.RatedResolveResult; import org.jetbrains.annotations.NotNull; @@ -23,37 +22,45 @@ import java.util.Objects; */ public final class PyParamSpecType implements PyTypeParameterType { @NotNull private final String myName; - @Nullable private final PyTargetExpression myTargetExpression; + @Nullable private final PyQualifiedNameOwner myDeclarationElement; @Nullable private final List myParameters; + @Nullable private final PyType myDefaultType; @Nullable private final PyQualifiedNameOwner myScopeOwner; public PyParamSpecType(@NotNull String name) { - this(name, null, null, null); + this(name, null, null, null, null); } private PyParamSpecType(@NotNull String name, - @Nullable PyTargetExpression target, + @Nullable PyQualifiedNameOwner declarationElement, @Nullable List parameters, + @Nullable PyType defaultType, @Nullable PyQualifiedNameOwner scopeOwner) { myName = name; - myTargetExpression = target; + myDeclarationElement = declarationElement; myParameters = parameters; + myDefaultType = defaultType; myScopeOwner = scopeOwner; } @NotNull public PyParamSpecType withParameters(@Nullable List parameters, @NotNull TypeEvalContext context) { - return new PyParamSpecType(myName, myTargetExpression, getNonPsiParameters(parameters, context), myScopeOwner); + return new PyParamSpecType(myName, myDeclarationElement, getNonPsiParameters(parameters, context), myDefaultType, myScopeOwner); } @NotNull - public PyParamSpecType withTargetExpression(@Nullable PyTargetExpression target) { - return new PyParamSpecType(myName, target, myParameters, myScopeOwner); + public PyParamSpecType withDeclarationElement(@Nullable PyQualifiedNameOwner declarationElement) { + return new PyParamSpecType(myName, declarationElement, myParameters, myDefaultType, myScopeOwner); } @NotNull public PyParamSpecType withScopeOwner(@Nullable PyQualifiedNameOwner scopeOwner) { - return new PyParamSpecType(myName, myTargetExpression, myParameters, scopeOwner); + return new PyParamSpecType(myName, myDeclarationElement, myParameters, myDefaultType, scopeOwner); + } + + @NotNull + public PyParamSpecType withDefaultType(@Nullable PyType defaultType) { + return new PyParamSpecType(myName, myDeclarationElement, myParameters, defaultType, myScopeOwner); } @Nullable @@ -72,10 +79,9 @@ public final class PyParamSpecType implements PyTypeParameterType { return myParameters; } - @Nullable @Override - public PyTargetExpression getDeclarationElement() { - return myTargetExpression; + public @Nullable PyQualifiedNameOwner getDeclarationElement() { + return myDeclarationElement; } @Nullable @@ -117,6 +123,12 @@ public final class PyParamSpecType implements PyTypeParameterType { return myScopeOwner; } + @Override + @Nullable + public PyType getDefaultType() { + return myDefaultType; + } + @NotNull public String getVariableName() { return myName; @@ -140,7 +152,7 @@ public final class PyParamSpecType implements PyTypeParameterType { return false; } final PyParamSpecType type = (PyParamSpecType)o; - return myName.equals(type.myName) && Objects.equals(myScopeOwner, type.myScopeOwner); + return myName.equals(type.myName) && Objects.equals(myScopeOwner, type.myScopeOwner) && Objects.equals(myParameters, type.myParameters); } @Override diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTupleTypeImpl.java b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTupleTypeImpl.java index a119cdf0eb6c..92441c8f2716 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTupleTypeImpl.java +++ b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTupleTypeImpl.java @@ -2,7 +2,6 @@ package com.jetbrains.python.psi.types; import com.jetbrains.python.psi.PyQualifiedNameOwner; -import com.jetbrains.python.psi.PyTargetExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -11,25 +10,33 @@ import java.util.Objects; public final class PyTypeVarTupleTypeImpl implements PyTypeVarTupleType { private final @NotNull String myName; private final @Nullable PyQualifiedNameOwner myScopeOwner; - private final @Nullable PyTargetExpression myTarget; + private final @Nullable PyType myDefaultType; + private final @Nullable PyQualifiedNameOwner myDeclarationElement; public PyTypeVarTupleTypeImpl(@NotNull String name) { - this(name, null, null); + this(name, null, null, null); } - private PyTypeVarTupleTypeImpl(@NotNull String name, @Nullable PyTargetExpression target, @Nullable PyQualifiedNameOwner scopeOwner) { + private PyTypeVarTupleTypeImpl(@NotNull String name, @Nullable PyQualifiedNameOwner declarationElement, @Nullable PyType defaultType, @Nullable PyQualifiedNameOwner scopeOwner) { myName = name; - myTarget = target; + myDeclarationElement = declarationElement; + myDefaultType = defaultType; myScopeOwner = scopeOwner; } @NotNull public PyTypeVarTupleTypeImpl withScopeOwner(@Nullable PyQualifiedNameOwner scopeOwner) { - return new PyTypeVarTupleTypeImpl(myName, myTarget, scopeOwner); + return new PyTypeVarTupleTypeImpl(myName, myDeclarationElement, myDefaultType, scopeOwner); } - public PyTypeVarTupleTypeImpl withTargetExpression(@Nullable PyTargetExpression targetExpression) { - return new PyTypeVarTupleTypeImpl(myName, targetExpression, myScopeOwner); + @NotNull + public PyTypeVarTupleTypeImpl withDeclarationElement(@Nullable PyQualifiedNameOwner declarationElement) { + return new PyTypeVarTupleTypeImpl(myName, declarationElement, myDefaultType, myScopeOwner); + } + + @NotNull + public PyTypeVarTupleTypeImpl withDefaultType(@Nullable PyType defaultType) { + return new PyTypeVarTupleTypeImpl(myName, myDeclarationElement, defaultType, myScopeOwner); } @NotNull @@ -43,6 +50,16 @@ public final class PyTypeVarTupleTypeImpl implements PyTypeVarTupleType { return myScopeOwner; } + @Override + public @Nullable PyType getDefaultType() { + return myDefaultType; + } + + @Override + public @Nullable PyQualifiedNameOwner getDeclarationElement() { + return myDeclarationElement; + } + @Override public boolean equals(Object o) { if (this == o) { diff --git a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTypeImpl.java b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTypeImpl.java index 249edcbf3936..bd7a459fd2ff 100644 --- a/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTypeImpl.java +++ b/python/python-psi-impl/src/com/jetbrains/python/psi/types/PyTypeVarTypeImpl.java @@ -7,4 +7,7 @@ public final class PyTypeVarTypeImpl extends PyGenericType { public PyTypeVarTypeImpl(@NotNull String name, @Nullable PyType bound) { super(name, bound); } + public PyTypeVarTypeImpl(@NotNull String name, @Nullable PyType bound, @Nullable PyType defaultType) { + super(name, bound, defaultType); + } }