From 2ecc08f2c4b698b4ac3248bb53a1913ed2100a3b Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Mon, 11 Jan 2021 14:15:54 -0600 Subject: [PATCH] Add AST mapping, simplify Located Nodes --- ast/asdl_rs.py | 162 +++++++++---- ast/src/ast_gen.rs | 435 +++++++++++++++++++++++++++++++++++ ast/src/lib.rs | 4 + ast/src/map_ast.rs | 66 ++++++ vm/src/stdlib/ast.rs | 41 +++- vm/src/stdlib/ast/gen.rs | 485 +++++++++++++++++++-------------------- 6 files changed, 888 insertions(+), 305 deletions(-) create mode 100644 ast/src/map_ast.rs diff --git a/ast/asdl_rs.py b/ast/asdl_rs.py index 33e1e0d88..d1f6dd7a0 100755 --- a/ast/asdl_rs.py +++ b/ast/asdl_rs.py @@ -249,6 +249,78 @@ class StructVisitor(EmitVisitor): else: return "", "" +class MapAstImplVisitor(EmitVisitor): + def __init__(self, file, typeinfo): + self.typeinfo = typeinfo + super().__init__(file) + + def get_generics(self, typ): + if self.typeinfo[typ].has_userdata: + return "", "" + else: + return "", "" + + def visitModule(self, mod): + for dfn in mod.dfns: + self.visit(dfn) + + def visitType(self, type, depth=0): + self.visit(type.value, type.name, depth) + + def visitSum(self, sum, name, depth): + apply_t, apply_u = self.get_generics(name) + enumname = get_rust_type(name) + if sum.attributes: + enumname += "Kind" + + if not apply_t: + self.emit(f"no_user!({enumname});", depth) + return + + + self.emit(f"impl MapAst for {enumname}{apply_t} {{", depth) + self.emit(f"type Mapped = {enumname}{apply_u};", depth + 1) + self.emit("fn try_map_ast Result>(self, f: &mut F) -> Result {", depth + 1) + self.emit("match self {", depth + 2) + for cons in sum.types: + fields_pattern = self.make_pattern(cons.fields) + self.emit(f"{enumname}::{cons.name} {{ {fields_pattern} }} => {{", depth + 3) + self.gen_construction(f"{enumname}::{cons.name}", cons.fields, depth + 4) + self.emit("}", depth + 3) + self.emit("}", depth + 2) + self.emit("}", depth + 1) + self.emit("}", depth) + + def visitProduct(self, product, name, depth): + apply_t, apply_u = self.get_generics(name) + structname = get_rust_type(name) + if product.attributes: + structname += "Data" + + if not apply_t: + self.emit(f"no_user!({structname});", depth) + return + + self.emit(f"impl MapAst for {structname}{apply_t} {{", depth) + self.emit(f"type Mapped = {structname}{apply_u};", depth + 1) + self.emit("fn try_map_ast Result>(self, f: &mut F) -> Result {", depth + 1) + fields_pattern = self.make_pattern(product.fields) + self.emit(f"let {structname} {{ {fields_pattern} }} = self;", depth + 2) + self.gen_construction(structname, product.fields, depth + 2) + self.emit("}", depth + 1) + self.emit("}", depth) + + def make_pattern(self, fields): + return ",".join(rust_field(f.name) for f in fields) + + def gen_construction(self, cons_path, fields, depth): + self.emit(f"Ok({cons_path} {{", depth) + for field in fields: + name = rust_field(field.name) + self.emit(f"{name}: {name}.try_map_ast(f)?,", depth + 1) + self.emit("})", depth) + + class ClassDefVisitor(EmitVisitor): def visitModule(self, mod): @@ -321,21 +393,20 @@ class TraitImplVisitor(EmitVisitor): self.visit(type.value, type.name, depth) def visitSum(self, sum, name, depth): - rustname = enumname = get_rust_type(name) - node = "self" + enumname = get_rust_type(name) if sum.attributes: - enumname = rustname + "Kind" - node = "self.node" + enumname += "Kind" - self.emit(f"impl Node for ast::{rustname} {{", depth) + + self.emit(f"impl NamedNode for ast::{enumname} {{", depth) + self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1) + self.emit("}", depth) + self.emit(f"impl Node for ast::{enumname} {{", depth) self.emit("fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1) - self.emit(f"let node = match {node} {{", depth + 2) + self.emit("match self {", depth + 2) for variant in sum.types: self.constructor_to_object(variant, enumname, depth + 3) - self.emit("};", depth + 2) - if sum.attributes: - self.add_location(depth + 2) - self.emit("node.into_object()", depth + 2) + self.emit("}", depth + 2) self.emit("}", depth + 1) self.emit("fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult {", depth + 1) self.gen_sum_fromobj(sum, name, enumname, depth + 2) @@ -349,22 +420,18 @@ class TraitImplVisitor(EmitVisitor): self.emit("}", depth) def visitProduct(self, product, name, depth): - rustname = structname = get_rust_type(name) - node = "self" + structname = get_rust_type(name) if product.attributes: - structname = rustname + "Data" - node = "self.node" + structname += "Data" - self.emit(f"impl Node for ast::{rustname} {{", depth) + self.emit(f"impl NamedNode for ast::{structname} {{", depth) + self.emit(f"const NAME: &'static str = {json.dumps(name)};", depth + 1) + self.emit("}", depth) + self.emit(f"impl Node for ast::{structname} {{", depth) self.emit("fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef {", depth + 1) fields_pattern = self.make_pattern(product.fields) - self.emit("let node = {", depth + 2) - self.emit(f"let ast::{structname} {{ {fields_pattern} }} = {node};", depth + 3) - self.make_node(name, product.fields, depth + 3) - self.emit("};", depth + 2) - if product.attributes: - self.add_location(depth + 2) - self.emit("node.into_object()", depth + 2) + self.emit(f"let ast::{structname} {{ {fields_pattern} }} = self;", depth + 2) + self.make_node(name, product.fields, depth + 2) self.emit("}", depth + 1) self.emit("fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult {", depth + 1) self.gen_product_fromobj(product, name, structname, depth + 2) @@ -378,20 +445,17 @@ class TraitImplVisitor(EmitVisitor): self.emit("let _dict = _node.as_object().dict().unwrap();", depth) for f in fields: self.emit(f"_dict.set_item({json.dumps(f.name)}, {rust_field(f.name)}.ast_to_object(_vm), _vm).unwrap();", depth) - self.emit("_node", depth) + self.emit("_node.into_object()", depth) def make_pattern(self, fields): return ",".join(rust_field(f.name) for f in fields) - def add_location(self, depth): - self.emit(f"node_add_location(&node, self.location, _vm);", depth) - def gen_sum_fromobj(self, sum, sumname, enumname, depth): if sum.attributes: self.extract_location(sumname, depth) self.emit("let _cls = _object.class();", depth) - self.emit("let node =", depth) + self.emit("Ok(", depth) for cons in sum.types: self.emit(f"if _cls.is(Node{cons.name}::static_type()) {{", depth) self.gen_construction(f"{enumname}::{cons.name}", cons, sumname, depth + 1) @@ -400,25 +464,15 @@ class TraitImplVisitor(EmitVisitor): self.emit("{", depth) msg = f'format!("expected some sort of {sumname}, but got {{}}",_vm.to_repr(&_object)?)' self.emit(f"return Err(_vm.new_type_error({msg}));", depth + 1) - self.emit("};", depth) - - if sum.attributes: - self.wrap_located_node(depth) - - self.emit("Ok(node)", depth) + self.emit("})", depth) def gen_product_fromobj(self, product, prodname, structname, depth): if product.attributes: self.extract_location(prodname, depth) - self.emit("let node =", depth) + self.emit("Ok(", depth) self.gen_construction(structname, product, prodname, depth + 1) - self.emit(";", depth) - - if product.attributes: - self.wrap_located_node(depth) - - self.emit("Ok(node)", depth) + self.emit(")", depth) def gen_construction(self, cons_path, cons, name, depth): self.emit(f"ast::{cons_path} {{", depth) @@ -441,9 +495,20 @@ class TraitImplVisitor(EmitVisitor): else: return f"Node::ast_from_object(_vm, get_node_field(_vm, &_object, {name}, {json.dumps(typename)})?)?" +class ChainOfVisitors: + def __init__(self, *visitors): + self.visitors = visitors + + def visit(self, object): + for v in self.visitors: + v.visit(object) + v.emit("", 0) + + def write_ast_def(mod, typeinfo, f): f.write('pub use crate::location::Location;\n') f.write('pub use crate::constant::*;\n') + f.write('use crate::map_ast::MapAst;\n') f.write('\n') f.write('type Ident = String;\n') f.write('\n') @@ -461,22 +526,19 @@ def write_ast_def(mod, typeinfo, f): f.write('}\n') f.write('\n') - StructVisitor(f, typeinfo).visit(mod) + c = ChainOfVisitors(StructVisitor(f, typeinfo), + MapAstImplVisitor(f, typeinfo)) + c.visit(mod) def write_ast_mod(mod, f): f.write('use super::*;\n') f.write('\n') - ClassDefVisitor(f).visit(mod) - - f.write('\n') - - TraitImplVisitor(f).visit(mod) - - f.write('\n') - - ExtendModuleVisitor(f).visit(mod) + c = ChainOfVisitors(ClassDefVisitor(f), + TraitImplVisitor(f), + ExtendModuleVisitor(f)) + c.visit(mod) def main(input_filename, ast_mod_filename, ast_def_filename, dump_module=False): auto_gen_msg = AUTOGEN_MESSAGE.format("/".join(Path(__file__).parts[-2:])) diff --git a/ast/src/ast_gen.rs b/ast/src/ast_gen.rs index 6dd97bae3..6ceb8414a 100644 --- a/ast/src/ast_gen.rs +++ b/ast/src/ast_gen.rs @@ -2,6 +2,7 @@ pub use crate::constant::*; pub use crate::location::Location; +use crate::map_ast::MapAst; type Ident = String; @@ -387,3 +388,437 @@ pub struct Withitem { pub enum TypeIgnore { TypeIgnore { lineno: usize, tag: String }, } + +impl MapAst for Mod { + type Mapped = Mod; + fn try_map_ast Result>(self, f: &mut F) -> Result { + match self { + Mod::Module { body, type_ignores } => Ok(Mod::Module { + body: body.try_map_ast(f)?, + type_ignores: type_ignores.try_map_ast(f)?, + }), + Mod::Interactive { body } => Ok(Mod::Interactive { + body: body.try_map_ast(f)?, + }), + Mod::Expression { body } => Ok(Mod::Expression { + body: body.try_map_ast(f)?, + }), + Mod::FunctionType { argtypes, returns } => Ok(Mod::FunctionType { + argtypes: argtypes.try_map_ast(f)?, + returns: returns.try_map_ast(f)?, + }), + } + } +} +impl MapAst for StmtKind { + type Mapped = StmtKind; + fn try_map_ast Result>(self, f: &mut F) -> Result { + match self { + StmtKind::FunctionDef { + name, + args, + body, + decorator_list, + returns, + type_comment, + } => Ok(StmtKind::FunctionDef { + name: name.try_map_ast(f)?, + args: args.try_map_ast(f)?, + body: body.try_map_ast(f)?, + decorator_list: decorator_list.try_map_ast(f)?, + returns: returns.try_map_ast(f)?, + type_comment: type_comment.try_map_ast(f)?, + }), + StmtKind::AsyncFunctionDef { + name, + args, + body, + decorator_list, + returns, + type_comment, + } => Ok(StmtKind::AsyncFunctionDef { + name: name.try_map_ast(f)?, + args: args.try_map_ast(f)?, + body: body.try_map_ast(f)?, + decorator_list: decorator_list.try_map_ast(f)?, + returns: returns.try_map_ast(f)?, + type_comment: type_comment.try_map_ast(f)?, + }), + StmtKind::ClassDef { + name, + bases, + keywords, + body, + decorator_list, + } => Ok(StmtKind::ClassDef { + name: name.try_map_ast(f)?, + bases: bases.try_map_ast(f)?, + keywords: keywords.try_map_ast(f)?, + body: body.try_map_ast(f)?, + decorator_list: decorator_list.try_map_ast(f)?, + }), + StmtKind::Return { value } => Ok(StmtKind::Return { + value: value.try_map_ast(f)?, + }), + StmtKind::Delete { targets } => Ok(StmtKind::Delete { + targets: targets.try_map_ast(f)?, + }), + StmtKind::Assign { + targets, + value, + type_comment, + } => Ok(StmtKind::Assign { + targets: targets.try_map_ast(f)?, + value: value.try_map_ast(f)?, + type_comment: type_comment.try_map_ast(f)?, + }), + StmtKind::AugAssign { target, op, value } => Ok(StmtKind::AugAssign { + target: target.try_map_ast(f)?, + op: op.try_map_ast(f)?, + value: value.try_map_ast(f)?, + }), + StmtKind::AnnAssign { + target, + annotation, + value, + simple, + } => Ok(StmtKind::AnnAssign { + target: target.try_map_ast(f)?, + annotation: annotation.try_map_ast(f)?, + value: value.try_map_ast(f)?, + simple: simple.try_map_ast(f)?, + }), + StmtKind::For { + target, + iter, + body, + orelse, + type_comment, + } => Ok(StmtKind::For { + target: target.try_map_ast(f)?, + iter: iter.try_map_ast(f)?, + body: body.try_map_ast(f)?, + orelse: orelse.try_map_ast(f)?, + type_comment: type_comment.try_map_ast(f)?, + }), + StmtKind::AsyncFor { + target, + iter, + body, + orelse, + type_comment, + } => Ok(StmtKind::AsyncFor { + target: target.try_map_ast(f)?, + iter: iter.try_map_ast(f)?, + body: body.try_map_ast(f)?, + orelse: orelse.try_map_ast(f)?, + type_comment: type_comment.try_map_ast(f)?, + }), + StmtKind::While { test, body, orelse } => Ok(StmtKind::While { + test: test.try_map_ast(f)?, + body: body.try_map_ast(f)?, + orelse: orelse.try_map_ast(f)?, + }), + StmtKind::If { test, body, orelse } => Ok(StmtKind::If { + test: test.try_map_ast(f)?, + body: body.try_map_ast(f)?, + orelse: orelse.try_map_ast(f)?, + }), + StmtKind::With { + items, + body, + type_comment, + } => Ok(StmtKind::With { + items: items.try_map_ast(f)?, + body: body.try_map_ast(f)?, + type_comment: type_comment.try_map_ast(f)?, + }), + StmtKind::AsyncWith { + items, + body, + type_comment, + } => Ok(StmtKind::AsyncWith { + items: items.try_map_ast(f)?, + body: body.try_map_ast(f)?, + type_comment: type_comment.try_map_ast(f)?, + }), + StmtKind::Raise { exc, cause } => Ok(StmtKind::Raise { + exc: exc.try_map_ast(f)?, + cause: cause.try_map_ast(f)?, + }), + StmtKind::Try { + body, + handlers, + orelse, + finalbody, + } => Ok(StmtKind::Try { + body: body.try_map_ast(f)?, + handlers: handlers.try_map_ast(f)?, + orelse: orelse.try_map_ast(f)?, + finalbody: finalbody.try_map_ast(f)?, + }), + StmtKind::Assert { test, msg } => Ok(StmtKind::Assert { + test: test.try_map_ast(f)?, + msg: msg.try_map_ast(f)?, + }), + StmtKind::Import { names } => Ok(StmtKind::Import { + names: names.try_map_ast(f)?, + }), + StmtKind::ImportFrom { + module, + names, + level, + } => Ok(StmtKind::ImportFrom { + module: module.try_map_ast(f)?, + names: names.try_map_ast(f)?, + level: level.try_map_ast(f)?, + }), + StmtKind::Global { names } => Ok(StmtKind::Global { + names: names.try_map_ast(f)?, + }), + StmtKind::Nonlocal { names } => Ok(StmtKind::Nonlocal { + names: names.try_map_ast(f)?, + }), + StmtKind::Expr { value } => Ok(StmtKind::Expr { + value: value.try_map_ast(f)?, + }), + StmtKind::Pass {} => Ok(StmtKind::Pass {}), + StmtKind::Break {} => Ok(StmtKind::Break {}), + StmtKind::Continue {} => Ok(StmtKind::Continue {}), + } + } +} +impl MapAst for ExprKind { + type Mapped = ExprKind; + fn try_map_ast Result>(self, f: &mut F) -> Result { + match self { + ExprKind::BoolOp { op, values } => Ok(ExprKind::BoolOp { + op: op.try_map_ast(f)?, + values: values.try_map_ast(f)?, + }), + ExprKind::NamedExpr { target, value } => Ok(ExprKind::NamedExpr { + target: target.try_map_ast(f)?, + value: value.try_map_ast(f)?, + }), + ExprKind::BinOp { left, op, right } => Ok(ExprKind::BinOp { + left: left.try_map_ast(f)?, + op: op.try_map_ast(f)?, + right: right.try_map_ast(f)?, + }), + ExprKind::UnaryOp { op, operand } => Ok(ExprKind::UnaryOp { + op: op.try_map_ast(f)?, + operand: operand.try_map_ast(f)?, + }), + ExprKind::Lambda { args, body } => Ok(ExprKind::Lambda { + args: args.try_map_ast(f)?, + body: body.try_map_ast(f)?, + }), + ExprKind::IfExp { test, body, orelse } => Ok(ExprKind::IfExp { + test: test.try_map_ast(f)?, + body: body.try_map_ast(f)?, + orelse: orelse.try_map_ast(f)?, + }), + ExprKind::Dict { keys, values } => Ok(ExprKind::Dict { + keys: keys.try_map_ast(f)?, + values: values.try_map_ast(f)?, + }), + ExprKind::Set { elts } => Ok(ExprKind::Set { + elts: elts.try_map_ast(f)?, + }), + ExprKind::ListComp { elt, generators } => Ok(ExprKind::ListComp { + elt: elt.try_map_ast(f)?, + generators: generators.try_map_ast(f)?, + }), + ExprKind::SetComp { elt, generators } => Ok(ExprKind::SetComp { + elt: elt.try_map_ast(f)?, + generators: generators.try_map_ast(f)?, + }), + ExprKind::DictComp { + key, + value, + generators, + } => Ok(ExprKind::DictComp { + key: key.try_map_ast(f)?, + value: value.try_map_ast(f)?, + generators: generators.try_map_ast(f)?, + }), + ExprKind::GeneratorExp { elt, generators } => Ok(ExprKind::GeneratorExp { + elt: elt.try_map_ast(f)?, + generators: generators.try_map_ast(f)?, + }), + ExprKind::Await { value } => Ok(ExprKind::Await { + value: value.try_map_ast(f)?, + }), + ExprKind::Yield { value } => Ok(ExprKind::Yield { + value: value.try_map_ast(f)?, + }), + ExprKind::YieldFrom { value } => Ok(ExprKind::YieldFrom { + value: value.try_map_ast(f)?, + }), + ExprKind::Compare { + left, + ops, + comparators, + } => Ok(ExprKind::Compare { + left: left.try_map_ast(f)?, + ops: ops.try_map_ast(f)?, + comparators: comparators.try_map_ast(f)?, + }), + ExprKind::Call { + func, + args, + keywords, + } => Ok(ExprKind::Call { + func: func.try_map_ast(f)?, + args: args.try_map_ast(f)?, + keywords: keywords.try_map_ast(f)?, + }), + ExprKind::FormattedValue { + value, + conversion, + format_spec, + } => Ok(ExprKind::FormattedValue { + value: value.try_map_ast(f)?, + conversion: conversion.try_map_ast(f)?, + format_spec: format_spec.try_map_ast(f)?, + }), + ExprKind::JoinedStr { values } => Ok(ExprKind::JoinedStr { + values: values.try_map_ast(f)?, + }), + ExprKind::Constant { value, kind } => Ok(ExprKind::Constant { + value: value.try_map_ast(f)?, + kind: kind.try_map_ast(f)?, + }), + ExprKind::Attribute { value, attr, ctx } => Ok(ExprKind::Attribute { + value: value.try_map_ast(f)?, + attr: attr.try_map_ast(f)?, + ctx: ctx.try_map_ast(f)?, + }), + ExprKind::Subscript { value, slice, ctx } => Ok(ExprKind::Subscript { + value: value.try_map_ast(f)?, + slice: slice.try_map_ast(f)?, + ctx: ctx.try_map_ast(f)?, + }), + ExprKind::Starred { value, ctx } => Ok(ExprKind::Starred { + value: value.try_map_ast(f)?, + ctx: ctx.try_map_ast(f)?, + }), + ExprKind::Name { id, ctx } => Ok(ExprKind::Name { + id: id.try_map_ast(f)?, + ctx: ctx.try_map_ast(f)?, + }), + ExprKind::List { elts, ctx } => Ok(ExprKind::List { + elts: elts.try_map_ast(f)?, + ctx: ctx.try_map_ast(f)?, + }), + ExprKind::Tuple { elts, ctx } => Ok(ExprKind::Tuple { + elts: elts.try_map_ast(f)?, + ctx: ctx.try_map_ast(f)?, + }), + ExprKind::Slice { lower, upper, step } => Ok(ExprKind::Slice { + lower: lower.try_map_ast(f)?, + upper: upper.try_map_ast(f)?, + step: step.try_map_ast(f)?, + }), + } + } +} +no_user!(ExprContext); +no_user!(Boolop); +no_user!(Operator); +no_user!(Unaryop); +no_user!(Cmpop); +impl MapAst for Comprehension { + type Mapped = Comprehension; + fn try_map_ast Result>(self, f: &mut F) -> Result { + let Comprehension { + target, + iter, + ifs, + is_async, + } = self; + Ok(Comprehension { + target: target.try_map_ast(f)?, + iter: iter.try_map_ast(f)?, + ifs: ifs.try_map_ast(f)?, + is_async: is_async.try_map_ast(f)?, + }) + } +} +impl MapAst for ExcepthandlerKind { + type Mapped = ExcepthandlerKind; + fn try_map_ast Result>(self, f: &mut F) -> Result { + match self { + ExcepthandlerKind::ExceptHandler { type_, name, body } => { + Ok(ExcepthandlerKind::ExceptHandler { + type_: type_.try_map_ast(f)?, + name: name.try_map_ast(f)?, + body: body.try_map_ast(f)?, + }) + } + } + } +} +impl MapAst for Arguments { + type Mapped = Arguments; + fn try_map_ast Result>(self, f: &mut F) -> Result { + let Arguments { + posonlyargs, + args, + vararg, + kwonlyargs, + kw_defaults, + kwarg, + defaults, + } = self; + Ok(Arguments { + posonlyargs: posonlyargs.try_map_ast(f)?, + args: args.try_map_ast(f)?, + vararg: vararg.try_map_ast(f)?, + kwonlyargs: kwonlyargs.try_map_ast(f)?, + kw_defaults: kw_defaults.try_map_ast(f)?, + kwarg: kwarg.try_map_ast(f)?, + defaults: defaults.try_map_ast(f)?, + }) + } +} +impl MapAst for ArgData { + type Mapped = ArgData; + fn try_map_ast Result>(self, f: &mut F) -> Result { + let ArgData { + arg, + annotation, + type_comment, + } = self; + Ok(ArgData { + arg: arg.try_map_ast(f)?, + annotation: annotation.try_map_ast(f)?, + type_comment: type_comment.try_map_ast(f)?, + }) + } +} +impl MapAst for KeywordData { + type Mapped = KeywordData; + fn try_map_ast Result>(self, f: &mut F) -> Result { + let KeywordData { arg, value } = self; + Ok(KeywordData { + arg: arg.try_map_ast(f)?, + value: value.try_map_ast(f)?, + }) + } +} +no_user!(Alias); +impl MapAst for Withitem { + type Mapped = Withitem; + fn try_map_ast Result>(self, f: &mut F) -> Result { + let Withitem { + context_expr, + optional_vars, + } = self; + Ok(Withitem { + context_expr: context_expr.try_map_ast(f)?, + optional_vars: optional_vars.try_map_ast(f)?, + }) + } +} +no_user!(TypeIgnore); diff --git a/ast/src/lib.rs b/ast/src/lib.rs index 4bbb1e024..371cb6ac0 100644 --- a/ast/src/lib.rs +++ b/ast/src/lib.rs @@ -1,3 +1,7 @@ +// above for the macro +#[macro_use] +pub mod map_ast; + mod ast_gen; mod constant; mod impls; diff --git a/ast/src/map_ast.rs b/ast/src/map_ast.rs new file mode 100644 index 000000000..8e7c885fa --- /dev/null +++ b/ast/src/map_ast.rs @@ -0,0 +1,66 @@ +use std::convert::Infallible; + +pub trait MapAst: Sized { + type Mapped; + fn try_map_ast Result>(self, f: &mut F) -> Result; + fn map_ast U>(self, mut f: F) -> Self::Mapped { + let result: Result<_, Infallible> = self.try_map_ast(&mut |u| Ok(f(u))); + match result { + Ok(mapped) => mapped, + Err(never) => match never {}, + } + } +} + +macro_rules! no_user { + ($t:ty) => { + impl MapAst for $t { + type Mapped = Self; + #[inline] + fn try_map_ast Result>( + self, + _f: &mut F, + ) -> Result { + Ok(self) + } + } + }; +} + +no_user!(String); +no_user!(crate::Constant); +no_user!(crate::ConversionFlag); +no_user!(bool); +no_user!(usize); + +impl> MapAst for crate::Located { + type Mapped = crate::Located; + fn try_map_ast Result>(self, f: &mut F) -> Result { + Ok(crate::Located { + location: self.location, + custom: f(self.custom)?, + node: self.node.try_map_ast(f)?, + }) + } +} + +impl> MapAst for Vec { + type Mapped = Vec; + fn try_map_ast Result>(self, f: &mut F) -> Result { + self.into_iter().map(|node| node.try_map_ast(f)).collect() + } +} + +impl> MapAst for Option { + type Mapped = Option; + fn try_map_ast Result>(self, f: &mut F) -> Result { + self.map(|node| node.try_map_ast(f)).transpose() + } +} + +impl> MapAst for Box { + type Mapped = Box; + fn try_map_ast Result>(self, f: &mut F) -> Result { + (*self).try_map_ast(f).map(Box::new) + } +} diff --git a/vm/src/stdlib/ast.rs b/vm/src/stdlib/ast.rs index 43edd7f6a..6bd126733 100644 --- a/vm/src/stdlib/ast.rs +++ b/vm/src/stdlib/ast.rs @@ -17,8 +17,8 @@ use rustpython_compiler as compile; use crate::builtins::{self, PyStrRef, PyTypeRef}; use crate::function::FuncArgs; use crate::pyobject::{ - BorrowValue, IdProtocol, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyRef, PyResult, - PyValue, StaticType, TryFromObject, TypeProtocol, + BorrowValue, IdProtocol, ItemProtocol, PyClassImpl, PyContext, PyObjectRef, PyResult, PyValue, + StaticType, TryFromObject, TypeProtocol, }; use crate::vm::VirtualMachine; @@ -26,13 +26,6 @@ use crate::vm::VirtualMachine; #[allow(clippy::all)] mod gen; -fn node_add_location(node: &AstNodeRef, location: ast::Location, vm: &VirtualMachine) { - let dict = node.as_object().dict().unwrap(); - dict.set_item("lineno", vm.ctx.new_int(location.row()), vm) - .unwrap(); - dict.set_item("col_offset", vm.ctx.new_int(location.column()), vm) - .unwrap(); -} fn get_node_field(vm: &VirtualMachine, obj: &PyObjectRef, field: &str, typ: &str) -> PyResult { vm.get_attribute_opt(obj.clone(), field)?.ok_or_else(|| { @@ -53,7 +46,6 @@ fn get_node_field_opt( #[pyclass(module = "_ast", name = "AST")] #[derive(Debug)] pub(crate) struct AstNode; -type AstNodeRef = PyRef; #[pyimpl(flags(HAS_DICT))] impl AstNode { @@ -103,6 +95,10 @@ trait Node: Sized { fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult; } +trait NamedNode: Node { + const NAME: &'static str; +} + impl Node for Vec { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { vm.ctx.new_list( @@ -144,6 +140,31 @@ impl Node for Option { } } +impl Node for ast::Located { + fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { + let obj = self.node.ast_to_object(vm); + node_add_location(&obj, self.location, vm); + obj + } + + fn ast_from_object(vm: &VirtualMachine, object: PyObjectRef) -> PyResult { + let location = ast::Location::new( + Node::ast_from_object(vm, get_node_field(vm, &object, "lineno", T::NAME)?)?, + Node::ast_from_object(vm, get_node_field(vm, &object, "col_offset", T::NAME)?)?, + ); + let node = T::ast_from_object(vm, object)?; + Ok(ast::Located::new(location, node)) + } +} + +fn node_add_location(node: &PyObjectRef, location: ast::Location, vm: &VirtualMachine) { + let dict = node.dict().unwrap(); + dict.set_item("lineno", vm.ctx.new_int(location.row()), vm) + .unwrap(); + dict.set_item("col_offset", vm.ctx.new_int(location.column()), vm) + .unwrap(); +} + impl Node for String { fn ast_to_object(self, vm: &VirtualMachine) -> PyObjectRef { vm.ctx.new_str(self) diff --git a/vm/src/stdlib/ast/gen.rs b/vm/src/stdlib/ast/gen.rs index 281b27f05..d865c91d8 100644 --- a/vm/src/stdlib/ast/gen.rs +++ b/vm/src/stdlib/ast/gen.rs @@ -963,41 +963,43 @@ impl NodeTypeIgnore { } } +impl NamedNode for ast::Mod { + const NAME: &'static str = "mod"; +} impl Node for ast::Mod { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self { + match self { ast::Mod::Module { body,type_ignores } => { let _node = AstNode.into_ref_with_type(_vm, NodeModule::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("type_ignores", type_ignores.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::Mod::Interactive { body } => { let _node = AstNode.into_ref_with_type(_vm, NodeInteractive::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::Mod::Expression { body } => { let _node = AstNode.into_ref_with_type(_vm, NodeExpression::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::Mod::FunctionType { argtypes,returns } => { let _node = AstNode.into_ref_with_type(_vm, NodeFunctionType::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("argtypes", argtypes.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("returns", returns.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } - }; - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeModule::static_type()) { ast::Mod::Module { body: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "body", "mod")?)?, @@ -1022,13 +1024,15 @@ impl Node for ast::Mod { } else { return Err(_vm.new_type_error(format!("expected some sort of mod, but got {}",_vm.to_repr(&_object)?))); - }; - Ok(node) + }) } } -impl Node for ast::Stmt { +impl NamedNode for ast::StmtKind { + const NAME: &'static str = "stmt"; +} +impl Node for ast::StmtKind { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self.node { + match self { ast::StmtKind::FunctionDef { name,args,body,decorator_list,returns,type_comment } => { let _node = AstNode.into_ref_with_type(_vm, NodeFunctionDef::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); @@ -1038,7 +1042,7 @@ impl Node for ast::Stmt { _dict.set_item("decorator_list", decorator_list.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("returns", returns.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::AsyncFunctionDef { name,args,body,decorator_list,returns,type_comment } => { let _node = AstNode.into_ref_with_type(_vm, NodeAsyncFunctionDef::static_type().clone()).unwrap(); @@ -1049,7 +1053,7 @@ impl Node for ast::Stmt { _dict.set_item("decorator_list", decorator_list.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("returns", returns.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::ClassDef { name,bases,keywords,body,decorator_list } => { let _node = AstNode.into_ref_with_type(_vm, NodeClassDef::static_type().clone()).unwrap(); @@ -1059,19 +1063,19 @@ impl Node for ast::Stmt { _dict.set_item("keywords", keywords.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("decorator_list", decorator_list.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Return { value } => { let _node = AstNode.into_ref_with_type(_vm, NodeReturn::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Delete { targets } => { let _node = AstNode.into_ref_with_type(_vm, NodeDelete::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("targets", targets.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Assign { targets,value,type_comment } => { let _node = AstNode.into_ref_with_type(_vm, NodeAssign::static_type().clone()).unwrap(); @@ -1079,7 +1083,7 @@ impl Node for ast::Stmt { _dict.set_item("targets", targets.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::AugAssign { target,op,value } => { let _node = AstNode.into_ref_with_type(_vm, NodeAugAssign::static_type().clone()).unwrap(); @@ -1087,7 +1091,7 @@ impl Node for ast::Stmt { _dict.set_item("target", target.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("op", op.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::AnnAssign { target,annotation,value,simple } => { let _node = AstNode.into_ref_with_type(_vm, NodeAnnAssign::static_type().clone()).unwrap(); @@ -1096,7 +1100,7 @@ impl Node for ast::Stmt { _dict.set_item("annotation", annotation.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("simple", simple.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::For { target,iter,body,orelse,type_comment } => { let _node = AstNode.into_ref_with_type(_vm, NodeFor::static_type().clone()).unwrap(); @@ -1106,7 +1110,7 @@ impl Node for ast::Stmt { _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("orelse", orelse.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::AsyncFor { target,iter,body,orelse,type_comment } => { let _node = AstNode.into_ref_with_type(_vm, NodeAsyncFor::static_type().clone()).unwrap(); @@ -1116,7 +1120,7 @@ impl Node for ast::Stmt { _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("orelse", orelse.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::While { test,body,orelse } => { let _node = AstNode.into_ref_with_type(_vm, NodeWhile::static_type().clone()).unwrap(); @@ -1124,7 +1128,7 @@ impl Node for ast::Stmt { _dict.set_item("test", test.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("orelse", orelse.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::If { test,body,orelse } => { let _node = AstNode.into_ref_with_type(_vm, NodeIf::static_type().clone()).unwrap(); @@ -1132,7 +1136,7 @@ impl Node for ast::Stmt { _dict.set_item("test", test.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("orelse", orelse.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::With { items,body,type_comment } => { let _node = AstNode.into_ref_with_type(_vm, NodeWith::static_type().clone()).unwrap(); @@ -1140,7 +1144,7 @@ impl Node for ast::Stmt { _dict.set_item("items", items.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::AsyncWith { items,body,type_comment } => { let _node = AstNode.into_ref_with_type(_vm, NodeAsyncWith::static_type().clone()).unwrap(); @@ -1148,14 +1152,14 @@ impl Node for ast::Stmt { _dict.set_item("items", items.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Raise { exc,cause } => { let _node = AstNode.into_ref_with_type(_vm, NodeRaise::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("exc", exc.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("cause", cause.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Try { body,handlers,orelse,finalbody } => { let _node = AstNode.into_ref_with_type(_vm, NodeTry::static_type().clone()).unwrap(); @@ -1164,20 +1168,20 @@ impl Node for ast::Stmt { _dict.set_item("handlers", handlers.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("orelse", orelse.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("finalbody", finalbody.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Assert { test,msg } => { let _node = AstNode.into_ref_with_type(_vm, NodeAssert::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("test", test.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("msg", msg.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Import { names } => { let _node = AstNode.into_ref_with_type(_vm, NodeImport::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("names", names.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::ImportFrom { module,names,level } => { let _node = AstNode.into_ref_with_type(_vm, NodeImportFrom::static_type().clone()).unwrap(); @@ -1185,46 +1189,44 @@ impl Node for ast::Stmt { _dict.set_item("module", module.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("names", names.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("level", level.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Global { names } => { let _node = AstNode.into_ref_with_type(_vm, NodeGlobal::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("names", names.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Nonlocal { names } => { let _node = AstNode.into_ref_with_type(_vm, NodeNonlocal::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("names", names.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Expr { value } => { let _node = AstNode.into_ref_with_type(_vm, NodeExpr::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::StmtKind::Pass { } => { let _node = AstNode.into_ref_with_type(_vm, NodePass::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::StmtKind::Break { } => { let _node = AstNode.into_ref_with_type(_vm, NodeBreak::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::StmtKind::Continue { } => { let _node = AstNode.into_ref_with_type(_vm, NodeContinue::static_type().clone()).unwrap(); - _node + _node.into_object() } - }; - node_add_location(&node, self.location, _vm); - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _location = ast::Location::new(Node::ast_from_object(_vm, get_node_field(_vm, &_object, "lineno", "stmt")?)?, Node::ast_from_object(_vm, get_node_field(_vm, &_object, "col_offset", "stmt")?)?); let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeFunctionDef::static_type()) { ast::StmtKind::FunctionDef { name: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "name", "stmt")?)?, @@ -1393,27 +1395,28 @@ impl Node for ast::Stmt { } else { return Err(_vm.new_type_error(format!("expected some sort of stmt, but got {}",_vm.to_repr(&_object)?))); - }; - let node = ast::Located::new(_location, node); - Ok(node) + }) } } -impl Node for ast::Expr { +impl NamedNode for ast::ExprKind { + const NAME: &'static str = "expr"; +} +impl Node for ast::ExprKind { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self.node { + match self { ast::ExprKind::BoolOp { op,values } => { let _node = AstNode.into_ref_with_type(_vm, NodeBoolOp::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("op", op.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("values", values.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::NamedExpr { target,value } => { let _node = AstNode.into_ref_with_type(_vm, NodeNamedExpr::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("target", target.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::BinOp { left,op,right } => { let _node = AstNode.into_ref_with_type(_vm, NodeBinOp::static_type().clone()).unwrap(); @@ -1421,21 +1424,21 @@ impl Node for ast::Expr { _dict.set_item("left", left.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("op", op.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("right", right.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::UnaryOp { op,operand } => { let _node = AstNode.into_ref_with_type(_vm, NodeUnaryOp::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("op", op.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("operand", operand.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Lambda { args,body } => { let _node = AstNode.into_ref_with_type(_vm, NodeLambda::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("args", args.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::IfExp { test,body,orelse } => { let _node = AstNode.into_ref_with_type(_vm, NodeIfExp::static_type().clone()).unwrap(); @@ -1443,34 +1446,34 @@ impl Node for ast::Expr { _dict.set_item("test", test.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("orelse", orelse.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Dict { keys,values } => { let _node = AstNode.into_ref_with_type(_vm, NodeDict::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("keys", keys.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("values", values.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Set { elts } => { let _node = AstNode.into_ref_with_type(_vm, NodeSet::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("elts", elts.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::ListComp { elt,generators } => { let _node = AstNode.into_ref_with_type(_vm, NodeListComp::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("elt", elt.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("generators", generators.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::SetComp { elt,generators } => { let _node = AstNode.into_ref_with_type(_vm, NodeSetComp::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("elt", elt.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("generators", generators.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::DictComp { key,value,generators } => { let _node = AstNode.into_ref_with_type(_vm, NodeDictComp::static_type().clone()).unwrap(); @@ -1478,32 +1481,32 @@ impl Node for ast::Expr { _dict.set_item("key", key.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("generators", generators.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::GeneratorExp { elt,generators } => { let _node = AstNode.into_ref_with_type(_vm, NodeGeneratorExp::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("elt", elt.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("generators", generators.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Await { value } => { let _node = AstNode.into_ref_with_type(_vm, NodeAwait::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Yield { value } => { let _node = AstNode.into_ref_with_type(_vm, NodeYield::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::YieldFrom { value } => { let _node = AstNode.into_ref_with_type(_vm, NodeYieldFrom::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Compare { left,ops,comparators } => { let _node = AstNode.into_ref_with_type(_vm, NodeCompare::static_type().clone()).unwrap(); @@ -1511,7 +1514,7 @@ impl Node for ast::Expr { _dict.set_item("left", left.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("ops", ops.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("comparators", comparators.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Call { func,args,keywords } => { let _node = AstNode.into_ref_with_type(_vm, NodeCall::static_type().clone()).unwrap(); @@ -1519,7 +1522,7 @@ impl Node for ast::Expr { _dict.set_item("func", func.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("args", args.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("keywords", keywords.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::FormattedValue { value,conversion,format_spec } => { let _node = AstNode.into_ref_with_type(_vm, NodeFormattedValue::static_type().clone()).unwrap(); @@ -1527,20 +1530,20 @@ impl Node for ast::Expr { _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("conversion", conversion.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("format_spec", format_spec.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::JoinedStr { values } => { let _node = AstNode.into_ref_with_type(_vm, NodeJoinedStr::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("values", values.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Constant { value,kind } => { let _node = AstNode.into_ref_with_type(_vm, NodeConstant::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("kind", kind.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Attribute { value,attr,ctx } => { let _node = AstNode.into_ref_with_type(_vm, NodeAttribute::static_type().clone()).unwrap(); @@ -1548,7 +1551,7 @@ impl Node for ast::Expr { _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("attr", attr.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("ctx", ctx.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Subscript { value,slice,ctx } => { let _node = AstNode.into_ref_with_type(_vm, NodeSubscript::static_type().clone()).unwrap(); @@ -1556,35 +1559,35 @@ impl Node for ast::Expr { _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("slice", slice.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("ctx", ctx.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Starred { value,ctx } => { let _node = AstNode.into_ref_with_type(_vm, NodeStarred::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("ctx", ctx.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Name { id,ctx } => { let _node = AstNode.into_ref_with_type(_vm, NodeName::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("id", id.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("ctx", ctx.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::List { elts,ctx } => { let _node = AstNode.into_ref_with_type(_vm, NodeList::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("elts", elts.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("ctx", ctx.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Tuple { elts,ctx } => { let _node = AstNode.into_ref_with_type(_vm, NodeTuple::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("elts", elts.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("ctx", ctx.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } ast::ExprKind::Slice { lower,upper,step } => { let _node = AstNode.into_ref_with_type(_vm, NodeSlice::static_type().clone()).unwrap(); @@ -1592,16 +1595,14 @@ impl Node for ast::Expr { _dict.set_item("lower", lower.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("upper", upper.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("step", step.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } - }; - node_add_location(&node, self.location, _vm); - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _location = ast::Location::new(Node::ast_from_object(_vm, get_node_field(_vm, &_object, "lineno", "expr")?)?, Node::ast_from_object(_vm, get_node_field(_vm, &_object, "col_offset", "expr")?)?); let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeBoolOp::static_type()) { ast::ExprKind::BoolOp { op: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "op", "expr")?)?, @@ -1770,32 +1771,32 @@ impl Node for ast::Expr { } else { return Err(_vm.new_type_error(format!("expected some sort of expr, but got {}",_vm.to_repr(&_object)?))); - }; - let node = ast::Located::new(_location, node); - Ok(node) + }) } } +impl NamedNode for ast::ExprContext { + const NAME: &'static str = "expr_context"; +} impl Node for ast::ExprContext { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self { + match self { ast::ExprContext::Load { } => { let _node = AstNode.into_ref_with_type(_vm, NodeLoad::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::ExprContext::Store { } => { let _node = AstNode.into_ref_with_type(_vm, NodeStore::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::ExprContext::Del { } => { let _node = AstNode.into_ref_with_type(_vm, NodeDel::static_type().clone()).unwrap(); - _node + _node.into_object() } - }; - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeLoad::static_type()) { ast::ExprContext::Load { } @@ -1810,27 +1811,28 @@ impl Node for ast::ExprContext { } else { return Err(_vm.new_type_error(format!("expected some sort of expr_context, but got {}",_vm.to_repr(&_object)?))); - }; - Ok(node) + }) } } +impl NamedNode for ast::Boolop { + const NAME: &'static str = "boolop"; +} impl Node for ast::Boolop { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self { + match self { ast::Boolop::And { } => { let _node = AstNode.into_ref_with_type(_vm, NodeAnd::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Boolop::Or { } => { let _node = AstNode.into_ref_with_type(_vm, NodeOr::static_type().clone()).unwrap(); - _node + _node.into_object() } - }; - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeAnd::static_type()) { ast::Boolop::And { } @@ -1841,71 +1843,72 @@ impl Node for ast::Boolop { } else { return Err(_vm.new_type_error(format!("expected some sort of boolop, but got {}",_vm.to_repr(&_object)?))); - }; - Ok(node) + }) } } +impl NamedNode for ast::Operator { + const NAME: &'static str = "operator"; +} impl Node for ast::Operator { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self { + match self { ast::Operator::Add { } => { let _node = AstNode.into_ref_with_type(_vm, NodeAdd::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::Sub { } => { let _node = AstNode.into_ref_with_type(_vm, NodeSub::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::Mult { } => { let _node = AstNode.into_ref_with_type(_vm, NodeMult::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::MatMult { } => { let _node = AstNode.into_ref_with_type(_vm, NodeMatMult::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::Div { } => { let _node = AstNode.into_ref_with_type(_vm, NodeDiv::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::Mod { } => { let _node = AstNode.into_ref_with_type(_vm, NodeMod::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::Pow { } => { let _node = AstNode.into_ref_with_type(_vm, NodePow::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::LShift { } => { let _node = AstNode.into_ref_with_type(_vm, NodeLShift::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::RShift { } => { let _node = AstNode.into_ref_with_type(_vm, NodeRShift::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::BitOr { } => { let _node = AstNode.into_ref_with_type(_vm, NodeBitOr::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::BitXor { } => { let _node = AstNode.into_ref_with_type(_vm, NodeBitXor::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::BitAnd { } => { let _node = AstNode.into_ref_with_type(_vm, NodeBitAnd::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Operator::FloorDiv { } => { let _node = AstNode.into_ref_with_type(_vm, NodeFloorDiv::static_type().clone()).unwrap(); - _node + _node.into_object() } - }; - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeAdd::static_type()) { ast::Operator::Add { } @@ -1960,35 +1963,36 @@ impl Node for ast::Operator { } else { return Err(_vm.new_type_error(format!("expected some sort of operator, but got {}",_vm.to_repr(&_object)?))); - }; - Ok(node) + }) } } +impl NamedNode for ast::Unaryop { + const NAME: &'static str = "unaryop"; +} impl Node for ast::Unaryop { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self { + match self { ast::Unaryop::Invert { } => { let _node = AstNode.into_ref_with_type(_vm, NodeInvert::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Unaryop::Not { } => { let _node = AstNode.into_ref_with_type(_vm, NodeNot::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Unaryop::UAdd { } => { let _node = AstNode.into_ref_with_type(_vm, NodeUAdd::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Unaryop::USub { } => { let _node = AstNode.into_ref_with_type(_vm, NodeUSub::static_type().clone()).unwrap(); - _node + _node.into_object() } - }; - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeInvert::static_type()) { ast::Unaryop::Invert { } @@ -2007,59 +2011,60 @@ impl Node for ast::Unaryop { } else { return Err(_vm.new_type_error(format!("expected some sort of unaryop, but got {}",_vm.to_repr(&_object)?))); - }; - Ok(node) + }) } } +impl NamedNode for ast::Cmpop { + const NAME: &'static str = "cmpop"; +} impl Node for ast::Cmpop { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self { + match self { ast::Cmpop::Eq { } => { let _node = AstNode.into_ref_with_type(_vm, NodeEq::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Cmpop::NotEq { } => { let _node = AstNode.into_ref_with_type(_vm, NodeNotEq::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Cmpop::Lt { } => { let _node = AstNode.into_ref_with_type(_vm, NodeLt::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Cmpop::LtE { } => { let _node = AstNode.into_ref_with_type(_vm, NodeLtE::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Cmpop::Gt { } => { let _node = AstNode.into_ref_with_type(_vm, NodeGt::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Cmpop::GtE { } => { let _node = AstNode.into_ref_with_type(_vm, NodeGtE::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Cmpop::Is { } => { let _node = AstNode.into_ref_with_type(_vm, NodeIs::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Cmpop::IsNot { } => { let _node = AstNode.into_ref_with_type(_vm, NodeIsNot::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Cmpop::In { } => { let _node = AstNode.into_ref_with_type(_vm, NodeIn::static_type().clone()).unwrap(); - _node + _node.into_object() } ast::Cmpop::NotIn { } => { let _node = AstNode.into_ref_with_type(_vm, NodeNotIn::static_type().clone()).unwrap(); - _node + _node.into_object() } - }; - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeEq::static_type()) { ast::Cmpop::Eq { } @@ -2102,55 +2107,54 @@ impl Node for ast::Cmpop { } else { return Err(_vm.new_type_error(format!("expected some sort of cmpop, but got {}",_vm.to_repr(&_object)?))); - }; - Ok(node) + }) } } +impl NamedNode for ast::Comprehension { + const NAME: &'static str = "comprehension"; +} impl Node for ast::Comprehension { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = { - let ast::Comprehension { target,iter,ifs,is_async } = self; - let _node = AstNode.into_ref_with_type(_vm, Nodecomprehension::static_type().clone()).unwrap(); - let _dict = _node.as_object().dict().unwrap(); - _dict.set_item("target", target.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("iter", iter.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("ifs", ifs.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("is_async", is_async.ast_to_object(_vm), _vm).unwrap(); - _node - }; - node.into_object() + let ast::Comprehension { target,iter,ifs,is_async } = self; + let _node = AstNode.into_ref_with_type(_vm, Nodecomprehension::static_type().clone()).unwrap(); + let _dict = _node.as_object().dict().unwrap(); + _dict.set_item("target", target.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("iter", iter.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("ifs", ifs.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("is_async", is_async.ast_to_object(_vm), _vm).unwrap(); + _node.into_object() } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { - let node = + Ok( ast::Comprehension { target: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "target", "comprehension")?)?, iter: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "iter", "comprehension")?)?, ifs: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "ifs", "comprehension")?)?, is_async: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "is_async", "comprehension")?)?, } - ; - Ok(node) + ) } } -impl Node for ast::Excepthandler { +impl NamedNode for ast::ExcepthandlerKind { + const NAME: &'static str = "excepthandler"; +} +impl Node for ast::ExcepthandlerKind { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self.node { + match self { ast::ExcepthandlerKind::ExceptHandler { type_,name,body } => { let _node = AstNode.into_ref_with_type(_vm, NodeExceptHandler::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("type", type_.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("name", name.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("body", body.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } - }; - node_add_location(&node, self.location, _vm); - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _location = ast::Location::new(Node::ast_from_object(_vm, get_node_field(_vm, &_object, "lineno", "excepthandler")?)?, Node::ast_from_object(_vm, get_node_field(_vm, &_object, "col_offset", "excepthandler")?)?); let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeExceptHandler::static_type()) { ast::ExcepthandlerKind::ExceptHandler { type_: get_node_field_opt(_vm, &_object, "type")?.map(|obj| Node::ast_from_object(_vm, obj)).transpose()?, @@ -2160,30 +2164,28 @@ impl Node for ast::Excepthandler { } else { return Err(_vm.new_type_error(format!("expected some sort of excepthandler, but got {}",_vm.to_repr(&_object)?))); - }; - let node = ast::Located::new(_location, node); - Ok(node) + }) } } +impl NamedNode for ast::Arguments { + const NAME: &'static str = "arguments"; +} impl Node for ast::Arguments { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = { - let ast::Arguments { posonlyargs,args,vararg,kwonlyargs,kw_defaults,kwarg,defaults } = self; - let _node = AstNode.into_ref_with_type(_vm, Nodearguments::static_type().clone()).unwrap(); - let _dict = _node.as_object().dict().unwrap(); - _dict.set_item("posonlyargs", posonlyargs.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("args", args.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("vararg", vararg.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("kwonlyargs", kwonlyargs.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("kw_defaults", kw_defaults.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("kwarg", kwarg.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("defaults", defaults.ast_to_object(_vm), _vm).unwrap(); - _node - }; - node.into_object() + let ast::Arguments { posonlyargs,args,vararg,kwonlyargs,kw_defaults,kwarg,defaults } = self; + let _node = AstNode.into_ref_with_type(_vm, Nodearguments::static_type().clone()).unwrap(); + let _dict = _node.as_object().dict().unwrap(); + _dict.set_item("posonlyargs", posonlyargs.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("args", args.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("vararg", vararg.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("kwonlyargs", kwonlyargs.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("kw_defaults", kw_defaults.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("kwarg", kwarg.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("defaults", defaults.ast_to_object(_vm), _vm).unwrap(); + _node.into_object() } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { - let node = + Ok( ast::Arguments { posonlyargs: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "posonlyargs", "arguments")?)?, args: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "args", "arguments")?)?, @@ -2193,122 +2195,115 @@ impl Node for ast::Arguments { kwarg: get_node_field_opt(_vm, &_object, "kwarg")?.map(|obj| Node::ast_from_object(_vm, obj)).transpose()?, defaults: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "defaults", "arguments")?)?, } - ; - Ok(node) + ) } } -impl Node for ast::Arg { +impl NamedNode for ast::ArgData { + const NAME: &'static str = "arg"; +} +impl Node for ast::ArgData { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = { - let ast::ArgData { arg,annotation,type_comment } = self.node; - let _node = AstNode.into_ref_with_type(_vm, Nodearg::static_type().clone()).unwrap(); - let _dict = _node.as_object().dict().unwrap(); - _dict.set_item("arg", arg.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("annotation", annotation.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm).unwrap(); - _node - }; - node_add_location(&node, self.location, _vm); - node.into_object() + let ast::ArgData { arg,annotation,type_comment } = self; + let _node = AstNode.into_ref_with_type(_vm, Nodearg::static_type().clone()).unwrap(); + let _dict = _node.as_object().dict().unwrap(); + _dict.set_item("arg", arg.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("annotation", annotation.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("type_comment", type_comment.ast_to_object(_vm), _vm).unwrap(); + _node.into_object() } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _location = ast::Location::new(Node::ast_from_object(_vm, get_node_field(_vm, &_object, "lineno", "arg")?)?, Node::ast_from_object(_vm, get_node_field(_vm, &_object, "col_offset", "arg")?)?); - let node = + Ok( ast::ArgData { arg: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "arg", "arg")?)?, annotation: get_node_field_opt(_vm, &_object, "annotation")?.map(|obj| Node::ast_from_object(_vm, obj)).transpose()?, type_comment: get_node_field_opt(_vm, &_object, "type_comment")?.map(|obj| Node::ast_from_object(_vm, obj)).transpose()?, } - ; - let node = ast::Located::new(_location, node); - Ok(node) + ) } } -impl Node for ast::Keyword { +impl NamedNode for ast::KeywordData { + const NAME: &'static str = "keyword"; +} +impl Node for ast::KeywordData { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = { - let ast::KeywordData { arg,value } = self.node; - let _node = AstNode.into_ref_with_type(_vm, Nodekeyword::static_type().clone()).unwrap(); - let _dict = _node.as_object().dict().unwrap(); - _dict.set_item("arg", arg.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); - _node - }; - node_add_location(&node, self.location, _vm); - node.into_object() + let ast::KeywordData { arg,value } = self; + let _node = AstNode.into_ref_with_type(_vm, Nodekeyword::static_type().clone()).unwrap(); + let _dict = _node.as_object().dict().unwrap(); + _dict.set_item("arg", arg.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("value", value.ast_to_object(_vm), _vm).unwrap(); + _node.into_object() } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _location = ast::Location::new(Node::ast_from_object(_vm, get_node_field(_vm, &_object, "lineno", "keyword")?)?, Node::ast_from_object(_vm, get_node_field(_vm, &_object, "col_offset", "keyword")?)?); - let node = + Ok( ast::KeywordData { arg: get_node_field_opt(_vm, &_object, "arg")?.map(|obj| Node::ast_from_object(_vm, obj)).transpose()?, value: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "value", "keyword")?)?, } - ; - let node = ast::Located::new(_location, node); - Ok(node) + ) } } +impl NamedNode for ast::Alias { + const NAME: &'static str = "alias"; +} impl Node for ast::Alias { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = { - let ast::Alias { name,asname } = self; - let _node = AstNode.into_ref_with_type(_vm, Nodealias::static_type().clone()).unwrap(); - let _dict = _node.as_object().dict().unwrap(); - _dict.set_item("name", name.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("asname", asname.ast_to_object(_vm), _vm).unwrap(); - _node - }; - node.into_object() + let ast::Alias { name,asname } = self; + let _node = AstNode.into_ref_with_type(_vm, Nodealias::static_type().clone()).unwrap(); + let _dict = _node.as_object().dict().unwrap(); + _dict.set_item("name", name.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("asname", asname.ast_to_object(_vm), _vm).unwrap(); + _node.into_object() } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { - let node = + Ok( ast::Alias { name: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "name", "alias")?)?, asname: get_node_field_opt(_vm, &_object, "asname")?.map(|obj| Node::ast_from_object(_vm, obj)).transpose()?, } - ; - Ok(node) + ) } } +impl NamedNode for ast::Withitem { + const NAME: &'static str = "withitem"; +} impl Node for ast::Withitem { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = { - let ast::Withitem { context_expr,optional_vars } = self; - let _node = AstNode.into_ref_with_type(_vm, Nodewithitem::static_type().clone()).unwrap(); - let _dict = _node.as_object().dict().unwrap(); - _dict.set_item("context_expr", context_expr.ast_to_object(_vm), _vm).unwrap(); - _dict.set_item("optional_vars", optional_vars.ast_to_object(_vm), _vm).unwrap(); - _node - }; - node.into_object() + let ast::Withitem { context_expr,optional_vars } = self; + let _node = AstNode.into_ref_with_type(_vm, Nodewithitem::static_type().clone()).unwrap(); + let _dict = _node.as_object().dict().unwrap(); + _dict.set_item("context_expr", context_expr.ast_to_object(_vm), _vm).unwrap(); + _dict.set_item("optional_vars", optional_vars.ast_to_object(_vm), _vm).unwrap(); + _node.into_object() } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { - let node = + Ok( ast::Withitem { context_expr: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "context_expr", "withitem")?)?, optional_vars: get_node_field_opt(_vm, &_object, "optional_vars")?.map(|obj| Node::ast_from_object(_vm, obj)).transpose()?, } - ; - Ok(node) + ) } } +impl NamedNode for ast::TypeIgnore { + const NAME: &'static str = "type_ignore"; +} impl Node for ast::TypeIgnore { fn ast_to_object(self, _vm: &VirtualMachine) -> PyObjectRef { - let node = match self { + match self { ast::TypeIgnore::TypeIgnore { lineno,tag } => { let _node = AstNode.into_ref_with_type(_vm, NodeTypeIgnore::static_type().clone()).unwrap(); let _dict = _node.as_object().dict().unwrap(); _dict.set_item("lineno", lineno.ast_to_object(_vm), _vm).unwrap(); _dict.set_item("tag", tag.ast_to_object(_vm), _vm).unwrap(); - _node + _node.into_object() } - }; - node.into_object() + } } fn ast_from_object(_vm: &VirtualMachine, _object: PyObjectRef) -> PyResult { let _cls = _object.class(); - let node = + Ok( if _cls.is(NodeTypeIgnore::static_type()) { ast::TypeIgnore::TypeIgnore { lineno: Node::ast_from_object(_vm, get_node_field(_vm, &_object, "lineno", "type_ignore")?)?, @@ -2317,8 +2312,7 @@ impl Node for ast::TypeIgnore { } else { return Err(_vm.new_type_error(format!("expected some sort of type_ignore, but got {}",_vm.to_repr(&_object)?))); - }; - Ok(node) + }) } } @@ -2422,3 +2416,4 @@ pub fn extend_module_nodes(vm: &VirtualMachine, module: &PyObjectRef) { "TypeIgnore" => NodeTypeIgnore::make_class(&vm.ctx), }) } +