diff --git a/ast/asdl_rs.py b/ast/asdl_rs.py index 0446dee..5ec4cfd 100755 --- a/ast/asdl_rs.py +++ b/ast/asdl_rs.py @@ -272,6 +272,17 @@ class StructVisitor(EmitVisitor): else: self.sum_with_constructors(sum, name, depth) + (generics_applied,) = self.apply_generics(name, "R") + self.emit( + f""" + impl{generics_applied} Node for {rust_type_name(name)}{generics_applied} {{ + const NAME: &'static str = "{name}"; + const FIELD_NAMES: &'static [&'static str] = &[]; + }} + """, + depth, + ) + def emit_attrs(self, depth): self.emit("#[derive(Clone, Debug, PartialEq)]", depth) @@ -327,9 +338,14 @@ class StructVisitor(EmitVisitor): ) self.emit("}", depth) + field_names = [f'"{f.name}"' for f in t.fields] self.emit( textwrap.dedent( f""" + impl Node for {payload_name} {{ + const NAME: &'static str = "{t.name}"; + const FIELD_NAMES: &'static [&'static str] = &[{', '.join(field_names)}]; + }} impl From<{payload_name}> for {rust_name} {{ fn from(payload: {payload_name}) -> Self {{ {rust_name}::{t.name}(payload) @@ -389,7 +405,19 @@ class StructVisitor(EmitVisitor): assert bool(product.attributes) == type_info.no_cfg(self.type_info) self.emit_range(product.attributes, depth + 1) self.emit("}", depth) - self.emit("", depth) + + field_names = [f'"{f.name}"' for f in product.fields] + self.emit( + f""" + impl Node for {product_name} {{ + const NAME: &'static str = "{name}"; + const FIELD_NAMES: &'static [&'static str] = &[ + {', '.join(field_names)} + ]; + }} + """, + depth, + ) class FoldTraitDefVisitor(EmitVisitor): @@ -575,6 +603,12 @@ class VisitorTraitDefVisitor(StructVisitor): def visitType(self, type, depth=0): self.visit(type.value, type.name, depth) + def visitSum(self, sum, name, depth): + if is_simple(sum): + self.simple_sum(sum, name, depth) + else: + self.sum_with_constructors(sum, name, depth) + def emit_visitor(self, nodename, depth, has_node=True): type_info = self.type_info[nodename] node_type = type_info.rust_sum_name diff --git a/ast/src/gen/generic.rs b/ast/src/gen/generic.rs index 94969b9..40643a2 100644 --- a/ast/src/gen/generic.rs +++ b/ast/src/gen/generic.rs @@ -8,6 +8,10 @@ pub struct ModModule { pub type_ignores: Vec>, } +impl Node for ModModule { + const NAME: &'static str = "Module"; + const FIELD_NAMES: &'static [&'static str] = &["body", "type_ignores"]; +} impl From> for Mod { fn from(payload: ModModule) -> Self { Mod::Module(payload) @@ -20,6 +24,10 @@ pub struct ModInteractive { pub body: Vec>, } +impl Node for ModInteractive { + const NAME: &'static str = "Interactive"; + const FIELD_NAMES: &'static [&'static str] = &["body"]; +} impl From> for Mod { fn from(payload: ModInteractive) -> Self { Mod::Interactive(payload) @@ -32,6 +40,10 @@ pub struct ModExpression { pub body: Box>, } +impl Node for ModExpression { + const NAME: &'static str = "Expression"; + const FIELD_NAMES: &'static [&'static str] = &["body"]; +} impl From> for Mod { fn from(payload: ModExpression) -> Self { Mod::Expression(payload) @@ -45,6 +57,10 @@ pub struct ModFunctionType { pub returns: Box>, } +impl Node for ModFunctionType { + const NAME: &'static str = "FunctionType"; + const FIELD_NAMES: &'static [&'static str] = &["argtypes", "returns"]; +} impl From> for Mod { fn from(payload: ModFunctionType) -> Self { Mod::FunctionType(payload) @@ -59,6 +75,11 @@ pub enum Mod { FunctionType(ModFunctionType), } +impl Node for Mod { + const NAME: &'static str = "mod"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq)] pub struct StmtFunctionDef { pub range: R, @@ -70,6 +91,17 @@ pub struct StmtFunctionDef { pub type_comment: Option, } +impl Node for StmtFunctionDef { + const NAME: &'static str = "FunctionDef"; + const FIELD_NAMES: &'static [&'static str] = &[ + "name", + "args", + "body", + "decorator_list", + "returns", + "type_comment", + ]; +} impl From> for Stmt { fn from(payload: StmtFunctionDef) -> Self { Stmt::FunctionDef(payload) @@ -87,6 +119,17 @@ pub struct StmtAsyncFunctionDef { pub type_comment: Option, } +impl Node for StmtAsyncFunctionDef { + const NAME: &'static str = "AsyncFunctionDef"; + const FIELD_NAMES: &'static [&'static str] = &[ + "name", + "args", + "body", + "decorator_list", + "returns", + "type_comment", + ]; +} impl From> for Stmt { fn from(payload: StmtAsyncFunctionDef) -> Self { Stmt::AsyncFunctionDef(payload) @@ -103,6 +146,11 @@ pub struct StmtClassDef { pub decorator_list: Vec>, } +impl Node for StmtClassDef { + const NAME: &'static str = "ClassDef"; + const FIELD_NAMES: &'static [&'static str] = + &["name", "bases", "keywords", "body", "decorator_list"]; +} impl From> for Stmt { fn from(payload: StmtClassDef) -> Self { Stmt::ClassDef(payload) @@ -115,6 +163,10 @@ pub struct StmtReturn { pub value: Option>>, } +impl Node for StmtReturn { + const NAME: &'static str = "Return"; + const FIELD_NAMES: &'static [&'static str] = &["value"]; +} impl From> for Stmt { fn from(payload: StmtReturn) -> Self { Stmt::Return(payload) @@ -127,6 +179,10 @@ pub struct StmtDelete { pub targets: Vec>, } +impl Node for StmtDelete { + const NAME: &'static str = "Delete"; + const FIELD_NAMES: &'static [&'static str] = &["targets"]; +} impl From> for Stmt { fn from(payload: StmtDelete) -> Self { Stmt::Delete(payload) @@ -141,6 +197,10 @@ pub struct StmtAssign { pub type_comment: Option, } +impl Node for StmtAssign { + const NAME: &'static str = "Assign"; + const FIELD_NAMES: &'static [&'static str] = &["targets", "value", "type_comment"]; +} impl From> for Stmt { fn from(payload: StmtAssign) -> Self { Stmt::Assign(payload) @@ -155,6 +215,10 @@ pub struct StmtAugAssign { pub value: Box>, } +impl Node for StmtAugAssign { + const NAME: &'static str = "AugAssign"; + const FIELD_NAMES: &'static [&'static str] = &["target", "op", "value"]; +} impl From> for Stmt { fn from(payload: StmtAugAssign) -> Self { Stmt::AugAssign(payload) @@ -170,6 +234,10 @@ pub struct StmtAnnAssign { pub simple: bool, } +impl Node for StmtAnnAssign { + const NAME: &'static str = "AnnAssign"; + const FIELD_NAMES: &'static [&'static str] = &["target", "annotation", "value", "simple"]; +} impl From> for Stmt { fn from(payload: StmtAnnAssign) -> Self { Stmt::AnnAssign(payload) @@ -186,6 +254,11 @@ pub struct StmtFor { pub type_comment: Option, } +impl Node for StmtFor { + const NAME: &'static str = "For"; + const FIELD_NAMES: &'static [&'static str] = + &["target", "iter", "body", "orelse", "type_comment"]; +} impl From> for Stmt { fn from(payload: StmtFor) -> Self { Stmt::For(payload) @@ -202,6 +275,11 @@ pub struct StmtAsyncFor { pub type_comment: Option, } +impl Node for StmtAsyncFor { + const NAME: &'static str = "AsyncFor"; + const FIELD_NAMES: &'static [&'static str] = + &["target", "iter", "body", "orelse", "type_comment"]; +} impl From> for Stmt { fn from(payload: StmtAsyncFor) -> Self { Stmt::AsyncFor(payload) @@ -216,6 +294,10 @@ pub struct StmtWhile { pub orelse: Vec>, } +impl Node for StmtWhile { + const NAME: &'static str = "While"; + const FIELD_NAMES: &'static [&'static str] = &["test", "body", "orelse"]; +} impl From> for Stmt { fn from(payload: StmtWhile) -> Self { Stmt::While(payload) @@ -230,6 +312,10 @@ pub struct StmtIf { pub orelse: Vec>, } +impl Node for StmtIf { + const NAME: &'static str = "If"; + const FIELD_NAMES: &'static [&'static str] = &["test", "body", "orelse"]; +} impl From> for Stmt { fn from(payload: StmtIf) -> Self { Stmt::If(payload) @@ -244,6 +330,10 @@ pub struct StmtWith { pub type_comment: Option, } +impl Node for StmtWith { + const NAME: &'static str = "With"; + const FIELD_NAMES: &'static [&'static str] = &["items", "body", "type_comment"]; +} impl From> for Stmt { fn from(payload: StmtWith) -> Self { Stmt::With(payload) @@ -258,6 +348,10 @@ pub struct StmtAsyncWith { pub type_comment: Option, } +impl Node for StmtAsyncWith { + const NAME: &'static str = "AsyncWith"; + const FIELD_NAMES: &'static [&'static str] = &["items", "body", "type_comment"]; +} impl From> for Stmt { fn from(payload: StmtAsyncWith) -> Self { Stmt::AsyncWith(payload) @@ -271,6 +365,10 @@ pub struct StmtMatch { pub cases: Vec>, } +impl Node for StmtMatch { + const NAME: &'static str = "Match"; + const FIELD_NAMES: &'static [&'static str] = &["subject", "cases"]; +} impl From> for Stmt { fn from(payload: StmtMatch) -> Self { Stmt::Match(payload) @@ -284,6 +382,10 @@ pub struct StmtRaise { pub cause: Option>>, } +impl Node for StmtRaise { + const NAME: &'static str = "Raise"; + const FIELD_NAMES: &'static [&'static str] = &["exc", "cause"]; +} impl From> for Stmt { fn from(payload: StmtRaise) -> Self { Stmt::Raise(payload) @@ -299,6 +401,10 @@ pub struct StmtTry { pub finalbody: Vec>, } +impl Node for StmtTry { + const NAME: &'static str = "Try"; + const FIELD_NAMES: &'static [&'static str] = &["body", "handlers", "orelse", "finalbody"]; +} impl From> for Stmt { fn from(payload: StmtTry) -> Self { Stmt::Try(payload) @@ -314,6 +420,10 @@ pub struct StmtTryStar { pub finalbody: Vec>, } +impl Node for StmtTryStar { + const NAME: &'static str = "TryStar"; + const FIELD_NAMES: &'static [&'static str] = &["body", "handlers", "orelse", "finalbody"]; +} impl From> for Stmt { fn from(payload: StmtTryStar) -> Self { Stmt::TryStar(payload) @@ -327,6 +437,10 @@ pub struct StmtAssert { pub msg: Option>>, } +impl Node for StmtAssert { + const NAME: &'static str = "Assert"; + const FIELD_NAMES: &'static [&'static str] = &["test", "msg"]; +} impl From> for Stmt { fn from(payload: StmtAssert) -> Self { Stmt::Assert(payload) @@ -339,6 +453,10 @@ pub struct StmtImport { pub names: Vec>, } +impl Node for StmtImport { + const NAME: &'static str = "Import"; + const FIELD_NAMES: &'static [&'static str] = &["names"]; +} impl From> for Stmt { fn from(payload: StmtImport) -> Self { Stmt::Import(payload) @@ -353,6 +471,10 @@ pub struct StmtImportFrom { pub level: Option, } +impl Node for StmtImportFrom { + const NAME: &'static str = "ImportFrom"; + const FIELD_NAMES: &'static [&'static str] = &["module", "names", "level"]; +} impl From> for Stmt { fn from(payload: StmtImportFrom) -> Self { Stmt::ImportFrom(payload) @@ -365,6 +487,10 @@ pub struct StmtGlobal { pub names: Vec, } +impl Node for StmtGlobal { + const NAME: &'static str = "Global"; + const FIELD_NAMES: &'static [&'static str] = &["names"]; +} impl From> for Stmt { fn from(payload: StmtGlobal) -> Self { Stmt::Global(payload) @@ -377,6 +503,10 @@ pub struct StmtNonlocal { pub names: Vec, } +impl Node for StmtNonlocal { + const NAME: &'static str = "Nonlocal"; + const FIELD_NAMES: &'static [&'static str] = &["names"]; +} impl From> for Stmt { fn from(payload: StmtNonlocal) -> Self { Stmt::Nonlocal(payload) @@ -389,6 +519,10 @@ pub struct StmtExpr { pub value: Box>, } +impl Node for StmtExpr { + const NAME: &'static str = "Expr"; + const FIELD_NAMES: &'static [&'static str] = &["value"]; +} impl From> for Stmt { fn from(payload: StmtExpr) -> Self { Stmt::Expr(payload) @@ -400,6 +534,10 @@ pub struct StmtPass { pub range: R, } +impl Node for StmtPass { + const NAME: &'static str = "Pass"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} impl From> for Stmt { fn from(payload: StmtPass) -> Self { Stmt::Pass(payload) @@ -411,6 +549,10 @@ pub struct StmtBreak { pub range: R, } +impl Node for StmtBreak { + const NAME: &'static str = "Break"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} impl From> for Stmt { fn from(payload: StmtBreak) -> Self { Stmt::Break(payload) @@ -422,6 +564,10 @@ pub struct StmtContinue { pub range: R, } +impl Node for StmtContinue { + const NAME: &'static str = "Continue"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} impl From> for Stmt { fn from(payload: StmtContinue) -> Self { Stmt::Continue(payload) @@ -486,6 +632,11 @@ pub enum Stmt { Continue(StmtContinue), } +impl Node for Stmt { + const NAME: &'static str = "stmt"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq)] pub struct ExprBoolOp { pub range: R, @@ -493,6 +644,10 @@ pub struct ExprBoolOp { pub values: Vec>, } +impl Node for ExprBoolOp { + const NAME: &'static str = "BoolOp"; + const FIELD_NAMES: &'static [&'static str] = &["op", "values"]; +} impl From> for Expr { fn from(payload: ExprBoolOp) -> Self { Expr::BoolOp(payload) @@ -506,6 +661,10 @@ pub struct ExprNamedExpr { pub value: Box>, } +impl Node for ExprNamedExpr { + const NAME: &'static str = "NamedExpr"; + const FIELD_NAMES: &'static [&'static str] = &["target", "value"]; +} impl From> for Expr { fn from(payload: ExprNamedExpr) -> Self { Expr::NamedExpr(payload) @@ -520,6 +679,10 @@ pub struct ExprBinOp { pub right: Box>, } +impl Node for ExprBinOp { + const NAME: &'static str = "BinOp"; + const FIELD_NAMES: &'static [&'static str] = &["left", "op", "right"]; +} impl From> for Expr { fn from(payload: ExprBinOp) -> Self { Expr::BinOp(payload) @@ -533,6 +696,10 @@ pub struct ExprUnaryOp { pub operand: Box>, } +impl Node for ExprUnaryOp { + const NAME: &'static str = "UnaryOp"; + const FIELD_NAMES: &'static [&'static str] = &["op", "operand"]; +} impl From> for Expr { fn from(payload: ExprUnaryOp) -> Self { Expr::UnaryOp(payload) @@ -546,6 +713,10 @@ pub struct ExprLambda { pub body: Box>, } +impl Node for ExprLambda { + const NAME: &'static str = "Lambda"; + const FIELD_NAMES: &'static [&'static str] = &["args", "body"]; +} impl From> for Expr { fn from(payload: ExprLambda) -> Self { Expr::Lambda(payload) @@ -560,6 +731,10 @@ pub struct ExprIfExp { pub orelse: Box>, } +impl Node for ExprIfExp { + const NAME: &'static str = "IfExp"; + const FIELD_NAMES: &'static [&'static str] = &["test", "body", "orelse"]; +} impl From> for Expr { fn from(payload: ExprIfExp) -> Self { Expr::IfExp(payload) @@ -573,6 +748,10 @@ pub struct ExprDict { pub values: Vec>, } +impl Node for ExprDict { + const NAME: &'static str = "Dict"; + const FIELD_NAMES: &'static [&'static str] = &["keys", "values"]; +} impl From> for Expr { fn from(payload: ExprDict) -> Self { Expr::Dict(payload) @@ -585,6 +764,10 @@ pub struct ExprSet { pub elts: Vec>, } +impl Node for ExprSet { + const NAME: &'static str = "Set"; + const FIELD_NAMES: &'static [&'static str] = &["elts"]; +} impl From> for Expr { fn from(payload: ExprSet) -> Self { Expr::Set(payload) @@ -598,6 +781,10 @@ pub struct ExprListComp { pub generators: Vec>, } +impl Node for ExprListComp { + const NAME: &'static str = "ListComp"; + const FIELD_NAMES: &'static [&'static str] = &["elt", "generators"]; +} impl From> for Expr { fn from(payload: ExprListComp) -> Self { Expr::ListComp(payload) @@ -611,6 +798,10 @@ pub struct ExprSetComp { pub generators: Vec>, } +impl Node for ExprSetComp { + const NAME: &'static str = "SetComp"; + const FIELD_NAMES: &'static [&'static str] = &["elt", "generators"]; +} impl From> for Expr { fn from(payload: ExprSetComp) -> Self { Expr::SetComp(payload) @@ -625,6 +816,10 @@ pub struct ExprDictComp { pub generators: Vec>, } +impl Node for ExprDictComp { + const NAME: &'static str = "DictComp"; + const FIELD_NAMES: &'static [&'static str] = &["key", "value", "generators"]; +} impl From> for Expr { fn from(payload: ExprDictComp) -> Self { Expr::DictComp(payload) @@ -638,6 +833,10 @@ pub struct ExprGeneratorExp { pub generators: Vec>, } +impl Node for ExprGeneratorExp { + const NAME: &'static str = "GeneratorExp"; + const FIELD_NAMES: &'static [&'static str] = &["elt", "generators"]; +} impl From> for Expr { fn from(payload: ExprGeneratorExp) -> Self { Expr::GeneratorExp(payload) @@ -650,6 +849,10 @@ pub struct ExprAwait { pub value: Box>, } +impl Node for ExprAwait { + const NAME: &'static str = "Await"; + const FIELD_NAMES: &'static [&'static str] = &["value"]; +} impl From> for Expr { fn from(payload: ExprAwait) -> Self { Expr::Await(payload) @@ -662,6 +865,10 @@ pub struct ExprYield { pub value: Option>>, } +impl Node for ExprYield { + const NAME: &'static str = "Yield"; + const FIELD_NAMES: &'static [&'static str] = &["value"]; +} impl From> for Expr { fn from(payload: ExprYield) -> Self { Expr::Yield(payload) @@ -674,6 +881,10 @@ pub struct ExprYieldFrom { pub value: Box>, } +impl Node for ExprYieldFrom { + const NAME: &'static str = "YieldFrom"; + const FIELD_NAMES: &'static [&'static str] = &["value"]; +} impl From> for Expr { fn from(payload: ExprYieldFrom) -> Self { Expr::YieldFrom(payload) @@ -688,6 +899,10 @@ pub struct ExprCompare { pub comparators: Vec>, } +impl Node for ExprCompare { + const NAME: &'static str = "Compare"; + const FIELD_NAMES: &'static [&'static str] = &["left", "ops", "comparators"]; +} impl From> for Expr { fn from(payload: ExprCompare) -> Self { Expr::Compare(payload) @@ -702,6 +917,10 @@ pub struct ExprCall { pub keywords: Vec>, } +impl Node for ExprCall { + const NAME: &'static str = "Call"; + const FIELD_NAMES: &'static [&'static str] = &["func", "args", "keywords"]; +} impl From> for Expr { fn from(payload: ExprCall) -> Self { Expr::Call(payload) @@ -716,6 +935,10 @@ pub struct ExprFormattedValue { pub format_spec: Option>>, } +impl Node for ExprFormattedValue { + const NAME: &'static str = "FormattedValue"; + const FIELD_NAMES: &'static [&'static str] = &["value", "conversion", "format_spec"]; +} impl From> for Expr { fn from(payload: ExprFormattedValue) -> Self { Expr::FormattedValue(payload) @@ -728,6 +951,10 @@ pub struct ExprJoinedStr { pub values: Vec>, } +impl Node for ExprJoinedStr { + const NAME: &'static str = "JoinedStr"; + const FIELD_NAMES: &'static [&'static str] = &["values"]; +} impl From> for Expr { fn from(payload: ExprJoinedStr) -> Self { Expr::JoinedStr(payload) @@ -741,6 +968,10 @@ pub struct ExprConstant { pub kind: Option, } +impl Node for ExprConstant { + const NAME: &'static str = "Constant"; + const FIELD_NAMES: &'static [&'static str] = &["value", "kind"]; +} impl From> for Expr { fn from(payload: ExprConstant) -> Self { Expr::Constant(payload) @@ -755,6 +986,10 @@ pub struct ExprAttribute { pub ctx: ExprContext, } +impl Node for ExprAttribute { + const NAME: &'static str = "Attribute"; + const FIELD_NAMES: &'static [&'static str] = &["value", "attr", "ctx"]; +} impl From> for Expr { fn from(payload: ExprAttribute) -> Self { Expr::Attribute(payload) @@ -769,6 +1004,10 @@ pub struct ExprSubscript { pub ctx: ExprContext, } +impl Node for ExprSubscript { + const NAME: &'static str = "Subscript"; + const FIELD_NAMES: &'static [&'static str] = &["value", "slice", "ctx"]; +} impl From> for Expr { fn from(payload: ExprSubscript) -> Self { Expr::Subscript(payload) @@ -782,6 +1021,10 @@ pub struct ExprStarred { pub ctx: ExprContext, } +impl Node for ExprStarred { + const NAME: &'static str = "Starred"; + const FIELD_NAMES: &'static [&'static str] = &["value", "ctx"]; +} impl From> for Expr { fn from(payload: ExprStarred) -> Self { Expr::Starred(payload) @@ -795,6 +1038,10 @@ pub struct ExprName { pub ctx: ExprContext, } +impl Node for ExprName { + const NAME: &'static str = "Name"; + const FIELD_NAMES: &'static [&'static str] = &["id", "ctx"]; +} impl From> for Expr { fn from(payload: ExprName) -> Self { Expr::Name(payload) @@ -808,6 +1055,10 @@ pub struct ExprList { pub ctx: ExprContext, } +impl Node for ExprList { + const NAME: &'static str = "List"; + const FIELD_NAMES: &'static [&'static str] = &["elts", "ctx"]; +} impl From> for Expr { fn from(payload: ExprList) -> Self { Expr::List(payload) @@ -821,6 +1072,10 @@ pub struct ExprTuple { pub ctx: ExprContext, } +impl Node for ExprTuple { + const NAME: &'static str = "Tuple"; + const FIELD_NAMES: &'static [&'static str] = &["elts", "ctx"]; +} impl From> for Expr { fn from(payload: ExprTuple) -> Self { Expr::Tuple(payload) @@ -835,6 +1090,10 @@ pub struct ExprSlice { pub step: Option>>, } +impl Node for ExprSlice { + const NAME: &'static str = "Slice"; + const FIELD_NAMES: &'static [&'static str] = &["lower", "upper", "step"]; +} impl From> for Expr { fn from(payload: ExprSlice) -> Self { Expr::Slice(payload) @@ -899,6 +1158,11 @@ pub enum Expr { Slice(ExprSlice), } +impl Node for Expr { + const NAME: &'static str = "expr"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)] pub enum ExprContext { Load, @@ -906,12 +1170,22 @@ pub enum ExprContext { Del, } +impl Node for ExprContext { + const NAME: &'static str = "expr_context"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)] pub enum Boolop { And, Or, } +impl Node for Boolop { + const NAME: &'static str = "boolop"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)] pub enum Operator { Add, @@ -929,6 +1203,11 @@ pub enum Operator { FloorDiv, } +impl Node for Operator { + const NAME: &'static str = "operator"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)] pub enum Unaryop { Invert, @@ -937,6 +1216,11 @@ pub enum Unaryop { USub, } +impl Node for Unaryop { + const NAME: &'static str = "unaryop"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq, is_macro::Is, Copy, Hash, Eq)] pub enum Cmpop { Eq, @@ -951,6 +1235,11 @@ pub enum Cmpop { NotIn, } +impl Node for Cmpop { + const NAME: &'static str = "cmpop"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq)] pub struct Comprehension { pub target: Expr, @@ -960,6 +1249,11 @@ pub struct Comprehension { pub range: OptionalRange, } +impl Node for Comprehension { + const NAME: &'static str = "comprehension"; + const FIELD_NAMES: &'static [&'static str] = &["target", "iter", "ifs", "is_async"]; +} + #[derive(Clone, Debug, PartialEq)] pub struct ExcepthandlerExceptHandler { pub range: R, @@ -968,6 +1262,10 @@ pub struct ExcepthandlerExceptHandler { pub body: Vec>, } +impl Node for ExcepthandlerExceptHandler { + const NAME: &'static str = "ExceptHandler"; + const FIELD_NAMES: &'static [&'static str] = &["type", "name", "body"]; +} impl From> for Excepthandler { fn from(payload: ExcepthandlerExceptHandler) -> Self { Excepthandler::ExceptHandler(payload) @@ -979,6 +1277,11 @@ pub enum Excepthandler { ExceptHandler(ExcepthandlerExceptHandler), } +impl Node for Excepthandler { + const NAME: &'static str = "excepthandler"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq)] pub struct Arguments { pub posonlyargs: Vec>, @@ -991,6 +1294,19 @@ pub struct Arguments { pub range: OptionalRange, } +impl Node for Arguments { + const NAME: &'static str = "arguments"; + const FIELD_NAMES: &'static [&'static str] = &[ + "posonlyargs", + "args", + "vararg", + "kwonlyargs", + "kw_defaults", + "kwarg", + "defaults", + ]; +} + #[derive(Clone, Debug, PartialEq)] pub struct Arg { pub arg: Identifier, @@ -999,6 +1315,11 @@ pub struct Arg { pub range: R, } +impl Node for Arg { + const NAME: &'static str = "arg"; + const FIELD_NAMES: &'static [&'static str] = &["arg", "annotation", "type_comment"]; +} + #[derive(Clone, Debug, PartialEq)] pub struct Keyword { pub arg: Option, @@ -1006,6 +1327,11 @@ pub struct Keyword { pub range: R, } +impl Node for Keyword { + const NAME: &'static str = "keyword"; + const FIELD_NAMES: &'static [&'static str] = &["arg", "value"]; +} + #[derive(Clone, Debug, PartialEq)] pub struct Alias { pub name: Identifier, @@ -1013,6 +1339,11 @@ pub struct Alias { pub range: R, } +impl Node for Alias { + const NAME: &'static str = "alias"; + const FIELD_NAMES: &'static [&'static str] = &["name", "asname"]; +} + #[derive(Clone, Debug, PartialEq)] pub struct Withitem { pub context_expr: Expr, @@ -1020,6 +1351,11 @@ pub struct Withitem { pub range: OptionalRange, } +impl Node for Withitem { + const NAME: &'static str = "withitem"; + const FIELD_NAMES: &'static [&'static str] = &["context_expr", "optional_vars"]; +} + #[derive(Clone, Debug, PartialEq)] pub struct MatchCase { pub pattern: Pattern, @@ -1028,12 +1364,21 @@ pub struct MatchCase { pub range: OptionalRange, } +impl Node for MatchCase { + const NAME: &'static str = "match_case"; + const FIELD_NAMES: &'static [&'static str] = &["pattern", "guard", "body"]; +} + #[derive(Clone, Debug, PartialEq)] pub struct PatternMatchValue { pub range: R, pub value: Box>, } +impl Node for PatternMatchValue { + const NAME: &'static str = "MatchValue"; + const FIELD_NAMES: &'static [&'static str] = &["value"]; +} impl From> for Pattern { fn from(payload: PatternMatchValue) -> Self { Pattern::MatchValue(payload) @@ -1046,6 +1391,10 @@ pub struct PatternMatchSingleton { pub value: Constant, } +impl Node for PatternMatchSingleton { + const NAME: &'static str = "MatchSingleton"; + const FIELD_NAMES: &'static [&'static str] = &["value"]; +} impl From> for Pattern { fn from(payload: PatternMatchSingleton) -> Self { Pattern::MatchSingleton(payload) @@ -1058,6 +1407,10 @@ pub struct PatternMatchSequence { pub patterns: Vec>, } +impl Node for PatternMatchSequence { + const NAME: &'static str = "MatchSequence"; + const FIELD_NAMES: &'static [&'static str] = &["patterns"]; +} impl From> for Pattern { fn from(payload: PatternMatchSequence) -> Self { Pattern::MatchSequence(payload) @@ -1072,6 +1425,10 @@ pub struct PatternMatchMapping { pub rest: Option, } +impl Node for PatternMatchMapping { + const NAME: &'static str = "MatchMapping"; + const FIELD_NAMES: &'static [&'static str] = &["keys", "patterns", "rest"]; +} impl From> for Pattern { fn from(payload: PatternMatchMapping) -> Self { Pattern::MatchMapping(payload) @@ -1087,6 +1444,10 @@ pub struct PatternMatchClass { pub kwd_patterns: Vec>, } +impl Node for PatternMatchClass { + const NAME: &'static str = "MatchClass"; + const FIELD_NAMES: &'static [&'static str] = &["cls", "patterns", "kwd_attrs", "kwd_patterns"]; +} impl From> for Pattern { fn from(payload: PatternMatchClass) -> Self { Pattern::MatchClass(payload) @@ -1099,6 +1460,10 @@ pub struct PatternMatchStar { pub name: Option, } +impl Node for PatternMatchStar { + const NAME: &'static str = "MatchStar"; + const FIELD_NAMES: &'static [&'static str] = &["name"]; +} impl From> for Pattern { fn from(payload: PatternMatchStar) -> Self { Pattern::MatchStar(payload) @@ -1112,6 +1477,10 @@ pub struct PatternMatchAs { pub name: Option, } +impl Node for PatternMatchAs { + const NAME: &'static str = "MatchAs"; + const FIELD_NAMES: &'static [&'static str] = &["pattern", "name"]; +} impl From> for Pattern { fn from(payload: PatternMatchAs) -> Self { Pattern::MatchAs(payload) @@ -1124,6 +1493,10 @@ pub struct PatternMatchOr { pub patterns: Vec>, } +impl Node for PatternMatchOr { + const NAME: &'static str = "MatchOr"; + const FIELD_NAMES: &'static [&'static str] = &["patterns"]; +} impl From> for Pattern { fn from(payload: PatternMatchOr) -> Self { Pattern::MatchOr(payload) @@ -1142,6 +1515,11 @@ pub enum Pattern { MatchOr(PatternMatchOr), } +impl Node for Pattern { + const NAME: &'static str = "pattern"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} + #[derive(Clone, Debug, PartialEq)] pub struct TypeIgnoreTypeIgnore { pub range: OptionalRange, @@ -1149,6 +1527,10 @@ pub struct TypeIgnoreTypeIgnore { pub tag: String, } +impl Node for TypeIgnoreTypeIgnore { + const NAME: &'static str = "TypeIgnore"; + const FIELD_NAMES: &'static [&'static str] = &["lineno", "tag"]; +} impl From> for TypeIgnore { fn from(payload: TypeIgnoreTypeIgnore) -> Self { TypeIgnore::TypeIgnore(payload) @@ -1159,3 +1541,8 @@ impl From> for TypeIgnore { pub enum TypeIgnore { TypeIgnore(TypeIgnoreTypeIgnore), } + +impl Node for TypeIgnore { + const NAME: &'static str = "type_ignore"; + const FIELD_NAMES: &'static [&'static str] = &[]; +} diff --git a/ast/src/generic.rs b/ast/src/generic.rs index b51589d..56ad5ce 100644 --- a/ast/src/generic.rs +++ b/ast/src/generic.rs @@ -1,5 +1,5 @@ #![allow(clippy::derive_partial_eq_without_eq)] -pub use crate::{builtin::*, text_size::TextSize}; +pub use crate::{builtin::*, text_size::TextSize, Node}; use std::fmt::{Debug, Display, Formatter}; use std::marker::PhantomData; diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 008a181..d1f63d1 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -10,6 +10,11 @@ pub use generic::*; pub use ranged::Ranged; pub use rustpython_parser_core::{text_size, ConversionFlag}; +pub trait Node { + const NAME: &'static str; + const FIELD_NAMES: &'static [&'static str]; +} + #[cfg(feature = "fold")] mod fold_helpers; #[cfg(feature = "fold")] @@ -18,6 +23,8 @@ pub mod fold { include!("gen/fold.rs"); } +#[cfg(feature = "fold")] +pub use fold::Fold; #[cfg(feature = "visitor")] mod visitor {