mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-15 02:59:33 +07:00
PY-71002 PEP-696: Support new syntax for default types of Type Parameters in new-style declarations
- PEP-696 adds a new syntax for declaring the default types of Type Parameters in new-new style generic classes, functions and type alias statements. Support these grammar changes. - Store info about default types in stubs for Type Parameters - Increment the stub version counter in PyFileElementType GitOrigin-RevId: b6b22e3eaa86ce06132885781e5775a89bf4b840
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d73bf77d9a
commit
7751fceaed
@@ -6,6 +6,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiNameIdentifierOwner;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -43,7 +44,30 @@ public interface PyAstTypeParameter extends PyAstElement, PsiNameIdentifierOwner
|
||||
|
||||
@Nullable
|
||||
default PyAstExpression getBoundExpression() {
|
||||
return PsiTreeUtil.getChildOfType(this, PyAstExpression.class);
|
||||
PsiElement element = StreamEx.of(getChildren())
|
||||
.findFirst(child -> {
|
||||
PsiElement e = PsiTreeUtil.skipWhitespacesBackward(child);
|
||||
return e != null && e.getNode().getElementType() == PyTokenTypes.COLON;
|
||||
})
|
||||
.orElse(null);
|
||||
if (element instanceof PyAstExpression expression) {
|
||||
return expression;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default PyAstExpression getDefaultExpression() {
|
||||
PsiElement element = StreamEx.of(getChildren())
|
||||
.findFirst(child -> {
|
||||
PsiElement e = PsiTreeUtil.skipWhitespacesBackward(child);
|
||||
return e != null && e.getNode().getElementType() == PyTokenTypes.EQ;
|
||||
})
|
||||
.orElse(null);
|
||||
if (element instanceof PyAstExpression expression) {
|
||||
return expression;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,6 +85,16 @@ public interface PyAstTypeParameter extends PyAstElement, PsiNameIdentifierOwner
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
default String getDefaultExpressionText() {
|
||||
PyAstExpression defaultExpression = getDefaultExpression();
|
||||
if (defaultExpression != null) {
|
||||
return defaultExpression.getText();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
default Kind getKind() {
|
||||
String paramText = getText();
|
||||
|
||||
@@ -1056,7 +1056,7 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
|
||||
nextToken();
|
||||
}
|
||||
|
||||
if (!parseIdentifierOrSkip(PyTokenTypes.RBRACKET, PyTokenTypes.COMMA, PyTokenTypes.COLON)) {
|
||||
if (!parseIdentifierOrSkip(PyTokenTypes.RBRACKET, PyTokenTypes.COMMA, PyTokenTypes.COLON, PyTokenTypes.EQ)) {
|
||||
typeParamMarker.drop();
|
||||
return false;
|
||||
}
|
||||
@@ -1066,6 +1066,12 @@ public class StatementParsing extends Parsing implements ITokenTypeRemapper {
|
||||
myBuilder.error(PyParsingBundle.message("PARSE.expected.expression"));
|
||||
}
|
||||
}
|
||||
|
||||
if (matchToken(PyTokenTypes.EQ)) {
|
||||
if (!myContext.getExpressionParser().parseSingleExpression(false)) {
|
||||
myBuilder.error(PyParsingBundle.message("PARSE.expected.expression"));
|
||||
}
|
||||
}
|
||||
typeParamMarker.done(PyElementTypes.TYPE_PARAMETER);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -12,9 +12,16 @@ import org.jetbrains.annotations.Nullable;
|
||||
* For more information see <a href="https://peps.python.org/pep-0695/">PEP 695</a>
|
||||
*/
|
||||
public interface PyTypeParameter extends PyAstTypeParameter, PyElement, PsiNameIdentifierOwner, PyTypedElement, StubBasedPsiElement<PyTypeParameterStub> {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
default PyExpression getBoundExpression() {
|
||||
return (PyExpression)PyAstTypeParameter.super.getBoundExpression();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
default PyExpression getDefaultExpression() {
|
||||
return (PyExpression)PyAstTypeParameter.super.getDefaultExpression();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,9 @@ public interface PyTypeParameterStub extends NamedStub<PyTypeParameter> {
|
||||
@Nullable
|
||||
String getBoundExpressionText();
|
||||
|
||||
@Nullable
|
||||
String getDefaultExpressionText();
|
||||
|
||||
@NotNull
|
||||
PyTypeParameter.Kind getKind();
|
||||
}
|
||||
|
||||
@@ -60,7 +60,7 @@ public class PyFileElementType extends IStubFileElementType<PyFileStub> {
|
||||
@Override
|
||||
public int getStubVersion() {
|
||||
// Don't forget to update versions of indexes that use the updated stub-based elements
|
||||
return 92;
|
||||
return 93;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -58,6 +58,16 @@ public class PyTypeParameterImpl extends PyBaseElementImpl<PyTypeParameterStub>
|
||||
return PyTypeParameter.super.getBoundExpressionText();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String getDefaultExpressionText() {
|
||||
PyTypeParameterStub stub = getStub();
|
||||
if (stub != null) {
|
||||
return stub.getDefaultExpressionText();
|
||||
}
|
||||
|
||||
return PyTypeParameter.super.getDefaultExpressionText();
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PyTypeParameter.Kind getKind() {
|
||||
|
||||
@@ -6,7 +6,6 @@ import com.intellij.psi.stubs.IStubElementType;
|
||||
import com.intellij.psi.stubs.StubElement;
|
||||
import com.intellij.psi.stubs.StubInputStream;
|
||||
import com.intellij.psi.stubs.StubOutputStream;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyStubElementTypes;
|
||||
import com.jetbrains.python.psi.PyStubElementType;
|
||||
import com.jetbrains.python.psi.PyTypeParameter;
|
||||
@@ -30,7 +29,9 @@ public class PyTypeParameterElementType extends PyStubElementType<PyTypeParamete
|
||||
@Override
|
||||
@NotNull
|
||||
public PyTypeParameterStub createStub(@NotNull PyTypeParameter psi, StubElement<? extends PsiElement> parentStub) {
|
||||
return new PyTypeParameterStubImpl(psi.getName(), psi.getKind(), psi.getBoundExpression() != null ? psi.getBoundExpression().getText() : null,
|
||||
return new PyTypeParameterStubImpl(psi.getName(), psi.getKind(),
|
||||
psi.getBoundExpression() != null ? psi.getBoundExpression().getText() : null,
|
||||
psi.getDefaultExpression() != null ? psi.getDefaultExpression().getText() : null,
|
||||
parentStub, getStubElementType());
|
||||
}
|
||||
|
||||
@@ -39,6 +40,7 @@ public class PyTypeParameterElementType extends PyStubElementType<PyTypeParamete
|
||||
dataStream.writeName(stub.getName());
|
||||
dataStream.writeVarInt(stub.getKind().getIndex());
|
||||
dataStream.writeName(stub.getBoundExpressionText());
|
||||
dataStream.writeName(stub.getDefaultExpressionText());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,9 +49,11 @@ public class PyTypeParameterElementType extends PyStubElementType<PyTypeParamete
|
||||
String name = dataStream.readNameString();
|
||||
PyTypeParameter.Kind kind = PyTypeParameter.Kind.fromIndex(dataStream.readVarInt());
|
||||
String boundExpressionText = dataStream.readNameString();
|
||||
String defaultExpressionText = dataStream.readNameString();
|
||||
return new PyTypeParameterStubImpl(name,
|
||||
kind,
|
||||
boundExpressionText,
|
||||
defaultExpressionText,
|
||||
parentStub, getStubElementType());
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ public class PyTypeParameterStubImpl extends StubBase<PyTypeParameter> implement
|
||||
|
||||
private final String myName;
|
||||
private final String myBoundExpressionText;
|
||||
private final String myDefaultExpressionText;
|
||||
|
||||
private final PyTypeParameter.Kind myKind;
|
||||
|
||||
@@ -19,12 +20,14 @@ public class PyTypeParameterStubImpl extends StubBase<PyTypeParameter> implement
|
||||
public PyTypeParameterStubImpl(@Nullable String name,
|
||||
@NotNull PyTypeParameter.Kind type,
|
||||
@Nullable String boundExpressionText,
|
||||
@Nullable String defaultExpressionText,
|
||||
@Nullable StubElement parent,
|
||||
@NotNull IStubElementType stubElementType) {
|
||||
super(parent, stubElementType);
|
||||
myName = name;
|
||||
myKind = type;
|
||||
myBoundExpressionText = boundExpressionText;
|
||||
myDefaultExpressionText = defaultExpressionText;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -33,6 +36,12 @@ public class PyTypeParameterStubImpl extends StubBase<PyTypeParameter> implement
|
||||
return myBoundExpressionText;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getDefaultExpressionText() {
|
||||
return myDefaultExpressionText;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public PyTypeParameter.Kind getKind() {
|
||||
@@ -47,6 +56,9 @@ public class PyTypeParameterStubImpl extends StubBase<PyTypeParameter> implement
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PyTypeParameterStub(name=" + myName + ", kind=" + myKind + ", bound=" + myBoundExpressionText + ")";
|
||||
return "PyTypeParameterStub(name=" + myName +
|
||||
", kind=" + myKind +
|
||||
", bound=" + myBoundExpressionText +
|
||||
", default=" + myDefaultExpressionText + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
class Baz[**P = [int, str]]: ...
|
||||
@@ -0,0 +1,33 @@
|
||||
PyFile:ParamSpecTypeParameterDefaultInClassDeclaration.py
|
||||
PyClass: Baz
|
||||
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('Baz')
|
||||
PyTypeParameterList
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTypeParameter
|
||||
PsiElement(Py:EXP)('**')
|
||||
PsiElement(Py:IDENTIFIER)('P')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PyListLiteralExpression
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyReferenceExpression: int
|
||||
PsiElement(Py:IDENTIFIER)('int')
|
||||
PsiElement(Py:COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: str
|
||||
PsiElement(Py:IDENTIFIER)('str')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PyArgumentList
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStatementList
|
||||
PyExpressionStatement
|
||||
PyNoneLiteralExpression
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
@@ -7,15 +7,15 @@ PyFile:TypeParameterListInTypeAliasStatementRecoveryNotClosedRightBracket.py
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTypeParameter
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: list
|
||||
PsiElement(Py:IDENTIFIER)('list')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyReferenceExpression: T
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiErrorElement:',' or ']' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: list
|
||||
PsiElement(Py:IDENTIFIER)('list')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyReferenceExpression: T
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
<empty list>
|
||||
@@ -0,0 +1 @@
|
||||
type MyType[T = list[T] = list[T]
|
||||
@@ -0,0 +1,31 @@
|
||||
PyFile:TypeParameterListInTypeAliasStatementRecoveryNotClosedRightBracketAfterDefault.py
|
||||
PyTypeAliasStatement
|
||||
PsiElement(Py:TYPE_KEYWORD)('type')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('MyType')
|
||||
PyTypeParameterList
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTypeParameter
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: list
|
||||
PsiElement(Py:IDENTIFIER)('list')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyReferenceExpression: T
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiErrorElement:',' or ']' expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: list
|
||||
PsiElement(Py:IDENTIFIER)('list')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyReferenceExpression: T
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
@@ -0,0 +1 @@
|
||||
class Qux[*Ts = *tuple[int, bool]]: ...
|
||||
@@ -0,0 +1,38 @@
|
||||
PyFile:TypeVarTupleTypeParameterDefaultInClassDeclaration.py
|
||||
PyClass: Qux
|
||||
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('Qux')
|
||||
PyTypeParameterList
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTypeParameter
|
||||
PsiElement(Py:MULT)('*')
|
||||
PsiElement(Py:IDENTIFIER)('Ts')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStarExpression
|
||||
PsiElement(Py:MULT)('*')
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: tuple
|
||||
PsiElement(Py:IDENTIFIER)('tuple')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTupleExpression
|
||||
PyReferenceExpression: int
|
||||
PsiElement(Py:IDENTIFIER)('int')
|
||||
PsiElement(Py:COMMA)(',')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: bool
|
||||
PsiElement(Py:IDENTIFIER)('bool')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PyArgumentList
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStatementList
|
||||
PyExpressionStatement
|
||||
PyNoneLiteralExpression
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
@@ -0,0 +1 @@
|
||||
class Foo[T = str]: ...
|
||||
@@ -0,0 +1,25 @@
|
||||
PyFile:TypeVarTypeParameterDefaultInClassDeclaration.py
|
||||
PyClass: Foo
|
||||
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('Foo')
|
||||
PyTypeParameterList
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTypeParameter
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: str
|
||||
PsiElement(Py:IDENTIFIER)('str')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PyArgumentList
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStatementList
|
||||
PyExpressionStatement
|
||||
PyNoneLiteralExpression
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
@@ -0,0 +1 @@
|
||||
type Foo[T = str] = Bar[T]
|
||||
@@ -0,0 +1,25 @@
|
||||
PyFile:TypeVarTypeParameterDefaultInTypeAliasStatement.py
|
||||
PyTypeAliasStatement
|
||||
PsiElement(Py:TYPE_KEYWORD)('type')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('Foo')
|
||||
PyTypeParameterList
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTypeParameter
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: str
|
||||
PsiElement(Py:IDENTIFIER)('str')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PySubscriptionExpression
|
||||
PyReferenceExpression: Bar
|
||||
PsiElement(Py:IDENTIFIER)('Bar')
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyReferenceExpression: T
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
@@ -0,0 +1 @@
|
||||
class Foo[T = ]: ...
|
||||
@@ -0,0 +1,25 @@
|
||||
PyFile:TypeVarTypeParameterDefaultMissingExpression.py
|
||||
PyClass: Foo
|
||||
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('Foo')
|
||||
PyTypeParameterList
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTypeParameter
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiErrorElement:Expression expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PyArgumentList
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStatementList
|
||||
PyExpressionStatement
|
||||
PyNoneLiteralExpression
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
@@ -0,0 +1 @@
|
||||
class Foo[T: str = ]: ...
|
||||
@@ -0,0 +1,29 @@
|
||||
PyFile:TypeVarTypeParameterWithBoundAndDefaultMissingExpression.py
|
||||
PyClass: Foo
|
||||
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('Foo')
|
||||
PyTypeParameterList
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTypeParameter
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: str
|
||||
PsiElement(Py:IDENTIFIER)('str')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiErrorElement:Expression expected
|
||||
<empty list>
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PyArgumentList
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStatementList
|
||||
PyExpressionStatement
|
||||
PyNoneLiteralExpression
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
@@ -0,0 +1 @@
|
||||
class Foo[T: str = str]: ...
|
||||
@@ -0,0 +1,29 @@
|
||||
PyFile:TypeVarTypeParameterWithDefaultAndBoundInClassDeclaration.py
|
||||
PyClass: Foo
|
||||
PsiElement(Py:CLASS_KEYWORD)('class')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:IDENTIFIER)('Foo')
|
||||
PyTypeParameterList
|
||||
PsiElement(Py:LBRACKET)('[')
|
||||
PyTypeParameter
|
||||
PsiElement(Py:IDENTIFIER)('T')
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: str
|
||||
PsiElement(Py:IDENTIFIER)('str')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(Py:EQ)('=')
|
||||
PsiWhiteSpace(' ')
|
||||
PyReferenceExpression: str
|
||||
PsiElement(Py:IDENTIFIER)('str')
|
||||
PsiElement(Py:RBRACKET)(']')
|
||||
PyArgumentList
|
||||
<empty list>
|
||||
PsiElement(Py:COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
PyStatementList
|
||||
PyExpressionStatement
|
||||
PyNoneLiteralExpression
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
PsiElement(Py:DOT)('.')
|
||||
@@ -1 +1 @@
|
||||
type myType[T, U: str, *Ts, **P] = Union[T, U]
|
||||
type myType[T, U: str, M = int, N: float = list, *Ts, **P] = Union[T, U]
|
||||
@@ -1,3 +1,3 @@
|
||||
class Clazz[T, U: str, *Ts, **P]:
|
||||
class Clazz[T, U: str, M = int, N: float = list, *Ts, **P]:
|
||||
a: T
|
||||
b: U
|
||||
@@ -1,2 +1,2 @@
|
||||
def foo[T, U: str, *Ts, **P](a: T, b: U):
|
||||
def foo[T, U: str, M = int, N: float = list, *Ts, **P](a: T, b: U):
|
||||
pass
|
||||
@@ -1227,11 +1227,15 @@ public class PyStubsTest extends PyTestCase {
|
||||
private static void doTestTypeParameterStub(@NotNull PyTypeParameterListOwner parameterListOwner, @NotNull PyFile file) {
|
||||
PyTypeParameter firstTypeParameter = parameterListOwner.getTypeParameterList().getTypeParameters().get(0);
|
||||
PyTypeParameter secondTypeParameter = parameterListOwner.getTypeParameterList().getTypeParameters().get(1);
|
||||
PyTypeParameter typeVarTupleTypeParameter = parameterListOwner.getTypeParameterList().getTypeParameters().get(2);
|
||||
PyTypeParameter paramSpecTypeParameter = parameterListOwner.getTypeParameterList().getTypeParameters().get(3);
|
||||
PyTypeParameter thirdTypeParameter = parameterListOwner.getTypeParameterList().getTypeParameters().get(2);
|
||||
PyTypeParameter fourthTypeParameter = parameterListOwner.getTypeParameterList().getTypeParameters().get(3);
|
||||
PyTypeParameter typeVarTupleTypeParameter = parameterListOwner.getTypeParameterList().getTypeParameters().get(4);
|
||||
PyTypeParameter paramSpecTypeParameter = parameterListOwner.getTypeParameterList().getTypeParameters().get(5);
|
||||
|
||||
assertNotNull(firstTypeParameter);
|
||||
assertNotNull(secondTypeParameter);
|
||||
assertNotNull(thirdTypeParameter);
|
||||
assertNotNull(fourthTypeParameter);
|
||||
assertNotNull(typeVarTupleTypeParameter);
|
||||
assertNotNull(paramSpecTypeParameter);
|
||||
|
||||
@@ -1239,13 +1243,20 @@ public class PyStubsTest extends PyTestCase {
|
||||
assertEquals(PyTypeParameter.Kind.TypeVar, firstTypeParameter.getKind());
|
||||
assertEquals("U", secondTypeParameter.getName());
|
||||
assertEquals(PyTypeParameter.Kind.TypeVar, secondTypeParameter.getKind());
|
||||
assertEquals("M", thirdTypeParameter.getName());
|
||||
assertEquals(PyTypeParameter.Kind.TypeVar, thirdTypeParameter.getKind());
|
||||
assertEquals("N", fourthTypeParameter.getName());
|
||||
assertEquals(PyTypeParameter.Kind.TypeVar, fourthTypeParameter.getKind());
|
||||
assertEquals("Ts", typeVarTupleTypeParameter.getName());
|
||||
assertEquals(PyTypeParameter.Kind.TypeVarTuple, typeVarTupleTypeParameter.getKind());
|
||||
assertEquals("P", paramSpecTypeParameter.getName());
|
||||
assertEquals(PyTypeParameter.Kind.ParamSpec, paramSpecTypeParameter.getKind());
|
||||
|
||||
assertNull(firstTypeParameter.getBoundExpressionText());
|
||||
assertEquals(secondTypeParameter.getBoundExpressionText(), "str");
|
||||
assertEquals("str", secondTypeParameter.getBoundExpressionText());
|
||||
assertEquals("int", thirdTypeParameter.getDefaultExpressionText());
|
||||
assertEquals("list", fourthTypeParameter.getDefaultExpressionText());
|
||||
assertEquals("float", fourthTypeParameter.getBoundExpressionText());
|
||||
|
||||
assertNotParsed(file);
|
||||
}
|
||||
|
||||
@@ -1308,6 +1308,11 @@ public class PythonParsingTest extends ParsingTestCase {
|
||||
doTest(LanguageLevel.PYTHON312);
|
||||
}
|
||||
|
||||
// PY-71002
|
||||
public void testTypeParameterListInTypeAliasStatementRecoveryNotClosedRightBracketAfterDefault() {
|
||||
doTest(LanguageLevel.PYTHON313);
|
||||
}
|
||||
|
||||
public void testTypeParameterListInTypeAliasStatementRecoveryUnexpectedSymbolAfterComma() {
|
||||
doTest(LanguageLevel.PYTHON312);
|
||||
}
|
||||
@@ -1324,6 +1329,41 @@ public class PythonParsingTest extends ParsingTestCase {
|
||||
doTest(LanguageLevel.PYTHON312);
|
||||
}
|
||||
|
||||
// PY-71002
|
||||
public void testTypeVarTypeParameterDefaultInClassDeclaration() {
|
||||
doTest(LanguageLevel.PYTHON313);
|
||||
}
|
||||
|
||||
// PY-71002
|
||||
public void testTypeVarTypeParameterDefaultInTypeAliasStatement() {
|
||||
doTest(LanguageLevel.PYTHON313);
|
||||
}
|
||||
|
||||
// PY-71002
|
||||
public void testParamSpecTypeParameterDefaultInClassDeclaration() {
|
||||
doTest(LanguageLevel.PYTHON313);
|
||||
}
|
||||
|
||||
// PY-71002
|
||||
public void testTypeVarTupleTypeParameterDefaultInClassDeclaration() {
|
||||
doTest(LanguageLevel.PYTHON313);
|
||||
}
|
||||
|
||||
// PY-71002
|
||||
public void testTypeVarTypeParameterWithDefaultAndBoundInClassDeclaration() {
|
||||
doTest(LanguageLevel.PYTHON313);
|
||||
}
|
||||
|
||||
// PY-71002
|
||||
public void testTypeVarTypeParameterDefaultMissingExpression() {
|
||||
doTest(LanguageLevel.PYTHON313);
|
||||
}
|
||||
|
||||
// PY-71002
|
||||
public void testTypeVarTypeParameterWithBoundAndDefaultMissingExpression() {
|
||||
doTest(LanguageLevel.PYTHON313);
|
||||
}
|
||||
|
||||
public void testTypeKeywordAsIdentifier() {
|
||||
doTest(LanguageLevel.PYTHON312);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user