diff --git a/ast/src/ast.rs b/ast/src/ast.rs index dc4acba89e..43b04ff44e 100644 --- a/ast/src/ast.rs +++ b/ast/src/ast.rs @@ -9,16 +9,16 @@ use num_bigint::BigInt; #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq)] -pub enum Top { - Program(Program), - Statement(Vec), - Expression(Expression), +pub enum Top { + Program(Program), + Statement(Vec>), + Expression(Expression), } #[derive(Debug, PartialEq)] /// A full python program, it's a sequence of statements. -pub struct Program { - pub statements: Suite, +pub struct Program { + pub statements: Suite, } #[derive(Debug, PartialEq)] @@ -28,17 +28,18 @@ pub struct ImportSymbol { } #[derive(Debug, PartialEq)] -pub struct Located { +pub struct Located { pub location: Location, pub node: T, + pub custom: U, } -pub type Statement = Located; -pub type Suite = Vec; +pub type Statement = Located, U>; +pub type Suite = Vec>; /// Abstract syntax tree nodes for python statements. #[derive(Debug, PartialEq)] -pub enum StatementType { +pub enum StatementType { /// A [`break`](https://docs.python.org/3/reference/simple_stmts.html#the-break-statement) statement. Break, @@ -47,7 +48,7 @@ pub enum StatementType { /// A [`return`](https://docs.python.org/3/reference/simple_stmts.html#the-return-statement) statement. /// This is used to return from a function. - Return { value: Option }, + Return { value: Option> }, /// An [`import`](https://docs.python.org/3/reference/simple_stmts.html#the-import-statement) statement. Import { names: Vec }, @@ -64,35 +65,35 @@ pub enum StatementType { /// An [`assert`](https://docs.python.org/3/reference/simple_stmts.html#the-assert-statement) statement. Assert { - test: Expression, - msg: Option, + test: Expression, + msg: Option>, }, /// A `del` statement, to delete some variables. - Delete { targets: Vec }, + Delete { targets: Vec> }, /// Variable assignment. Note that we can assign to multiple targets. Assign { - targets: Vec, - value: Expression, + targets: Vec>, + value: Expression, }, /// Augmented assignment. AugAssign { - target: Box, + target: Box>, op: Operator, - value: Box, + value: Box>, }, /// A type annotated assignment. AnnAssign { - target: Box, - annotation: Box, - value: Option, + target: Box>, + annotation: Box>, + value: Option>, }, /// An expression used as a statement. - Expression { expression: Expression }, + Expression { expression: Expression }, /// The [`global`](https://docs.python.org/3/reference/simple_stmts.html#the-global-statement) statement, /// to declare names as global variables. @@ -104,56 +105,56 @@ pub enum StatementType { /// An [`if`](https://docs.python.org/3/reference/compound_stmts.html#the-if-statement) statement. If { - test: Expression, - body: Suite, - orelse: Option, + test: Expression, + body: Suite, + orelse: Option>, }, /// A [`while`](https://docs.python.org/3/reference/compound_stmts.html#the-while-statement) statement. While { - test: Expression, - body: Suite, - orelse: Option, + test: Expression, + body: Suite, + orelse: Option>, }, /// The [`with`](https://docs.python.org/3/reference/compound_stmts.html#the-with-statement) statement. With { is_async: bool, - items: Vec, - body: Suite, + items: Vec>, + body: Suite, }, /// A [`for`](https://docs.python.org/3/reference/compound_stmts.html#the-for-statement) statement. /// Contains the body of the loop, and the `else` clause. For { is_async: bool, - target: Box, - iter: Box, - body: Suite, - orelse: Option, + target: Box>, + iter: Box>, + body: Suite, + orelse: Option>, }, /// A `raise` statement. Raise { - exception: Option, - cause: Option, + exception: Option>, + cause: Option>, }, /// A [`try`](https://docs.python.org/3/reference/compound_stmts.html#the-try-statement) statement. Try { - body: Suite, - handlers: Vec, - orelse: Option, - finalbody: Option, + body: Suite, + handlers: Vec>, + orelse: Option>, + finalbody: Option>, }, /// A [class definition](https://docs.python.org/3/reference/compound_stmts.html#class-definitions). ClassDef { name: String, - body: Suite, - bases: Vec, - keywords: Vec, - decorator_list: Vec, + body: Suite, + bases: Vec>, + keywords: Vec>, + decorator_list: Vec>, }, /// A [function definition](https://docs.python.org/3/reference/compound_stmts.html#function-definitions). @@ -162,82 +163,82 @@ pub enum StatementType { FunctionDef { is_async: bool, name: String, - args: Box, - body: Suite, - decorator_list: Vec, - returns: Option, + args: Box>, + body: Suite, + decorator_list: Vec>, + returns: Option>, }, } #[derive(Debug, PartialEq)] -pub struct WithItem { - pub context_expr: Expression, - pub optional_vars: Option, +pub struct WithItem { + pub context_expr: Expression, + pub optional_vars: Option>, } /// An expression at a given location in the sourcecode. -pub type Expression = Located; +pub type Expression = Located, U>; /// A certain type of expression. #[derive(Debug, PartialEq)] -pub enum ExpressionType { +pub enum ExpressionType { BoolOp { op: BooleanOperator, - values: Vec, + values: Vec>, }, /// A binary operation on two operands. Binop { - a: Box, + a: Box>, op: Operator, - b: Box, + b: Box>, }, /// Subscript operation. Subscript { - a: Box, - b: Box, + a: Box>, + b: Box>, }, /// An unary operation. Unop { op: UnaryOperator, - a: Box, + a: Box>, }, /// An await expression. Await { - value: Box, + value: Box>, }, /// A yield expression. Yield { - value: Option>, + value: Option>>, }, // A yield from expression. YieldFrom { - value: Box, + value: Box>, }, /// A chained comparison. Note that in python you can use /// `1 < a < 10` for example. Compare { - vals: Vec, + vals: Vec>, ops: Vec, }, /// Attribute access in the form of `value.name`. Attribute { - value: Box, + value: Box>, name: String, }, /// A call expression. Call { - function: Box, - args: Vec, - keywords: Vec, + function: Box>, + args: Vec>, + keywords: Vec>, }, /// A numeric literal. @@ -247,43 +248,43 @@ pub enum ExpressionType { /// A `list` literal value. List { - elements: Vec, + elements: Vec>, }, /// A `tuple` literal value. Tuple { - elements: Vec, + elements: Vec>, }, /// A `dict` literal value. /// For example: `{2: 'two', 3: 'three'}` Dict { - elements: Vec<(Option, Expression)>, + elements: Vec<(Option>, Expression)>, }, /// A `set` literal. Set { - elements: Vec, + elements: Vec>, }, Comprehension { - kind: Box, - generators: Vec, + kind: Box>, + generators: Vec>, }, /// A starred expression. Starred { - value: Box, + value: Box>, }, /// A slice expression. Slice { - elements: Vec, + elements: Vec>, }, /// A string literal. String { - value: StringGroup, + value: StringGroup, }, /// A bytes literal. @@ -298,21 +299,21 @@ pub enum ExpressionType { /// A `lambda` function expression. Lambda { - args: Box, - body: Box, + args: Box>, + body: Box>, }, /// An if-expression. IfExpression { - test: Box, - body: Box, - orelse: Box, + test: Box>, + body: Box>, + orelse: Box>, }, // A named expression NamedExpression { - left: Box, - right: Box, + left: Box>, + right: Box>, }, /// The literal 'True'. @@ -328,7 +329,7 @@ pub enum ExpressionType { Ellipsis, } -impl Expression { +impl Expression { /// Returns a short name for the node suitable for use in error messages. pub fn name(&self) -> &'static str { use self::ExpressionType::*; @@ -380,61 +381,70 @@ impl Expression { /// In cpython this is called arguments, but we choose parameters to /// distinguish between function parameters and actual call arguments. #[derive(Debug, PartialEq, Default)] -pub struct Parameters { +pub struct Parameters { pub posonlyargs_count: usize, - pub args: Vec, - pub kwonlyargs: Vec, - pub vararg: Varargs, // Optionally we handle optionally named '*args' or '*' - pub kwarg: Varargs, - pub defaults: Vec, - pub kw_defaults: Vec>, + pub args: Vec>, + pub kwonlyargs: Vec>, + pub vararg: Varargs, // Optionally we handle optionally named '*args' or '*' + pub kwarg: Varargs, + pub defaults: Vec>, + pub kw_defaults: Vec>>, } /// A single formal parameter to a function. #[derive(Debug, PartialEq, Default)] -pub struct Parameter { +pub struct Parameter { pub location: Location, pub arg: String, - pub annotation: Option>, + pub annotation: Option>>, } #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq)] -pub enum ComprehensionKind { - GeneratorExpression { element: Expression }, - List { element: Expression }, - Set { element: Expression }, - Dict { key: Expression, value: Expression }, +pub enum ComprehensionKind { + GeneratorExpression { + element: Expression, + }, + List { + element: Expression, + }, + Set { + element: Expression, + }, + Dict { + key: Expression, + value: Expression, + }, } /// A list/set/dict/generator compression. #[derive(Debug, PartialEq)] -pub struct Comprehension { +pub struct Comprehension { pub location: Location, - pub target: Expression, - pub iter: Expression, - pub ifs: Vec, + pub target: Expression, + pub iter: Expression, + pub ifs: Vec>, pub is_async: bool, } #[derive(Debug, PartialEq)] -pub struct ArgumentList { - pub args: Vec, - pub keywords: Vec, +pub struct ArgumentList { + pub args: Vec>, + pub keywords: Vec>, } #[derive(Debug, PartialEq)] -pub struct Keyword { +pub struct Keyword { pub name: Option, - pub value: Expression, + pub value: Expression, } #[derive(Debug, PartialEq)] -pub struct ExceptHandler { +pub struct ExceptHandler { pub location: Location, - pub typ: Option, + pub typ: Option>, pub name: Option, - pub body: Suite, + pub body: Suite, } /// An operator for a binary operation (an operation with two operands). @@ -506,35 +516,35 @@ pub enum ConversionFlag { } #[derive(Debug, PartialEq)] -pub enum StringGroup { +pub enum StringGroup { Constant { value: String, }, FormattedValue { - value: Box, + value: Box>, conversion: Option, - spec: Option>, + spec: Option>>, }, Joined { - values: Vec, + values: Vec>, }, } #[derive(Debug, PartialEq)] -pub enum Varargs { +pub enum Varargs { None, Unnamed, - Named(Parameter), + Named(Parameter), } -impl Default for Varargs { - fn default() -> Varargs { +impl Default for Varargs { + fn default() -> Varargs { Varargs::None } } -impl From>> for Varargs { - fn from(opt: Option>) -> Varargs { +impl From>>> for Varargs { + fn from(opt: Option>>) -> Varargs { match opt { Some(inner_opt) => match inner_opt { Some(param) => Varargs::Named(param), diff --git a/parser/src/fstring.rs b/parser/src/fstring.rs index d71bcbb0cc..b67f9e462d 100644 --- a/parser/src/fstring.rs +++ b/parser/src/fstring.rs @@ -283,6 +283,7 @@ mod tests { fn mk_ident(name: &str, row: usize, col: usize) -> ast::Expression { ast::Expression { location: ast::Location::new(row, col), + custom: (), node: ast::ExpressionType::Identifier { name: name.to_owned(), }, diff --git a/parser/src/parser.rs b/parser/src/parser.rs index 4be140e779..a2659c4280 100644 --- a/parser/src/parser.rs +++ b/parser/src/parser.rs @@ -60,9 +60,11 @@ pub fn parse_statement(source: &str) -> Result, ParseError> /// /// assert_eq!(ast::Expression { /// location: ast::Location::new(1, 3), +/// custom: (), /// node: ast::ExpressionType::Binop { /// a: Box::new(ast::Expression { /// location: ast::Location::new(1, 1), +/// custom: (), /// node: ast::ExpressionType::Number { /// value: ast::Number::Integer { value: BigInt::from(1) } /// } @@ -70,6 +72,7 @@ pub fn parse_statement(source: &str) -> Result, ParseError> /// op: ast::Operator::Add, /// b: Box::new(ast::Expression { /// location: ast::Location::new(1, 5), +/// custom: (), /// node: ast::ExpressionType::Number { /// value: ast::Number::Integer { value: BigInt::from(2) } /// } @@ -108,6 +111,7 @@ mod tests { fn mk_ident(name: &str, row: usize, col: usize) -> ast::Expression { ast::Expression { location: ast::Location::new(row, col), + custom: (), node: ast::ExpressionType::Identifier { name: name.to_owned(), }, @@ -117,6 +121,7 @@ mod tests { fn make_int(value: i32, row: usize, col: usize) -> ast::Expression { ast::Expression { location: ast::Location::new(row, col), + custom: (), node: ast::ExpressionType::Number { value: ast::Number::Integer { value: BigInt::from(value), @@ -128,6 +133,7 @@ mod tests { fn make_string(value: &str, row: usize, col: usize) -> ast::Expression { ast::Expression { location: ast::Location::new(row, col), + custom: (), node: ast::ExpressionType::String { value: ast::StringGroup::Constant { value: String::from(value), @@ -139,6 +145,7 @@ mod tests { fn as_statement(expr: ast::Expression) -> ast::Statement { ast::Statement { location: expr.location, + custom: (), node: ast::StatementType::Expression { expression: expr }, } } @@ -158,8 +165,10 @@ mod tests { ast::Program { statements: vec![ast::Statement { location: ast::Location::new(1, 1), + custom: (), node: ast::StatementType::Expression { expression: ast::Expression { + custom: (), location: ast::Location::new(1, 6), node: ast::ExpressionType::Call { function: Box::new(mk_ident("print", 1, 1)), @@ -182,9 +191,11 @@ mod tests { ast::Program { statements: vec![ast::Statement { location: ast::Location::new(1, 1), + custom: (), node: ast::StatementType::Expression { expression: ast::Expression { location: ast::Location::new(1, 6), + custom: (), node: ast::ExpressionType::Call { function: Box::new(mk_ident("print", 1, 1)), args: vec![make_string("Hello world", 1, 8), make_int(2, 1, 22),], @@ -206,9 +217,11 @@ mod tests { ast::Program { statements: vec![ast::Statement { location: ast::Location::new(1, 1), + custom: (), node: ast::StatementType::Expression { expression: ast::Expression { location: ast::Location::new(1, 8), + custom: (), node: ast::ExpressionType::Call { function: Box::new(mk_ident("my_func", 1, 1)), args: vec![make_string("positional", 1, 10)], @@ -232,11 +245,13 @@ mod tests { parse_ast, vec![ast::Statement { location: ast::Location::new(1, 1), + custom: (), node: ast::StatementType::If { test: make_int(1, 1, 4), body: vec![as_statement(make_int(10, 1, 7))], orelse: Some(vec![ast::Statement { location: ast::Location::new(2, 1), + custom: (), node: ast::StatementType::If { test: make_int(2, 2, 6), body: vec![as_statement(make_int(20, 2, 9))], @@ -256,6 +271,7 @@ mod tests { parse_ast, Ok(vec![as_statement(ast::Expression { location: ast::Location::new(1, 1), + custom: (), node: ast::ExpressionType::Lambda { args: Box::new(ast::Parameters { posonlyargs_count: 0, @@ -279,6 +295,7 @@ mod tests { }), body: Box::new(ast::Expression { location: ast::Location::new(1, 16), + custom: (), node: ast::ExpressionType::Binop { a: Box::new(mk_ident("x", 1, 14)), op: ast::Operator::Mult, @@ -298,8 +315,10 @@ mod tests { parse_statement(&source), Ok(vec![ast::Statement { location: ast::Location::new(1, 1), + custom: (), node: ast::StatementType::Assign { targets: vec![ast::Expression { + custom: (), location: ast::Location::new(1, 1), node: ast::ExpressionType::Tuple { elements: vec![mk_ident("a", 1, 1), mk_ident("b", 1, 4),] @@ -307,6 +326,7 @@ mod tests { }], value: ast::Expression { location: ast::Location::new(1, 8), + custom: (), node: ast::ExpressionType::Tuple { elements: vec![make_int(4, 1, 8), make_int(5, 1, 11),] } @@ -325,6 +345,7 @@ mod tests { parse_statement(&source), Ok(vec![ast::Statement { location: ast::Location::new(1, 1), + custom: (), node: ast::StatementType::ClassDef { name: String::from("Foo"), bases: vec![mk_ident("A", 1, 11), mk_ident("B", 1, 14)], @@ -332,6 +353,7 @@ mod tests { body: vec![ ast::Statement { location: ast::Location::new(2, 2), + custom: (), node: ast::StatementType::FunctionDef { is_async: false, name: String::from("__init__"), @@ -350,6 +372,7 @@ mod tests { }), body: vec![ast::Statement { location: ast::Location::new(3, 3), + custom: (), node: ast::StatementType::Pass, }], decorator_list: vec![], @@ -358,6 +381,7 @@ mod tests { }, ast::Statement { location: ast::Location::new(4, 2), + custom: (), node: ast::StatementType::FunctionDef { is_async: false, name: String::from("method_with_default"), @@ -383,6 +407,7 @@ mod tests { }), body: vec![ast::Statement { location: ast::Location::new(5, 3), + custom: (), node: ast::StatementType::Pass, }], decorator_list: vec![], @@ -404,6 +429,7 @@ mod tests { parse_ast, ast::Expression { location: ast::Location::new(1, 1), + custom: (), node: ast::ExpressionType::Comprehension { kind: Box::new(ast::ComprehensionKind::Dict { key: mk_ident("x1", 1, 2), @@ -428,6 +454,7 @@ mod tests { assert_eq!( parse_ast, ast::Expression { + custom: (), location: ast::Location::new(1, 1), node: ast::ExpressionType::Comprehension { kind: Box::new(ast::ComprehensionKind::List { @@ -452,6 +479,7 @@ mod tests { assert_eq!( parse_ast, ast::Expression { + custom: (), location: ast::Location::new(1, 1), node: ast::ExpressionType::Comprehension { kind: Box::new(ast::ComprehensionKind::List { @@ -461,6 +489,7 @@ mod tests { ast::Comprehension { location: ast::Location::new(1, 4), target: ast::Expression { + custom: (), location: ast::Location::new(1, 8), node: ast::ExpressionType::Tuple { elements: vec![mk_ident("y", 1, 8), mk_ident("y2", 1, 11),], @@ -476,6 +505,7 @@ mod tests { iter: mk_ident("b", 1, 28), ifs: vec![ ast::Expression { + custom: (), location: ast::Location::new(1, 35), node: ast::ExpressionType::Compare { vals: vec![mk_ident("a", 1, 33), make_int(5, 1, 37),], @@ -483,6 +513,7 @@ mod tests { } }, ast::Expression { + custom: (), location: ast::Location::new(1, 44), node: ast::ExpressionType::Compare { vals: vec![mk_ident("a", 1, 42), make_int(10, 1, 46),], diff --git a/parser/src/python.lalrpop b/parser/src/python.lalrpop index e9b9aaaeaf..4fdfdc2f32 100644 --- a/parser/src/python.lalrpop +++ b/parser/src/python.lalrpop @@ -69,6 +69,7 @@ PassStatement: ast::Statement = { "pass" => { ast::Statement { location, + custom: (), node: ast::StatementType::Pass, } }, @@ -78,6 +79,7 @@ DelStatement: ast::Statement = { "del" => { ast::Statement { location, + custom: (), node: ast::StatementType::Delete { targets }, } }, @@ -88,6 +90,7 @@ ExpressionStatement: ast::Statement = { // Just an expression, no assignment: if suffix.is_empty() { ast::Statement { + custom: (), location, node: ast::StatementType::Expression { expression } } @@ -102,6 +105,7 @@ ExpressionStatement: ast::Statement = { let value = values.into_iter().next().unwrap(); ast::Statement { + custom: (), location, node: ast::StatementType::Assign { targets, value }, } @@ -109,6 +113,7 @@ ExpressionStatement: ast::Statement = { }, => { ast::Statement { + custom: (), location, node: ast::StatementType::AugAssign { target: Box::new(target), @@ -119,6 +124,7 @@ ExpressionStatement: ast::Statement = { }, ":" => { ast::Statement { + custom: (), location, node: ast::StatementType::AnnAssign { target: Box::new(target), @@ -145,6 +151,7 @@ TestOrStarExprList: ast::Expression = { } else { ast::Expression { location, + custom: (), node: ast::ExpressionType::Tuple { elements } } } @@ -158,6 +165,7 @@ TestOrStarNamedExprList: ast::Expression = { } else { ast::Expression { location, + custom: (), node: ast::ExpressionType::Tuple { elements } } } @@ -193,24 +201,28 @@ AugAssign: ast::Operator = { FlowStatement: ast::Statement = { "break" => { ast::Statement { + custom: (), location, node: ast::StatementType::Break, } }, "continue" => { ast::Statement { + custom: (), location, node: ast::StatementType::Continue, } }, "return" => { ast::Statement { + custom: (), location, node: ast::StatementType::Return { value }, } }, => { ast::Statement { + custom: (), location, node: ast::StatementType::Expression { expression }, } @@ -221,12 +233,14 @@ FlowStatement: ast::Statement = { RaiseStatement: ast::Statement = { "raise" => { ast::Statement { + custom: (), location, node: ast::StatementType::Raise { exception: None, cause: None }, } }, "raise" => { ast::Statement { + custom: (), location, node: ast::StatementType::Raise { exception: Some(t), cause: c.map(|x| x.1) }, } @@ -236,6 +250,7 @@ RaiseStatement: ast::Statement = { ImportStatement: ast::Statement = { "import" >> => { ast::Statement { + custom: (), location, node: ast::StatementType::Import { names }, } @@ -243,6 +258,7 @@ ImportStatement: ast::Statement = { "from" "import" => { let (level, module) = source; ast::Statement { + custom: (), location, node: ast::StatementType::ImportFrom { level, @@ -298,6 +314,7 @@ DottedName: String = { GlobalStatement: ast::Statement = { "global" > => { ast::Statement { + custom: (), location, node: ast::StatementType::Global { names } } @@ -307,6 +324,7 @@ GlobalStatement: ast::Statement = { NonlocalStatement: ast::Statement = { "nonlocal" > => { ast::Statement { + custom: (), location, node: ast::StatementType::Nonlocal { names } } @@ -316,6 +334,7 @@ NonlocalStatement: ast::Statement = { AssertStatement: ast::Statement = { "assert" => { ast::Statement { + custom: (), location, node: ast::StatementType::Assert { test, msg: msg.map(|e| e.1) @@ -342,6 +361,7 @@ IfStatement: ast::Statement = { // handle elif: for i in s2.into_iter().rev() { let x = ast::Statement { + custom: (), location: i.0, node: ast::StatementType::If { test: i.2, body: i.4, orelse: last }, }; @@ -349,6 +369,7 @@ IfStatement: ast::Statement = { } ast::Statement { + custom: (), location, node: ast::StatementType::If { test, body, orelse: last } } @@ -359,6 +380,7 @@ WhileStatement: ast::Statement = { "while" ":" => { let orelse = s2.map(|s| s.2); ast::Statement { + custom: (), location, node: ast::StatementType::While { test, @@ -374,6 +396,7 @@ ForStatement: ast::Statement = { let is_async = is_async.is_some(); let orelse = s2.map(|s| s.2); ast::Statement { + custom: (), location, node: ast::StatementType::For { is_async, @@ -391,6 +414,7 @@ TryStatement: ast::Statement = { let orelse = else_suite.map(|s| s.2); let finalbody = finally.map(|s| s.2); ast::Statement { + custom: (), location, node: ast::StatementType::Try { body, @@ -405,6 +429,7 @@ TryStatement: ast::Statement = { let orelse = None; let finalbody = Some(finally.2); ast::Statement { + custom: (), location, node: ast::StatementType::Try { body, @@ -439,6 +464,7 @@ WithStatement: ast::Statement = { "with" > ":" => { let is_async = is_async.is_some(); ast::Statement { + custom: (), location, node: ast::StatementType::With { is_async, items, body }, } @@ -456,6 +482,7 @@ FuncDef: ast::Statement = { "def" " Test)?> ":" => { let is_async = is_async.is_some(); ast::Statement { + custom: (), location, node: ast::StatementType::FunctionDef { is_async, @@ -597,6 +624,7 @@ ClassDef: ast::Statement = { None => (vec![], vec![]), }; ast::Statement { + custom: (), location, node: ast::StatementType::ClassDef { name, @@ -612,11 +640,13 @@ ClassDef: ast::Statement = { Path: ast::Expression = { => ast::Expression { location, + custom: (), node: ast::ExpressionType::Identifier { name: n } }, "." => { ast::Expression { location, + custom: (), node: ast::ExpressionType::Attribute { value: Box::new(p), name: n, @@ -635,10 +665,12 @@ Decorator: ast::Expression = { YieldExpr: ast::Expression = { "yield" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Yield { value: value.map(Box::new) } }, "yield" "from" => ast::Expression { location, + custom: (), node: ast::ExpressionType::YieldFrom { value: Box::new(e) } }, }; @@ -648,6 +680,7 @@ Test: ast::Expression = { if let Some(c) = condition { ast::Expression { location: c.0, + custom: (), node: ast::ExpressionType::IfExpression { test: Box::new(c.2), body: Box::new(expr), @@ -666,10 +699,12 @@ NamedExpressionTest: ast::Expression = { if let Some(l) = left { ast::Expression { location: location, + custom: (), node: ast::ExpressionType::NamedExpression { left: Box::new( ast::Expression { location: location, + custom: (), node: ast::ExpressionType::Identifier { name: l.0, }, }), right: Box::new(right), @@ -685,6 +720,7 @@ LambdaDef: ast::Expression = { "lambda" ?> ":" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Lambda { args: Box::new(p.unwrap_or_default()), body: Box::new(body) @@ -701,6 +737,7 @@ OrTest: ast::Expression = { values.extend(e2.into_iter().map(|e| e.1)); ast::Expression { location, + custom: (), node: ast::ExpressionType::BoolOp { op: ast::BooleanOperator::Or, values } } } @@ -716,6 +753,7 @@ AndTest: ast::Expression = { values.extend(e2.into_iter().map(|e| e.1)); ast::Expression { location, + custom: (), node: ast::ExpressionType::BoolOp { op: ast::BooleanOperator::And, values } } } @@ -725,6 +763,7 @@ AndTest: ast::Expression = { NotTest: ast::Expression = { "not" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Unop { a: Box::new(e), op: ast::UnaryOperator::Not } }, Comparison, @@ -740,6 +779,7 @@ Comparison: ast::Expression = { } ast::Expression { location, + custom: (), node: ast::ExpressionType::Compare { vals, ops } } }, @@ -762,6 +802,7 @@ CompOp: ast::Comparison = { Expression: ast::Expression = { "|" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Binop { a: Box::new(e1), op: ast::Operator::BitOr, b: Box::new(e2) } }, XorExpression, @@ -770,6 +811,7 @@ Expression: ast::Expression = { XorExpression: ast::Expression = { "^" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Binop { a: Box::new(e1), op: ast::Operator::BitXor, b: Box::new(e2) } }, AndExpression, @@ -778,6 +820,7 @@ XorExpression: ast::Expression = { AndExpression: ast::Expression = { "&" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Binop { a: Box::new(e1), op: ast::Operator::BitAnd, b: Box::new(e2) } }, ShiftExpression, @@ -786,6 +829,7 @@ AndExpression: ast::Expression = { ShiftExpression: ast::Expression = { => ast::Expression { location, + custom: (), node: ast::ExpressionType::Binop { a: Box::new(e1), op, b: Box::new(e2) } }, ArithmaticExpression, @@ -799,6 +843,7 @@ ShiftOp: ast::Operator = { ArithmaticExpression: ast::Expression = { => ast::Expression { location, + custom: (), node: ast::ExpressionType::Binop { a: Box::new(a), op, b: Box::new(b) } }, Term, @@ -812,6 +857,7 @@ AddOp: ast::Operator = { Term: ast::Expression = { => ast::Expression { location, + custom: (), node: ast::ExpressionType::Binop { a: Box::new(a), op, b: Box::new(b) } }, Factor, @@ -828,6 +874,7 @@ MulOp: ast::Operator = { Factor: ast::Expression = { => ast::Expression { location, + custom: (), node: ast::ExpressionType::Unop { a: Box::new(e), op } }, Power, @@ -845,6 +892,7 @@ Power: ast::Expression = { None => e, Some((location, _, b)) => ast::Expression { location, + custom: (), node: ast::ExpressionType::Binop { a: Box::new(e), op: ast::Operator::Pow, b: Box::new(b) } }, } @@ -856,6 +904,7 @@ AtomExpr: ast::Expression = { if is_await.is_some() { ast::Expression { location, + custom: (), node: ast::ExpressionType::Await { value: Box::new(atom) } } } else { @@ -869,15 +918,18 @@ AtomExpr2: ast::Expression = { "(" ")" => { ast::Expression { location, + custom: (), node: ast::ExpressionType::Call { function: Box::new(f), args: a.args, keywords: a.keywords } } }, "[" "]" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Subscript { a: Box::new(e), b: Box::new(s) } }, "." => ast::Expression { location, + custom: (), node: ast::ExpressionType::Attribute { value: Box::new(e), name } }, }; @@ -894,6 +946,7 @@ SubscriptList: ast::Expression = { ast::Expression { location, + custom: (), node: ast::ExpressionType::Tuple { elements: dims }, } } @@ -903,47 +956,54 @@ SubscriptList: ast::Expression = { Subscript: ast::Expression = { Test, ":" => { - let s1 = e1.unwrap_or(ast::Expression { location, node: ast::ExpressionType::None }); - let s2 = e2.unwrap_or(ast::Expression { location, node: ast::ExpressionType::None }); - let s3 = e3.unwrap_or(ast::Expression { location, node: ast::ExpressionType::None }); + let s1 = e1.unwrap_or(ast::Expression { location, custom: (), node: ast::ExpressionType::None }); + let s2 = e2.unwrap_or(ast::Expression { location, custom: (), node: ast::ExpressionType::None }); + let s3 = e3.unwrap_or(ast::Expression { location, custom: (), node: ast::ExpressionType::None }); ast::Expression { location, + custom: (), node: ast::ExpressionType::Slice { elements: vec![s1, s2, s3] } } } }; SliceOp: ast::Expression = { - ":" => e.unwrap_or(ast::Expression {location, node: ast::ExpressionType::None}) + ":" => e.unwrap_or(ast::Expression {location, custom: (), node: ast::ExpressionType::None}) } Atom: ast::Expression = { => ast::Expression { location, + custom: (), node: ast::ExpressionType::String { value } }, => ast::Expression { location, + custom: (), node: ast::ExpressionType::Bytes { value } }, => ast::Expression { location, + custom: (), node: ast::ExpressionType::Number { value } }, => ast::Expression { location, + custom: (), node: ast::ExpressionType::Identifier { name } }, "[" "]" => { let elements = e.unwrap_or_default(); ast::Expression { location, + custom: (), node: ast::ExpressionType::List { elements } } }, "[" "]" => { ast::Expression { location, + custom: (), node: ast::ExpressionType::Comprehension { kind: Box::new(ast::ComprehensionKind::List { element }), generators, @@ -953,6 +1013,7 @@ Atom: ast::Expression = { "(" ")" => { elements.unwrap_or(ast::Expression { location, + custom: (), node: ast::ExpressionType::Tuple { elements: Vec::new() } }) }, @@ -960,6 +1021,7 @@ Atom: ast::Expression = { "(" ")" => { ast::Expression { location, + custom: (), node: ast::ExpressionType::Comprehension { kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element }), generators, @@ -968,11 +1030,13 @@ Atom: ast::Expression = { }, "{" "}" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Dict { elements: e.unwrap_or_default() } }, "{" "}" => { ast::Expression { location, + custom: (), node: ast::ExpressionType::Comprehension { kind: Box::new(ast::ComprehensionKind::Dict { key: e1.0, value: e1.1 }), generators, @@ -981,21 +1045,23 @@ Atom: ast::Expression = { }, "{" "}" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Set { elements } }, "{" "}" => { ast::Expression { location, + custom: (), node: ast::ExpressionType::Comprehension { kind: Box::new(ast::ComprehensionKind::Set { element }), generators, } } }, - "True" => ast::Expression { location, node: ast::ExpressionType::True }, - "False" => ast::Expression { location, node: ast::ExpressionType::False }, - "None" => ast::Expression { location, node: ast::ExpressionType::None }, - "..." => ast::Expression { location, node: ast::ExpressionType::Ellipsis }, + "True" => ast::Expression { location, custom: (), node: ast::ExpressionType::True }, + "False" => ast::Expression { location, custom: (), node: ast::ExpressionType::False }, + "None" => ast::Expression { location, custom: (), node: ast::ExpressionType::None }, + "..." => ast::Expression { location, custom: (), node: ast::ExpressionType::Ellipsis }, }; ListLiteralValues: Vec = { @@ -1031,6 +1097,7 @@ ExpressionList: ast::Expression = { } else { ast::Expression { location, + custom: (), node: ast::ExpressionType::Tuple { elements }, } } @@ -1052,6 +1119,7 @@ TestList: ast::Expression = { } else { ast::Expression { location, + custom: (), node: ast::ExpressionType::Tuple { elements }, } } @@ -1062,6 +1130,7 @@ TestList: ast::Expression = { StarExpr: ast::Expression = { "*" => ast::Expression { location, + custom: (), node: ast::ExpressionType::Starred { value: Box::new(e) }, } }; @@ -1091,6 +1160,7 @@ FunctionArgument: (Option>, ast::Expression) = { let expr = match c { Some(c) => ast::Expression { location: e.location, + custom: (), node: ast::ExpressionType::Comprehension { kind: Box::new(ast::ComprehensionKind::GeneratorExpression { element: e }), generators: c, @@ -1101,7 +1171,7 @@ FunctionArgument: (Option>, ast::Expression) = { (None, expr) }, "=" => (Some(Some(i)), e), - "*" => (None, ast::Expression { location, node: ast::ExpressionType::Starred { value: Box::new(e) } }), + "*" => (None, ast::Expression { location, custom: (), node: ast::ExpressionType::Starred { value: Box::new(e) } }), "**" => (Some(None), e), };