Parse type parameters in class definitions

This commit is contained in:
Zanie 2023-07-12 10:24:43 -05:00
parent c8092b20a2
commit d923aa92bb
9 changed files with 24303 additions and 22583 deletions

View file

@ -636,6 +636,79 @@ class Foo(A, B):
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
}
#[test]
#[cfg(feature = "all-nodes-with-ranges")]
fn test_parse_class_with_empty_generic() {
let source = "\
class Foo[](A, B):
pass
";
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
}
#[test]
#[cfg(feature = "all-nodes-with-ranges")]
fn test_parse_class_with_generic_type() {
let source = "\
class Foo[T](A, B):
pass
";
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
}
#[test]
#[cfg(feature = "all-nodes-with-ranges")]
fn test_parse_class_with_generic_type_with_bound() {
let source = "\
class Foo[T: str](A, B):
pass
";
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
}
#[test]
#[cfg(feature = "all-nodes-with-ranges")]
fn test_parse_class_with_multiple_generic_types() {
let source = "\
class Foo[T, U](A, B):
pass
";
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
}
#[test]
#[cfg(feature = "all-nodes-with-ranges")]
fn test_parse_class_with_generic_type_var_tuple() {
let source = "\
class Foo[*U](A, B):
pass
";
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
}
#[test]
#[cfg(feature = "all-nodes-with-ranges")]
fn test_parse_class_with_generic_param_spec() {
let source = "\
class Foo[**P](A, B):
pass
";
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
}
#[test]
#[cfg(feature = "all-nodes-with-ranges")]
fn test_parse_class_with_all_possible_generic_types() {
let source = "\
class Foo[X, Y, *U, **P](A, B):
pass
";
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
}
#[test]
#[cfg(feature = "all-nodes-with-ranges")]
fn test_parse_dict_comprehension() {

View file

@ -1126,13 +1126,12 @@ KwargParameter<ArgType>: Option<Box<ast::Arg>> = {
};
ClassDef: ast::Stmt = {
<decorator_list:Decorator*> <location:@L> "class" <name:Identifier> <a:("(" ArgumentList ")")?> ":" <body:Suite> => {
<decorator_list:Decorator*> <location:@L> "class" <name:Identifier> <type_params:TypeParamList?> <a:("(" ArgumentList ")")?> ":" <body:Suite> => {
let (bases, keywords) = match a {
Some((_, arg, _)) => (arg.args, arg.keywords),
None => (vec![], vec![]),
};
let end_location = body.last().unwrap().end();
let type_params = Vec::new();
ast::Stmt::ClassDef(
ast::StmtClassDef {
name,
@ -1140,13 +1139,38 @@ ClassDef: ast::Stmt = {
keywords,
body,
decorator_list,
type_params,
type_params: type_params.unwrap_or_default(),
range: (location..end_location).into()
},
)
},
};
TypeParamList: Vec<ast::TypeParam> = {
<location:@L> "[" <vars:OneOrMore<TypeParam>> ","? "]" <end_location:@R> => {
vars
}
};
TypeParam: ast::TypeParam = {
<location:@L> <name:Identifier> <bound:(":" <Test<"all">>)?> <end_location:@R> => {
ast::TypeParam::TypeVar(
ast::TypeParamTypeVar { name, bound: bound.map(Box::new), range: (location..end_location).into() }
)
},
<location:@L> "*" <name:Identifier> <end_location:@R> => {
ast::TypeParam::TypeVarTuple(
ast::TypeParamTypeVarTuple { name, range: (location..end_location).into() }
)
},
<location:@L> "**" <name:Identifier> <end_location:@R> => {
ast::TypeParam::ParamSpec(
ast::TypeParamParamSpec { name, range: (location..end_location).into() }
)
}
};
// Decorators:
Decorator: ast::Expr = {
<location:@L> "@" <p:NamedExpressionTest> "\n" => {

46417
parser/src/python.rs generated

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,79 @@
---
source: parser/src/parser.rs
expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
---
[
ClassDef(
StmtClassDef {
range: 0..38,
name: Identifier(
"Foo",
),
bases: [
Name(
ExprName {
range: 25..26,
id: Identifier(
"A",
),
ctx: Load,
},
),
Name(
ExprName {
range: 28..29,
id: Identifier(
"B",
),
ctx: Load,
},
),
],
keywords: [],
body: [
Pass(
StmtPass {
range: 34..38,
},
),
],
decorator_list: [],
type_params: [
TypeVar(
TypeParamTypeVar {
range: 10..11,
name: Identifier(
"X",
),
bound: None,
},
),
TypeVar(
TypeParamTypeVar {
range: 13..14,
name: Identifier(
"Y",
),
bound: None,
},
),
TypeVarTuple(
TypeParamTypeVarTuple {
range: 16..18,
name: Identifier(
"U",
),
},
),
ParamSpec(
TypeParamParamSpec {
range: 20..23,
name: Identifier(
"P",
),
},
),
],
},
),
]

View file

@ -0,0 +1,53 @@
---
source: parser/src/parser.rs
expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
---
[
ClassDef(
StmtClassDef {
range: 0..28,
name: Identifier(
"Foo",
),
bases: [
Name(
ExprName {
range: 15..16,
id: Identifier(
"A",
),
ctx: Load,
},
),
Name(
ExprName {
range: 18..19,
id: Identifier(
"B",
),
ctx: Load,
},
),
],
keywords: [],
body: [
Pass(
StmtPass {
range: 24..28,
},
),
],
decorator_list: [],
type_params: [
ParamSpec(
TypeParamParamSpec {
range: 10..13,
name: Identifier(
"P",
),
},
),
],
},
),
]

View file

@ -0,0 +1,54 @@
---
source: parser/src/parser.rs
expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
---
[
ClassDef(
StmtClassDef {
range: 0..26,
name: Identifier(
"Foo",
),
bases: [
Name(
ExprName {
range: 13..14,
id: Identifier(
"A",
),
ctx: Load,
},
),
Name(
ExprName {
range: 16..17,
id: Identifier(
"B",
),
ctx: Load,
},
),
],
keywords: [],
body: [
Pass(
StmtPass {
range: 22..26,
},
),
],
decorator_list: [],
type_params: [
TypeVar(
TypeParamTypeVar {
range: 10..11,
name: Identifier(
"T",
),
bound: None,
},
),
],
},
),
]

View file

@ -0,0 +1,53 @@
---
source: parser/src/parser.rs
expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
---
[
ClassDef(
StmtClassDef {
range: 0..27,
name: Identifier(
"Foo",
),
bases: [
Name(
ExprName {
range: 14..15,
id: Identifier(
"A",
),
ctx: Load,
},
),
Name(
ExprName {
range: 17..18,
id: Identifier(
"B",
),
ctx: Load,
},
),
],
keywords: [],
body: [
Pass(
StmtPass {
range: 23..27,
},
),
],
decorator_list: [],
type_params: [
TypeVarTuple(
TypeParamTypeVarTuple {
range: 10..12,
name: Identifier(
"U",
),
},
),
],
},
),
]

View file

@ -0,0 +1,64 @@
---
source: parser/src/parser.rs
expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
---
[
ClassDef(
StmtClassDef {
range: 0..31,
name: Identifier(
"Foo",
),
bases: [
Name(
ExprName {
range: 18..19,
id: Identifier(
"A",
),
ctx: Load,
},
),
Name(
ExprName {
range: 21..22,
id: Identifier(
"B",
),
ctx: Load,
},
),
],
keywords: [],
body: [
Pass(
StmtPass {
range: 27..31,
},
),
],
decorator_list: [],
type_params: [
TypeVar(
TypeParamTypeVar {
range: 10..16,
name: Identifier(
"T",
),
bound: Some(
Name(
ExprName {
range: 13..16,
id: Identifier(
"str",
),
ctx: Load,
},
),
),
},
),
],
},
),
]

View file

@ -0,0 +1,63 @@
---
source: parser/src/parser.rs
expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
---
[
ClassDef(
StmtClassDef {
range: 0..29,
name: Identifier(
"Foo",
),
bases: [
Name(
ExprName {
range: 16..17,
id: Identifier(
"A",
),
ctx: Load,
},
),
Name(
ExprName {
range: 19..20,
id: Identifier(
"B",
),
ctx: Load,
},
),
],
keywords: [],
body: [
Pass(
StmtPass {
range: 25..29,
},
),
],
decorator_list: [],
type_params: [
TypeVar(
TypeParamTypeVar {
range: 10..11,
name: Identifier(
"T",
),
bound: None,
},
),
TypeVar(
TypeParamTypeVar {
range: 13..14,
name: Identifier(
"U",
),
bound: None,
},
),
],
},
),
]