diff --git a/native/Cargo.lock b/native/Cargo.lock index 92b17afe..d05669ad 100644 --- a/native/Cargo.lock +++ b/native/Cargo.lock @@ -450,8 +450,9 @@ dependencies = [ [[package]] name = "peg" -version = "0.7.0" -source = "git+https://github.com/kevinmehall/rust-peg#4b146b4b78a80c07e43d7ace2d97f65bfde279a8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af728fe826811af3b38c37e93de6d104485953ea373d656eebae53d6987fcd2c" dependencies = [ "peg-macros", "peg-runtime", @@ -459,8 +460,9 @@ dependencies = [ [[package]] name = "peg-macros" -version = "0.7.0" -source = "git+https://github.com/kevinmehall/rust-peg#4b146b4b78a80c07e43d7ace2d97f65bfde279a8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4536be147b770b824895cbad934fccce8e49f14b4c4946eaa46a6e4a12fcdc16" dependencies = [ "peg-runtime", "proc-macro2", @@ -469,8 +471,9 @@ dependencies = [ [[package]] name = "peg-runtime" -version = "0.7.0" -source = "git+https://github.com/kevinmehall/rust-peg#4b146b4b78a80c07e43d7ace2d97f65bfde279a8" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9b0efd3ba03c3a409d44d60425f279ec442bcf0b9e63ff4e410da31c8b0f69f" [[package]] name = "plotters" diff --git a/native/libcst/Cargo.toml b/native/libcst/Cargo.toml index 04b8013c..28252b65 100644 --- a/native/libcst/Cargo.toml +++ b/native/libcst/Cargo.toml @@ -30,7 +30,7 @@ trace = ["peg/trace"] paste = "1.0.4" pyo3 = "0.14.4" thiserror = "1.0.23" -peg = { git = "https://github.com/kevinmehall/rust-peg" } +peg = "0.8.0" chic = "1.2.2" itertools = "0.10.0" once_cell = "1.5.2" diff --git a/native/libcst/src/lib.rs b/native/libcst/src/lib.rs index e4355997..3e9fe793 100644 --- a/native/libcst/src/lib.rs +++ b/native/libcst/src/lib.rs @@ -14,7 +14,7 @@ mod nodes; pub use nodes::*; mod parser; -use parser::{ParserError, Result}; +use parser::{ParserError, Result, TokVec}; pub mod py; @@ -31,43 +31,45 @@ pub fn tokenize(text: &str) -> Result> { .map_err(|err| ParserError::TokenizerError(err, text)) } -pub fn parse_tokens_without_whitespace<'a>( - tokens: Vec>, +pub fn parse_tokens_without_whitespace<'r, 'a>( + tokens: TokVec<'a>, module_text: &'a str, encoding: Option<&str>, -) -> Result<'a, Module<'a>> { - parser::python::file(&tokens.into(), module_text, encoding) +) -> Result<'a, Module<'r, 'a>> { + parser::python::file(&tokens, module_text, encoding) .map_err(|err| ParserError::ParserError(err, module_text)) } -pub fn parse_module<'a>( +pub fn parse_module<'r, 'a>( mut module_text: &'a str, encoding: Option<&str>, -) -> Result<'a, Module<'a>> { +) -> Result<'a, Module<'r, 'a>> { // Strip UTF-8 BOM if let Some(stripped) = module_text.strip_prefix('\u{feff}') { module_text = stripped; } - let tokens = tokenize(module_text)?; - let conf = whitespace_parser::Config::new(module_text, &tokens); + let tokens: TokVec = tokenize(module_text)?.into(); + let conf = whitespace_parser::Config::new(module_text, tokens.0.as_slice()); let m = parse_tokens_without_whitespace(tokens, module_text, encoding)?; Ok(m.inflate(&conf)?) } pub fn parse_statement(text: &str) -> Result { - let tokens = tokenize(text)?; - let conf = whitespace_parser::Config::new(text, &tokens); - let stm = parser::python::statement_input(&tokens.into(), text) + let tokens: TokVec = tokenize(text)?.into(); + let conf = whitespace_parser::Config::new(text, tokens.0.as_slice()); + let stm = parser::python::statement_input(&tokens, text) .map_err(|err| ParserError::ParserError(err, text))?; Ok(stm.inflate(&conf)?) } -pub fn parse_expression(text: &str) -> Result { - let tokens = tokenize(text)?; - let conf = whitespace_parser::Config::new(text, &tokens); - let expr = parser::python::expression_input(&tokens.into(), text) +pub fn parse_expression<'a>(text: &'a str) -> Result> { + let tokens: TokVec = tokenize(text)?.into(); + let conf = whitespace_parser::Config::new(text, tokens.0.as_slice()); + let expr = parser::python::expression_input(&tokens, text) .map_err(|err| ParserError::ParserError(err, text))?; - Ok(expr.inflate(&conf)?) + + let inflated = expr.inflate(&conf)?; + Ok(inflated) } // n starts from 1 diff --git a/native/libcst/src/nodes/common.rs b/native/libcst/src/nodes/common.rs new file mode 100644 index 00000000..ecd4704e --- /dev/null +++ b/native/libcst/src/nodes/common.rs @@ -0,0 +1,5 @@ +use std::rc::Rc; + +use crate::tokenizer::Token; + +pub(crate) type TokenRef<'r, 'a> = &'r Rc>; diff --git a/native/libcst/src/nodes/expression.rs b/native/libcst/src/nodes/expression.rs index c55e327d..4cf98ad9 100644 --- a/native/libcst/src/nodes/expression.rs +++ b/native/libcst/src/nodes/expression.rs @@ -3,37 +3,33 @@ // This source code is licensed under the MIT license found in the // LICENSE file in the root directory of this source tree. -use std::{mem::swap, rc::Rc}; +use std::mem::swap; use crate::{ inflate_helpers::adjust_parameters_trailing_whitespace, nodes::{ + common::TokenRef, traits::{Inflate, ParenthesizedNode, Result, WithComma}, whitespace::ParenthesizableWhitespace, Annotation, AssignEqual, AssignTargetExpression, BinaryOp, BooleanOp, Codegen, CodegenState, Colon, Comma, CompOp, Dot, UnaryOp, }, - tokenizer::{ - whitespace_parser::{parse_parenthesizable_whitespace, Config}, - Token, - }, + tokenizer::whitespace_parser::{parse_parenthesizable_whitespace, Config}, }; -use libcst_derive::{Codegen, Inflate, IntoPy, ParenthesizedNode}; +use libcst_derive::{cst_node, Codegen, Inflate, IntoPy, ParenthesizedNode}; use pyo3::{types::PyModule, IntoPy}; -type TokenRef<'a> = Rc>; - #[derive(Debug, Eq, PartialEq, Default, Clone, IntoPy)] -pub struct Parameters<'a> { - pub params: Vec>, - pub star_arg: Option>, - pub kwonly_params: Vec>, - pub star_kwarg: Option>, - pub posonly_params: Vec>, - pub posonly_ind: Option>, +pub struct Parameters<'r, 'a> { + pub params: Vec>, + pub star_arg: Option>, + pub kwonly_params: Vec>, + pub star_kwarg: Option>, + pub posonly_params: Vec>, + pub posonly_ind: Option>, } -impl<'a> Parameters<'a> { +impl<'r, 'a> Parameters<'r, 'a> { pub fn is_empty(&self) -> bool { self.params.is_empty() && self.star_arg.is_none() @@ -44,7 +40,8 @@ impl<'a> Parameters<'a> { } } -impl<'a> Inflate<'a> for Parameters<'a> { +impl<'r, 'a> Inflate<'a> for Parameters<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.posonly_params = self.posonly_params.inflate(config)?; self.posonly_ind = self.posonly_ind.inflate(config)?; @@ -58,12 +55,12 @@ impl<'a> Inflate<'a> for Parameters<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, Inflate, IntoPy)] -pub enum StarArg<'a> { - Star(ParamStar<'a>), - Param(Box>), +pub enum StarArg<'r, 'a> { + Star(ParamStar<'r, 'a>), + Param(Box>), } -impl<'a> Codegen<'a> for Parameters<'a> { +impl<'r, 'a> Codegen<'a> for Parameters<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { let params_after_kwonly = self.star_kwarg.is_some(); let params_after_regular = !self.kwonly_params.is_empty() || params_after_kwonly; @@ -118,11 +115,11 @@ impl<'a> Codegen<'a> for Parameters<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct ParamSlash<'a> { - pub comma: Option>, +pub struct ParamSlash<'r, 'a> { + pub comma: Option>, } -impl<'a> ParamSlash<'a> { +impl<'r, 'a> ParamSlash<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) { state.add_token("/"); match (&self.comma, default_comma) { @@ -133,7 +130,8 @@ impl<'a> ParamSlash<'a> { } } -impl<'a> Inflate<'a> for ParamSlash<'a> { +impl<'r, 'a> Inflate<'a> for ParamSlash<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.comma = self.comma.inflate(config)?; Ok(self) @@ -141,18 +139,19 @@ impl<'a> Inflate<'a> for ParamSlash<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct ParamStar<'a> { - pub comma: Comma<'a>, +pub struct ParamStar<'r, 'a> { + pub comma: Comma<'r, 'a>, } -impl<'a> Codegen<'a> for ParamStar<'a> { +impl<'r, 'a> Codegen<'a> for ParamStar<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("*"); self.comma.codegen(state); } } -impl<'a> Inflate<'a> for ParamStar<'a> { +impl<'r, 'a> Inflate<'a> for ParamStar<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.comma = self.comma.inflate(config)?; Ok(self) @@ -160,13 +159,14 @@ impl<'a> Inflate<'a> for ParamStar<'a> { } #[derive(Debug, Eq, PartialEq, Default, Clone, ParenthesizedNode, IntoPy)] -pub struct Name<'a> { +pub struct Name<'r, 'a> { pub value: &'a str, - pub lpar: Vec>, - pub rpar: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Inflate<'a> for Name<'a> { +impl<'r, 'a> Inflate<'a> for Name<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.rpar = self.rpar.inflate(config)?; @@ -174,7 +174,7 @@ impl<'a> Inflate<'a> for Name<'a> { } } -impl<'a> Codegen<'a> for Name<'a> { +impl<'r, 'a> Codegen<'a> for Name<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token(self.value); @@ -183,23 +183,24 @@ impl<'a> Codegen<'a> for Name<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Param<'a> { - pub name: Name<'a>, - pub annotation: Option>, - pub equal: Option>, - pub default: Option>, +pub struct Param<'r, 'a> { + pub name: Name<'r, 'a>, + pub annotation: Option>, + pub equal: Option>, + pub default: Option>, - pub comma: Option>, + pub comma: Option>, pub star: Option<&'a str>, pub whitespace_after_star: ParenthesizableWhitespace<'a>, pub whitespace_after_param: ParenthesizableWhitespace<'a>, - pub(crate) star_tok: Option>, + pub(crate) star_tok: Option>, } -impl<'a> Inflate<'a> for Param<'a> { +impl<'r, 'a> Inflate<'a> for Param<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { // TODO: whitespace_after_param missing? self.name = self.name.inflate(config)?; @@ -217,7 +218,7 @@ impl<'a> Inflate<'a> for Param<'a> { } } -impl<'a> Default for Param<'a> { +impl<'r, 'a> Default for Param<'r, 'a> { fn default() -> Self { Self { name: Default::default(), @@ -233,7 +234,7 @@ impl<'a> Default for Param<'a> { } } -impl<'a> Param<'a> { +impl<'r, 'a> Param<'r, 'a> { fn codegen( &self, state: &mut CodegenState<'a>, @@ -275,19 +276,20 @@ impl<'a> Param<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Arg<'a> { - pub value: Expression<'a>, - pub keyword: Option>, - pub equal: Option>, - pub comma: Option>, +pub struct Arg<'r, 'a> { + pub value: Expression<'r, 'a>, + pub keyword: Option>, + pub equal: Option>, + pub comma: Option>, pub star: &'a str, pub whitespace_after_star: ParenthesizableWhitespace<'a>, pub whitespace_after_arg: ParenthesizableWhitespace<'a>, - pub(crate) star_tok: Option>, + pub(crate) star_tok: Option>, } -impl<'a> Inflate<'a> for Arg<'a> { +impl<'r, 'a> Inflate<'a> for Arg<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { if let Some(star_tok) = self.star_tok.as_mut() { self.whitespace_after_star = parse_parenthesizable_whitespace( @@ -304,7 +306,7 @@ impl<'a> Inflate<'a> for Arg<'a> { } } -impl<'a> Arg<'a> { +impl<'r, 'a> Arg<'r, 'a> { pub fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) { state.add_token(self.star); self.whitespace_after_star.codegen(state); @@ -328,8 +330,8 @@ impl<'a> Arg<'a> { } } -impl<'a> WithComma<'a> for Arg<'a> { - fn with_comma(self, c: Comma<'a>) -> Self { +impl<'r, 'a> WithComma<'r, 'a> for Arg<'r, 'a> { + fn with_comma(self, c: Comma<'r, 'a>) -> Self { Self { comma: Some(c), ..self @@ -338,21 +340,22 @@ impl<'a> WithComma<'a> for Arg<'a> { } #[derive(Debug, Eq, PartialEq, Clone, IntoPy)] -pub struct LeftParen<'a> { +pub struct LeftParen<'r, 'a> { /// Any space that appears directly after this left parenthesis. pub whitespace_after: ParenthesizableWhitespace<'a>, - pub(crate) lpar_tok: TokenRef<'a>, + pub(crate) lpar_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for LeftParen<'a> { +impl<'r, 'a> Codegen<'a> for LeftParen<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("("); self.whitespace_after.codegen(state); } } -impl<'a> Inflate<'a> for LeftParen<'a> { +impl<'r, 'a> Inflate<'a> for LeftParen<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_after = parse_parenthesizable_whitespace( config, @@ -363,21 +366,22 @@ impl<'a> Inflate<'a> for LeftParen<'a> { } #[derive(Debug, Eq, PartialEq, Clone, IntoPy)] -pub struct RightParen<'a> { +pub struct RightParen<'r, 'a> { /// Any space that appears directly before this right parenthesis. pub whitespace_before: ParenthesizableWhitespace<'a>, - pub(crate) rpar_tok: TokenRef<'a>, + pub(crate) rpar_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for RightParen<'a> { +impl<'r, 'a> Codegen<'a> for RightParen<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); state.add_token(")"); } } -impl<'a> Inflate<'a> for RightParen<'a> { +impl<'r, 'a> Inflate<'a> for RightParen<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -389,52 +393,53 @@ impl<'a> Inflate<'a> for RightParen<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, Eq, PartialEq, Clone, ParenthesizedNode, Codegen, Inflate, IntoPy)] -pub enum Expression<'a> { - Name(Name<'a>), - Ellipsis(Ellipsis<'a>), - Integer(Integer<'a>), - Float(Float<'a>), - Imaginary(Imaginary<'a>), - Comparison(Comparison<'a>), - UnaryOperation(UnaryOperation<'a>), - BinaryOperation(BinaryOperation<'a>), - BooleanOperation(BooleanOperation<'a>), - Attribute(Attribute<'a>), - Tuple(Tuple<'a>), - Call(Call<'a>), - GeneratorExp(GeneratorExp<'a>), - ListComp(ListComp<'a>), - SetComp(SetComp<'a>), - DictComp(DictComp<'a>), - List(List<'a>), - Set(Set<'a>), - Dict(Dict<'a>), - Subscript(Subscript<'a>), - StarredElement(StarredElement<'a>), - IfExp(IfExp<'a>), - Lambda(Lambda<'a>), - Yield(Yield<'a>), - Await(Await<'a>), - SimpleString(SimpleString<'a>), - ConcatenatedString(ConcatenatedString<'a>), - FormattedString(FormattedString<'a>), - NamedExpr(NamedExpr<'a>), +pub enum Expression<'r, 'a> { + Name(Name<'r, 'a>), + Ellipsis(Ellipsis<'r, 'a>), + Integer(Integer<'r, 'a>), + Float(Float<'r, 'a>), + Imaginary(Imaginary<'r, 'a>), + Comparison(Comparison<'r, 'a>), + UnaryOperation(UnaryOperation<'r, 'a>), + BinaryOperation(BinaryOperation<'r, 'a>), + BooleanOperation(BooleanOperation<'r, 'a>), + Attribute(Attribute<'r, 'a>), + Tuple(Tuple<'r, 'a>), + Call(Call<'r, 'a>), + GeneratorExp(GeneratorExp<'r, 'a>), + ListComp(ListComp<'r, 'a>), + SetComp(SetComp<'r, 'a>), + DictComp(DictComp<'r, 'a>), + List(List<'r, 'a>), + Set(Set<'r, 'a>), + Dict(Dict<'r, 'a>), + Subscript(Subscript<'r, 'a>), + StarredElement(StarredElement<'r, 'a>), + IfExp(IfExp<'r, 'a>), + Lambda(Lambda<'r, 'a>), + Yield(Yield<'r, 'a>), + Await(Await<'r, 'a>), + SimpleString(SimpleString<'r, 'a>), + ConcatenatedString(ConcatenatedString<'r, 'a>), + FormattedString(FormattedString<'r, 'a>), + NamedExpr(NamedExpr<'r, 'a>), } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Ellipsis<'a> { - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Ellipsis<'r, 'a> { + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for Ellipsis<'a> { +impl<'r, 'a> Codegen<'a> for Ellipsis<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token("..."); }) } } -impl<'a> Inflate<'a> for Ellipsis<'a> { +impl<'r, 'a> Inflate<'a> for Ellipsis<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.rpar = self.rpar.inflate(config)?; @@ -443,15 +448,15 @@ impl<'a> Inflate<'a> for Ellipsis<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Integer<'a> { +pub struct Integer<'r, 'a> { /// A string representation of the integer, such as ``"100000"`` or /// ``"100_000"``. pub value: &'a str, - pub lpar: Vec>, - pub rpar: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for Integer<'a> { +impl<'r, 'a> Codegen<'a> for Integer<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token(self.value); @@ -459,7 +464,8 @@ impl<'a> Codegen<'a> for Integer<'a> { } } -impl<'a> Inflate<'a> for Integer<'a> { +impl<'r, 'a> Inflate<'a> for Integer<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.rpar = self.rpar.inflate(config)?; @@ -468,15 +474,15 @@ impl<'a> Inflate<'a> for Integer<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Float<'a> { +pub struct Float<'r, 'a> { /// A string representation of the floating point number, such as ```"0.05"``, /// ``".050"``, or ``"5e-2"``. pub value: &'a str, - pub lpar: Vec>, - pub rpar: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for Float<'a> { +impl<'r, 'a> Codegen<'a> for Float<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token(self.value); @@ -484,7 +490,8 @@ impl<'a> Codegen<'a> for Float<'a> { } } -impl<'a> Inflate<'a> for Float<'a> { +impl<'r, 'a> Inflate<'a> for Float<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.rpar = self.rpar.inflate(config)?; @@ -493,14 +500,14 @@ impl<'a> Inflate<'a> for Float<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Imaginary<'a> { +pub struct Imaginary<'r, 'a> { /// A string representation of the complex number, such as ``"2j"`` pub value: &'a str, - pub lpar: Vec>, - pub rpar: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for Imaginary<'a> { +impl<'r, 'a> Codegen<'a> for Imaginary<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token(self.value); @@ -508,7 +515,8 @@ impl<'a> Codegen<'a> for Imaginary<'a> { } } -impl<'a> Inflate<'a> for Imaginary<'a> { +impl<'r, 'a> Inflate<'a> for Imaginary<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.rpar = self.rpar.inflate(config)?; @@ -517,14 +525,14 @@ impl<'a> Inflate<'a> for Imaginary<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Comparison<'a> { - pub left: Box>, - pub comparisons: Vec>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Comparison<'r, 'a> { + pub left: Box>, + pub comparisons: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for Comparison<'a> { +impl<'r, 'a> Codegen<'a> for Comparison<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.left.codegen(state); @@ -534,7 +542,8 @@ impl<'a> Codegen<'a> for Comparison<'a> { }) } } -impl<'a> Inflate<'a> for Comparison<'a> { +impl<'r, 'a> Inflate<'a> for Comparison<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.left = self.left.inflate(config)?; @@ -545,14 +554,14 @@ impl<'a> Inflate<'a> for Comparison<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct UnaryOperation<'a> { - pub operator: UnaryOp<'a>, - pub expression: Box>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct UnaryOperation<'r, 'a> { + pub operator: UnaryOp<'r, 'a>, + pub expression: Box>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for UnaryOperation<'a> { +impl<'r, 'a> Codegen<'a> for UnaryOperation<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.operator.codegen(state); @@ -561,7 +570,8 @@ impl<'a> Codegen<'a> for UnaryOperation<'a> { } } -impl<'a> Inflate<'a> for UnaryOperation<'a> { +impl<'r, 'a> Inflate<'a> for UnaryOperation<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.operator = self.operator.inflate(config)?; @@ -572,15 +582,15 @@ impl<'a> Inflate<'a> for UnaryOperation<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct BinaryOperation<'a> { - pub left: Box>, - pub operator: BinaryOp<'a>, - pub right: Box>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct BinaryOperation<'r, 'a> { + pub left: Box>, + pub operator: BinaryOp<'r, 'a>, + pub right: Box>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for BinaryOperation<'a> { +impl<'r, 'a> Codegen<'a> for BinaryOperation<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.left.codegen(state); @@ -590,7 +600,8 @@ impl<'a> Codegen<'a> for BinaryOperation<'a> { } } -impl<'a> Inflate<'a> for BinaryOperation<'a> { +impl<'r, 'a> Inflate<'a> for BinaryOperation<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.left = self.left.inflate(config)?; @@ -602,15 +613,15 @@ impl<'a> Inflate<'a> for BinaryOperation<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct BooleanOperation<'a> { - pub left: Box>, - pub operator: BooleanOp<'a>, - pub right: Box>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct BooleanOperation<'r, 'a> { + pub left: Box>, + pub operator: BooleanOp<'r, 'a>, + pub right: Box>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for BooleanOperation<'a> { +impl<'r, 'a> Codegen<'a> for BooleanOperation<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.left.codegen(state); @@ -620,7 +631,8 @@ impl<'a> Codegen<'a> for BooleanOperation<'a> { } } -impl<'a> Inflate<'a> for BooleanOperation<'a> { +impl<'r, 'a> Inflate<'a> for BooleanOperation<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.left = self.left.inflate(config)?; @@ -632,19 +644,20 @@ impl<'a> Inflate<'a> for BooleanOperation<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Call<'a> { - pub func: Box>, - pub args: Vec>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Call<'r, 'a> { + pub func: Box>, + pub args: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_after_func: ParenthesizableWhitespace<'a>, pub whitespace_before_args: ParenthesizableWhitespace<'a>, - pub(crate) lpar_tok: TokenRef<'a>, - pub(crate) rpar_tok: TokenRef<'a>, + pub(crate) lpar_tok: TokenRef<'r, 'a>, + pub(crate) rpar_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Call<'a> { +impl<'r, 'a> Inflate<'a> for Call<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.func = self.func.inflate(config)?; @@ -672,7 +685,7 @@ impl<'a> Inflate<'a> for Call<'a> { } } -impl<'a> Codegen<'a> for Call<'a> { +impl<'r, 'a> Codegen<'a> for Call<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.func.codegen(state); @@ -689,15 +702,16 @@ impl<'a> Codegen<'a> for Call<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Attribute<'a> { - pub value: Box>, - pub attr: Name<'a>, - pub dot: Dot<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Attribute<'r, 'a> { + pub value: Box>, + pub attr: Name<'r, 'a>, + pub dot: Dot<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Inflate<'a> for Attribute<'a> { +impl<'r, 'a> Inflate<'a> for Attribute<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.value = self.value.inflate(config)?; @@ -708,7 +722,7 @@ impl<'a> Inflate<'a> for Attribute<'a> { } } -impl<'a> Codegen<'a> for Attribute<'a> { +impl<'r, 'a> Codegen<'a> for Attribute<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.value.codegen(state); @@ -720,13 +734,13 @@ impl<'a> Codegen<'a> for Attribute<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, Codegen, Inflate, IntoPy)] -pub enum NameOrAttribute<'a> { - N(Name<'a>), - A(Attribute<'a>), +pub enum NameOrAttribute<'r, 'a> { + N(Name<'r, 'a>), + A(Attribute<'r, 'a>), } -impl<'a> std::convert::From> for Expression<'a> { - fn from(x: NameOrAttribute<'a>) -> Self { +impl<'r, 'a> std::convert::From> for Expression<'r, 'a> { + fn from(x: NameOrAttribute<'r, 'a>) -> Self { match x { NameOrAttribute::N(n) => Self::Name(n), NameOrAttribute::A(a) => Self::Attribute(a), @@ -735,19 +749,20 @@ impl<'a> std::convert::From> for Expression<'a> { } #[derive(Debug, Eq, PartialEq, Clone, IntoPy)] -pub struct ComparisonTarget<'a> { - pub operator: CompOp<'a>, - pub comparator: Expression<'a>, +pub struct ComparisonTarget<'r, 'a> { + pub operator: CompOp<'r, 'a>, + pub comparator: Expression<'r, 'a>, } -impl<'a> Codegen<'a> for ComparisonTarget<'a> { +impl<'r, 'a> Codegen<'a> for ComparisonTarget<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.operator.codegen(state); self.comparator.codegen(state); } } -impl<'a> Inflate<'a> for ComparisonTarget<'a> { +impl<'r, 'a> Inflate<'a> for ComparisonTarget<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.operator = self.operator.inflate(config)?; self.comparator = self.comparator.inflate(config)?; @@ -756,17 +771,17 @@ impl<'a> Inflate<'a> for ComparisonTarget<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct StarredElement<'a> { - pub value: Box>, - pub comma: Option>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct StarredElement<'r, 'a> { + pub value: Box>, + pub comma: Option>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_before_value: ParenthesizableWhitespace<'a>, - pub(crate) star_tok: TokenRef<'a>, + pub(crate) star_tok: TokenRef<'r, 'a>, } -impl<'a> StarredElement<'a> { +impl<'r, 'a> StarredElement<'r, 'a> { pub fn inflate_element(mut self, config: &Config<'a>, is_last: bool) -> Result { self.lpar = self.lpar.inflate(config)?; self.whitespace_before_value = parse_parenthesizable_whitespace( @@ -783,13 +798,14 @@ impl<'a> StarredElement<'a> { } } -impl<'a> Inflate<'a> for StarredElement<'a> { +impl<'r, 'a> Inflate<'a> for StarredElement<'r, 'a> { + type Inflated = Self; fn inflate(self, config: &Config<'a>) -> Result { self.inflate_element(config, false) } } -impl<'a> Codegen<'a> for StarredElement<'a> { +impl<'r, 'a> Codegen<'a> for StarredElement<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token("*"); @@ -804,16 +820,16 @@ impl<'a> Codegen<'a> for StarredElement<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone)] -pub enum Element<'a> { +pub enum Element<'r, 'a> { Simple { - value: Expression<'a>, - comma: Option>, + value: Expression<'r, 'a>, + comma: Option>, }, - Starred(StarredElement<'a>), + Starred(StarredElement<'r, 'a>), } // TODO: this could be a derive helper attribute to override the python class name -impl<'a> IntoPy for Element<'a> { +impl<'r, 'a> IntoPy for Element<'r, 'a> { fn into_py(self, py: pyo3::Python) -> pyo3::PyObject { match self { Self::Starred(s) => s.into_py(py), @@ -839,7 +855,7 @@ impl<'a> IntoPy for Element<'a> { } } -impl<'a> Element<'a> { +impl<'r, 'a> Element<'r, 'a> { fn codegen( &self, state: &mut CodegenState<'a>, @@ -879,8 +895,8 @@ impl<'a> Element<'a> { } } -impl<'a> WithComma<'a> for Element<'a> { - fn with_comma(self, comma: Comma<'a>) -> Self { +impl<'r, 'a> WithComma<'r, 'a> for Element<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> Self { let comma = Some(comma); match self { Self::Simple { value, .. } => Self::Simple { comma, value }, @@ -888,8 +904,8 @@ impl<'a> WithComma<'a> for Element<'a> { } } } -impl<'a> std::convert::From> for Element<'a> { - fn from(e: Expression<'a>) -> Self { +impl<'r, 'a> std::convert::From> for Element<'r, 'a> { + fn from(e: Expression<'r, 'a>) -> Self { match e { Expression::StarredElement(e) => Element::Starred(e), value => Element::Simple { value, comma: None }, @@ -898,14 +914,15 @@ impl<'a> std::convert::From> for Element<'a> { } #[derive(Debug, PartialEq, Eq, Clone, Default, ParenthesizedNode, IntoPy)] -pub struct Tuple<'a> { - pub elements: Vec>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Tuple<'r, 'a> { + pub elements: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Inflate<'a> for Tuple<'a> { - fn inflate(mut self, config: &Config<'a>) -> Result> { +impl<'r, 'a> Inflate<'a> for Tuple<'r, 'a> { + type Inflated = Self; + fn inflate(mut self, config: &Config<'a>) -> Result> { self.lpar = self.lpar.inflate(config)?; let len = self.elements.len(); self.elements = self @@ -922,7 +939,7 @@ impl<'a> Inflate<'a> for Tuple<'a> { } } -impl<'a> Codegen<'a> for Tuple<'a> { +impl<'r, 'a> Codegen<'a> for Tuple<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { let len = self.elements.len(); @@ -938,14 +955,14 @@ impl<'a> Codegen<'a> for Tuple<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct GeneratorExp<'a> { - pub elt: Box>, - pub for_in: Box>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct GeneratorExp<'r, 'a> { + pub elt: Box>, + pub for_in: Box>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for GeneratorExp<'a> { +impl<'r, 'a> Codegen<'a> for GeneratorExp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.elt.codegen(state); @@ -954,7 +971,8 @@ impl<'a> Codegen<'a> for GeneratorExp<'a> { } } -impl<'a> Inflate<'a> for GeneratorExp<'a> { +impl<'r, 'a> Inflate<'a> for GeneratorExp<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.elt = self.elt.inflate(config)?; @@ -965,16 +983,16 @@ impl<'a> Inflate<'a> for GeneratorExp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct ListComp<'a> { - pub elt: Box>, - pub for_in: Box>, - pub lbracket: LeftSquareBracket<'a>, - pub rbracket: RightSquareBracket<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct ListComp<'r, 'a> { + pub elt: Box>, + pub for_in: Box>, + pub lbracket: LeftSquareBracket<'r, 'a>, + pub rbracket: RightSquareBracket<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for ListComp<'a> { +impl<'r, 'a> Codegen<'a> for ListComp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.lbracket.codegen(state); @@ -985,7 +1003,8 @@ impl<'a> Codegen<'a> for ListComp<'a> { } } -impl<'a> Inflate<'a> for ListComp<'a> { +impl<'r, 'a> Inflate<'a> for ListComp<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.lbracket = self.lbracket.inflate(config)?; @@ -998,19 +1017,20 @@ impl<'a> Inflate<'a> for ListComp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct LeftSquareBracket<'a> { +pub struct LeftSquareBracket<'r, 'a> { pub whitespace_after: ParenthesizableWhitespace<'a>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for LeftSquareBracket<'a> { +impl<'r, 'a> Codegen<'a> for LeftSquareBracket<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("["); self.whitespace_after.codegen(state); } } -impl<'a> Inflate<'a> for LeftSquareBracket<'a> { +impl<'r, 'a> Inflate<'a> for LeftSquareBracket<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_after = parse_parenthesizable_whitespace( config, @@ -1021,19 +1041,20 @@ impl<'a> Inflate<'a> for LeftSquareBracket<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct RightSquareBracket<'a> { +pub struct RightSquareBracket<'r, 'a> { pub whitespace_before: ParenthesizableWhitespace<'a>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for RightSquareBracket<'a> { +impl<'r, 'a> Codegen<'a> for RightSquareBracket<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); state.add_token("]"); } } -impl<'a> Inflate<'a> for RightSquareBracket<'a> { +impl<'r, 'a> Inflate<'a> for RightSquareBracket<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -1044,16 +1065,17 @@ impl<'a> Inflate<'a> for RightSquareBracket<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct SetComp<'a> { - pub elt: Box>, - pub for_in: Box>, - pub lbrace: LeftCurlyBrace<'a>, - pub rbrace: RightCurlyBrace<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct SetComp<'r, 'a> { + pub elt: Box>, + pub for_in: Box>, + pub lbrace: LeftCurlyBrace<'r, 'a>, + pub rbrace: RightCurlyBrace<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Inflate<'a> for SetComp<'a> { +impl<'r, 'a> Inflate<'a> for SetComp<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.lbrace = self.lbrace.inflate(config)?; @@ -1065,7 +1087,7 @@ impl<'a> Inflate<'a> for SetComp<'a> { } } -impl<'a> Codegen<'a> for SetComp<'a> { +impl<'r, 'a> Codegen<'a> for SetComp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.lbrace.codegen(state); @@ -1077,21 +1099,22 @@ impl<'a> Codegen<'a> for SetComp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct DictComp<'a> { - pub key: Box>, - pub value: Box>, - pub for_in: Box>, - pub lbrace: LeftCurlyBrace<'a>, - pub rbrace: RightCurlyBrace<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct DictComp<'r, 'a> { + pub key: Box>, + pub value: Box>, + pub for_in: Box>, + pub lbrace: LeftCurlyBrace<'r, 'a>, + pub rbrace: RightCurlyBrace<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_before_colon: ParenthesizableWhitespace<'a>, pub whitespace_after_colon: ParenthesizableWhitespace<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for DictComp<'a> { +impl<'r, 'a> Inflate<'a> for DictComp<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.lbrace = self.lbrace.inflate(config)?; @@ -1112,7 +1135,7 @@ impl<'a> Inflate<'a> for DictComp<'a> { } } -impl<'a> Codegen<'a> for DictComp<'a> { +impl<'r, 'a> Codegen<'a> for DictComp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.lbrace.codegen(state); @@ -1128,12 +1151,13 @@ impl<'a> Codegen<'a> for DictComp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct LeftCurlyBrace<'a> { +pub struct LeftCurlyBrace<'r, 'a> { pub whitespace_after: ParenthesizableWhitespace<'a>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for LeftCurlyBrace<'a> { +impl<'r, 'a> Inflate<'a> for LeftCurlyBrace<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_after = parse_parenthesizable_whitespace( config, @@ -1143,7 +1167,7 @@ impl<'a> Inflate<'a> for LeftCurlyBrace<'a> { } } -impl<'a> Codegen<'a> for LeftCurlyBrace<'a> { +impl<'r, 'a> Codegen<'a> for LeftCurlyBrace<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("{"); self.whitespace_after.codegen(state); @@ -1151,12 +1175,13 @@ impl<'a> Codegen<'a> for LeftCurlyBrace<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct RightCurlyBrace<'a> { +pub struct RightCurlyBrace<'r, 'a> { pub whitespace_before: ParenthesizableWhitespace<'a>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for RightCurlyBrace<'a> { +impl<'r, 'a> Inflate<'a> for RightCurlyBrace<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -1166,37 +1191,37 @@ impl<'a> Inflate<'a> for RightCurlyBrace<'a> { } } -impl<'a> Codegen<'a> for RightCurlyBrace<'a> { +impl<'r, 'a> Codegen<'a> for RightCurlyBrace<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); state.add_token("}"); } } -impl<'a> pyo3::conversion::IntoPy for Box> { +impl<'r, 'a> pyo3::conversion::IntoPy for Box> { fn into_py(self, py: pyo3::Python) -> pyo3::PyObject { (*self).into_py(py) } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct CompFor<'a> { - pub target: AssignTargetExpression<'a>, - pub iter: Expression<'a>, - pub ifs: Vec>, - pub inner_for_in: Option>>, +pub struct CompFor<'r, 'a> { + pub target: AssignTargetExpression<'r, 'a>, + pub iter: Expression<'r, 'a>, + pub ifs: Vec>, + pub inner_for_in: Option>>, pub asynchronous: Option>, pub whitespace_before: ParenthesizableWhitespace<'a>, pub whitespace_after_for: ParenthesizableWhitespace<'a>, pub whitespace_before_in: ParenthesizableWhitespace<'a>, pub whitespace_after_in: ParenthesizableWhitespace<'a>, - pub(crate) async_tok: Option>, - pub(crate) for_tok: TokenRef<'a>, - pub(crate) in_tok: TokenRef<'a>, + pub(crate) async_tok: Option>, + pub(crate) for_tok: TokenRef<'r, 'a>, + pub(crate) in_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for CompFor<'a> { +impl<'r, 'a> Codegen<'a> for CompFor<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); if let Some(asynchronous) = &self.asynchronous { @@ -1218,7 +1243,8 @@ impl<'a> Codegen<'a> for CompFor<'a> { } } -impl<'a> Inflate<'a> for CompFor<'a> { +impl<'r, 'a> Inflate<'a> for CompFor<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -1267,15 +1293,15 @@ impl<'a> Codegen<'a> for Asynchronous<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct CompIf<'a> { - pub test: Expression<'a>, +pub struct CompIf<'r, 'a> { + pub test: Expression<'r, 'a>, pub whitespace_before: ParenthesizableWhitespace<'a>, pub whitespace_before_test: ParenthesizableWhitespace<'a>, - pub(crate) if_tok: TokenRef<'a>, + pub(crate) if_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for CompIf<'a> { +impl<'r, 'a> Codegen<'a> for CompIf<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); state.add_token("if"); @@ -1284,7 +1310,8 @@ impl<'a> Codegen<'a> for CompIf<'a> { } } -impl<'a> Inflate<'a> for CompIf<'a> { +impl<'r, 'a> Inflate<'a> for CompIf<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -1300,15 +1327,16 @@ impl<'a> Inflate<'a> for CompIf<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct List<'a> { - pub elements: Vec>, - pub lbracket: LeftSquareBracket<'a>, - pub rbracket: RightSquareBracket<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct List<'r, 'a> { + pub elements: Vec>, + pub lbracket: LeftSquareBracket<'r, 'a>, + pub rbracket: RightSquareBracket<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Inflate<'a> for List<'a> { +impl<'r, 'a> Inflate<'a> for List<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.lbracket = self.lbracket.inflate(config)?; @@ -1328,7 +1356,7 @@ impl<'a> Inflate<'a> for List<'a> { } } -impl<'a> Codegen<'a> for List<'a> { +impl<'r, 'a> Codegen<'a> for List<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.lbracket.codegen(state); @@ -1342,15 +1370,16 @@ impl<'a> Codegen<'a> for List<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Set<'a> { - pub elements: Vec>, - pub lbrace: LeftCurlyBrace<'a>, - pub rbrace: RightCurlyBrace<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Set<'r, 'a> { + pub elements: Vec>, + pub lbrace: LeftCurlyBrace<'r, 'a>, + pub rbrace: RightCurlyBrace<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Inflate<'a> for Set<'a> { +impl<'r, 'a> Inflate<'a> for Set<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.lbrace = self.lbrace.inflate(config)?; @@ -1369,7 +1398,7 @@ impl<'a> Inflate<'a> for Set<'a> { } } -impl<'a> Codegen<'a> for Set<'a> { +impl<'r, 'a> Codegen<'a> for Set<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.lbrace.codegen(state); @@ -1383,15 +1412,16 @@ impl<'a> Codegen<'a> for Set<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Dict<'a> { - pub elements: Vec>, - pub lbrace: LeftCurlyBrace<'a>, - pub rbrace: RightCurlyBrace<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Dict<'r, 'a> { + pub elements: Vec>, + pub lbrace: LeftCurlyBrace<'r, 'a>, + pub rbrace: RightCurlyBrace<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Inflate<'a> for Dict<'a> { +impl<'r, 'a> Inflate<'a> for Dict<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.lbrace = self.lbrace.inflate(config)?; @@ -1410,7 +1440,7 @@ impl<'a> Inflate<'a> for Dict<'a> { } } -impl<'a> Codegen<'a> for Dict<'a> { +impl<'r, 'a> Codegen<'a> for Dict<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.lbrace.codegen(state); @@ -1425,20 +1455,20 @@ impl<'a> Codegen<'a> for Dict<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone)] -pub enum DictElement<'a> { +pub enum DictElement<'r, 'a> { Simple { - key: Expression<'a>, - value: Expression<'a>, - comma: Option>, + key: Expression<'r, 'a>, + value: Expression<'r, 'a>, + comma: Option>, whitespace_before_colon: ParenthesizableWhitespace<'a>, whitespace_after_colon: ParenthesizableWhitespace<'a>, - colon_tok: TokenRef<'a>, + colon_tok: TokenRef<'r, 'a>, }, - Starred(StarredDictElement<'a>), + Starred(StarredDictElement<'r, 'a>), } // TODO: this could be a derive helper attribute to override the python class name -impl<'a> IntoPy for DictElement<'a> { +impl<'r, 'a> IntoPy for DictElement<'r, 'a> { fn into_py(self, py: pyo3::Python) -> pyo3::PyObject { match self { Self::Starred(s) => s.into_py(py), @@ -1477,7 +1507,7 @@ impl<'a> IntoPy for DictElement<'a> { } } -impl<'a> DictElement<'a> { +impl<'r, 'a> DictElement<'r, 'a> { pub fn inflate_element(self, config: &Config<'a>, last_element: bool) -> Result { Ok(match self { Self::Starred(s) => Self::Starred(s.inflate_element(config, last_element)?), @@ -1513,7 +1543,7 @@ impl<'a> DictElement<'a> { } } -impl<'a> DictElement<'a> { +impl<'r, 'a> DictElement<'r, 'a> { fn codegen( &self, state: &mut CodegenState<'a>, @@ -1550,8 +1580,8 @@ impl<'a> DictElement<'a> { } } -impl<'a> WithComma<'a> for DictElement<'a> { - fn with_comma(self, comma: Comma<'a>) -> Self { +impl<'r, 'a> WithComma<'r, 'a> for DictElement<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> Self { let comma = Some(comma); match self { Self::Starred(s) => Self::Starred(StarredDictElement { comma, ..s }), @@ -1575,15 +1605,15 @@ impl<'a> WithComma<'a> for DictElement<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct StarredDictElement<'a> { - pub value: Expression<'a>, - pub comma: Option>, +pub struct StarredDictElement<'r, 'a> { + pub value: Expression<'r, 'a>, + pub comma: Option>, pub whitespace_before_value: ParenthesizableWhitespace<'a>, - pub(crate) star_tok: TokenRef<'a>, + pub(crate) star_tok: TokenRef<'r, 'a>, } -impl<'a> StarredDictElement<'a> { +impl<'r, 'a> StarredDictElement<'r, 'a> { fn inflate_element(mut self, config: &Config<'a>, last_element: bool) -> Result { self.whitespace_before_value = parse_parenthesizable_whitespace( config, @@ -1599,7 +1629,7 @@ impl<'a> StarredDictElement<'a> { } } -impl<'a> Codegen<'a> for StarredDictElement<'a> { +impl<'r, 'a> Codegen<'a> for StarredDictElement<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("**"); self.whitespace_before_value.codegen(state); @@ -1612,41 +1642,43 @@ impl<'a> Codegen<'a> for StarredDictElement<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, Codegen, Inflate, IntoPy)] -pub enum BaseSlice<'a> { - Index(Index<'a>), - Slice(Slice<'a>), +pub enum BaseSlice<'r, 'a> { + Index(Index<'r, 'a>), + Slice(Slice<'r, 'a>), } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Index<'a> { - pub value: Expression<'a>, +pub struct Index<'r, 'a> { + pub value: Expression<'r, 'a>, } -impl<'a> Inflate<'a> for Index<'a> { +impl<'r, 'a> Inflate<'a> for Index<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.value = self.value.inflate(config)?; Ok(self) } } -impl<'a> Codegen<'a> for Index<'a> { +impl<'r, 'a> Codegen<'a> for Index<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.value.codegen(state); } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Slice<'a> { +pub struct Slice<'r, 'a> { #[no_py_default] - pub lower: Option>, + pub lower: Option>, #[no_py_default] - pub upper: Option>, - pub step: Option>, - pub first_colon: Colon<'a>, - pub second_colon: Option>, + pub upper: Option>, + pub step: Option>, + pub first_colon: Colon<'r, 'a>, + pub second_colon: Option>, } -impl<'a> Inflate<'a> for Slice<'a> { +impl<'r, 'a> Inflate<'a> for Slice<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lower = self.lower.inflate(config)?; self.first_colon = self.first_colon.inflate(config)?; @@ -1657,7 +1689,7 @@ impl<'a> Inflate<'a> for Slice<'a> { } } -impl<'a> Codegen<'a> for Slice<'a> { +impl<'r, 'a> Codegen<'a> for Slice<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { if let Some(lower) = &self.lower { lower.codegen(state); @@ -1678,12 +1710,13 @@ impl<'a> Codegen<'a> for Slice<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct SubscriptElement<'a> { - pub slice: BaseSlice<'a>, - pub comma: Option>, +pub struct SubscriptElement<'r, 'a> { + pub slice: BaseSlice<'r, 'a>, + pub comma: Option>, } -impl<'a> Inflate<'a> for SubscriptElement<'a> { +impl<'r, 'a> Inflate<'a> for SubscriptElement<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.slice = self.slice.inflate(config)?; self.comma = self.comma.inflate(config)?; @@ -1691,7 +1724,7 @@ impl<'a> Inflate<'a> for SubscriptElement<'a> { } } -impl<'a> Codegen<'a> for SubscriptElement<'a> { +impl<'r, 'a> Codegen<'a> for SubscriptElement<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.slice.codegen(state); if let Some(comma) = &self.comma { @@ -1701,19 +1734,20 @@ impl<'a> Codegen<'a> for SubscriptElement<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Subscript<'a> { - pub value: Box>, - pub slice: Vec>, - pub lbracket: LeftSquareBracket<'a>, - pub rbracket: RightSquareBracket<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Subscript<'r, 'a> { + pub value: Box>, + pub slice: Vec>, + pub lbracket: LeftSquareBracket<'r, 'a>, + pub rbracket: RightSquareBracket<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_after_value: ParenthesizableWhitespace<'a>, - pub(crate) lbracket_tok: TokenRef<'a>, + pub(crate) lbracket_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Subscript<'a> { +impl<'r, 'a> Inflate<'a> for Subscript<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.value = self.value.inflate(config)?; @@ -1729,7 +1763,7 @@ impl<'a> Inflate<'a> for Subscript<'a> { } } -impl<'a> Codegen<'a> for Subscript<'a> { +impl<'r, 'a> Codegen<'a> for Subscript<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.value.codegen(state); @@ -1748,22 +1782,23 @@ impl<'a> Codegen<'a> for Subscript<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct IfExp<'a> { - pub test: Box>, - pub body: Box>, - pub orelse: Box>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct IfExp<'r, 'a> { + pub test: Box>, + pub body: Box>, + pub orelse: Box>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_before_if: ParenthesizableWhitespace<'a>, pub whitespace_after_if: ParenthesizableWhitespace<'a>, pub whitespace_before_else: ParenthesizableWhitespace<'a>, pub whitespace_after_else: ParenthesizableWhitespace<'a>, - pub(crate) if_tok: TokenRef<'a>, - pub(crate) else_tok: TokenRef<'a>, + pub(crate) if_tok: TokenRef<'r, 'a>, + pub(crate) else_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for IfExp<'a> { +impl<'r, 'a> Inflate<'a> for IfExp<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.body = self.body.inflate(config)?; @@ -1790,7 +1825,7 @@ impl<'a> Inflate<'a> for IfExp<'a> { } } -impl<'a> Codegen<'a> for IfExp<'a> { +impl<'r, 'a> Codegen<'a> for IfExp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.body.codegen(state); @@ -1807,18 +1842,19 @@ impl<'a> Codegen<'a> for IfExp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Lambda<'a> { - pub params: Box>, - pub body: Box>, - pub colon: Colon<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Lambda<'r, 'a> { + pub params: Box>, + pub body: Box>, + pub colon: Colon<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_after_lambda: Option>, - pub(crate) lambda_tok: TokenRef<'a>, + pub(crate) lambda_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Lambda<'a> { +impl<'r, 'a> Inflate<'a> for Lambda<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; if !self.params.is_empty() { @@ -1836,7 +1872,7 @@ impl<'a> Inflate<'a> for Lambda<'a> { } } -impl<'a> Codegen<'a> for Lambda<'a> { +impl<'r, 'a> Codegen<'a> for Lambda<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token("lambda"); @@ -1854,15 +1890,15 @@ impl<'a> Codegen<'a> for Lambda<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct From<'a> { - pub item: Expression<'a>, +pub struct From<'r, 'a> { + pub item: Expression<'r, 'a>, pub whitespace_before_from: Option>, pub whitespace_after_from: ParenthesizableWhitespace<'a>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> From<'a> { +impl<'r, 'a> From<'r, 'a> { pub fn codegen(&self, state: &mut CodegenState<'a>, default_space: &'a str) { if let Some(ws) = &self.whitespace_before_from { ws.codegen(state); @@ -1875,7 +1911,8 @@ impl<'a> From<'a> { } } -impl<'a> Inflate<'a> for From<'a> { +impl<'r, 'a> Inflate<'a> for From<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before_from = Some(parse_parenthesizable_whitespace( config, @@ -1892,12 +1929,13 @@ impl<'a> Inflate<'a> for From<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub enum YieldValue<'a> { - Expression(Expression<'a>), - From(From<'a>), +pub enum YieldValue<'r, 'a> { + Expression(Expression<'r, 'a>), + From(From<'r, 'a>), } -impl<'a> Inflate<'a> for YieldValue<'a> { +impl<'r, 'a> Inflate<'a> for YieldValue<'r, 'a> { + type Inflated = Self; fn inflate(self, config: &Config<'a>) -> Result { Ok(match self { Self::Expression(e) => Self::Expression(e.inflate(config)?), @@ -1910,7 +1948,7 @@ impl<'a> Inflate<'a> for YieldValue<'a> { } } -impl<'a> YieldValue<'a> { +impl<'r, 'a> YieldValue<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>, default_space: &'a str) { match self { Self::Expression(e) => e.codegen(state), @@ -1919,23 +1957,24 @@ impl<'a> YieldValue<'a> { } } -impl<'a> pyo3::conversion::IntoPy for Box> { +impl<'r, 'a> pyo3::conversion::IntoPy for Box> { fn into_py(self, py: pyo3::Python) -> pyo3::PyObject { (*self).into_py(py) } } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Yield<'a> { - pub value: Option>>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Yield<'r, 'a> { + pub value: Option>>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_after_yield: Option>, - pub(crate) yield_tok: TokenRef<'a>, + pub(crate) yield_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Yield<'a> { +impl<'r, 'a> Inflate<'a> for Yield<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; if self.value.is_some() { @@ -1950,7 +1989,7 @@ impl<'a> Inflate<'a> for Yield<'a> { } } -impl<'a> Codegen<'a> for Yield<'a> { +impl<'r, 'a> Codegen<'a> for Yield<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token("yield"); @@ -1968,16 +2007,17 @@ impl<'a> Codegen<'a> for Yield<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct Await<'a> { - pub expression: Box>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct Await<'r, 'a> { + pub expression: Box>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_after_await: ParenthesizableWhitespace<'a>, - pub(crate) await_tok: TokenRef<'a>, + pub(crate) await_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Await<'a> { +impl<'r, 'a> Inflate<'a> for Await<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.whitespace_after_await = parse_parenthesizable_whitespace( @@ -1990,7 +2030,7 @@ impl<'a> Inflate<'a> for Await<'a> { } } -impl<'a> Codegen<'a> for Await<'a> { +impl<'r, 'a> Codegen<'a> for Await<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token("await"); @@ -2002,14 +2042,14 @@ impl<'a> Codegen<'a> for Await<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, Codegen, Inflate, IntoPy)] -pub enum String<'a> { - Simple(SimpleString<'a>), - Concatenated(ConcatenatedString<'a>), - Formatted(FormattedString<'a>), +pub enum String<'r, 'a> { + Simple(SimpleString<'r, 'a>), + Concatenated(ConcatenatedString<'r, 'a>), + Formatted(FormattedString<'r, 'a>), } -impl<'a> std::convert::From> for Expression<'a> { - fn from(s: String<'a>) -> Self { +impl<'r, 'a> std::convert::From> for Expression<'r, 'a> { + fn from(s: String<'r, 'a>) -> Self { match s { String::Simple(s) => Self::SimpleString(s), String::Concatenated(s) => Self::ConcatenatedString(s), @@ -2019,19 +2059,20 @@ impl<'a> std::convert::From> for Expression<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct ConcatenatedString<'a> { - pub left: Box>, - pub right: Box>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct ConcatenatedString<'r, 'a> { + pub left: Box>, + pub right: Box>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_between: ParenthesizableWhitespace<'a>, // we capture the next token after each string piece so Inflate can extract the // whitespace between individual pieces - pub(crate) right_tok: TokenRef<'a>, + pub(crate) right_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for ConcatenatedString<'a> { +impl<'r, 'a> Inflate<'a> for ConcatenatedString<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.left = self.left.inflate(config)?; @@ -2045,7 +2086,7 @@ impl<'a> Inflate<'a> for ConcatenatedString<'a> { } } -impl<'a> Codegen<'a> for ConcatenatedString<'a> { +impl<'r, 'a> Codegen<'a> for ConcatenatedString<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.left.codegen(state); @@ -2056,16 +2097,17 @@ impl<'a> Codegen<'a> for ConcatenatedString<'a> { } #[derive(Debug, PartialEq, Eq, Clone, Default, ParenthesizedNode, IntoPy)] -pub struct SimpleString<'a> { +pub struct SimpleString<'r, 'a> { /// The texual representation of the string, including quotes, prefix /// characters, and any escape characters present in the original source code, /// such as ``r"my string\n"``. pub value: &'a str, - pub lpar: Vec>, - pub rpar: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Inflate<'a> for SimpleString<'a> { +impl<'r, 'a> Inflate<'a> for SimpleString<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.rpar = self.rpar.inflate(config)?; @@ -2073,7 +2115,7 @@ impl<'a> Inflate<'a> for SimpleString<'a> { } } -impl<'a> Codegen<'a> for SimpleString<'a> { +impl<'r, 'a> Codegen<'a> for SimpleString<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| state.add_token(self.value)) } @@ -2085,6 +2127,7 @@ pub struct FormattedStringText<'a> { } impl<'a> Inflate<'a> for FormattedStringText<'a> { + type Inflated = Self; fn inflate(self, _config: &Config<'a>) -> Result { Ok(self) } @@ -2097,21 +2140,22 @@ impl<'a> Codegen<'a> for FormattedStringText<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct FormattedStringExpression<'a> { - pub expression: Expression<'a>, +pub struct FormattedStringExpression<'r, 'a> { + pub expression: Expression<'r, 'a>, pub conversion: Option<&'a str>, - pub format_spec: Option>>, + pub format_spec: Option>>, pub whitespace_before_expression: ParenthesizableWhitespace<'a>, pub whitespace_after_expression: ParenthesizableWhitespace<'a>, - pub equal: Option>, + pub equal: Option>, - pub(crate) lbrace_tok: TokenRef<'a>, + pub(crate) lbrace_tok: TokenRef<'r, 'a>, // This is None if there's an equal sign, otherwise it's the first token of // (conversion, format spec, right brace) in that order - pub(crate) after_expr_tok: Option>, + pub(crate) after_expr_tok: Option>, } -impl<'a> Inflate<'a> for FormattedStringExpression<'a> { +impl<'r, 'a> Inflate<'a> for FormattedStringExpression<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before_expression = parse_parenthesizable_whitespace( config, @@ -2130,7 +2174,7 @@ impl<'a> Inflate<'a> for FormattedStringExpression<'a> { } } -impl<'a> Codegen<'a> for FormattedStringExpression<'a> { +impl<'r, 'a> Codegen<'a> for FormattedStringExpression<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("{"); self.whitespace_before_expression.codegen(state); @@ -2161,15 +2205,16 @@ pub enum FormattedStringContent<'a> { } #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] -pub struct FormattedString<'a> { - pub parts: Vec>, +pub struct FormattedString<'r, 'a> { + pub parts: Vec>, pub start: &'a str, pub end: &'a str, - pub lpar: Vec>, - pub rpar: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Inflate<'a> for FormattedString<'a> { +impl<'r, 'a> Inflate<'a> for FormattedString<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.parts = self.parts.inflate(config)?; @@ -2178,7 +2223,7 @@ impl<'a> Inflate<'a> for FormattedString<'a> { } } -impl<'a> Codegen<'a> for FormattedString<'a> { +impl<'r, 'a> Codegen<'a> for FormattedString<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { state.add_token(self.start); @@ -2190,6 +2235,7 @@ impl<'a> Codegen<'a> for FormattedString<'a> { } } +#[cst_node] #[derive(Debug, PartialEq, Eq, Clone, ParenthesizedNode, IntoPy)] pub struct NamedExpr<'a> { pub target: Box>, @@ -2200,7 +2246,7 @@ pub struct NamedExpr<'a> { pub whitespace_before_walrus: ParenthesizableWhitespace<'a>, pub whitespace_after_walrus: ParenthesizableWhitespace<'a>, - pub(crate) walrus_tok: TokenRef<'a>, + pub(crate) walrus_tok: TokenRef, } impl<'a> Codegen<'a> for NamedExpr<'a> { @@ -2215,8 +2261,9 @@ impl<'a> Codegen<'a> for NamedExpr<'a> { } } -impl<'a> Inflate<'a> for NamedExpr<'a> { - fn inflate(mut self, config: &Config<'a>) -> Result { +impl<'r, 'a> Inflate<'a> for DeflatedNamedExpr<'r, 'a> { + type Inflated = NamedExpr<'a>; + fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.target = self.target.inflate(config)?; self.whitespace_before_walrus = parse_parenthesizable_whitespace( diff --git a/native/libcst/src/nodes/inflate_helpers.rs b/native/libcst/src/nodes/inflate_helpers.rs index 262de5ac..afbbabe7 100644 --- a/native/libcst/src/nodes/inflate_helpers.rs +++ b/native/libcst/src/nodes/inflate_helpers.rs @@ -12,12 +12,12 @@ use crate::{ Param, Parameters, StarArg, }; -pub(crate) fn adjust_parameters_trailing_whitespace<'a>( +pub(crate) fn adjust_parameters_trailing_whitespace<'r, 'a>( config: &Config<'a>, - parameters: &mut Parameters<'a>, + parameters: &mut Parameters<'r, 'a>, next_tok: &Token<'a>, ) -> Result<()> { - let do_adjust = |param: &mut Param<'a>| -> Result<()> { + let do_adjust = |param: &mut Param<'r, 'a>| -> Result<()> { let whitespace_after = parse_parenthesizable_whitespace(config, &mut next_tok.whitespace_before.borrow_mut())?; if param.comma.is_none() { diff --git a/native/libcst/src/nodes/mod.rs b/native/libcst/src/nodes/mod.rs index b6be09df..36b4ef0a 100644 --- a/native/libcst/src/nodes/mod.rs +++ b/native/libcst/src/nodes/mod.rs @@ -48,4 +48,7 @@ pub use codegen::{Codegen, CodegenState}; mod traits; pub use traits::{Inflate, ParenthesizedNode, WithComma, WithLeadingLines}; +pub(crate) mod common; pub(crate) mod inflate_helpers; + +pub(crate) use op::*; diff --git a/native/libcst/src/nodes/module.rs b/native/libcst/src/nodes/module.rs index 03c6afb5..08318f94 100644 --- a/native/libcst/src/nodes/module.rs +++ b/native/libcst/src/nodes/module.rs @@ -4,13 +4,12 @@ // LICENSE file in the root directory of this source tree. use std::mem::swap; -use std::rc::Rc; use crate::tokenizer::whitespace_parser::parse_empty_lines; -use crate::tokenizer::Token; use crate::{ nodes::{ codegen::{Codegen, CodegenState}, + common::TokenRef, statement::Statement, whitespace::EmptyLine, }, @@ -20,11 +19,9 @@ use libcst_derive::IntoPy; use super::traits::{Inflate, Result, WithLeadingLines}; -type TokenRef<'a> = Rc>; - #[derive(Debug, Eq, PartialEq, IntoPy)] -pub struct Module<'a> { - pub body: Vec>, +pub struct Module<'r, 'a> { + pub body: Vec>, pub header: Vec>, pub footer: Vec>, @@ -33,10 +30,10 @@ pub struct Module<'a> { pub has_trailing_newline: bool, pub encoding: String, - pub(crate) eof_tok: TokenRef<'a>, + pub(crate) eof_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Module<'a> { +impl<'r, 'a> Codegen<'a> for Module<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for h in &self.header { h.codegen(state); @@ -50,7 +47,8 @@ impl<'a> Codegen<'a> for Module<'a> { } } -impl<'a> Inflate<'a> for Module<'a> { +impl<'r, 'a> Inflate<'a> for Module<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.default_indent = config.default_indent; self.default_newline = config.default_newline; diff --git a/native/libcst/src/nodes/op.rs b/native/libcst/src/nodes/op.rs index 48b9839f..a48097e5 100644 --- a/native/libcst/src/nodes/op.rs +++ b/native/libcst/src/nodes/op.rs @@ -3,29 +3,28 @@ // This source code is licensed under the MIT license found in the // LICENSE file in the root directory of this source tree. -use std::rc::Rc; - use super::{whitespace::ParenthesizableWhitespace, Codegen, CodegenState}; use crate::{ + nodes::common::TokenRef, nodes::traits::{Inflate, Result}, - tokenizer::{ - whitespace_parser::{parse_parenthesizable_whitespace, parse_simple_whitespace, Config}, - Token, + tokenizer::whitespace_parser::{ + parse_parenthesizable_whitespace, parse_simple_whitespace, Config, }, }; use libcst_derive::IntoPy; -type TokenRef<'a> = Rc>; - #[derive(Debug, Eq, PartialEq, Clone, IntoPy)] pub struct Semicolon<'a> { /// Any space that appears directly before this semicolon. pub whitespace_before: ParenthesizableWhitespace<'a>, /// Any space that appears directly after this semicolon. pub whitespace_after: ParenthesizableWhitespace<'a>, +} - #[skip_py] - pub(crate) tok: TokenRef<'a>, +#[derive(Debug, Eq, PartialEq, Clone)] +pub(crate) struct SemicolonTokens<'r, 'a> { + pub inner: Semicolon<'a>, + pub tok: TokenRef<'r, 'a>, } impl<'a> Codegen<'a> for Semicolon<'a> { @@ -36,12 +35,13 @@ impl<'a> Codegen<'a> for Semicolon<'a> { } } -impl<'a> Inflate<'a> for Semicolon<'a> { +impl<'r, 'a> Inflate<'a> for SemicolonTokens<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { - self.whitespace_before = ParenthesizableWhitespace::SimpleWhitespace( + self.inner.whitespace_before = ParenthesizableWhitespace::SimpleWhitespace( parse_simple_whitespace(config, &mut (*self.tok).whitespace_before.borrow_mut())?, ); - self.whitespace_after = ParenthesizableWhitespace::SimpleWhitespace( + self.inner.whitespace_after = ParenthesizableWhitespace::SimpleWhitespace( parse_simple_whitespace(config, &mut (*self.tok).whitespace_after.borrow_mut())?, ); Ok(self) @@ -49,17 +49,17 @@ impl<'a> Inflate<'a> for Semicolon<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Comma<'a> { +pub struct Comma<'r, 'a> { /// Any space that appears directly before this comma. pub whitespace_before: ParenthesizableWhitespace<'a>, /// Any space that appears directly after this comma. pub whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Comma<'a> { +impl<'r, 'a> Codegen<'a> for Comma<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); state.add_token(","); @@ -67,7 +67,8 @@ impl<'a> Codegen<'a> for Comma<'a> { } } -impl<'a> Inflate<'a> for Comma<'a> { +impl<'r, 'a> Inflate<'a> for Comma<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -81,7 +82,7 @@ impl<'a> Inflate<'a> for Comma<'a> { } } -impl<'a> Comma<'a> { +impl<'r, 'a> Comma<'r, 'a> { pub fn inflate_before(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -92,17 +93,17 @@ impl<'a> Comma<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct AssignEqual<'a> { +pub struct AssignEqual<'r, 'a> { /// Any space that appears directly before this equal sign. pub whitespace_before: ParenthesizableWhitespace<'a>, /// Any space that appears directly after this equal sign. pub whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for AssignEqual<'a> { +impl<'r, 'a> Codegen<'a> for AssignEqual<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); state.add_token("="); @@ -110,7 +111,8 @@ impl<'a> Codegen<'a> for AssignEqual<'a> { } } -impl<'a> Inflate<'a> for AssignEqual<'a> { +impl<'r, 'a> Inflate<'a> for AssignEqual<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -125,17 +127,17 @@ impl<'a> Inflate<'a> for AssignEqual<'a> { } #[derive(Debug, Eq, PartialEq, Clone, IntoPy)] -pub struct Dot<'a> { +pub struct Dot<'r, 'a> { /// Any space that appears directly before this dot. pub whitespace_before: ParenthesizableWhitespace<'a>, /// Any space that appears directly after this dot. pub whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Dot<'a> { +impl<'r, 'a> Codegen<'a> for Dot<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); state.add_token("."); @@ -143,7 +145,8 @@ impl<'a> Codegen<'a> for Dot<'a> { } } -impl<'a> Inflate<'a> for Dot<'a> { +impl<'r, 'a> Inflate<'a> for Dot<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.inflate_before(config)?; self.inflate_after(config)?; @@ -151,7 +154,7 @@ impl<'a> Inflate<'a> for Dot<'a> { } } -impl<'a> Dot<'a> { +impl<'r, 'a> Dot<'r, 'a> { fn inflate_before(&mut self, config: &Config<'a>) -> Result<()> { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -172,43 +175,44 @@ impl<'a> Dot<'a> { #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] pub struct ImportStar {} -impl<'a> Codegen<'a> for ImportStar { +impl<'r, 'a> Codegen<'a> for ImportStar { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("*"); } } -impl<'a> Inflate<'a> for ImportStar { +impl<'r, 'a> Inflate<'a> for ImportStar { + type Inflated = Self; fn inflate(self, _config: &Config<'a>) -> Result { Ok(self) } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub enum UnaryOp<'a> { +pub enum UnaryOp<'r, 'a> { Plus { whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, Minus { whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, BitInvert { whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, Not { whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, } -impl<'a> Codegen<'a> for UnaryOp<'a> { +impl<'r, 'a> Codegen<'a> for UnaryOp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { let (tok, whitespace_after) = match self { Self::Plus { @@ -229,7 +233,8 @@ impl<'a> Codegen<'a> for UnaryOp<'a> { } } -impl<'a> Inflate<'a> for UnaryOp<'a> { +impl<'r, 'a> Inflate<'a> for UnaryOp<'r, 'a> { + type Inflated = Self; fn inflate(self, config: &Config<'a>) -> Result { Ok(match self { Self::Plus { tok, .. } => { @@ -277,22 +282,22 @@ impl<'a> Inflate<'a> for UnaryOp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub enum BooleanOp<'a> { +pub enum BooleanOp<'r, 'a> { And { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, Or { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, } -impl<'a> Codegen<'a> for BooleanOp<'a> { +impl<'r, 'a> Codegen<'a> for BooleanOp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { let (tok, ws_bef, ws_aft) = match self { Self::And { @@ -312,7 +317,8 @@ impl<'a> Codegen<'a> for BooleanOp<'a> { } } -impl<'a> Inflate<'a> for BooleanOp<'a> { +impl<'r, 'a> Inflate<'a> for BooleanOp<'r, 'a> { + type Inflated = Self; fn inflate(self, config: &Config<'a>) -> Result { Ok(match self { Self::And { tok, .. } => { @@ -350,88 +356,88 @@ impl<'a> Inflate<'a> for BooleanOp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub enum BinaryOp<'a> { +pub enum BinaryOp<'r, 'a> { Add { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, Subtract { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, Multiply { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, Divide { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, FloorDivide { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, Modulo { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, Power { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, LeftShift { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, RightShift { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, BitOr { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, BitAnd { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, BitXor { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, MatrixMultiply { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, } -impl<'a> Codegen<'a> for BinaryOp<'a> { +impl<'r, 'a> Codegen<'a> for BinaryOp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { let (whitespace_before, whitespace_after, tok) = match self { Self::Add { @@ -506,7 +512,8 @@ impl<'a> Codegen<'a> for BinaryOp<'a> { } } -impl<'a> Inflate<'a> for BinaryOp<'a> { +impl<'r, 'a> Inflate<'a> for BinaryOp<'r, 'a> { + type Inflated = Self; fn inflate(self, config: &Config<'a>) -> Result { Ok(match self { Self::Add { tok, .. } => { @@ -709,76 +716,76 @@ impl<'a> Inflate<'a> for BinaryOp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub enum CompOp<'a> { +pub enum CompOp<'r, 'a> { LessThan { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, GreaterThan { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, LessThanEqual { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, GreaterThanEqual { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, Equal { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, NotEqual { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, In { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, NotIn { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_between: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - not_tok: TokenRef<'a>, + not_tok: TokenRef<'r, 'a>, #[skip_py] - in_tok: TokenRef<'a>, + in_tok: TokenRef<'r, 'a>, }, Is { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, IsNot { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_between: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - is_tok: TokenRef<'a>, + is_tok: TokenRef<'r, 'a>, #[skip_py] - not_tok: TokenRef<'a>, + not_tok: TokenRef<'r, 'a>, }, } -impl<'a> Codegen<'a> for CompOp<'a> { +impl<'r, 'a> Codegen<'a> for CompOp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { let (bef, aft, first_tok, between) = match self { Self::LessThan { @@ -856,7 +863,8 @@ impl<'a> Codegen<'a> for CompOp<'a> { } } -impl<'a> Inflate<'a> for CompOp<'a> { +impl<'r, 'a> Inflate<'a> for CompOp<'r, 'a> { + type Inflated = Self; fn inflate(self, config: &Config<'a>) -> Result { Ok(match self { Self::LessThan { tok, .. } => { @@ -1030,15 +1038,16 @@ impl<'a> Inflate<'a> for CompOp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Colon<'a> { +pub struct Colon<'r, 'a> { pub whitespace_before: ParenthesizableWhitespace<'a>, pub whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Colon<'a> { +impl<'r, 'a> Inflate<'a> for Colon<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -1052,7 +1061,7 @@ impl<'a> Inflate<'a> for Colon<'a> { } } -impl<'a> Codegen<'a> for Colon<'a> { +impl<'r, 'a> Codegen<'a> for Colon<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); state.add_token(":"); @@ -1061,88 +1070,89 @@ impl<'a> Codegen<'a> for Colon<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub enum AugOp<'a> { +pub enum AugOp<'r, 'a> { AddAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, SubtractAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, MultiplyAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, MatrixMultiplyAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, DivideAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, ModuloAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, BitAndAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, BitOrAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, BitXorAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, LeftShiftAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, RightShiftAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, PowerAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, FloorDivideAssign { whitespace_before: ParenthesizableWhitespace<'a>, whitespace_after: ParenthesizableWhitespace<'a>, #[skip_py] - tok: TokenRef<'a>, + tok: TokenRef<'r, 'a>, }, } -impl<'a> Inflate<'a> for AugOp<'a> { +impl<'r, 'a> Inflate<'a> for AugOp<'r, 'a> { + type Inflated = Self; fn inflate(self, config: &Config<'a>) -> Result { Ok(match self { Self::AddAssign { tok, .. } => { @@ -1344,7 +1354,7 @@ impl<'a> Inflate<'a> for AugOp<'a> { } } -impl<'a> Codegen<'a> for AugOp<'a> { +impl<'r, 'a> Codegen<'a> for AugOp<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { let (tok, bef, aft) = match self { Self::AddAssign { @@ -1420,14 +1430,15 @@ impl<'a> Codegen<'a> for AugOp<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct BitOr<'a> { +pub struct BitOr<'r, 'a> { pub whitespace_before: ParenthesizableWhitespace<'a>, pub whitespace_after: ParenthesizableWhitespace<'a>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for BitOr<'a> { +impl<'r, 'a> Inflate<'a> for BitOr<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before = parse_parenthesizable_whitespace( config, @@ -1441,7 +1452,7 @@ impl<'a> Inflate<'a> for BitOr<'a> { } } -impl<'a> Codegen<'a> for BitOr<'a> { +impl<'r, 'a> Codegen<'a> for BitOr<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before.codegen(state); state.add_token("|"); diff --git a/native/libcst/src/nodes/statement.rs b/native/libcst/src/nodes/statement.rs index 7d7da873..b454b735 100644 --- a/native/libcst/src/nodes/statement.rs +++ b/native/libcst/src/nodes/statement.rs @@ -3,40 +3,36 @@ // This source code is licensed under the MIT license found in the // LICENSE file in the root directory of this source tree. -use std::{mem::swap, rc::Rc}; +use std::mem::swap; use super::{ - inflate_helpers::adjust_parameters_trailing_whitespace, Attribute, Codegen, CodegenState, - Comma, Dot, EmptyLine, Expression, From, ImportStar, LeftParen, List, Name, NameOrAttribute, - Parameters, ParenthesizableWhitespace, RightParen, Semicolon, SimpleWhitespace, StarredElement, - Subscript, TrailingWhitespace, Tuple, + inflate_helpers::adjust_parameters_trailing_whitespace, op::SemicolonTokens, Attribute, + Codegen, CodegenState, Comma, Dot, EmptyLine, Expression, From, ImportStar, LeftParen, List, + Name, NameOrAttribute, Parameters, ParenthesizableWhitespace, RightParen, Semicolon, + SimpleWhitespace, StarredElement, Subscript, TrailingWhitespace, Tuple, }; use crate::{ nodes::{ + common::TokenRef, traits::{Inflate, Result, WithComma, WithLeadingLines}, Arg, AssignEqual, Asynchronous, AugOp, BitOr, Element, ParenthesizedNode, }, - tokenizer::{ - whitespace_parser::{ - parse_empty_lines, parse_parenthesizable_whitespace, parse_simple_whitespace, - parse_trailing_whitespace, Config, - }, - Token, + tokenizer::whitespace_parser::{ + parse_empty_lines, parse_parenthesizable_whitespace, parse_simple_whitespace, + parse_trailing_whitespace, Config, }, LeftCurlyBrace, LeftSquareBracket, RightCurlyBrace, RightSquareBracket, }; use libcst_derive::{Codegen, Inflate, IntoPy, ParenthesizedNode}; -type TokenRef<'a> = Rc>; - #[allow(clippy::large_enum_variant)] #[derive(Debug, Eq, PartialEq, Clone, Inflate, Codegen, IntoPy)] -pub enum Statement<'a> { - Simple(SimpleStatementLine<'a>), - Compound(CompoundStatement<'a>), +pub enum Statement<'r, 'a> { + Simple(SimpleStatementLine<'r, 'a>), + Compound(CompoundStatement<'r, 'a>), } -impl<'a> WithLeadingLines<'a> for Statement<'a> { +impl<'r, 'a> WithLeadingLines<'a> for Statement<'r, 'a> { fn leading_lines(&mut self) -> &mut Vec> { match self { Self::Simple(s) => &mut s.leading_lines, @@ -47,19 +43,19 @@ impl<'a> WithLeadingLines<'a> for Statement<'a> { #[derive(Debug, PartialEq, Eq, Clone, Inflate, Codegen, IntoPy)] #[allow(clippy::large_enum_variant)] -pub enum CompoundStatement<'a> { - FunctionDef(FunctionDef<'a>), - If(If<'a>), - For(For<'a>), - While(While<'a>), - ClassDef(ClassDef<'a>), - Try(Try<'a>), - TryStar(TryStar<'a>), - With(With<'a>), - Match(Match<'a>), +pub enum CompoundStatement<'r, 'a> { + FunctionDef(FunctionDef<'r, 'a>), + If(If<'r, 'a>), + For(For<'r, 'a>), + While(While<'r, 'a>), + ClassDef(ClassDef<'r, 'a>), + Try(Try<'r, 'a>), + TryStar(TryStar<'r, 'a>), + With(With<'r, 'a>), + Match(Match<'r, 'a>), } -impl<'a> WithLeadingLines<'a> for CompoundStatement<'a> { +impl<'r, 'a> WithLeadingLines<'a> for CompoundStatement<'r, 'a> { fn leading_lines(&mut self) -> &mut Vec> { match self { Self::FunctionDef(f) => &mut f.leading_lines, @@ -76,15 +72,15 @@ impl<'a> WithLeadingLines<'a> for CompoundStatement<'a> { } #[derive(Debug, PartialEq, Eq, Clone, Inflate, Codegen, IntoPy)] -pub enum Suite<'a> { - IndentedBlock(IndentedBlock<'a>), - SimpleStatementSuite(SimpleStatementSuite<'a>), +pub enum Suite<'r, 'a> { + IndentedBlock(IndentedBlock<'r, 'a>), + SimpleStatementSuite(SimpleStatementSuite<'r, 'a>), } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct IndentedBlock<'a> { +pub struct IndentedBlock<'r, 'a> { /// Sequence of statements belonging to this indented block. - pub body: Vec>, + pub body: Vec>, /// Any optional trailing comment and the final ``NEWLINE`` at the end of the line. pub header: TrailingWhitespace<'a>, /// A string represents a specific indentation. A ``None`` value uses the modules's @@ -100,12 +96,12 @@ pub struct IndentedBlock<'a> { /// further. pub footer: Vec>, - pub(crate) newline_tok: TokenRef<'a>, - pub(crate) indent_tok: TokenRef<'a>, - pub(crate) dedent_tok: TokenRef<'a>, + pub(crate) newline_tok: TokenRef<'r, 'a>, + pub(crate) indent_tok: TokenRef<'r, 'a>, + pub(crate) dedent_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for IndentedBlock<'a> { +impl<'r, 'a> Codegen<'a> for IndentedBlock<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.header.codegen(state); @@ -138,7 +134,8 @@ impl<'a> Codegen<'a> for IndentedBlock<'a> { } } -impl<'a> Inflate<'a> for IndentedBlock<'a> { +impl<'r, 'a> Inflate<'a> for IndentedBlock<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.body = self.body.inflate(config)?; // We want to be able to only keep comments in the footer that are actually for @@ -172,21 +169,22 @@ impl<'a> Inflate<'a> for IndentedBlock<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct SimpleStatementSuite<'a> { +pub struct SimpleStatementSuite<'r, 'a> { /// Sequence of small statements. All but the last statement are required to have /// a semicolon. - pub body: Vec>, + pub body: Vec>, /// The whitespace between the colon in the parent statement and the body. pub leading_whitespace: SimpleWhitespace<'a>, /// Any optional trailing comment and the final ``NEWLINE`` at the end of the line. pub trailing_whitespace: TrailingWhitespace<'a>, - pub(crate) first_tok: TokenRef<'a>, - pub(crate) newline_tok: TokenRef<'a>, + pub(crate) first_tok: TokenRef<'r, 'a>, + pub(crate) newline_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for SimpleStatementSuite<'a> { +impl<'r, 'a> Inflate<'a> for SimpleStatementSuite<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_whitespace = parse_simple_whitespace( config, @@ -201,8 +199,8 @@ impl<'a> Inflate<'a> for SimpleStatementSuite<'a> { } } -fn _simple_statement_codegen<'a>( - body: &[SmallStatement<'a>], +fn _simple_statement_codegen<'r, 'a>( + body: &[SmallStatement<'r, 'a>], trailing_whitespace: &TrailingWhitespace<'a>, state: &mut CodegenState<'a>, ) { @@ -218,7 +216,7 @@ fn _simple_statement_codegen<'a>( trailing_whitespace.codegen(state); } -impl<'a> Codegen<'a> for SimpleStatementSuite<'a> { +impl<'r, 'a> Codegen<'a> for SimpleStatementSuite<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.leading_whitespace.codegen(state); _simple_statement_codegen(&self.body, &self.trailing_whitespace, state); @@ -226,21 +224,21 @@ impl<'a> Codegen<'a> for SimpleStatementSuite<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct SimpleStatementLine<'a> { +pub struct SimpleStatementLine<'r, 'a> { /// Sequence of small statements. All but the last statement are required to have /// a semicolon. - pub body: Vec>, + pub body: Vec>, /// Sequence of empty lines appearing before this simple statement line. pub leading_lines: Vec>, /// Any optional trailing comment and the final ``NEWLINE`` at the end of the line. pub trailing_whitespace: TrailingWhitespace<'a>, - pub(crate) first_tok: TokenRef<'a>, - pub(crate) newline_tok: TokenRef<'a>, + pub(crate) first_tok: TokenRef<'r, 'a>, + pub(crate) newline_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for SimpleStatementLine<'a> { +impl<'r, 'a> Codegen<'a> for SimpleStatementLine<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for line in &self.leading_lines { line.codegen(state); @@ -250,7 +248,8 @@ impl<'a> Codegen<'a> for SimpleStatementLine<'a> { } } -impl<'a> Inflate<'a> for SimpleStatementLine<'a> { +impl<'r, 'a> Inflate<'a> for SimpleStatementLine<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -268,26 +267,26 @@ impl<'a> Inflate<'a> for SimpleStatementLine<'a> { #[allow(dead_code, clippy::large_enum_variant)] #[derive(Debug, Eq, PartialEq, Clone, Codegen, Inflate, IntoPy)] -pub enum SmallStatement<'a> { - Pass(Pass<'a>), - Break(Break<'a>), - Continue(Continue<'a>), - Return(Return<'a>), - Expr(Expr<'a>), - Assert(Assert<'a>), - Import(Import<'a>), - ImportFrom(ImportFrom<'a>), - Assign(Assign<'a>), - AnnAssign(AnnAssign<'a>), - Raise(Raise<'a>), - Global(Global<'a>), - Nonlocal(Nonlocal<'a>), - AugAssign(AugAssign<'a>), - Del(Del<'a>), +pub enum SmallStatement<'r, 'a> { + Pass(Pass<'r, 'a>), + Break(Break<'r, 'a>), + Continue(Continue<'r, 'a>), + Return(Return<'r, 'a>), + Expr(Expr<'r, 'a>), + Assert(Assert<'r, 'a>), + Import(Import<'r, 'a>), + ImportFrom(ImportFrom<'r, 'a>), + Assign(Assign<'r, 'a>), + AnnAssign(AnnAssign<'r, 'a>), + Raise(Raise<'r, 'a>), + Global(Global<'r, 'a>), + Nonlocal(Nonlocal<'r, 'a>), + AugAssign(AugAssign<'r, 'a>), + Del(Del<'r, 'a>), } -impl<'a> SmallStatement<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> SmallStatement<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { match self { Self::Pass(p) => Self::Pass(p.with_semicolon(semicolon)), Self::Break(p) => Self::Break(p.with_semicolon(semicolon)), @@ -309,21 +308,22 @@ impl<'a> SmallStatement<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Pass<'a> { - pub semicolon: Option>, +pub struct Pass<'r, 'a> { + pub semicolon: Option>, } -impl<'a> Pass<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Pass<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon } } } -impl<'a> Codegen<'a> for Pass<'a> { +impl<'r, 'a> Codegen<'a> for Pass<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("pass"); self.semicolon.codegen(state); } } -impl<'a> Inflate<'a> for Pass<'a> { +impl<'r, 'a> Inflate<'a> for Pass<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.semicolon = self.semicolon.inflate(config)?; Ok(self) @@ -331,21 +331,22 @@ impl<'a> Inflate<'a> for Pass<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Break<'a> { - pub semicolon: Option>, +pub struct Break<'r, 'a> { + pub semicolon: Option>, } -impl<'a> Break<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Break<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon } } } -impl<'a> Codegen<'a> for Break<'a> { +impl<'r, 'a> Codegen<'a> for Break<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("break"); self.semicolon.codegen(state); } } -impl<'a> Inflate<'a> for Break<'a> { +impl<'r, 'a> Inflate<'a> for Break<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.semicolon = self.semicolon.inflate(config)?; Ok(self) @@ -353,21 +354,22 @@ impl<'a> Inflate<'a> for Break<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Continue<'a> { - pub semicolon: Option>, +pub struct Continue<'r, 'a> { + pub semicolon: Option>, } -impl<'a> Continue<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Continue<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon } } } -impl<'a> Codegen<'a> for Continue<'a> { +impl<'r, 'a> Codegen<'a> for Continue<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("continue"); self.semicolon.codegen(state); } } -impl<'a> Inflate<'a> for Continue<'a> { +impl<'r, 'a> Inflate<'a> for Continue<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.semicolon = self.semicolon.inflate(config)?; Ok(self) @@ -375,22 +377,23 @@ impl<'a> Inflate<'a> for Continue<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Expr<'a> { - pub value: Expression<'a>, - pub semicolon: Option>, +pub struct Expr<'r, 'a> { + pub value: Expression<'r, 'a>, + pub semicolon: Option>, } -impl<'a> Expr<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Expr<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } -impl<'a> Codegen<'a> for Expr<'a> { +impl<'r, 'a> Codegen<'a> for Expr<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.value.codegen(state); self.semicolon.codegen(state); } } -impl<'a> Inflate<'a> for Expr<'a> { +impl<'r, 'a> Inflate<'a> for Expr<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.value = self.value.inflate(config)?; self.semicolon = self.semicolon.inflate(config)?; @@ -399,13 +402,13 @@ impl<'a> Inflate<'a> for Expr<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Assign<'a> { - pub targets: Vec>, - pub value: Expression<'a>, - pub semicolon: Option>, +pub struct Assign<'r, 'a> { + pub targets: Vec>, + pub value: Expression<'r, 'a>, + pub semicolon: Option>, } -impl<'a> Codegen<'a> for Assign<'a> { +impl<'r, 'a> Codegen<'a> for Assign<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for target in &self.targets { target.codegen(state); @@ -417,7 +420,8 @@ impl<'a> Codegen<'a> for Assign<'a> { } } -impl<'a> Inflate<'a> for Assign<'a> { +impl<'r, 'a> Inflate<'a> for Assign<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.targets = self.targets.inflate(config)?; self.value = self.value.inflate(config)?; @@ -426,22 +430,22 @@ impl<'a> Inflate<'a> for Assign<'a> { } } -impl<'a> Assign<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Assign<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct AssignTarget<'a> { - pub target: AssignTargetExpression<'a>, +pub struct AssignTarget<'r, 'a> { + pub target: AssignTargetExpression<'r, 'a>, pub whitespace_before_equal: SimpleWhitespace<'a>, pub whitespace_after_equal: SimpleWhitespace<'a>, - pub(crate) equal_tok: TokenRef<'a>, + pub(crate) equal_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for AssignTarget<'a> { +impl<'r, 'a> Codegen<'a> for AssignTarget<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.target.codegen(state); self.whitespace_before_equal.codegen(state); @@ -450,7 +454,8 @@ impl<'a> Codegen<'a> for AssignTarget<'a> { } } -impl<'a> Inflate<'a> for AssignTarget<'a> { +impl<'r, 'a> Inflate<'a> for AssignTarget<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.target = self.target.inflate(config)?; self.whitespace_before_equal = parse_simple_whitespace( @@ -465,25 +470,25 @@ impl<'a> Inflate<'a> for AssignTarget<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, Codegen, ParenthesizedNode, Inflate, IntoPy)] -pub enum AssignTargetExpression<'a> { - Name(Name<'a>), - Attribute(Attribute<'a>), - StarredElement(StarredElement<'a>), - Tuple(Tuple<'a>), - List(List<'a>), - Subscript(Subscript<'a>), +pub enum AssignTargetExpression<'r, 'a> { + Name(Name<'r, 'a>), + Attribute(Attribute<'r, 'a>), + StarredElement(StarredElement<'r, 'a>), + Tuple(Tuple<'r, 'a>), + List(List<'r, 'a>), + Subscript(Subscript<'r, 'a>), } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Import<'a> { - pub names: Vec>, - pub semicolon: Option>, +pub struct Import<'r, 'a> { + pub names: Vec>, + pub semicolon: Option>, pub whitespace_after_import: SimpleWhitespace<'a>, - pub(crate) import_tok: TokenRef<'a>, + pub(crate) import_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Import<'a> { +impl<'r, 'a> Codegen<'a> for Import<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("import"); self.whitespace_after_import.codegen(state); @@ -499,7 +504,8 @@ impl<'a> Codegen<'a> for Import<'a> { } } -impl<'a> Inflate<'a> for Import<'a> { +impl<'r, 'a> Inflate<'a> for Import<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_after_import = parse_simple_whitespace( config, @@ -511,30 +517,30 @@ impl<'a> Inflate<'a> for Import<'a> { } } -impl<'a> Import<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Import<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct ImportFrom<'a> { +pub struct ImportFrom<'r, 'a> { #[no_py_default] - pub module: Option>, - pub names: ImportNames<'a>, - pub relative: Vec>, - pub lpar: Option>, - pub rpar: Option>, - pub semicolon: Option>, + pub module: Option>, + pub names: ImportNames<'r, 'a>, + pub relative: Vec>, + pub lpar: Option>, + pub rpar: Option>, + pub semicolon: Option>, pub whitespace_after_from: SimpleWhitespace<'a>, pub whitespace_before_import: SimpleWhitespace<'a>, pub whitespace_after_import: SimpleWhitespace<'a>, - pub(crate) from_tok: TokenRef<'a>, - pub(crate) import_tok: TokenRef<'a>, + pub(crate) from_tok: TokenRef<'r, 'a>, + pub(crate) import_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for ImportFrom<'a> { +impl<'r, 'a> Codegen<'a> for ImportFrom<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("from"); self.whitespace_after_from.codegen(state); @@ -561,7 +567,8 @@ impl<'a> Codegen<'a> for ImportFrom<'a> { } } -impl<'a> Inflate<'a> for ImportFrom<'a> { +impl<'r, 'a> Inflate<'a> for ImportFrom<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_after_from = parse_simple_whitespace(config, &mut (*self.from_tok).whitespace_after.borrow_mut())?; @@ -602,9 +609,9 @@ impl<'a> Inflate<'a> for ImportFrom<'a> { } } -fn inflate_dots<'a>(dots: Vec>, config: &Config<'a>) -> Result>> { - let mut ret: Vec> = vec![]; - let mut last_tok: Option> = None; +fn inflate_dots<'r, 'a>(dots: Vec>, config: &Config<'a>) -> Result>> { + let mut ret: Vec> = vec![]; + let mut last_tok: Option> = None; for mut dot in dots { if let Some(last_tokref) = &last_tok { // Consecutive dots having the same Token can only happen if `...` was @@ -620,26 +627,27 @@ fn inflate_dots<'a>(dots: Vec>, config: &Config<'a>) -> Result ImportFrom<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> ImportFrom<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct ImportAlias<'a> { - pub name: NameOrAttribute<'a>, - pub asname: Option>, - pub comma: Option>, +pub struct ImportAlias<'r, 'a> { + pub name: NameOrAttribute<'r, 'a>, + pub asname: Option>, + pub comma: Option>, } -impl<'a> Inflate<'a> for ImportAlias<'a> { +impl<'r, 'a> Inflate<'a> for ImportAlias<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.name = self.name.inflate(config)?; self.asname = self.asname.inflate(config)?; @@ -648,14 +656,14 @@ impl<'a> Inflate<'a> for ImportAlias<'a> { } } -impl<'a> WithComma<'a> for ImportAlias<'a> { - fn with_comma(self, comma: Comma<'a>) -> ImportAlias<'a> { +impl<'r, 'a> WithComma<'r, 'a> for ImportAlias<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> ImportAlias<'r, 'a> { let comma = Some(comma); Self { comma, ..self } } } -impl<'a> Codegen<'a> for ImportAlias<'a> { +impl<'r, 'a> Codegen<'a> for ImportAlias<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.name.codegen(state); if let Some(asname) = &self.asname { @@ -668,15 +676,15 @@ impl<'a> Codegen<'a> for ImportAlias<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct AsName<'a> { - pub name: AssignTargetExpression<'a>, +pub struct AsName<'r, 'a> { + pub name: AssignTargetExpression<'r, 'a>, pub whitespace_before_as: ParenthesizableWhitespace<'a>, pub whitespace_after_as: ParenthesizableWhitespace<'a>, - pub(crate) as_tok: TokenRef<'a>, + pub(crate) as_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for AsName<'a> { +impl<'r, 'a> Codegen<'a> for AsName<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.whitespace_before_as.codegen(state); state.add_token("as"); @@ -685,7 +693,8 @@ impl<'a> Codegen<'a> for AsName<'a> { } } -impl<'a> Inflate<'a> for AsName<'a> { +impl<'r, 'a> Inflate<'a> for AsName<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before_as = parse_parenthesizable_whitespace( config, @@ -701,12 +710,12 @@ impl<'a> Inflate<'a> for AsName<'a> { } #[derive(Debug, PartialEq, Eq, Clone, Inflate, IntoPy)] -pub enum ImportNames<'a> { +pub enum ImportNames<'r, 'a> { Star(ImportStar), - Aliases(Vec>), + Aliases(Vec>), } -impl<'a> Codegen<'a> for ImportNames<'a> { +impl<'r, 'a> Codegen<'a> for ImportNames<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { match self { Self::Star(s) => s.codegen(state), @@ -723,12 +732,12 @@ impl<'a> Codegen<'a> for ImportNames<'a> { } #[derive(Debug, Eq, PartialEq, Clone, IntoPy)] -pub struct FunctionDef<'a> { - pub name: Name<'a>, - pub params: Parameters<'a>, - pub body: Suite<'a>, - pub decorators: Vec>, - pub returns: Option>, +pub struct FunctionDef<'r, 'a> { + pub name: Name<'r, 'a>, + pub params: Parameters<'r, 'a>, + pub body: Suite<'r, 'a>, + pub decorators: Vec>, + pub returns: Option>, pub asynchronous: Option>, pub leading_lines: Vec>, pub lines_after_decorators: Vec>, @@ -737,20 +746,20 @@ pub struct FunctionDef<'a> { pub whitespace_before_params: ParenthesizableWhitespace<'a>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) async_tok: Option>, - pub(crate) def_tok: TokenRef<'a>, - pub(crate) open_paren_tok: TokenRef<'a>, - pub(crate) close_paren_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) async_tok: Option>, + pub(crate) def_tok: TokenRef<'r, 'a>, + pub(crate) open_paren_tok: TokenRef<'r, 'a>, + pub(crate) close_paren_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> FunctionDef<'a> { - pub fn with_decorators(self, decorators: Vec>) -> Self { +impl<'r, 'a> FunctionDef<'r, 'a> { + pub fn with_decorators(self, decorators: Vec>) -> Self { Self { decorators, ..self } } } -impl<'a> Codegen<'a> for FunctionDef<'a> { +impl<'r, 'a> Codegen<'a> for FunctionDef<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for l in &self.leading_lines { l.codegen(state); @@ -785,7 +794,8 @@ impl<'a> Codegen<'a> for FunctionDef<'a> { } } -impl<'a> Inflate<'a> for FunctionDef<'a> { +impl<'r, 'a> Inflate<'a> for FunctionDef<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.decorators = self.decorators.inflate(config)?; let (asynchronous, leading_lines) = if let Some(asy) = self.async_tok.as_mut() { @@ -848,17 +858,17 @@ impl<'a> Inflate<'a> for FunctionDef<'a> { } #[derive(Debug, Eq, PartialEq, Clone, IntoPy)] -pub struct Decorator<'a> { - pub decorator: Expression<'a>, +pub struct Decorator<'r, 'a> { + pub decorator: Expression<'r, 'a>, pub leading_lines: Vec>, pub whitespace_after_at: SimpleWhitespace<'a>, pub trailing_whitespace: TrailingWhitespace<'a>, - pub(crate) at_tok: TokenRef<'a>, - pub(crate) newline_tok: TokenRef<'a>, + pub(crate) at_tok: TokenRef<'r, 'a>, + pub(crate) newline_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Decorator<'a> { +impl<'r, 'a> Codegen<'a> for Decorator<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in self.leading_lines.iter() { ll.codegen(state); @@ -871,7 +881,8 @@ impl<'a> Codegen<'a> for Decorator<'a> { } } -impl<'a> Inflate<'a> for Decorator<'a> { +impl<'r, 'a> Inflate<'a> for Decorator<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -889,21 +900,21 @@ impl<'a> Inflate<'a> for Decorator<'a> { } } -impl<'a> pyo3::conversion::IntoPy for Box> { +impl<'r, 'a> pyo3::conversion::IntoPy for Box> { fn into_py(self, py: pyo3::Python) -> pyo3::PyObject { (*self).into_py(py) } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct If<'a> { +pub struct If<'r, 'a> { /// The expression that, when evaluated, should give us a truthy value - pub test: Expression<'a>, + pub test: Expression<'r, 'a>, // The body of this compound statement. - pub body: Suite<'a>, + pub body: Suite<'r, 'a>, /// An optional ``elif`` or ``else`` clause. ``If`` signifies an ``elif`` block. - pub orelse: Option>>, + pub orelse: Option>>, /// Sequence of empty lines appearing before this compound statement line. pub leading_lines: Vec>, @@ -919,11 +930,11 @@ pub struct If<'a> { #[skip_py] pub is_elif: bool, - pub(crate) if_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) if_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for If<'a> { +impl<'r, 'a> Codegen<'a> for If<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for l in &self.leading_lines { l.codegen(state); @@ -942,7 +953,8 @@ impl<'a> Codegen<'a> for If<'a> { } } -impl<'a> Inflate<'a> for If<'a> { +impl<'r, 'a> Inflate<'a> for If<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -965,24 +977,24 @@ impl<'a> Inflate<'a> for If<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, Inflate, Codegen, IntoPy)] -pub enum OrElse<'a> { - Elif(If<'a>), - Else(Else<'a>), +pub enum OrElse<'r, 'a> { + Elif(If<'r, 'a>), + Else(Else<'r, 'a>), } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Else<'a> { - pub body: Suite<'a>, +pub struct Else<'r, 'a> { + pub body: Suite<'r, 'a>, /// Sequence of empty lines appearing before this compound statement line. pub leading_lines: Vec>, /// The whitespace appearing after the ``else`` keyword but before the colon. pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) else_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) else_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Else<'a> { +impl<'r, 'a> Codegen<'a> for Else<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for l in &self.leading_lines { l.codegen(state); @@ -996,7 +1008,8 @@ impl<'a> Codegen<'a> for Else<'a> { } } -impl<'a> Inflate<'a> for Else<'a> { +impl<'r, 'a> Inflate<'a> for Else<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -1014,15 +1027,15 @@ impl<'a> Inflate<'a> for Else<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Annotation<'a> { - pub annotation: Expression<'a>, +pub struct Annotation<'r, 'a> { + pub annotation: Expression<'r, 'a>, pub whitespace_before_indicator: Option>, pub whitespace_after_indicator: ParenthesizableWhitespace<'a>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Annotation<'a> { +impl<'r, 'a> Annotation<'r, 'a> { pub fn codegen(&self, state: &mut CodegenState<'a>, default_indicator: &'a str) { if let Some(ws) = &self.whitespace_before_indicator { ws.codegen(state); @@ -1038,7 +1051,8 @@ impl<'a> Annotation<'a> { } } -impl<'a> Inflate<'a> for Annotation<'a> { +impl<'r, 'a> Inflate<'a> for Annotation<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_before_indicator = Some(parse_parenthesizable_whitespace( config, @@ -1054,15 +1068,15 @@ impl<'a> Inflate<'a> for Annotation<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct AnnAssign<'a> { - pub target: AssignTargetExpression<'a>, - pub annotation: Annotation<'a>, - pub value: Option>, - pub equal: Option>, - pub semicolon: Option>, +pub struct AnnAssign<'r, 'a> { + pub target: AssignTargetExpression<'r, 'a>, + pub annotation: Annotation<'r, 'a>, + pub value: Option>, + pub equal: Option>, + pub semicolon: Option>, } -impl<'a> Codegen<'a> for AnnAssign<'a> { +impl<'r, 'a> Codegen<'a> for AnnAssign<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.target.codegen(state); self.annotation.codegen(state, ":"); @@ -1081,7 +1095,8 @@ impl<'a> Codegen<'a> for AnnAssign<'a> { } } -impl<'a> Inflate<'a> for AnnAssign<'a> { +impl<'r, 'a> Inflate<'a> for AnnAssign<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.target = self.target.inflate(config)?; self.annotation = self.annotation.inflate(config)?; @@ -1092,22 +1107,22 @@ impl<'a> Inflate<'a> for AnnAssign<'a> { } } -impl<'a> AnnAssign<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> AnnAssign<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Return<'a> { - pub value: Option>, +pub struct Return<'r, 'a> { + pub value: Option>, pub whitespace_after_return: Option>, - pub semicolon: Option>, + pub semicolon: Option>, - pub(crate) return_tok: TokenRef<'a>, + pub(crate) return_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Return<'a> { +impl<'r, 'a> Codegen<'a> for Return<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("return"); if let Some(ws) = &self.whitespace_after_return { @@ -1125,7 +1140,8 @@ impl<'a> Codegen<'a> for Return<'a> { } } -impl<'a> Inflate<'a> for Return<'a> { +impl<'r, 'a> Inflate<'a> for Return<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { if self.value.is_some() { self.whitespace_after_return = Some(parse_simple_whitespace( @@ -1143,24 +1159,24 @@ impl<'a> Inflate<'a> for Return<'a> { } } -impl<'a> Return<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Return<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Assert<'a> { - pub test: Expression<'a>, - pub msg: Option>, - pub comma: Option>, +pub struct Assert<'r, 'a> { + pub test: Expression<'r, 'a>, + pub msg: Option>, + pub comma: Option>, pub whitespace_after_assert: SimpleWhitespace<'a>, - pub semicolon: Option>, + pub semicolon: Option>, - pub(crate) assert_tok: TokenRef<'a>, + pub(crate) assert_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Assert<'a> { +impl<'r, 'a> Codegen<'a> for Assert<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("assert"); self.whitespace_after_assert.codegen(state); @@ -1178,7 +1194,8 @@ impl<'a> Codegen<'a> for Assert<'a> { } } } -impl<'a> Inflate<'a> for Assert<'a> { +impl<'r, 'a> Inflate<'a> for Assert<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_after_assert = parse_simple_whitespace( config, @@ -1194,23 +1211,24 @@ impl<'a> Inflate<'a> for Assert<'a> { } } -impl<'a> Assert<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Assert<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Raise<'a> { - pub exc: Option>, - pub cause: Option>, +pub struct Raise<'r, 'a> { + pub exc: Option>, + pub cause: Option>, pub whitespace_after_raise: Option>, - pub semicolon: Option>, + pub semicolon: Option>, - pub(crate) raise_tok: TokenRef<'a>, + pub(crate) raise_tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Raise<'a> { +impl<'r, 'a> Inflate<'a> for Raise<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { if self.exc.is_some() { self.whitespace_after_raise = Some(parse_simple_whitespace( @@ -1233,7 +1251,7 @@ impl<'a> Inflate<'a> for Raise<'a> { } } -impl<'a> Codegen<'a> for Raise<'a> { +impl<'r, 'a> Codegen<'a> for Raise<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("raise"); if let Some(ws) = &self.whitespace_after_raise { @@ -1256,19 +1274,20 @@ impl<'a> Codegen<'a> for Raise<'a> { } } -impl<'a> Raise<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Raise<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct NameItem<'a> { - pub name: Name<'a>, - pub comma: Option>, +pub struct NameItem<'r, 'a> { + pub name: Name<'r, 'a>, + pub comma: Option>, } -impl<'a> Inflate<'a> for NameItem<'a> { +impl<'r, 'a> Inflate<'a> for NameItem<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.name = self.name.inflate(config)?; self.comma = self.comma.inflate(config)?; @@ -1276,7 +1295,7 @@ impl<'a> Inflate<'a> for NameItem<'a> { } } -impl<'a> NameItem<'a> { +impl<'r, 'a> NameItem<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) { self.name.codegen(state); if let Some(comma) = &self.comma { @@ -1288,15 +1307,16 @@ impl<'a> NameItem<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Global<'a> { - pub names: Vec>, +pub struct Global<'r, 'a> { + pub names: Vec>, pub whitespace_after_global: SimpleWhitespace<'a>, - pub semicolon: Option>, + pub semicolon: Option>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Global<'a> { +impl<'r, 'a> Inflate<'a> for Global<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_after_global = parse_simple_whitespace(config, &mut (*self.tok).whitespace_after.borrow_mut())?; @@ -1306,7 +1326,7 @@ impl<'a> Inflate<'a> for Global<'a> { } } -impl<'a> Codegen<'a> for Global<'a> { +impl<'r, 'a> Codegen<'a> for Global<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("global"); self.whitespace_after_global.codegen(state); @@ -1321,22 +1341,23 @@ impl<'a> Codegen<'a> for Global<'a> { } } -impl<'a> Global<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Global<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Nonlocal<'a> { - pub names: Vec>, +pub struct Nonlocal<'r, 'a> { + pub names: Vec>, pub whitespace_after_nonlocal: SimpleWhitespace<'a>, - pub semicolon: Option>, + pub semicolon: Option>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Nonlocal<'a> { +impl<'r, 'a> Inflate<'a> for Nonlocal<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_after_nonlocal = parse_simple_whitespace(config, &mut (*self.tok).whitespace_after.borrow_mut())?; @@ -1346,7 +1367,7 @@ impl<'a> Inflate<'a> for Nonlocal<'a> { } } -impl<'a> Codegen<'a> for Nonlocal<'a> { +impl<'r, 'a> Codegen<'a> for Nonlocal<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("nonlocal"); self.whitespace_after_nonlocal.codegen(state); @@ -1361,18 +1382,18 @@ impl<'a> Codegen<'a> for Nonlocal<'a> { } } -impl<'a> Nonlocal<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Nonlocal<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct For<'a> { - pub target: AssignTargetExpression<'a>, - pub iter: Expression<'a>, - pub body: Suite<'a>, - pub orelse: Option>, +pub struct For<'r, 'a> { + pub target: AssignTargetExpression<'r, 'a>, + pub iter: Expression<'r, 'a>, + pub body: Suite<'r, 'a>, + pub orelse: Option>, pub asynchronous: Option>, pub leading_lines: Vec>, @@ -1381,13 +1402,13 @@ pub struct For<'a> { pub whitespace_after_in: SimpleWhitespace<'a>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) async_tok: Option>, - pub(crate) for_tok: TokenRef<'a>, - pub(crate) in_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) async_tok: Option>, + pub(crate) for_tok: TokenRef<'r, 'a>, + pub(crate) in_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for For<'a> { +impl<'r, 'a> Codegen<'a> for For<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in &self.leading_lines { ll.codegen(state); @@ -1413,7 +1434,8 @@ impl<'a> Codegen<'a> for For<'a> { } } -impl<'a> Inflate<'a> for For<'a> { +impl<'r, 'a> Inflate<'a> for For<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { let (asynchronous, leading_lines) = if let Some(asy) = self.async_tok.as_mut() { let whitespace_after = @@ -1460,19 +1482,19 @@ impl<'a> Inflate<'a> for For<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct While<'a> { - pub test: Expression<'a>, - pub body: Suite<'a>, - pub orelse: Option>, +pub struct While<'r, 'a> { + pub test: Expression<'r, 'a>, + pub body: Suite<'r, 'a>, + pub orelse: Option>, pub leading_lines: Vec>, pub whitespace_after_while: SimpleWhitespace<'a>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) while_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) while_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for While<'a> { +impl<'r, 'a> Codegen<'a> for While<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in &self.leading_lines { ll.codegen(state); @@ -1491,7 +1513,8 @@ impl<'a> Codegen<'a> for While<'a> { } } -impl<'a> Inflate<'a> for While<'a> { +impl<'r, 'a> Inflate<'a> for While<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -1513,26 +1536,26 @@ impl<'a> Inflate<'a> for While<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct ClassDef<'a> { - pub name: Name<'a>, - pub body: Suite<'a>, - pub bases: Vec>, - pub keywords: Vec>, - pub decorators: Vec>, - pub lpar: Option>, - pub rpar: Option>, +pub struct ClassDef<'r, 'a> { + pub name: Name<'r, 'a>, + pub body: Suite<'r, 'a>, + pub bases: Vec>, + pub keywords: Vec>, + pub decorators: Vec>, + pub lpar: Option>, + pub rpar: Option>, pub leading_lines: Vec>, pub lines_after_decorators: Vec>, pub whitespace_after_class: SimpleWhitespace<'a>, pub whitespace_after_name: SimpleWhitespace<'a>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) class_tok: TokenRef<'a>, - pub(crate) parens_tok: Option<(TokenRef<'a>, TokenRef<'a>)>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) class_tok: TokenRef<'r, 'a>, + pub(crate) parens_tok: Option<(TokenRef<'r, 'a>, TokenRef<'r, 'a>)>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for ClassDef<'a> { +impl<'r, 'a> Codegen<'a> for ClassDef<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in &self.leading_lines { ll.codegen(state); @@ -1575,7 +1598,8 @@ impl<'a> Codegen<'a> for ClassDef<'a> { } } -impl<'a> Inflate<'a> for ClassDef<'a> { +impl<'r, 'a> Inflate<'a> for ClassDef<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -1612,23 +1636,23 @@ impl<'a> Inflate<'a> for ClassDef<'a> { } } -impl<'a> ClassDef<'a> { - pub fn with_decorators(self, decorators: Vec>) -> Self { +impl<'r, 'a> ClassDef<'r, 'a> { + pub fn with_decorators(self, decorators: Vec>) -> Self { Self { decorators, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Finally<'a> { - pub body: Suite<'a>, +pub struct Finally<'r, 'a> { + pub body: Suite<'r, 'a>, pub leading_lines: Vec>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) finally_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) finally_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Finally<'a> { +impl<'r, 'a> Codegen<'a> for Finally<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in &self.leading_lines { ll.codegen(state); @@ -1642,7 +1666,8 @@ impl<'a> Codegen<'a> for Finally<'a> { } } -impl<'a> Inflate<'a> for Finally<'a> { +impl<'r, 'a> Inflate<'a> for Finally<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -1659,19 +1684,19 @@ impl<'a> Inflate<'a> for Finally<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct ExceptHandler<'a> { - pub body: Suite<'a>, - pub r#type: Option>, - pub name: Option>, +pub struct ExceptHandler<'r, 'a> { + pub body: Suite<'r, 'a>, + pub r#type: Option>, + pub name: Option>, pub leading_lines: Vec>, pub whitespace_after_except: SimpleWhitespace<'a>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) except_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) except_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for ExceptHandler<'a> { +impl<'r, 'a> Codegen<'a> for ExceptHandler<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in &self.leading_lines { ll.codegen(state); @@ -1692,7 +1717,8 @@ impl<'a> Codegen<'a> for ExceptHandler<'a> { } } -impl<'a> Inflate<'a> for ExceptHandler<'a> { +impl<'r, 'a> Inflate<'a> for ExceptHandler<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -1719,21 +1745,21 @@ impl<'a> Inflate<'a> for ExceptHandler<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct ExceptStarHandler<'a> { - pub body: Suite<'a>, - pub r#type: Expression<'a>, - pub name: Option>, +pub struct ExceptStarHandler<'r, 'a> { + pub body: Suite<'r, 'a>, + pub r#type: Expression<'r, 'a>, + pub name: Option>, pub leading_lines: Vec>, pub whitespace_after_except: SimpleWhitespace<'a>, pub whitespace_after_star: SimpleWhitespace<'a>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) except_tok: TokenRef<'a>, - pub(crate) star_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) except_tok: TokenRef<'r, 'a>, + pub(crate) star_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for ExceptStarHandler<'a> { +impl<'r, 'a> Codegen<'a> for ExceptStarHandler<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in &self.leading_lines { ll.codegen(state); @@ -1754,7 +1780,8 @@ impl<'a> Codegen<'a> for ExceptStarHandler<'a> { } } -impl<'a> Inflate<'a> for ExceptStarHandler<'a> { +impl<'r, 'a> Inflate<'a> for ExceptStarHandler<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -1781,19 +1808,19 @@ impl<'a> Inflate<'a> for ExceptStarHandler<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Try<'a> { - pub body: Suite<'a>, - pub handlers: Vec>, - pub orelse: Option>, - pub finalbody: Option>, +pub struct Try<'r, 'a> { + pub body: Suite<'r, 'a>, + pub handlers: Vec>, + pub orelse: Option>, + pub finalbody: Option>, pub leading_lines: Vec>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) try_tok: TokenRef<'a>, + pub(crate) try_tok: TokenRef<'r, 'a>, // colon_tok unnecessary } -impl<'a> Codegen<'a> for Try<'a> { +impl<'r, 'a> Codegen<'a> for Try<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in &self.leading_lines { ll.codegen(state); @@ -1815,7 +1842,8 @@ impl<'a> Codegen<'a> for Try<'a> { } } -impl<'a> Inflate<'a> for Try<'a> { +impl<'r, 'a> Inflate<'a> for Try<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -1833,19 +1861,19 @@ impl<'a> Inflate<'a> for Try<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct TryStar<'a> { - pub body: Suite<'a>, - pub handlers: Vec>, - pub orelse: Option>, - pub finalbody: Option>, +pub struct TryStar<'r, 'a> { + pub body: Suite<'r, 'a>, + pub handlers: Vec>, + pub orelse: Option>, + pub finalbody: Option>, pub leading_lines: Vec>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) try_tok: TokenRef<'a>, + pub(crate) try_tok: TokenRef<'r, 'a>, // colon_tok unnecessary } -impl<'a> Codegen<'a> for TryStar<'a> { +impl<'r, 'a> Codegen<'a> for TryStar<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in &self.leading_lines { ll.codegen(state); @@ -1867,7 +1895,8 @@ impl<'a> Codegen<'a> for TryStar<'a> { } } -impl<'a> Inflate<'a> for TryStar<'a> { +impl<'r, 'a> Inflate<'a> for TryStar<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -1885,14 +1914,15 @@ impl<'a> Inflate<'a> for TryStar<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct AugAssign<'a> { - pub target: AssignTargetExpression<'a>, - pub operator: AugOp<'a>, - pub value: Expression<'a>, - pub semicolon: Option>, +pub struct AugAssign<'r, 'a> { + pub target: AssignTargetExpression<'r, 'a>, + pub operator: AugOp<'r, 'a>, + pub value: Expression<'r, 'a>, + pub semicolon: Option>, } -impl<'a> Inflate<'a> for AugAssign<'a> { +impl<'r, 'a> Inflate<'a> for AugAssign<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.target = self.target.inflate(config)?; self.operator = self.operator.inflate(config)?; @@ -1902,7 +1932,7 @@ impl<'a> Inflate<'a> for AugAssign<'a> { } } -impl<'a> Codegen<'a> for AugAssign<'a> { +impl<'r, 'a> Codegen<'a> for AugAssign<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.target.codegen(state); self.operator.codegen(state); @@ -1914,20 +1944,20 @@ impl<'a> Codegen<'a> for AugAssign<'a> { } } -impl<'a> AugAssign<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> AugAssign<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct WithItem<'a> { - pub item: Expression<'a>, - pub asname: Option>, - pub comma: Option>, +pub struct WithItem<'r, 'a> { + pub item: Expression<'r, 'a>, + pub asname: Option>, + pub comma: Option>, } -impl<'a> Codegen<'a> for WithItem<'a> { +impl<'r, 'a> Codegen<'a> for WithItem<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.item.codegen(state); if let Some(n) = &self.asname { @@ -1939,8 +1969,8 @@ impl<'a> Codegen<'a> for WithItem<'a> { } } -impl<'a> WithComma<'a> for WithItem<'a> { - fn with_comma(self, comma: Comma<'a>) -> Self { +impl<'r, 'a> WithComma<'r, 'a> for WithItem<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> Self { Self { comma: Some(comma), ..self @@ -1948,7 +1978,8 @@ impl<'a> WithComma<'a> for WithItem<'a> { } } -impl<'a> Inflate<'a> for WithItem<'a> { +impl<'r, 'a> Inflate<'a> for WithItem<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.item = self.item.inflate(config)?; self.asname = self.asname.inflate(config)?; @@ -1958,20 +1989,20 @@ impl<'a> Inflate<'a> for WithItem<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct With<'a> { - pub items: Vec>, - pub body: Suite<'a>, +pub struct With<'r, 'a> { + pub items: Vec>, + pub body: Suite<'r, 'a>, pub asynchronous: Option>, pub leading_lines: Vec>, pub whitespace_after_with: SimpleWhitespace<'a>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) async_tok: Option>, - pub(crate) with_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) async_tok: Option>, + pub(crate) with_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for With<'a> { +impl<'r, 'a> Codegen<'a> for With<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for ll in &self.leading_lines { ll.codegen(state); @@ -1996,7 +2027,8 @@ impl<'a> Codegen<'a> for With<'a> { } } -impl<'a> Inflate<'a> for With<'a> { +impl<'r, 'a> Inflate<'a> for With<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { let (asynchronous, leading_lines) = if let Some(asy) = self.async_tok.as_mut() { let whitespace_after = @@ -2040,16 +2072,16 @@ impl<'a> Inflate<'a> for With<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, Codegen, ParenthesizedNode, Inflate, IntoPy)] -pub enum DelTargetExpression<'a> { - Name(Name<'a>), - Attribute(Attribute<'a>), - Tuple(Tuple<'a>), - List(List<'a>), - Subscript(Subscript<'a>), +pub enum DelTargetExpression<'r, 'a> { + Name(Name<'r, 'a>), + Attribute(Attribute<'r, 'a>), + Tuple(Tuple<'r, 'a>), + List(List<'r, 'a>), + Subscript(Subscript<'r, 'a>), } -impl<'a> std::convert::From> for Expression<'a> { - fn from(d: DelTargetExpression<'a>) -> Self { +impl<'r, 'a> std::convert::From> for Expression<'r, 'a> { + fn from(d: DelTargetExpression<'r, 'a>) -> Self { match d { DelTargetExpression::Attribute(a) => Expression::Attribute(a), DelTargetExpression::List(l) => Expression::List(l), @@ -2059,8 +2091,8 @@ impl<'a> std::convert::From> for Expression<'a> { } } } -impl<'a> std::convert::From> for Element<'a> { - fn from(d: DelTargetExpression<'a>) -> Element { +impl<'r, 'a> std::convert::From> for Element<'r, 'a> { + fn from(d: DelTargetExpression<'r, 'a>) -> Self { Element::Simple { value: d.into(), comma: None, @@ -2069,15 +2101,16 @@ impl<'a> std::convert::From> for Element<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Del<'a> { - pub target: DelTargetExpression<'a>, +pub struct Del<'r, 'a> { + pub target: DelTargetExpression<'r, 'a>, pub whitespace_after_del: SimpleWhitespace<'a>, - pub semicolon: Option>, + pub semicolon: Option>, - pub(crate) tok: TokenRef<'a>, + pub(crate) tok: TokenRef<'r, 'a>, } -impl<'a> Inflate<'a> for Del<'a> { +impl<'r, 'a> Inflate<'a> for Del<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.whitespace_after_del = parse_simple_whitespace(config, &mut (*self.tok).whitespace_after.borrow_mut())?; @@ -2087,7 +2120,7 @@ impl<'a> Inflate<'a> for Del<'a> { } } -impl<'a> Codegen<'a> for Del<'a> { +impl<'r, 'a> Codegen<'a> for Del<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { state.add_token("del"); self.whitespace_after_del.codegen(state); @@ -2098,16 +2131,16 @@ impl<'a> Codegen<'a> for Del<'a> { } } -impl<'a> Del<'a> { - pub fn with_semicolon(self, semicolon: Option>) -> Self { +impl<'r, 'a> Del<'r, 'a> { + pub fn with_semicolon(self, semicolon: Option>) -> Self { Self { semicolon, ..self } } } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct Match<'a> { - pub subject: Expression<'a>, - pub cases: Vec>, +pub struct Match<'r, 'a> { + pub subject: Expression<'r, 'a>, + pub cases: Vec>, pub leading_lines: Vec>, pub whitespace_after_match: SimpleWhitespace<'a>, @@ -2116,13 +2149,13 @@ pub struct Match<'a> { pub indent: Option<&'a str>, pub footer: Vec>, - pub(crate) match_tok: TokenRef<'a>, - pub(crate) colon_tok: TokenRef<'a>, - pub(crate) indent_tok: TokenRef<'a>, - pub(crate) dedent_tok: TokenRef<'a>, + pub(crate) match_tok: TokenRef<'r, 'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, + pub(crate) indent_tok: TokenRef<'r, 'a>, + pub(crate) dedent_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for Match<'a> { +impl<'r, 'a> Codegen<'a> for Match<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for l in &self.leading_lines { l.codegen(state); @@ -2150,7 +2183,8 @@ impl<'a> Codegen<'a> for Match<'a> { } } -impl<'a> Inflate<'a> for Match<'a> { +impl<'r, 'a> Inflate<'a> for Match<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -2180,10 +2214,10 @@ impl<'a> Inflate<'a> for Match<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct MatchCase<'a> { - pub pattern: MatchPattern<'a>, - pub guard: Option>, - pub body: Suite<'a>, +pub struct MatchCase<'r, 'a> { + pub pattern: MatchPattern<'r, 'a>, + pub guard: Option>, + pub body: Suite<'r, 'a>, pub leading_lines: Vec>, pub whitespace_after_case: SimpleWhitespace<'a>, @@ -2191,12 +2225,12 @@ pub struct MatchCase<'a> { pub whitespace_after_if: SimpleWhitespace<'a>, pub whitespace_before_colon: SimpleWhitespace<'a>, - pub(crate) case_tok: TokenRef<'a>, - pub(crate) if_tok: Option>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) case_tok: TokenRef<'r, 'a>, + pub(crate) if_tok: Option>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for MatchCase<'a> { +impl<'r, 'a> Codegen<'a> for MatchCase<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { for l in &self.leading_lines { l.codegen(state); @@ -2217,7 +2251,8 @@ impl<'a> Codegen<'a> for MatchCase<'a> { } } -impl<'a> Inflate<'a> for MatchCase<'a> { +impl<'r, 'a> Inflate<'a> for MatchCase<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.leading_lines = parse_empty_lines( config, @@ -2244,26 +2279,26 @@ impl<'a> Inflate<'a> for MatchCase<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, IntoPy, Codegen, Inflate, ParenthesizedNode)] -pub enum MatchPattern<'a> { - Value(MatchValue<'a>), - Singleton(MatchSingleton<'a>), - Sequence(MatchSequence<'a>), - Mapping(MatchMapping<'a>), - Class(MatchClass<'a>), - As(Box>), - Or(Box>), +pub enum MatchPattern<'r, 'a> { + Value(MatchValue<'r, 'a>), + Singleton(MatchSingleton<'r, 'a>), + Sequence(MatchSequence<'r, 'a>), + Mapping(MatchMapping<'r, 'a>), + Class(MatchClass<'r, 'a>), + As(Box>), + Or(Box>), } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct MatchValue<'a> { - pub value: Expression<'a>, +pub struct MatchValue<'r, 'a> { + pub value: Expression<'r, 'a>, } -impl<'a> ParenthesizedNode<'a> for MatchValue<'a> { - fn lpar(&self) -> &Vec> { +impl<'r, 'a> ParenthesizedNode<'r, 'a> for MatchValue<'r, 'a> { + fn lpar(&self) -> &Vec> { self.value.lpar() } - fn rpar(&self) -> &Vec> { + fn rpar(&self) -> &Vec> { self.value.rpar() } fn parenthesize(&self, state: &mut CodegenState<'a>, f: F) @@ -2272,20 +2307,21 @@ impl<'a> ParenthesizedNode<'a> for MatchValue<'a> { { self.value.parenthesize(state, f) } - fn with_parens(self, left: LeftParen<'a>, right: RightParen<'a>) -> Self { + fn with_parens(self, left: LeftParen<'r, 'a>, right: RightParen<'r, 'a>) -> Self { Self { value: self.value.with_parens(left, right), } } } -impl<'a> Codegen<'a> for MatchValue<'a> { +impl<'r, 'a> Codegen<'a> for MatchValue<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.value.codegen(state) } } -impl<'a> Inflate<'a> for MatchValue<'a> { +impl<'r, 'a> Inflate<'a> for MatchValue<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.value = self.value.inflate(config)?; Ok(self) @@ -2293,15 +2329,15 @@ impl<'a> Inflate<'a> for MatchValue<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct MatchSingleton<'a> { - pub value: Name<'a>, +pub struct MatchSingleton<'r, 'a> { + pub value: Name<'r, 'a>, } -impl<'a> ParenthesizedNode<'a> for MatchSingleton<'a> { - fn lpar(&self) -> &Vec> { +impl<'r, 'a> ParenthesizedNode<'r, 'a> for MatchSingleton<'r, 'a> { + fn lpar(&self) -> &Vec> { self.value.lpar() } - fn rpar(&self) -> &Vec> { + fn rpar(&self) -> &Vec> { self.value.rpar() } fn parenthesize(&self, state: &mut CodegenState<'a>, f: F) @@ -2310,20 +2346,21 @@ impl<'a> ParenthesizedNode<'a> for MatchSingleton<'a> { { self.value.parenthesize(state, f) } - fn with_parens(self, left: LeftParen<'a>, right: RightParen<'a>) -> Self { + fn with_parens(self, left: LeftParen<'r, 'a>, right: RightParen<'r, 'a>) -> Self { Self { value: self.value.with_parens(left, right), } } } -impl<'a> Codegen<'a> for MatchSingleton<'a> { +impl<'r, 'a> Codegen<'a> for MatchSingleton<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.value.codegen(state) } } -impl<'a> Inflate<'a> for MatchSingleton<'a> { +impl<'r, 'a> Inflate<'a> for MatchSingleton<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.value = self.value.inflate(config)?; Ok(self) @@ -2332,21 +2369,21 @@ impl<'a> Inflate<'a> for MatchSingleton<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, IntoPy, Codegen, Inflate, ParenthesizedNode)] -pub enum MatchSequence<'a> { - MatchList(MatchList<'a>), - MatchTuple(MatchTuple<'a>), +pub enum MatchSequence<'r, 'a> { + MatchList(MatchList<'r, 'a>), + MatchTuple(MatchTuple<'r, 'a>), } #[derive(Debug, PartialEq, Eq, Clone, IntoPy, ParenthesizedNode)] -pub struct MatchList<'a> { - pub patterns: Vec>, - pub lbracket: Option>, - pub rbracket: Option>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct MatchList<'r, 'a> { + pub patterns: Vec>, + pub lbracket: Option>, + pub rbracket: Option>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for MatchList<'a> { +impl<'r, 'a> Codegen<'a> for MatchList<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.lbracket.codegen(state); @@ -2363,7 +2400,8 @@ impl<'a> Codegen<'a> for MatchList<'a> { } } -impl<'a> Inflate<'a> for MatchList<'a> { +impl<'r, 'a> Inflate<'a> for MatchList<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.lbracket = self.lbracket.inflate(config)?; @@ -2383,13 +2421,13 @@ impl<'a> Inflate<'a> for MatchList<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy, ParenthesizedNode)] -pub struct MatchTuple<'a> { - pub patterns: Vec>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct MatchTuple<'r, 'a> { + pub patterns: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for MatchTuple<'a> { +impl<'r, 'a> Codegen<'a> for MatchTuple<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { let len = self.patterns.len(); @@ -2404,7 +2442,8 @@ impl<'a> Codegen<'a> for MatchTuple<'a> { } } -impl<'a> Inflate<'a> for MatchTuple<'a> { +impl<'r, 'a> Inflate<'a> for MatchTuple<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; let len = self.patterns.len(); @@ -2421,12 +2460,12 @@ impl<'a> Inflate<'a> for MatchTuple<'a> { #[allow(clippy::large_enum_variant)] #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub enum StarrableMatchSequenceElement<'a> { - Simple(MatchSequenceElement<'a>), - Starred(MatchStar<'a>), +pub enum StarrableMatchSequenceElement<'r, 'a> { + Simple(MatchSequenceElement<'r, 'a>), + Starred(MatchStar<'r, 'a>), } -impl<'a> StarrableMatchSequenceElement<'a> { +impl<'r, 'a> StarrableMatchSequenceElement<'r, 'a> { fn codegen( &self, state: &mut CodegenState<'a>, @@ -2446,8 +2485,8 @@ impl<'a> StarrableMatchSequenceElement<'a> { } } -impl<'a> WithComma<'a> for StarrableMatchSequenceElement<'a> { - fn with_comma(self, comma: Comma<'a>) -> Self { +impl<'r, 'a> WithComma<'r, 'a> for StarrableMatchSequenceElement<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> Self { match self { Self::Simple(s) => Self::Simple(s.with_comma(comma)), Self::Starred(s) => Self::Starred(s.with_comma(comma)), @@ -2456,12 +2495,12 @@ impl<'a> WithComma<'a> for StarrableMatchSequenceElement<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct MatchSequenceElement<'a> { - pub value: MatchPattern<'a>, - pub comma: Option>, +pub struct MatchSequenceElement<'r, 'a> { + pub value: MatchPattern<'r, 'a>, + pub comma: Option>, } -impl<'a> MatchSequenceElement<'a> { +impl<'r, 'a> MatchSequenceElement<'r, 'a> { fn codegen( &self, state: &mut CodegenState<'a>, @@ -2486,8 +2525,8 @@ impl<'a> MatchSequenceElement<'a> { } } -impl<'a> WithComma<'a> for MatchSequenceElement<'a> { - fn with_comma(self, comma: Comma<'a>) -> Self { +impl<'r, 'a> WithComma<'r, 'a> for MatchSequenceElement<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> Self { Self { comma: Some(comma), ..self @@ -2496,15 +2535,15 @@ impl<'a> WithComma<'a> for MatchSequenceElement<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct MatchStar<'a> { - pub name: Option>, - pub comma: Option>, +pub struct MatchStar<'r, 'a> { + pub name: Option>, + pub comma: Option>, pub whitespace_before_name: ParenthesizableWhitespace<'a>, - pub(crate) star_tok: TokenRef<'a>, + pub(crate) star_tok: TokenRef<'r, 'a>, } -impl<'a> MatchStar<'a> { +impl<'r, 'a> MatchStar<'r, 'a> { fn codegen( &self, state: &mut CodegenState<'a>, @@ -2539,8 +2578,8 @@ impl<'a> MatchStar<'a> { } } -impl<'a> WithComma<'a> for MatchStar<'a> { - fn with_comma(self, comma: Comma<'a>) -> Self { +impl<'r, 'a> WithComma<'r, 'a> for MatchStar<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> Self { Self { comma: Some(comma), ..self @@ -2549,21 +2588,21 @@ impl<'a> WithComma<'a> for MatchStar<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy, ParenthesizedNode)] -pub struct MatchMapping<'a> { - pub elements: Vec>, - pub rest: Option>, - pub trailing_comma: Option>, - pub lbrace: LeftCurlyBrace<'a>, - pub rbrace: RightCurlyBrace<'a>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct MatchMapping<'r, 'a> { + pub elements: Vec>, + pub rest: Option>, + pub trailing_comma: Option>, + pub lbrace: LeftCurlyBrace<'r, 'a>, + pub rbrace: RightCurlyBrace<'r, 'a>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_before_rest: SimpleWhitespace<'a>, - pub(crate) star_tok: Option>, + pub(crate) star_tok: Option>, } -impl<'a> Codegen<'a> for MatchMapping<'a> { +impl<'r, 'a> Codegen<'a> for MatchMapping<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.lbrace.codegen(state); @@ -2582,7 +2621,8 @@ impl<'a> Codegen<'a> for MatchMapping<'a> { } } -impl<'a> Inflate<'a> for MatchMapping<'a> { +impl<'r, 'a> Inflate<'a> for MatchMapping<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.lbrace = self.lbrace.inflate(config)?; @@ -2613,18 +2653,18 @@ impl<'a> Inflate<'a> for MatchMapping<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct MatchMappingElement<'a> { - pub key: Expression<'a>, - pub pattern: MatchPattern<'a>, - pub comma: Option>, +pub struct MatchMappingElement<'r, 'a> { + pub key: Expression<'r, 'a>, + pub pattern: MatchPattern<'r, 'a>, + pub comma: Option>, pub whitespace_before_colon: ParenthesizableWhitespace<'a>, pub whitespace_after_colon: ParenthesizableWhitespace<'a>, - pub(crate) colon_tok: TokenRef<'a>, + pub(crate) colon_tok: TokenRef<'r, 'a>, } -impl<'a> MatchMappingElement<'a> { +impl<'r, 'a> MatchMappingElement<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) { self.key.codegen(state); self.whitespace_before_colon.codegen(state); @@ -2657,8 +2697,8 @@ impl<'a> MatchMappingElement<'a> { } } -impl<'a> WithComma<'a> for MatchMappingElement<'a> { - fn with_comma(self, comma: Comma<'a>) -> Self { +impl<'r, 'a> WithComma<'r, 'a> for MatchMappingElement<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> Self { Self { comma: Some(comma), ..self @@ -2667,22 +2707,22 @@ impl<'a> WithComma<'a> for MatchMappingElement<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy, ParenthesizedNode)] -pub struct MatchClass<'a> { - pub cls: NameOrAttribute<'a>, - pub patterns: Vec>, - pub kwds: Vec>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct MatchClass<'r, 'a> { + pub cls: NameOrAttribute<'r, 'a>, + pub patterns: Vec>, + pub kwds: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_after_cls: ParenthesizableWhitespace<'a>, pub whitespace_before_patterns: ParenthesizableWhitespace<'a>, pub whitespace_after_kwds: ParenthesizableWhitespace<'a>, - pub(crate) lpar_tok: TokenRef<'a>, - pub(crate) rpar_tok: TokenRef<'a>, + pub(crate) lpar_tok: TokenRef<'r, 'a>, + pub(crate) rpar_tok: TokenRef<'r, 'a>, } -impl<'a> Codegen<'a> for MatchClass<'a> { +impl<'r, 'a> Codegen<'a> for MatchClass<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { self.cls.codegen(state); @@ -2703,7 +2743,8 @@ impl<'a> Codegen<'a> for MatchClass<'a> { } } -impl<'a> Inflate<'a> for MatchClass<'a> { +impl<'r, 'a> Inflate<'a> for MatchClass<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; @@ -2743,18 +2784,18 @@ impl<'a> Inflate<'a> for MatchClass<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct MatchKeywordElement<'a> { - pub key: Name<'a>, - pub pattern: MatchPattern<'a>, - pub comma: Option>, +pub struct MatchKeywordElement<'r, 'a> { + pub key: Name<'r, 'a>, + pub pattern: MatchPattern<'r, 'a>, + pub comma: Option>, pub whitespace_before_equal: ParenthesizableWhitespace<'a>, pub whitespace_after_equal: ParenthesizableWhitespace<'a>, - pub(crate) equal_tok: TokenRef<'a>, + pub(crate) equal_tok: TokenRef<'r, 'a>, } -impl<'a> MatchKeywordElement<'a> { +impl<'r, 'a> MatchKeywordElement<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>, default_comma: bool) { self.key.codegen(state); self.whitespace_before_equal.codegen(state); @@ -2786,8 +2827,8 @@ impl<'a> MatchKeywordElement<'a> { } } -impl<'a> WithComma<'a> for MatchKeywordElement<'a> { - fn with_comma(self, comma: Comma<'a>) -> Self { +impl<'r, 'a> WithComma<'r, 'a> for MatchKeywordElement<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> Self { Self { comma: Some(comma), ..self @@ -2796,19 +2837,19 @@ impl<'a> WithComma<'a> for MatchKeywordElement<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy, ParenthesizedNode)] -pub struct MatchAs<'a> { - pub pattern: Option>, - pub name: Option>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct MatchAs<'r, 'a> { + pub pattern: Option>, + pub name: Option>, + pub lpar: Vec>, + pub rpar: Vec>, pub whitespace_before_as: Option>, pub whitespace_after_as: Option>, - pub(crate) as_tok: Option>, + pub(crate) as_tok: Option>, } -impl<'a> Codegen<'a> for MatchAs<'a> { +impl<'r, 'a> Codegen<'a> for MatchAs<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { if let Some(pat) = &self.pattern { @@ -2826,7 +2867,8 @@ impl<'a> Codegen<'a> for MatchAs<'a> { } } -impl<'a> Inflate<'a> for MatchAs<'a> { +impl<'r, 'a> Inflate<'a> for MatchAs<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.pattern = self.pattern.inflate(config)?; @@ -2847,12 +2889,12 @@ impl<'a> Inflate<'a> for MatchAs<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy)] -pub struct MatchOrElement<'a> { - pub pattern: MatchPattern<'a>, - pub separator: Option>, +pub struct MatchOrElement<'r, 'a> { + pub pattern: MatchPattern<'r, 'a>, + pub separator: Option>, } -impl<'a> MatchOrElement<'a> { +impl<'r, 'a> MatchOrElement<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>, default_separator: bool) { self.pattern.codegen(state); self.separator.codegen(state); @@ -2862,7 +2904,8 @@ impl<'a> MatchOrElement<'a> { } } -impl<'a> Inflate<'a> for MatchOrElement<'a> { +impl<'r, 'a> Inflate<'a> for MatchOrElement<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.pattern = self.pattern.inflate(config)?; self.separator = self.separator.inflate(config)?; @@ -2871,13 +2914,13 @@ impl<'a> Inflate<'a> for MatchOrElement<'a> { } #[derive(Debug, PartialEq, Eq, Clone, IntoPy, ParenthesizedNode)] -pub struct MatchOr<'a> { - pub patterns: Vec>, - pub lpar: Vec>, - pub rpar: Vec>, +pub struct MatchOr<'r, 'a> { + pub patterns: Vec>, + pub lpar: Vec>, + pub rpar: Vec>, } -impl<'a> Codegen<'a> for MatchOr<'a> { +impl<'r, 'a> Codegen<'a> for MatchOr<'r, 'a> { fn codegen(&self, state: &mut CodegenState<'a>) { self.parenthesize(state, |state| { let len = self.patterns.len(); @@ -2888,7 +2931,8 @@ impl<'a> Codegen<'a> for MatchOr<'a> { } } -impl<'a> Inflate<'a> for MatchOr<'a> { +impl<'r, 'a> Inflate<'a> for MatchOr<'r, 'a> { + type Inflated = Self; fn inflate(mut self, config: &Config<'a>) -> Result { self.lpar = self.lpar.inflate(config)?; self.patterns = self.patterns.inflate(config)?; diff --git a/native/libcst/src/nodes/traits.rs b/native/libcst/src/nodes/traits.rs index b6ab115c..8a700560 100644 --- a/native/libcst/src/nodes/traits.rs +++ b/native/libcst/src/nodes/traits.rs @@ -9,13 +9,13 @@ use crate::{ }; use std::ops::Deref; -pub trait WithComma<'a> { - fn with_comma(self, comma: Comma<'a>) -> Self; +pub trait WithComma<'r, 'a> { + fn with_comma(self, comma: Comma<'r, 'a>) -> Self; } -pub trait ParenthesizedNode<'a> { - fn lpar(&self) -> &Vec>; - fn rpar(&self) -> &Vec>; +pub trait ParenthesizedNode<'r, 'a: 'r> { + fn lpar(&self) -> &Vec>; + fn rpar(&self) -> &Vec>; fn parenthesize(&self, state: &mut CodegenState<'a>, f: F) where @@ -30,14 +30,14 @@ pub trait ParenthesizedNode<'a> { } } - fn with_parens(self, left: LeftParen<'a>, right: RightParen<'a>) -> Self; + fn with_parens(self, left: LeftParen<'r, 'a>, right: RightParen<'r, 'a>) -> Self; } -impl<'a, T: ParenthesizedNode<'a>> ParenthesizedNode<'a> for Box { - fn lpar(&self) -> &Vec> { +impl<'r, 'a: 'r, T: ParenthesizedNode<'r, 'a>> ParenthesizedNode<'r, 'a> for Box { + fn lpar(&self) -> &Vec> { self.deref().lpar() } - fn rpar(&self) -> &Vec> { + fn rpar(&self) -> &Vec> { self.deref().rpar() } fn parenthesize(&self, state: &mut CodegenState<'a>, f: F) @@ -46,7 +46,7 @@ impl<'a, T: ParenthesizedNode<'a>> ParenthesizedNode<'a> for Box { { self.deref().parenthesize(state, f) } - fn with_parens(self, left: LeftParen<'a>, right: RightParen<'a>) -> Self { + fn with_parens(self, left: LeftParen<'r, 'a>, right: RightParen<'r, 'a>) -> Self { Self::new((*self).with_parens(left, right)) } } @@ -61,17 +61,20 @@ pub trait Inflate<'a> where Self: Sized, { - fn inflate(self, config: &Config<'a>) -> Result; + type Inflated; + fn inflate(self, config: &Config<'a>) -> Result; } impl<'a, T: Inflate<'a>> Inflate<'a> for Option { - fn inflate(self, config: &Config<'a>) -> Result { + type Inflated = Option; + fn inflate(self, config: &Config<'a>) -> Result { self.map(|x| x.inflate(config)).transpose() } } impl<'a, T: Inflate<'a> + ?Sized> Inflate<'a> for Box { - fn inflate(self, config: &Config<'a>) -> Result { + type Inflated = Box; + fn inflate(self, config: &Config<'a>) -> Result { match (*self).inflate(config) { Ok(a) => Ok(Box::new(a)), Err(e) => Err(e), @@ -80,7 +83,8 @@ impl<'a, T: Inflate<'a> + ?Sized> Inflate<'a> for Box { } impl<'a, T: Inflate<'a>> Inflate<'a> for Vec { - fn inflate(self, config: &Config<'a>) -> Result { + type Inflated = Vec; + fn inflate(self, config: &Config<'a>) -> Result { self.into_iter().map(|item| item.inflate(config)).collect() } } diff --git a/native/libcst/src/parser/errors.rs b/native/libcst/src/parser/errors.rs index 44573248..26e83606 100644 --- a/native/libcst/src/parser/errors.rs +++ b/native/libcst/src/parser/errors.rs @@ -6,10 +6,9 @@ use pyo3::types::{IntoPyDict, PyModule}; use pyo3::{IntoPy, PyErr, PyErrArguments, Python}; -use crate::parser::grammar::TokVec; +use crate::parser::grammar::ParseLoc; use crate::tokenizer::whitespace_parser::WhitespaceError; use crate::tokenizer::TokError; -use peg::Parse; use thiserror::Error; #[allow(clippy::enum_variant_names)] @@ -18,10 +17,7 @@ pub enum ParserError<'a> { #[error("tokenizer error: {0}")] TokenizerError(TokError<'a>, &'a str), #[error("parser error: {0}")] - ParserError( - peg::error::ParseError< as Parse>::PositionRepr>, - &'a str, - ), + ParserError(peg::error::ParseError, &'a str), #[error(transparent)] WhitespaceError(#[from] WhitespaceError), #[error("invalid operator")] diff --git a/native/libcst/src/parser/grammar.rs b/native/libcst/src/parser/grammar.rs index c881be57..263965f3 100644 --- a/native/libcst/src/parser/grammar.rs +++ b/native/libcst/src/parser/grammar.rs @@ -5,6 +5,7 @@ use std::rc::Rc; +use crate::nodes::common::TokenRef; use crate::nodes::*; use crate::parser::ParserError; use crate::tokenizer::{TokType, Token}; @@ -19,7 +20,7 @@ pub type Result<'a, T> = std::result::Result>; type GrammarResult = std::result::Result; #[derive(Debug)] -pub struct TokVec<'a>(Vec>>); +pub struct TokVec<'a>(pub Vec>>); impl<'a> std::convert::From>> for TokVec<'a> { fn from(vec: Vec>) -> Self { @@ -67,14 +68,12 @@ impl<'a> Parse for TokVec<'a> { } } -type TokenRef<'a> = Rc>; +impl<'r, 'a: 'r> ParseElem<'r> for TokVec<'a> { + type Element = TokenRef<'r, 'a>; -impl<'a> ParseElem for TokVec<'a> { - type Element = TokenRef<'a>; - - fn parse_elem(&self, pos: usize) -> RuleResult { + fn parse_elem(&'r self, pos: usize) -> RuleResult { match self.0.get(pos) { - Some(tok) => RuleResult::Matched(pos + 1, tok.clone()), + Some(tok) => RuleResult::Matched(pos + 1, &tok), None => RuleResult::Failed, } } @@ -85,32 +84,32 @@ parser! { // Starting Rules - pub rule file(encoding: Option<&str>) -> Module<'a> + pub rule file(encoding: Option<&str>) -> Module<'input, 'a> = traced(<_file(encoding.unwrap_or("utf-8"))>) - pub rule expression_input() -> Expression<'a> + pub rule expression_input() -> Expression<'input, 'a> = traced() - pub rule statement_input() -> Statement<'a> + pub rule statement_input() -> Statement<'input, 'a> = traced() - rule _file(encoding: &str) -> Module<'a> + rule _file(encoding: &str) -> Module<'input, 'a> = s:statements()? eof:tok(EndMarker, "EOF") { make_module(s.unwrap_or_default(), eof, encoding) } // General statements - rule statements() -> Vec> + rule statements() -> Vec> = statement()+ - rule statement() -> Statement<'a> + rule statement() -> Statement<'input, 'a> = c:compound_stmt() { Statement::Compound(c) } / s:simple_stmts() { Statement::Simple(make_simple_statement_line(s)) } - rule simple_stmts() -> SimpleStatementParts<'a> + rule simple_stmts() -> SimpleStatementParts<'input, 'a> = first_tok:&_ stmts:separated_trailer(, ) nl:tok(NL, "NEWLINE") { SimpleStatementParts { first_tok, @@ -122,7 +121,7 @@ parser! { } #[cache] - rule simple_stmt() -> SmallStatement<'a> + rule simple_stmt() -> SmallStatement<'input, 'a> = assignment() / e:star_expressions() { SmallStatement::Expr(Expr { value: e, semicolon: None }) } / &lit("return") s:return_stmt() { SmallStatement::Return(s) } @@ -140,7 +139,7 @@ parser! { / &lit("nonlocal") s:nonlocal_stmt() {SmallStatement::Nonlocal(s)} - rule compound_stmt() -> CompoundStatement<'a> + rule compound_stmt() -> CompoundStatement<'input, 'a> = &(lit("def") / lit("@") / tok(Async, "ASYNC")) f:function_def() { CompoundStatement::FunctionDef(f) } @@ -155,7 +154,7 @@ parser! { // Simple statements - rule assignment() -> SmallStatement<'a> + rule assignment() -> SmallStatement<'input, 'a> = a:name() col:lit(":") ann:expression() rhs:(eq:lit("=") d:annotated_rhs() {(eq, d)})? { SmallStatement::AnnAssign( @@ -173,10 +172,10 @@ parser! { SmallStatement::AugAssign(make_aug_assign(t, op, rhs)) } - rule annotated_rhs() -> Expression<'a> + rule annotated_rhs() -> Expression<'input, 'a> = yield_expr() / star_expressions() - rule augassign() -> AugOp<'a> + rule augassign() -> AugOp<'input, 'a> = &(lit("+=") / lit("-=") / lit("*=") @@ -193,12 +192,12 @@ parser! { make_aug_op(tok).map_err(|_| "aug_op") } - rule return_stmt() -> Return<'a> + rule return_stmt() -> Return<'input, 'a> = kw:lit("return") a:star_expressions()? { make_return(kw, a) } - rule raise_stmt() -> Raise<'a> + rule raise_stmt() -> Raise<'input, 'a> = kw:lit("raise") exc:expression() rest:(f:lit("from") cau:expression() {(f, cau)})? { make_raise(kw, Some(exc), rest) @@ -207,17 +206,17 @@ parser! { make_raise(kw, None, None) } - rule global_stmt() -> Global<'a> + rule global_stmt() -> Global<'input, 'a> = kw:lit("global") init:(n:name() c:comma() {(n, c)})* last:name() { make_global(kw, init, last) } - rule nonlocal_stmt() -> Nonlocal<'a> + rule nonlocal_stmt() -> Nonlocal<'input, 'a> = kw:lit("nonlocal") init:(n:name() c:comma() {(n, c)})* last:name() { make_nonlocal(kw, init, last) } - rule del_stmt() -> Del<'a> + rule del_stmt() -> Del<'input, 'a> = kw:lit("del") t:del_target() &(lit(";") / tok(NL, "NEWLINE")) { make_del(kw, t) } @@ -225,22 +224,22 @@ parser! { make_del(kw, make_del_tuple(None, t, None)) } - rule yield_stmt() -> Expression<'a> + rule yield_stmt() -> Expression<'input, 'a> = yield_expr() - rule assert_stmt() -> Assert<'a> + rule assert_stmt() -> Assert<'input, 'a> = kw:lit("assert") test:expression() rest:(c:comma() msg:expression() {(c, msg)})? { make_assert(kw, test, rest) } // Import statements - rule import_name() -> Import<'a> + rule import_name() -> Import<'input, 'a> = kw:lit("import") a:dotted_as_names() { make_import(kw, a) } - rule import_from() -> ImportFrom<'a> + rule import_from() -> ImportFrom<'input, 'a> = from:lit("from") dots:dots()? m:dotted_name() import:lit("import") als:import_from_targets() { make_import_from(from, dots.unwrap_or_default(), Some(m), import, als) @@ -250,7 +249,7 @@ parser! { make_import_from(from, dots, None, import, als) } - rule import_from_targets() -> ParenthesizedImportNames<'a> + rule import_from_targets() -> ParenthesizedImportNames<'input, 'a> = lpar:lpar() als:import_from_as_names() c:comma()? rpar:rpar() { let mut als = als; if let (comma@Some(_), Some(mut last)) = (c, als.last_mut()) { @@ -261,29 +260,29 @@ parser! { / als:import_from_as_names() !lit(",") { (None, ImportNames::Aliases(als), None)} / star:lit("*") { (None, ImportNames::Star(ImportStar {}), None) } - rule import_from_as_names() -> Vec> + rule import_from_as_names() -> Vec> = items:separated(, ) { make_import_from_as_names(items.0, items.1) } - rule import_from_as_name() -> ImportAlias<'a> + rule import_from_as_name() -> ImportAlias<'input, 'a> = n:name() asname:(kw:lit("as") z:name() {(kw, z)})? { make_import_alias(NameOrAttribute::N(n), asname) } - rule dotted_as_names() -> Vec> + rule dotted_as_names() -> Vec> = init:(d:dotted_as_name() c:comma() {d.with_comma(c)})* last:dotted_as_name() { concat(init, vec![last]) } - rule dotted_as_name() -> ImportAlias<'a> + rule dotted_as_name() -> ImportAlias<'input, 'a> = n:dotted_name() asname:(kw:lit("as") z:name() {(kw, z)})? { make_import_alias(n, asname) } // TODO: why does this diverge from CPython? - rule dotted_name() -> NameOrAttribute<'a> + rule dotted_name() -> NameOrAttribute<'input, 'a> = first:name() tail:(dot:lit(".") n:name() {(dot, n)})* { make_name_or_attr(first, tail) } @@ -293,7 +292,7 @@ parser! { // Common elements #[cache] - rule block() -> Suite<'a> + rule block() -> Suite<'input, 'a> = n:tok(NL, "NEWLINE") ind:tok(Indent, "INDENT") s:statements() ded:tok(Dedent, "DEDENT") { make_indented_block(n, ind, s, ded) } @@ -301,18 +300,18 @@ parser! { make_simple_statement_suite(s) } - rule decorators() -> Vec> + rule decorators() -> Vec> = (at:lit("@") e:named_expression() nl:tok(NL, "NEWLINE") { make_decorator(at, e, nl) } )+ // Class definitions - rule class_def() -> ClassDef<'a> + rule class_def() -> ClassDef<'input, 'a> = d:decorators() c:class_def_raw() { c.with_decorators(d) } / class_def_raw() - rule class_def_raw() -> ClassDef<'a> + rule class_def_raw() -> ClassDef<'input, 'a> = kw:lit("class") n:name() arg:(l:lpar() a:arguments()? r:rpar() {(l, a, r)})? col:lit(":") b:block() {? make_class_def(kw, n, arg, col, b) @@ -320,16 +319,16 @@ parser! { // Function definitions - rule function_def() -> FunctionDef<'a> + rule function_def() -> FunctionDef<'input, 'a> = d:decorators() f:function_def_raw() {f.with_decorators(d)} / function_def_raw() - rule _returns() -> Annotation<'a> + rule _returns() -> Annotation<'input, 'a> = l:lit("->") e:expression() { make_annotation(l, e) } - rule function_def_raw() -> FunctionDef<'a> + rule function_def_raw() -> FunctionDef<'input, 'a> = def:lit("def") n:name() op:lit("(") params:params()? cp:lit(")") ty:_returns()? c:lit(":") b:block() { make_function_def(None, def, n, op, params, cp, ty, c, b) @@ -341,10 +340,10 @@ parser! { // Function parameters - rule params() -> Parameters<'a> + rule params() -> Parameters<'input, 'a> = parameters() - rule parameters() -> Parameters<'a> + rule parameters() -> Parameters<'input, 'a> = a:slash_no_default() b:param_no_default()* c:param_with_default()* d:star_etc()? { make_parameters(Some(a), concat(b, c), d) } @@ -361,7 +360,7 @@ parser! { make_parameters(None, vec![], Some(d)) } - rule slash_no_default() -> (Vec>, ParamSlash<'a>) + rule slash_no_default() -> (Vec>, ParamSlash<'input, 'a>) = a:param_no_default()+ slash:lit("/") com:comma() { (a, ParamSlash { comma: Some(com)}) } @@ -369,7 +368,7 @@ parser! { (a, ParamSlash { comma: None }) } - rule slash_with_default() -> (Vec>, ParamSlash<'a>) + rule slash_with_default() -> (Vec>, ParamSlash<'input, 'a>) = a:param_no_default()* b:param_with_default()+ slash:lit("/") c:comma() { (concat(a, b), ParamSlash { comma: Some(c) }) } @@ -377,7 +376,7 @@ parser! { (concat(a, b), ParamSlash { comma: None }) } - rule star_etc() -> StarEtc<'a> + rule star_etc() -> StarEtc<'input, 'a> = star:lit("*") a:param_no_default() b:param_maybe_default()* kw:kwds()? { StarEtc(Some(StarArg::Param(Box::new( add_param_star(a, star)))), b, kw) @@ -387,16 +386,16 @@ parser! { } / kw:kwds() { StarEtc(None, vec![], Some(kw)) } - rule kwds() -> Param<'a> + rule kwds() -> Param<'input, 'a> = star:lit("**") a:param_no_default() { add_param_star(a, star) } - rule param_no_default() -> Param<'a> + rule param_no_default() -> Param<'input, 'a> = a:param() c:lit(",") { add_param_default(a, None, Some(c)) } / a:param() &lit(")") {a} - rule param_with_default() -> Param<'a> + rule param_with_default() -> Param<'input, 'a> = a:param() def:default() c:lit(",") { add_param_default(a, Some(def), Some(c)) } @@ -404,7 +403,7 @@ parser! { add_param_default(a, Some(def), None) } - rule param_maybe_default() -> Param<'a> + rule param_maybe_default() -> Param<'input, 'a> = a:param() def:default()? c:lit(",") { add_param_default(a, def, Some(c)) } @@ -412,24 +411,24 @@ parser! { add_param_default(a, def, None) } - rule param() -> Param<'a> + rule param() -> Param<'input, 'a> = n:name() a:annotation()? { Param {name: n, annotation: a, ..Default::default() } } - rule annotation() -> Annotation<'a> + rule annotation() -> Annotation<'input, 'a> = col:lit(":") e:expression() { make_annotation(col, e) } - rule default() -> (AssignEqual<'a>, Expression<'a>) + rule default() -> (AssignEqual<'input, 'a>, Expression<'input, 'a>) = eq:lit("=") ex:expression() { (make_assign_equal(eq), ex) } // If statement - rule if_stmt() -> If<'a> + rule if_stmt() -> If<'input, 'a> = i:lit("if") a:named_expression() col:lit(":") b:block() elif:elif_stmt() { make_if(i, a, col, b, Some(OrElse::Elif(elif)), false) } @@ -437,7 +436,7 @@ parser! { make_if(i, a, col, b, el.map(OrElse::Else), false) } - rule elif_stmt() -> If<'a> + rule elif_stmt() -> If<'input, 'a> = i:lit("elif") a:named_expression() col:lit(":") b:block() elif:elif_stmt() { make_if(i, a, col, b, Some(OrElse::Elif(elif)), true) } @@ -445,21 +444,21 @@ parser! { make_if(i, a, col, b, el.map(OrElse::Else), true) } - rule else_block() -> Else<'a> + rule else_block() -> Else<'input, 'a> = el:lit("else") col:lit(":") b:block() { make_else(el, col, b) } // While statement - rule while_stmt() -> While<'a> + rule while_stmt() -> While<'input, 'a> = kw:lit("while") test:named_expression() col:lit(":") b:block() el:else_block()? { make_while(kw, test, col, b, el) } // For statement - rule for_stmt() -> For<'a> + rule for_stmt() -> For<'input, 'a> = f:lit("for") t:star_targets() i:lit("in") it:star_expressions() c:lit(":") b:block() el:else_block()? { make_for(None, f, t, i, it, c, b, el) @@ -472,7 +471,7 @@ parser! { // With statement - rule with_stmt() -> With<'a> + rule with_stmt() -> With<'input, 'a> = kw:lit("with") items:separated(, ) col:lit(":") b:block() { make_with(None, kw, comma_separate(items.0, items.1, None), col, b) @@ -482,7 +481,7 @@ parser! { make_with(Some(asy), kw, comma_separate(items.0, items.1, None), col, b) } - rule with_item() -> WithItem<'a> + rule with_item() -> WithItem<'input, 'a> = e:expression() a:lit("as") t:star_target() &(lit(",") / lit(":")) { make_with_item(e, Some(a), Some(t)) } @@ -492,7 +491,7 @@ parser! { // Try statement - rule try_stmt() -> Try<'a> + rule try_stmt() -> Try<'input, 'a> = kw:lit("try") lit(":") b:block() f:finally_block() { make_try(kw, b, vec![], None, Some(f)) } @@ -502,7 +501,7 @@ parser! { } // Note: this is separate because TryStar is a different type in LibCST - rule try_star_stmt() -> TryStar<'a> + rule try_star_stmt() -> TryStar<'input, 'a> = kw:lit("try") lit(":") b:block() ex:except_star_block()+ el:else_block()? f:finally_block()? { make_try_star(kw, b, ex, el, f) @@ -510,7 +509,7 @@ parser! { // Except statement - rule except_block() -> ExceptHandler<'a> + rule except_block() -> ExceptHandler<'input, 'a> = kw:lit("except") e:expression() a:(k:lit("as") n:name() {(k, n)})? col:lit(":") b:block() { make_except(kw, Some(e), a, col, b) @@ -519,13 +518,13 @@ parser! { make_except(kw, None, None, col, b) } - rule except_star_block() -> ExceptStarHandler<'a> + rule except_star_block() -> ExceptStarHandler<'input, 'a> = kw:lit("except") star:lit("*") e:expression() a:(k:lit("as") n:name() {(k, n)})? col:lit(":") b:block() { make_except_star(kw, star, e, a, col, b) } - rule finally_block() -> Finally<'a> + rule finally_block() -> Finally<'input, 'a> = kw:lit("finally") col:lit(":") b:block() { make_finally(kw, col, b) } @@ -533,13 +532,13 @@ parser! { // Match statement - rule match_stmt() -> Match<'a> + rule match_stmt() -> Match<'input, 'a> = kw:lit("match") subject:subject_expr() col:lit(":") tok(NL, "NEWLINE") i:tok(Indent, "INDENT") cases:case_block()+ d:tok(Dedent, "DEDENT") { make_match(kw, subject, col, i, cases, d) } - rule subject_expr() -> Expression<'a> + rule subject_expr() -> Expression<'input, 'a> = first:star_named_expression() c:comma() rest:star_named_expressions()? { Expression::Tuple( make_tuple_from_elements(first.with_comma(c), rest.unwrap_or_default()) @@ -547,35 +546,35 @@ parser! { } / named_expression() - rule case_block() -> MatchCase<'a> + rule case_block() -> MatchCase<'input, 'a> = kw:lit("case") pattern:patterns() guard:guard()? col:lit(":") body:block() { make_case(kw, pattern, guard, col, body) } - rule guard() -> (TokenRef<'a>, Expression<'a>) + rule guard() -> (TokenRef<'input, 'a>, Expression<'input, 'a>) = kw:lit("if") exp:named_expression() { (kw, exp) } - rule patterns() -> MatchPattern<'a> + rule patterns() -> MatchPattern<'input, 'a> = pats:open_sequence_pattern() { MatchPattern::Sequence(make_list_pattern(None, pats, None)) } / pattern() - rule pattern() -> MatchPattern<'a> + rule pattern() -> MatchPattern<'input, 'a> = as_pattern() / or_pattern() - rule as_pattern() -> MatchPattern<'a> + rule as_pattern() -> MatchPattern<'input, 'a> = pat:or_pattern() kw:lit("as") target:pattern_capture_target() { make_as_pattern(Some(pat), Some(kw), Some(target)) } - rule or_pattern() -> MatchPattern<'a> + rule or_pattern() -> MatchPattern<'input, 'a> = pats:separated(, ) { make_or_pattern(pats.0, pats.1) } - rule closed_pattern() -> MatchPattern<'a> + rule closed_pattern() -> MatchPattern<'input, 'a> = literal_pattern() / capture_pattern() / wildcard_pattern() @@ -585,7 +584,7 @@ parser! { / mapping_pattern() / class_pattern() - rule literal_pattern() -> MatchPattern<'a> + rule literal_pattern() -> MatchPattern<'input, 'a> = val:signed_number() !(lit("+") / lit("-")) { make_match_value(val) } / val:complex_number() { make_match_value(val) } / val:strings() { make_match_value(val.into()) } @@ -593,7 +592,7 @@ parser! { / n:lit("True") { make_match_singleton(make_name(n)) } / n:lit("False") { make_match_singleton(make_name(n)) } - rule literal_expr() -> Expression<'a> + rule literal_expr() -> Expression<'input, 'a> = val:signed_number() !(lit("+") / lit("-")) { val } / val:complex_number() { val } / val:strings() { val.into() } @@ -601,59 +600,59 @@ parser! { / n:lit("True") { Expression::Name(make_name(n)) } / n:lit("False") { Expression::Name(make_name(n)) } - rule complex_number() -> Expression<'a> + rule complex_number() -> Expression<'input, 'a> = re:signed_real_number() op:(lit("+")/lit("-")) im:imaginary_number() {? make_binary_op(re, op, im).map_err(|_| "complex number") } - rule signed_number() -> Expression<'a> + rule signed_number() -> Expression<'input, 'a> = n:tok(Number, "number") { make_number(n) } / op:lit("-") n:tok(Number, "number") {? make_unary_op(op, make_number(n)).map_err(|_| "signed number") } - rule signed_real_number() -> Expression<'a> + rule signed_real_number() -> Expression<'input, 'a> = real_number() / op:lit("-") n:real_number() {? make_unary_op(op, n).map_err(|_| "signed real number") } - rule real_number() -> Expression<'a> + rule real_number() -> Expression<'input, 'a> = n:tok(Number, "number") {? ensure_real_number(n) } - rule imaginary_number() -> Expression<'a> + rule imaginary_number() -> Expression<'input, 'a> = n:tok(Number, "number") {? ensure_imaginary_number(n) } - rule capture_pattern() -> MatchPattern<'a> + rule capture_pattern() -> MatchPattern<'input, 'a> = t:pattern_capture_target() { make_as_pattern(None, None, Some(t)) } - rule pattern_capture_target() -> Name<'a> + rule pattern_capture_target() -> Name<'input, 'a> = !lit("_") n:name() !(lit(".") / lit("(") / lit("=")) { n } - rule wildcard_pattern() -> MatchPattern<'a> + rule wildcard_pattern() -> MatchPattern<'input, 'a> = lit("_") { make_as_pattern(None, None, None) } - rule value_pattern() -> MatchPattern<'a> + rule value_pattern() -> MatchPattern<'input, 'a> = v:attr() !(lit(".") / lit("(") / lit("=")) { make_match_value(v.into()) } // In upstream attr and name_or_attr are mutually recursive, but rust-peg // doesn't support this yet. - rule attr() -> NameOrAttribute<'a> + rule attr() -> NameOrAttribute<'input, 'a> = &(name() lit(".")) v:name_or_attr() { v } #[cache_left_rec] - rule name_or_attr() -> NameOrAttribute<'a> + rule name_or_attr() -> NameOrAttribute<'input, 'a> = val:name_or_attr() d:lit(".") attr:name() { NameOrAttribute::A(make_attribute(val.into(), d, attr)) } / n:name() { NameOrAttribute::N(n) } - rule group_pattern() -> MatchPattern<'a> + rule group_pattern() -> MatchPattern<'input, 'a> = l:lpar() pat:pattern() r:rpar() { pat.with_parens(l, r) } - rule sequence_pattern() -> MatchPattern<'a> + rule sequence_pattern() -> MatchPattern<'input, 'a> = l:lbrak() pats:maybe_sequence_pattern()? r:rbrak() { MatchPattern::Sequence( make_list_pattern(Some(l), pats.unwrap_or_default(), Some(r)) @@ -663,17 +662,17 @@ parser! { MatchPattern::Sequence(make_tuple_pattern(l, pats.unwrap_or_default(), r)) } - rule open_sequence_pattern() -> Vec> + rule open_sequence_pattern() -> Vec> = pat:maybe_star_pattern() c:comma() pats:maybe_sequence_pattern()? { make_open_sequence_pattern(pat, c, pats.unwrap_or_default()) } - rule maybe_sequence_pattern() -> Vec> + rule maybe_sequence_pattern() -> Vec> = pats:separated_trailer(, ) { comma_separate(pats.0, pats.1, pats.2) } - rule maybe_star_pattern() -> StarrableMatchSequenceElement<'a> + rule maybe_star_pattern() -> StarrableMatchSequenceElement<'input, 'a> = s:star_pattern() { StarrableMatchSequenceElement::Starred(s) } / p:pattern() { StarrableMatchSequenceElement::Simple( @@ -681,11 +680,11 @@ parser! { ) } - rule star_pattern() -> MatchStar<'a> + rule star_pattern() -> MatchStar<'input, 'a> = star:lit("*") t:pattern_capture_target() {make_match_star(star, Some(t))} / star:lit("*") t:wildcard_pattern() { make_match_star(star, None) } - rule mapping_pattern() -> MatchPattern<'a> + rule mapping_pattern() -> MatchPattern<'input, 'a> = l:lbrace() r:rbrace() { make_match_mapping(l, vec![], None, None, None, None, r) } @@ -700,20 +699,20 @@ parser! { make_match_mapping(l, items, trail, None, None, None, r) } - rule items_pattern() -> Vec> + rule items_pattern() -> Vec> = pats:separated(, ) { comma_separate(pats.0, pats.1, None) } - rule key_value_pattern() -> MatchMappingElement<'a> + rule key_value_pattern() -> MatchMappingElement<'input, 'a> = key:(literal_expr() / a:attr() {a.into()}) colon:lit(":") pat:pattern() { make_match_mapping_element(key, colon, pat) } - rule double_star_pattern() -> (TokenRef<'a>, Name<'a>) + rule double_star_pattern() -> (TokenRef<'input, 'a>, Name<'input, 'a>) = star:lit("**") n:pattern_capture_target() { (star, n) } - rule class_pattern() -> MatchPattern<'a> + rule class_pattern() -> MatchPattern<'input, 'a> = cls:name_or_attr() l:lit("(") r:lit(")") { make_class_pattern(cls, l, vec![], None, vec![], None, r) } @@ -728,17 +727,17 @@ parser! { make_class_pattern(cls, l, pats, Some(c), kwds, trail, r) } - rule positional_patterns() -> Vec> + rule positional_patterns() -> Vec> = pats:separated(, ) { comma_separate(pats.0, pats.1, None) } - rule keyword_patterns() -> Vec> + rule keyword_patterns() -> Vec> = pats:separated(, ) { comma_separate(pats.0, pats.1, None) } - rule keyword_pattern() -> MatchKeywordElement<'a> + rule keyword_pattern() -> MatchKeywordElement<'input, 'a> = arg:name() eq:lit("=") value:pattern() { make_match_keyword_element(arg, eq, value) } @@ -746,17 +745,17 @@ parser! { // Expressions #[cache] - rule expression() -> Expression<'a> + rule expression() -> Expression<'input, 'a> = _conditional_expression() / lambdef() - rule _conditional_expression() -> Expression<'a> + rule _conditional_expression() -> Expression<'input, 'a> = body:disjunction() i:lit("if") test:disjunction() e:lit("else") oe:expression() { Expression::IfExp(make_ifexp(body, i, test, e, oe)) } / disjunction() - rule yield_expr() -> Expression<'a> + rule yield_expr() -> Expression<'input, 'a> = y:lit("yield") f:lit("from") a:expression() { Expression::Yield(make_yield(y, Some(f), Some(a))) } @@ -764,7 +763,7 @@ parser! { Expression::Yield(make_yield(y, None, a)) } - rule star_expressions() -> Expression<'a> + rule star_expressions() -> Expression<'input, 'a> = first:star_expression() rest:(comma:comma() e:star_expression() { (comma, expr_to_element(e)) })+ comma:comma()? { @@ -776,45 +775,45 @@ parser! { / star_expression() #[cache] - rule star_expression() -> Expression<'a> + rule star_expression() -> Expression<'input, 'a> = star:lit("*") e:bitwise_or() { Expression::StarredElement(make_starred_element(star, expr_to_element(e))) } / expression() - rule star_named_expressions() -> Vec> + rule star_named_expressions() -> Vec> = exps:separated_trailer(, ) { comma_separate(exps.0, exps.1, exps.2) } - rule star_named_expression() -> Element<'a> + rule star_named_expression() -> Element<'input, 'a> = star:lit("*") e:bitwise_or() { Element::Starred(make_starred_element(star, expr_to_element(e))) } / e:named_expression() { expr_to_element(e) } - rule named_expression() -> Expression<'a> + rule named_expression() -> Expression<'input, 'a> = a:name() op:lit(":=") b:expression() { Expression::NamedExpr(make_named_expr(a, op, b)) } / e:expression() !lit(":=") { e } #[cache] - rule disjunction() -> Expression<'a> + rule disjunction() -> Expression<'input, 'a> = a:conjunction() b:(or:lit("or") inner:conjunction() { (or, inner) })+ {? make_boolean_op(a, b).map_err(|e| "expected disjunction") } / conjunction() #[cache] - rule conjunction() -> Expression<'a> + rule conjunction() -> Expression<'input, 'a> = a:inversion() b:(and:lit("and") inner:inversion() { (and, inner) })+ {? make_boolean_op(a, b).map_err(|e| "expected conjunction") } / inversion() #[cache] - rule inversion() -> Expression<'a> + rule inversion() -> Expression<'input, 'a> = not:lit("not") a:inversion() {? make_unary_op(not, a).map_err(|e| "expected inversion") } @@ -823,14 +822,14 @@ parser! { // Comparison operators #[cache] - rule comparison() -> Expression<'a> + rule comparison() -> Expression<'input, 'a> = a:bitwise_or() b:compare_op_bitwise_or_pair()+ { make_comparison(a, b) } / bitwise_or() // This implementation diverges slightly from CPython (3.9) to avoid bloating // the parser cache and increase readability. #[cache] - rule compare_op_bitwise_or_pair() -> (CompOp<'a>, Expression<'a>) + rule compare_op_bitwise_or_pair() -> (CompOp<'input, 'a>, Expression<'input, 'a>) = _op_bitwise_or("==") / _op_bitwise_or("!=") // TODO: support barry_as_flufl / _op_bitwise_or("<=") @@ -842,14 +841,14 @@ parser! { / _op_bitwise_or2("is", "not") / _op_bitwise_or("is") - rule _op_bitwise_or(o: &'static str) -> (CompOp<'a>, Expression<'a>) + rule _op_bitwise_or(o: &'static str) -> (CompOp<'input, 'a>, Expression<'input, 'a>) = op:lit(o) e:bitwise_or() {? make_comparison_operator(op) .map(|op| (op, e)) .map_err(|_| "comparison") } - rule _op_bitwise_or2(first: &'static str, second: &'static str) -> (CompOp<'a>, Expression<'a>) + rule _op_bitwise_or2(first: &'static str, second: &'static str) -> (CompOp<'input, 'a>, Expression<'input, 'a>) = f:lit(first) s:lit(second) e:bitwise_or() {? make_comparison_operator_2(f, s) .map(|op| (op, e)) @@ -857,28 +856,28 @@ parser! { } #[cache_left_rec] - rule bitwise_or() -> Expression<'a> + rule bitwise_or() -> Expression<'input, 'a> = a:bitwise_or() op:lit("|") b:bitwise_xor() {? make_binary_op(a, op, b).map_err(|e| "expected bitwise_or") } / bitwise_xor() #[cache_left_rec] - rule bitwise_xor() -> Expression<'a> + rule bitwise_xor() -> Expression<'input, 'a> = a:bitwise_xor() op:lit("^") b:bitwise_and() {? make_binary_op(a, op, b).map_err(|e| "expected bitwise_xor") } / bitwise_and() #[cache_left_rec] - rule bitwise_and() -> Expression<'a> + rule bitwise_and() -> Expression<'input, 'a> = a:bitwise_and() op:lit("&") b:shift_expr() {? make_binary_op(a, op, b).map_err(|e| "expected bitwise_and") } / shift_expr() #[cache_left_rec] - rule shift_expr() -> Expression<'a> + rule shift_expr() -> Expression<'input, 'a> = a:shift_expr() op:lit("<<") b:sum() {? make_binary_op(a, op, b).map_err(|e| "expected shift_expr") } @@ -888,7 +887,7 @@ parser! { / sum() #[cache_left_rec] - rule sum() -> Expression<'a> + rule sum() -> Expression<'input, 'a> = a:sum() op:lit("+") b:term() {? make_binary_op(a, op, b).map_err(|e| "expected sum") } @@ -898,7 +897,7 @@ parser! { / term() #[cache_left_rec] - rule term() -> Expression<'a> + rule term() -> Expression<'input, 'a> = a:term() op:lit("*") b:factor() {? make_binary_op(a, op, b).map_err(|e| "expected term") } @@ -917,7 +916,7 @@ parser! { / factor() #[cache] - rule factor() -> Expression<'a> + rule factor() -> Expression<'input, 'a> = op:lit("+") a:factor() {? make_unary_op(op, a).map_err(|e| "expected factor") } @@ -929,7 +928,7 @@ parser! { } / power() - rule power() -> Expression<'a> + rule power() -> Expression<'input, 'a> = a:await_primary() op:lit("**") b:factor() {? make_binary_op(a, op, b).map_err(|e| "expected power") } @@ -937,14 +936,14 @@ parser! { // Primary elements - rule await_primary() -> Expression<'a> + rule await_primary() -> Expression<'input, 'a> = aw:tok(AWAIT, "AWAIT") e:primary() { Expression::Await(make_await(aw, e)) } / primary() #[cache_left_rec] - rule primary() -> Expression<'a> + rule primary() -> Expression<'input, 'a> = v:primary() dot:lit(".") attr:name() { Expression::Attribute(make_attribute(v, dot, attr)) } @@ -959,20 +958,20 @@ parser! { } / atom() - rule slices() -> Vec> + rule slices() -> Vec> = s:slice() !lit(",") { vec![SubscriptElement { slice: s, comma: None }] } / slices:separated_trailer(, ) { make_slices(slices.0, slices.1, slices.2) } - rule slice() -> BaseSlice<'a> + rule slice() -> BaseSlice<'input, 'a> = l:expression()? col:lit(":") u:expression()? rest:(c:lit(":") s:expression()? {(c, s)})? { make_slice(l, col, u, rest) } / v:expression() { make_index(v) } - rule atom() -> Expression<'a> + rule atom() -> Expression<'input, 'a> = n:name() { Expression::Name(n) } / n:lit("True") { Expression::Name(make_name(n)) } / n:lit("False") { Expression::Name(make_name(n)) } @@ -984,26 +983,26 @@ parser! { / &lit("{") e:(dict() / set() / dictcomp() / setcomp()) {e} / lit("...") { Expression::Ellipsis(Ellipsis {lpar: vec![], rpar: vec![]})} - rule group() -> Expression<'a> + rule group() -> Expression<'input, 'a> = lpar:lpar() e:(yield_expr() / named_expression()) rpar:rpar() { e.with_parens(lpar, rpar) } // Lambda functions - rule lambdef() -> Expression<'a> + rule lambdef() -> Expression<'input, 'a> = kw:lit("lambda") p:lambda_params()? c:lit(":") b:expression() { Expression::Lambda(make_lambda(kw, p.unwrap_or_default(), c, b)) } - rule lambda_params() -> Parameters<'a> + rule lambda_params() -> Parameters<'input, 'a> = lambda_parameters() // lambda_parameters etc. duplicates parameters but without annotations or type // comments, and if there's no comma after a parameter, we expect a colon, not a // close parenthesis. - rule lambda_parameters() -> Parameters<'a> + rule lambda_parameters() -> Parameters<'input, 'a> = a:lambda_slash_no_default() b:lambda_param_no_default()* c:lambda_param_with_default()* d:lambda_star_etc()? { make_parameters(Some(a), concat(b, c), d) @@ -1023,7 +1022,7 @@ parser! { make_parameters(None, vec![], Some(d)) } - rule lambda_slash_no_default() -> (Vec>, ParamSlash<'a>) + rule lambda_slash_no_default() -> (Vec>, ParamSlash<'input, 'a>) = a:lambda_param_no_default()+ slash:lit("/") com:comma() { (a, ParamSlash { comma: Some(com) } ) } @@ -1031,7 +1030,7 @@ parser! { (a, ParamSlash { comma: None }) } - rule lambda_slash_with_default() -> (Vec>, ParamSlash<'a>) + rule lambda_slash_with_default() -> (Vec>, ParamSlash<'input, 'a>) = a:lambda_param_no_default()* b:lambda_param_with_default()+ slash:lit("/") c:comma(){ (concat(a, b), ParamSlash { comma: Some(c) }) } @@ -1039,7 +1038,7 @@ parser! { (concat(a, b), ParamSlash { comma: None }) } - rule lambda_star_etc() -> StarEtc<'a> + rule lambda_star_etc() -> StarEtc<'input, 'a> = star:lit("*") a:lambda_param_no_default() b:lambda_param_maybe_default()* kw:lambda_kwds()? { StarEtc(Some(StarArg::Param( @@ -1051,18 +1050,18 @@ parser! { } / kw:lambda_kwds() { StarEtc(None, vec![], Some(kw)) } - rule lambda_kwds() -> Param<'a> + rule lambda_kwds() -> Param<'input, 'a> = star:lit("**") a:lambda_param_no_default() { add_param_star(a, star) } - rule lambda_param_no_default() -> Param<'a> + rule lambda_param_no_default() -> Param<'input, 'a> = a:lambda_param() c:lit(",") { add_param_default(a, None, Some(c)) } / a:lambda_param() &lit(":") {a} - rule lambda_param_with_default() -> Param<'a> + rule lambda_param_with_default() -> Param<'input, 'a> = a:lambda_param() def:default() c:lit(",") { add_param_default(a, Some(def), Some(c)) } @@ -1070,7 +1069,7 @@ parser! { add_param_default(a, Some(def), None) } - rule lambda_param_maybe_default() -> Param<'a> + rule lambda_param_maybe_default() -> Param<'input, 'a> = a:lambda_param() def:default()? c:lit(",") { add_param_default(a, def, Some(c)) } @@ -1078,25 +1077,25 @@ parser! { add_param_default(a, def, None) } - rule lambda_param() -> Param<'a> + rule lambda_param() -> Param<'input, 'a> = name:name() { Param { name, ..Default::default() } } // Literals - rule strings() -> String<'a> + rule strings() -> String<'input, 'a> = s:(str:tok(STRING, "STRING") t:&_ {(make_string(str), t)} / str:fstring() t:&_ {(String::Formatted(str), t)})+ { make_strings(s) } - rule list() -> Expression<'a> + rule list() -> Expression<'input, 'a> = lbrak:lbrak() e:star_named_expressions()? rbrak:rbrak() { Expression::List( make_list(lbrak, e.unwrap_or_default(), rbrak) ) } - rule tuple() -> Expression<'a> + rule tuple() -> Expression<'input, 'a> = lpar:lpar() first:star_named_expression() &lit(",") rest:(c:comma() e:star_named_expression() {(c, e)})* trailing_comma:comma()? rpar:rpar() { @@ -1109,39 +1108,39 @@ parser! { lpar, RightParen { whitespace_before: Default::default(), rpar_tok: rpar } ))} - rule set() -> Expression<'a> + rule set() -> Expression<'input, 'a> = lbrace:lbrace() e:star_named_expressions()? rbrace:rbrace() { Expression::Set(make_set(lbrace, e.unwrap_or_default(), rbrace)) } // Dicts - rule dict() -> Expression<'a> + rule dict() -> Expression<'input, 'a> = lbrace:lbrace() els:double_starred_keypairs()? rbrace:rbrace() { Expression::Dict(make_dict(lbrace, els.unwrap_or_default(), rbrace)) } - rule double_starred_keypairs() -> Vec> + rule double_starred_keypairs() -> Vec> = pairs:separated_trailer(, ) { make_double_starred_keypairs(pairs.0, pairs.1, pairs.2) } - rule double_starred_kvpair() -> DictElement<'a> + rule double_starred_kvpair() -> DictElement<'input, 'a> = s:lit("**") e:bitwise_or() { DictElement::Starred(make_double_starred_element(s, e)) } / k:kvpair() { make_dict_element(k) } - rule kvpair() -> (Expression<'a>, TokenRef<'a>, Expression<'a>) + rule kvpair() -> (Expression<'input, 'a>, TokenRef<'input, 'a>, Expression<'input, 'a>) = k:expression() colon:lit(":") v:expression() { (k, colon, v) } // Comprehensions & generators - rule for_if_clauses() -> CompFor<'a> + rule for_if_clauses() -> CompFor<'input, 'a> = c:for_if_clause()+ { merge_comp_fors(c) } - rule for_if_clause() -> CompFor<'a> + rule for_if_clause() -> CompFor<'input, 'a> = asy:_async() f:lit("for") tgt:star_targets() i:lit("in") iter:disjunction() ifs:_comp_if()* { make_for_if(Some(asy), f, tgt, i, iter, ifs) @@ -1151,42 +1150,42 @@ parser! { make_for_if(None, f, tgt, i, iter, ifs) } - rule _comp_if() -> CompIf<'a> + rule _comp_if() -> CompIf<'input, 'a> = kw:lit("if") cond:disjunction() { make_comp_if(kw, cond) } - rule listcomp() -> Expression<'a> + rule listcomp() -> Expression<'input, 'a> = lbrak:lbrak() elt:named_expression() comp:for_if_clauses() rbrak:rbrak() { Expression::ListComp(make_list_comp(lbrak, elt, comp, rbrak)) } - rule setcomp() -> Expression<'a> + rule setcomp() -> Expression<'input, 'a> = l:lbrace() elt:named_expression() comp:for_if_clauses() r:rbrace() { Expression::SetComp(make_set_comp(l, elt, comp, r)) } - rule genexp() -> GeneratorExp<'a> + rule genexp() -> GeneratorExp<'input, 'a> = lpar:lpar() g:_bare_genexp() rpar:rpar() { g.with_parens(lpar, rpar) } - rule _bare_genexp() -> GeneratorExp<'a> + rule _bare_genexp() -> GeneratorExp<'input, 'a> = elt:named_expression() comp:for_if_clauses() { make_bare_genexp(elt, comp) } - rule dictcomp() -> Expression<'a> + rule dictcomp() -> Expression<'input, 'a> = lbrace:lbrace() elt:kvpair() comp:for_if_clauses() rbrace:rbrace() { Expression::DictComp(make_dict_comp(lbrace, elt, comp, rbrace)) } // Function call arguments - rule arguments() -> Vec> + rule arguments() -> Vec> = a:args() trail:comma()? &lit(")") {add_arguments_trailing_comma(a, trail)} - rule args() -> Vec> + rule args() -> Vec> = first:_posarg() rest:(c:comma() a:_posarg() {(c, a)})* kw:(c:comma() k:kwargs() {(c, k)})? { @@ -1198,11 +1197,11 @@ parser! { } / kwargs() - rule _posarg() -> Arg<'a> + rule _posarg() -> Arg<'input, 'a> = a:(starred_expression() / e:named_expression() { make_arg(e) }) !lit("=") { a } - rule kwargs() -> Vec> + rule kwargs() -> Vec> = sitems:separated(, ) scomma:comma() ditems:separated(, ) { @@ -1218,18 +1217,18 @@ parser! { comma_separate(items.0, items.1, None) } - rule starred_expression() -> Arg<'a> + rule starred_expression() -> Arg<'input, 'a> = star:lit("*") e:expression() { make_star_arg(star, e) } - rule kwarg_or_starred() -> Arg<'a> + rule kwarg_or_starred() -> Arg<'input, 'a> = _kwarg() / starred_expression() - rule kwarg_or_double_starred() -> Arg<'a> + rule kwarg_or_double_starred() -> Arg<'input, 'a> = _kwarg() / star:lit("**") e:expression() { make_star_arg(star, e) } - rule _kwarg() -> Arg<'a> + rule _kwarg() -> Arg<'input, 'a> = n:name() eq:lit("=") v:expression() { make_kwarg(n, eq, v) } @@ -1237,7 +1236,7 @@ parser! { // Assignment targets // Generic targets - rule star_targets() -> AssignTargetExpression<'a> + rule star_targets() -> AssignTargetExpression<'input, 'a> = a:star_target() !lit(",") {a} / targets:separated_trailer(, ) { AssignTargetExpression::Tuple( @@ -1245,14 +1244,14 @@ parser! { ) } - rule star_targets_list_seq() -> Vec> + rule star_targets_list_seq() -> Vec> = targets:separated_trailer(, ) { comma_separate(targets.0, targets.1, targets.2) } // This differs from star_targets below because it requires at least two items // in the tuple - rule star_targets_tuple_seq() -> Tuple<'a> + rule star_targets_tuple_seq() -> Tuple<'input, 'a> = first:(t:star_target() {assign_target_to_element(t)}) rest:(c:comma() t:star_target() {(c, assign_target_to_element(t))})+ trail:comma()? { @@ -1263,7 +1262,7 @@ parser! { } #[cache] - rule star_target() -> AssignTargetExpression<'a> + rule star_target() -> AssignTargetExpression<'input, 'a> = star:lit("*") !lit("*") t:star_target() { AssignTargetExpression::StarredElement( make_starred_element(star, assign_target_to_element(t)) @@ -1272,7 +1271,7 @@ parser! { / target_with_star_atom() #[cache] - rule target_with_star_atom() -> AssignTargetExpression<'a> + rule target_with_star_atom() -> AssignTargetExpression<'input, 'a> = a:t_primary() dot:lit(".") n:name() !t_lookahead() { AssignTargetExpression::Attribute(make_attribute(a, dot, n)) } @@ -1283,7 +1282,7 @@ parser! { } / a:star_atom() {a} - rule star_atom() -> AssignTargetExpression<'a> + rule star_atom() -> AssignTargetExpression<'input, 'a> = a:name() { AssignTargetExpression::Name(a) } / lpar:lpar() a:target_with_star_atom() rpar:rpar() { a.with_parens(lpar, rpar) } / lpar:lpar() a:star_targets_tuple_seq()? rpar:rpar() { @@ -1297,12 +1296,12 @@ parser! { ) } - rule single_target() -> AssignTargetExpression<'a> + rule single_target() -> AssignTargetExpression<'input, 'a> = single_subscript_attribute_target() / n:name() { AssignTargetExpression::Name(n) } / lpar:lpar() t:single_target() rpar:rpar() { t.with_parens(lpar, rpar) } - rule single_subscript_attribute_target() -> AssignTargetExpression<'a> + rule single_subscript_attribute_target() -> AssignTargetExpression<'input, 'a> = a:t_primary() dot:lit(".") n:name() !t_lookahead() { AssignTargetExpression::Attribute(make_attribute(a, dot, n)) } @@ -1314,7 +1313,7 @@ parser! { #[cache_left_rec] - rule t_primary() -> Expression<'a> + rule t_primary() -> Expression<'input, 'a> = value:t_primary() dot:lit(".") attr:name() &t_lookahead() { Expression::Attribute(make_attribute(value, dot, attr)) } @@ -1334,12 +1333,12 @@ parser! { // Targets for del statements - rule del_targets() -> Vec> + rule del_targets() -> Vec> = t:separated_trailer(, ) { comma_separate(t.0, t.1, t.2) } - rule del_target() -> DelTargetExpression<'a> + rule del_target() -> DelTargetExpression<'input, 'a> = a:t_primary() d:lit(".") n:name() !t_lookahead() { DelTargetExpression::Attribute(make_attribute(a, d, n)) } @@ -1350,7 +1349,7 @@ parser! { } / del_t_atom() - rule del_t_atom() -> DelTargetExpression<'a> + rule del_t_atom() -> DelTargetExpression<'input, 'a> = n:name() { DelTargetExpression::Name(n) } / l:lpar() d:del_target() r:rpar() { d.with_parens(l, r) } / l:lpar() d:del_targets()? r:rpar() { @@ -1364,79 +1363,80 @@ parser! { // F-strings - rule fstring() -> FormattedString<'a> + rule fstring() -> FormattedString<'input, 'a> = start:tok(FStringStart, "f\"") parts:(_f_string() / _f_replacement())* end:tok(FStringEnd, "\"") { make_fstring(start.string, parts, end.string) } - rule _f_string() -> FormattedStringContent<'a> + rule _f_string() -> FormattedStringContent<'input, 'a> = t:tok(FStringString, "f-string contents") { FormattedStringContent::Text(FormattedStringText { value: t.string }) } - rule _f_replacement() -> FormattedStringContent<'a> - = lb:lit("{") e:_f_expr() eq:lit("=")? - conv:(t:lit("!") c:_f_conversion() {(t,c)})? - spec:(t:lit(":") s:_f_spec() {(t,s)})? - rb:lit("}") { - FormattedStringContent::Expression( - make_fstring_expression(lb, e, eq, conv, spec, rb) - ) - } + rule _f_replacement() -> FormattedStringContent<'input, 'a> + // = lb:lit("{") e:_f_expr() eq:lit("=")? + // conv:(t:lit("!") c:_f_conversion() {(t,c)})? + // spec:(t:lit(":") s:_f_spec() {(t,s)})? + // rb:lit("}") { + // FormattedStringContent::Expression( + // make_fstring_expression(lb, e, eq, conv, spec, rb) + // ) + // } + = _ {? Err("foo") } - rule _f_expr() -> Expression<'a> + rule _f_expr() -> Expression<'input, 'a> = (g:_bare_genexp() {Expression::GeneratorExp(g)}) / _conditional_expression() / yield_expr() - rule _f_conversion() -> &'a str + rule _f_conversion() -> &'input str = lit("r") {"r"} / lit("s") {"s"} / lit("a") {"a"} - rule _f_spec() -> Vec> + rule _f_spec() -> Vec> = (_f_string() / _f_replacement())* // CST helpers - rule comma() -> Comma<'a> + rule comma() -> Comma<'input, 'a> = c:lit(",") { make_comma(c) } - rule dots() -> Vec> + rule dots() -> Vec> = ds:((dot:lit(".") { make_dot(dot) })+ / tok:lit("...") { - vec![make_dot(tok.clone()), make_dot(tok.clone()), make_dot(tok.clone())]} + vec![make_dot(&tok), make_dot(&tok), make_dot(&tok)]} )+ { ds.into_iter().flatten().collect() } - rule lpar() -> LeftParen<'a> + rule lpar() -> LeftParen<'input, 'a> = a:lit("(") { make_lpar(a) } - rule rpar() -> RightParen<'a> + rule rpar() -> RightParen<'input, 'a> = a:lit(")") { make_rpar(a) } - rule lbrak() -> LeftSquareBracket<'a> + rule lbrak() -> LeftSquareBracket<'input, 'a> = tok:lit("[") { make_left_bracket(tok) } - rule rbrak() -> RightSquareBracket<'a> + rule rbrak() -> RightSquareBracket<'input, 'a> = tok:lit("]") { make_right_bracket(tok) } - rule lbrace() -> LeftCurlyBrace<'a> + rule lbrace() -> LeftCurlyBrace<'input, 'a> = tok:lit("{") { make_left_brace(tok) } - rule rbrace() -> RightCurlyBrace<'a> + rule rbrace() -> RightCurlyBrace<'input, 'a> = tok:lit("}") { make_right_brace(tok) } /// matches any token, not just whitespace - rule _() -> TokenRef<'a> - = [t] { t } + rule _() -> TokenRef<'input, 'a> + = t:[_] { t } - rule lit(lit: &'static str) -> TokenRef<'a> + rule lit(lit: &'static str) -> TokenRef<'input, 'a> = [t] {? if t.string == lit { Ok(t) } else { Err(lit) } } - rule tok(tok: TokType, err: &'static str) -> TokenRef<'a> + rule tok(tok: TokType, err: &'static str) -> TokenRef<'input, 'a> = [t] {? if t.r#type == tok { Ok(t) } else { Err(err) } } - rule name() -> Name<'a> + rule name() -> Name<'input, 'a> = !( lit("False") / lit("None") / lit("True") / lit("and") / lit("as") / lit("assert") / lit("async") / lit("await") / lit("break") / lit("class") / lit("continue") / lit("def") / lit("del") / lit("elif") / lit("else") / lit("except") / lit("finally") / lit("for") / lit("from") / lit("global") / lit("if") / lit("import") @@ -1445,7 +1445,7 @@ parser! { ) t:tok(NameTok, "NAME") {make_name(t)} - rule _async() -> TokenRef<'a> + rule _async() -> TokenRef<'input, 'a> = tok(Async, "ASYNC") rule separated_trailer(el: rule, sep: rule) -> (El, Vec<(Sep, El)>, Option) @@ -1473,17 +1473,17 @@ parser! { } #[allow(clippy::too_many_arguments)] -fn make_function_def<'a>( - async_tok: Option>, - def_tok: TokenRef<'a>, - name: Name<'a>, - open_paren_tok: TokenRef<'a>, - params: Option>, - close_paren_tok: TokenRef<'a>, - returns: Option>, - colon_tok: TokenRef<'a>, - body: Suite<'a>, -) -> FunctionDef<'a> { +fn make_function_def<'r, 'a>( + async_tok: Option>, + def_tok: TokenRef<'r, 'a>, + name: Name<'r, 'a>, + open_paren_tok: TokenRef<'r, 'a>, + params: Option>, + close_paren_tok: TokenRef<'r, 'a>, + returns: Option>, + colon_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, +) -> FunctionDef<'r, 'a> { let asynchronous = async_tok.as_ref().map(|_| Asynchronous { whitespace_after: Default::default(), }); @@ -1508,11 +1508,11 @@ fn make_function_def<'a>( } } -fn make_decorator<'a>( - at_tok: TokenRef<'a>, - name: Expression<'a>, - newline_tok: TokenRef<'a>, -) -> Decorator<'a> { +fn make_decorator<'r, 'a>( + at_tok: TokenRef<'r, 'a>, + name: Expression<'r, 'a>, + newline_tok: TokenRef<'r, 'a>, +) -> Decorator<'r, 'a> { Decorator { decorator: name, leading_lines: Default::default(), @@ -1523,10 +1523,10 @@ fn make_decorator<'a>( } } -fn make_comparison<'a>( - head: Expression<'a>, - tail: Vec<(CompOp<'a>, Expression<'a>)>, -) -> Expression<'a> { +fn make_comparison<'r, 'a>( + head: Expression<'r, 'a>, + tail: Vec<(CompOp<'r, 'a>, Expression<'r, 'a>)>, +) -> Expression<'r, 'a> { let mut comparisons = vec![]; for (operator, e) in tail { comparisons.push(ComparisonTarget { @@ -1542,7 +1542,7 @@ fn make_comparison<'a>( }) } -fn make_comparison_operator(tok: TokenRef) -> Result { +fn make_comparison_operator<'r, 'a>(tok: TokenRef<'r, 'a>) -> Result<'a, CompOp<'r, 'a>> { let whitespace_before = Default::default(); let whitespace_after = Default::default(); match tok.string { @@ -1590,10 +1590,10 @@ fn make_comparison_operator(tok: TokenRef) -> Result { } } -fn make_comparison_operator_2<'a>( - first: TokenRef<'a>, - second: TokenRef<'a>, -) -> Result<'a, CompOp<'a>> { +fn make_comparison_operator_2<'r, 'a>( + first: TokenRef<'r, 'a>, + second: TokenRef<'r, 'a>, +) -> Result<'a, CompOp<'r, 'a>> { let whitespace_before = Default::default(); let whitespace_between = Default::default(); let whitespace_after = Default::default(); @@ -1617,10 +1617,10 @@ fn make_comparison_operator_2<'a>( } } -fn make_boolean_op<'a>( - head: Expression<'a>, - tail: Vec<(TokenRef<'a>, Expression<'a>)>, -) -> Result<'a, Expression<'a>> { +fn make_boolean_op<'r, 'a>( + head: Expression<'r, 'a>, + tail: Vec<(TokenRef<'r, 'a>, Expression<'r, 'a>)>, +) -> Result<'a, Expression<'r, 'a>> { if tail.is_empty() { return Ok(head); } @@ -1638,7 +1638,7 @@ fn make_boolean_op<'a>( Ok(expr) } -fn make_boolean_operator(tok: TokenRef) -> Result { +fn make_boolean_operator<'r, 'a>(tok: TokenRef<'r, 'a>) -> Result<'a, BooleanOp<'r, 'a>> { let whitespace_before = Default::default(); let whitespace_after = Default::default(); match tok.string { @@ -1656,11 +1656,11 @@ fn make_boolean_operator(tok: TokenRef) -> Result { } } -fn make_binary_op<'a>( - left: Expression<'a>, - op: TokenRef<'a>, - right: Expression<'a>, -) -> Result<'a, Expression<'a>> { +fn make_binary_op<'r, 'a>( + left: Expression<'r, 'a>, + op: TokenRef<'r, 'a>, + right: Expression<'r, 'a>, +) -> Result<'a, Expression<'r, 'a>> { let operator = make_binary_operator(op)?; Ok(Expression::BinaryOperation(BinaryOperation { left: Box::new(left), @@ -1671,7 +1671,7 @@ fn make_binary_op<'a>( })) } -fn make_binary_operator(tok: TokenRef) -> Result { +fn make_binary_operator<'r, 'a>(tok: TokenRef<'r, 'a>) -> Result<'a, BinaryOp<'r, 'a>> { let whitespace_before = Default::default(); let whitespace_after = Default::default(); @@ -1745,7 +1745,10 @@ fn make_binary_operator(tok: TokenRef) -> Result { } } -fn make_unary_op<'a>(op: TokenRef<'a>, tail: Expression<'a>) -> Result<'a, Expression<'a>> { +fn make_unary_op<'r, 'a>( + op: TokenRef<'r, 'a>, + tail: Expression<'r, 'a>, +) -> Result<'a, Expression<'r, 'a>> { let operator = make_unary_operator(op)?; Ok(Expression::UnaryOperation(UnaryOperation { operator, @@ -1755,7 +1758,7 @@ fn make_unary_op<'a>(op: TokenRef<'a>, tail: Expression<'a>) -> Result<'a, Expre })) } -fn make_unary_operator(tok: TokenRef) -> Result { +fn make_unary_operator<'r, 'a>(tok: TokenRef<'r, 'a>) -> Result<'a, UnaryOp<'r, 'a>> { let whitespace_after = Default::default(); match tok.string { "+" => Ok(UnaryOp::Plus { @@ -1778,16 +1781,16 @@ fn make_unary_operator(tok: TokenRef) -> Result { } } -fn make_number(num: TokenRef) -> Expression { +fn make_number<'r, 'a>(num: TokenRef<'r, 'a>) -> Expression<'r, 'a> { super::numbers::parse_number(num.string) } -fn make_indented_block<'a>( - nl: TokenRef<'a>, - indent: TokenRef<'a>, - statements: Vec>, - dedent: TokenRef<'a>, -) -> Suite<'a> { +fn make_indented_block<'r, 'a>( + nl: TokenRef<'r, 'a>, + indent: TokenRef<'r, 'a>, + statements: Vec>, + dedent: TokenRef<'r, 'a>, +) -> Suite<'r, 'a> { Suite::IndentedBlock(IndentedBlock { body: statements, header: Default::default(), @@ -1799,15 +1802,15 @@ fn make_indented_block<'a>( }) } -struct SimpleStatementParts<'a> { - first_tok: TokenRef<'a>, // The first token of the first statement. Used for its whitespace - first_statement: SmallStatement<'a>, - rest: Vec<(TokenRef<'a>, SmallStatement<'a>)>, // semicolon, statement pairs - last_semi: Option>, - nl: TokenRef<'a>, +struct SimpleStatementParts<'r, 'a> { + first_tok: TokenRef<'r, 'a>, // The first token of the first statement. Used for its whitespace + first_statement: SmallStatement<'r, 'a>, + rest: Vec<(TokenRef<'r, 'a>, SmallStatement<'r, 'a>)>, // semicolon, statement pairs + last_semi: Option>, + nl: TokenRef<'r, 'a>, } -fn make_semicolon(tok: TokenRef) -> Semicolon { +fn make_semicolon<'r, 'a>(tok: TokenRef<'r, 'a>) -> SemicolonTokens<'r, 'a> { Semicolon { whitespace_before: Default::default(), whitespace_after: Default::default(), @@ -1815,9 +1818,13 @@ fn make_semicolon(tok: TokenRef) -> Semicolon { } } -fn _make_simple_statement( - parts: SimpleStatementParts, -) -> (TokenRef, Vec, TokenRef) { +fn _make_simple_statement<'r, 'a>( + parts: SimpleStatementParts<'r, 'a>, +) -> ( + TokenRef<'r, 'a>, + Vec>, + TokenRef<'r, 'a>, +) { let mut body = vec![]; let mut current = parts.first_statement; @@ -1833,7 +1840,7 @@ fn _make_simple_statement( (parts.first_tok, body, parts.nl) } -fn make_simple_statement_suite(parts: SimpleStatementParts) -> Suite { +fn make_simple_statement_suite<'r, 'a>(parts: SimpleStatementParts<'r, 'a>) -> Suite<'r, 'a> { let (first_tok, body, newline_tok) = _make_simple_statement(parts); Suite::SimpleStatementSuite(SimpleStatementSuite { @@ -1845,7 +1852,9 @@ fn make_simple_statement_suite(parts: SimpleStatementParts) -> Suite { }) } -fn make_simple_statement_line(parts: SimpleStatementParts) -> SimpleStatementLine { +fn make_simple_statement_line<'r, 'a>( + parts: SimpleStatementParts<'r, 'a>, +) -> SimpleStatementLine<'r, 'a> { let (first_tok, body, newline_tok) = _make_simple_statement(parts); SimpleStatementLine { body, @@ -1856,14 +1865,14 @@ fn make_simple_statement_line(parts: SimpleStatementParts) -> SimpleStatementLin } } -fn make_if<'a>( - if_tok: TokenRef<'a>, - cond: Expression<'a>, - colon_tok: TokenRef<'a>, - block: Suite<'a>, - orelse: Option>, +fn make_if<'r, 'a>( + if_tok: TokenRef<'r, 'a>, + cond: Expression<'r, 'a>, + colon_tok: TokenRef<'r, 'a>, + block: Suite<'r, 'a>, + orelse: Option>, is_elif: bool, -) -> If<'a> { +) -> If<'r, 'a> { If { leading_lines: Default::default(), whitespace_before_test: Default::default(), @@ -1877,7 +1886,11 @@ fn make_if<'a>( } } -fn make_else<'a>(else_tok: TokenRef<'a>, colon_tok: TokenRef<'a>, block: Suite<'a>) -> Else<'a> { +fn make_else<'r, 'a>( + else_tok: TokenRef<'r, 'a>, + colon_tok: TokenRef<'r, 'a>, + block: Suite<'r, 'a>, +) -> Else<'r, 'a> { Else { leading_lines: Default::default(), whitespace_before_colon: Default::default(), @@ -1887,13 +1900,17 @@ fn make_else<'a>(else_tok: TokenRef<'a>, colon_tok: TokenRef<'a>, block: Suite<' } } -struct StarEtc<'a>(Option>, Vec>, Option>); +struct StarEtc<'r, 'a>( + Option>, + Vec>, + Option>, +); -fn make_parameters<'a>( - posonly: Option<(Vec>, ParamSlash<'a>)>, - params: Vec>, - star_etc: Option>, -) -> Parameters<'a> { +fn make_parameters<'r, 'a>( + posonly: Option<(Vec>, ParamSlash<'r, 'a>)>, + params: Vec>, + star_etc: Option>, +) -> Parameters<'r, 'a> { let (posonly_params, posonly_ind) = match posonly { Some((a, b)) => (a, Some(b)), None => (vec![], None), @@ -1912,11 +1929,11 @@ fn make_parameters<'a>( } } -fn add_param_default<'a>( - param: Param<'a>, - def: Option<(AssignEqual<'a>, Expression<'a>)>, - comma_tok: Option>, -) -> Param<'a> { +fn add_param_default<'r, 'a>( + param: Param<'r, 'a>, + def: Option<(AssignEqual<'r, 'a>, Expression<'r, 'a>)>, + comma_tok: Option>, +) -> Param<'r, 'a> { let comma = comma_tok.map(make_comma); let (equal, default) = match def { @@ -1931,7 +1948,7 @@ fn add_param_default<'a>( } } -fn add_param_star<'a>(param: Param<'a>, star: TokenRef<'a>) -> Param<'a> { +fn add_param_star<'r, 'a>(param: Param<'r, 'a>, star: TokenRef<'r, 'a>) -> Param<'r, 'a> { let str = star.string; Param { star: Some(str), @@ -1940,7 +1957,7 @@ fn add_param_star<'a>(param: Param<'a>, star: TokenRef<'a>) -> Param<'a> { } } -fn make_assign_equal(tok: TokenRef) -> AssignEqual { +fn make_assign_equal<'r, 'a>(tok: TokenRef<'r, 'a>) -> AssignEqual<'r, 'a> { AssignEqual { whitespace_before: Default::default(), whitespace_after: Default::default(), @@ -1948,7 +1965,7 @@ fn make_assign_equal(tok: TokenRef) -> AssignEqual { } } -fn make_comma(tok: TokenRef) -> Comma { +fn make_comma<'r, 'a>(tok: TokenRef<'r, 'a>) -> Comma<'r, 'a> { Comma { whitespace_before: Default::default(), whitespace_after: Default::default(), @@ -1960,10 +1977,10 @@ fn concat(a: Vec, b: Vec) -> Vec { a.into_iter().chain(b.into_iter()).collect() } -fn make_name_or_attr<'a>( - first_tok: Name<'a>, - mut tail: Vec<(TokenRef<'a>, Name<'a>)>, -) -> NameOrAttribute<'a> { +fn make_name_or_attr<'r, 'a>( + first_tok: Name<'r, 'a>, + mut tail: Vec<(TokenRef<'r, 'a>, Name<'r, 'a>)>, +) -> NameOrAttribute<'r, 'a> { if let Some((dot, name)) = tail.pop() { let dot = make_dot(dot); return NameOrAttribute::A(Attribute { @@ -1978,14 +1995,14 @@ fn make_name_or_attr<'a>( } } -fn make_name(tok: TokenRef) -> Name { +fn make_name<'r, 'a>(tok: TokenRef<'r, 'a>) -> Name<'r, 'a> { Name { value: tok.string, ..Default::default() } } -fn make_dot(tok: TokenRef) -> Dot { +fn make_dot<'r, 'a>(tok: TokenRef<'r, 'a>) -> Dot<'r, 'a> { Dot { whitespace_before: Default::default(), whitespace_after: Default::default(), @@ -1993,10 +2010,10 @@ fn make_dot(tok: TokenRef) -> Dot { } } -fn make_import_alias<'a>( - name: NameOrAttribute<'a>, - asname: Option<(TokenRef<'a>, Name<'a>)>, -) -> ImportAlias<'a> { +fn make_import_alias<'r, 'a>( + name: NameOrAttribute<'r, 'a>, + asname: Option<(TokenRef<'r, 'a>, Name<'r, 'a>)>, +) -> ImportAlias<'r, 'a> { ImportAlias { name, asname: asname.map(|(x, y)| make_as_name(x, AssignTargetExpression::Name(y))), @@ -2004,7 +2021,10 @@ fn make_import_alias<'a>( } } -fn make_as_name<'a>(as_tok: TokenRef<'a>, name: AssignTargetExpression<'a>) -> AsName<'a> { +fn make_as_name<'r, 'a>( + as_tok: TokenRef<'r, 'a>, + name: AssignTargetExpression<'r, 'a>, +) -> AsName<'r, 'a> { AsName { name, whitespace_before_as: Default::default(), @@ -2013,19 +2033,19 @@ fn make_as_name<'a>(as_tok: TokenRef<'a>, name: AssignTargetExpression<'a>) -> A } } -type ParenthesizedImportNames<'a> = ( - Option>, - ImportNames<'a>, - Option>, +type ParenthesizedImportNames<'r, 'a> = ( + Option>, + ImportNames<'r, 'a>, + Option>, ); -fn make_import_from<'a>( - from_tok: TokenRef<'a>, - dots: Vec>, - module: Option>, - import_tok: TokenRef<'a>, - aliases: ParenthesizedImportNames<'a>, -) -> ImportFrom<'a> { +fn make_import_from<'r, 'a>( + from_tok: TokenRef<'r, 'a>, + dots: Vec>, + module: Option>, + import_tok: TokenRef<'r, 'a>, + aliases: ParenthesizedImportNames<'r, 'a>, +) -> ImportFrom<'r, 'a> { let (lpar, names, rpar) = aliases; ImportFrom { @@ -2043,7 +2063,10 @@ fn make_import_from<'a>( } } -fn make_import<'a>(import_tok: TokenRef<'a>, names: Vec>) -> Import<'a> { +fn make_import<'r, 'a>( + import_tok: TokenRef<'r, 'a>, + names: Vec>, +) -> Import<'r, 'a> { Import { names, whitespace_after_import: Default::default(), @@ -2052,10 +2075,10 @@ fn make_import<'a>(import_tok: TokenRef<'a>, names: Vec>) -> Imp } } -fn make_import_from_as_names<'a>( - first: ImportAlias<'a>, - tail: Vec<(Comma<'a>, ImportAlias<'a>)>, -) -> Vec> { +fn make_import_from_as_names<'r, 'a>( + first: ImportAlias<'r, 'a>, + tail: Vec<(Comma<'r, 'a>, ImportAlias<'r, 'a>)>, +) -> Vec> { let mut ret = vec![]; let mut cur = first; for (comma, alias) in tail { @@ -2066,21 +2089,25 @@ fn make_import_from_as_names<'a>( ret } -fn make_lpar(tok: TokenRef) -> LeftParen { +fn make_lpar<'r, 'a>(tok: TokenRef<'r, 'a>) -> LeftParen<'r, 'a> { LeftParen { whitespace_after: Default::default(), lpar_tok: tok, } } -fn make_rpar(tok: TokenRef) -> RightParen { +fn make_rpar<'r, 'a>(tok: TokenRef<'r, 'a>) -> RightParen<'r, 'a> { RightParen { whitespace_before: Default::default(), rpar_tok: tok, } } -fn make_module<'a>(body: Vec>, tok: TokenRef<'a>, encoding: &str) -> Module<'a> { +fn make_module<'r, 'a>( + body: Vec>, + tok: TokenRef<'r, 'a>, + encoding: &str, +) -> Module<'r, 'a> { Module { body, header: Default::default(), @@ -2093,7 +2120,11 @@ fn make_module<'a>(body: Vec>, tok: TokenRef<'a>, encoding: &str) } } -fn make_attribute<'a>(value: Expression<'a>, dot: TokenRef<'a>, attr: Name<'a>) -> Attribute<'a> { +fn make_attribute<'r, 'a>( + value: Expression<'r, 'a>, + dot: TokenRef<'r, 'a>, + attr: Name<'r, 'a>, +) -> Attribute<'r, 'a> { let dot = make_dot(dot); Attribute { attr, @@ -2104,7 +2135,10 @@ fn make_attribute<'a>(value: Expression<'a>, dot: TokenRef<'a>, attr: Name<'a>) } } -fn make_starred_element<'a>(star_tok: TokenRef<'a>, rest: Element<'a>) -> StarredElement<'a> { +fn make_starred_element<'r, 'a>( + star_tok: TokenRef<'r, 'a>, + rest: Element<'r, 'a>, +) -> StarredElement<'r, 'a> { let value = match rest { Element::Simple { value, .. } => value, _ => panic!("Internal error while making starred element"), @@ -2119,7 +2153,7 @@ fn make_starred_element<'a>(star_tok: TokenRef<'a>, rest: Element<'a>) -> Starre } } -fn assign_target_to_element(expr: AssignTargetExpression) -> Element { +fn assign_target_to_element<'r, 'a>(expr: AssignTargetExpression<'r, 'a>) -> Element<'r, 'a> { match expr { AssignTargetExpression::Attribute(a) => Element::Simple { value: Expression::Attribute(a), @@ -2145,10 +2179,10 @@ fn assign_target_to_element(expr: AssignTargetExpression) -> Element { } } -fn make_assignment<'a>( - lhs: Vec<(AssignTargetExpression<'a>, TokenRef<'a>)>, - rhs: Expression<'a>, -) -> Assign<'a> { +fn make_assignment<'r, 'a>( + lhs: Vec<(AssignTargetExpression<'r, 'a>, TokenRef<'r, 'a>)>, + rhs: Expression<'r, 'a>, +) -> Assign<'r, 'a> { let mut targets = vec![]; for (target, equal_tok) in lhs { targets.push(AssignTarget { @@ -2165,20 +2199,20 @@ fn make_assignment<'a>( } } -fn expr_to_element(expr: Expression) -> Element { +fn expr_to_element<'r, 'a>(expr: Expression<'r, 'a>) -> Element<'r, 'a> { Element::Simple { value: expr, comma: Default::default(), } } -fn make_tuple<'a>( - first: Element<'a>, - rest: Vec<(Comma<'a>, Element<'a>)>, - trailing_comma: Option>, - lpar: Option>, - rpar: Option>, -) -> Tuple<'a> { +fn make_tuple<'r, 'a>( + first: Element<'r, 'a>, + rest: Vec<(Comma<'r, 'a>, Element<'r, 'a>)>, + trailing_comma: Option>, + lpar: Option>, + rpar: Option>, +) -> Tuple<'r, 'a> { let elements = comma_separate(first, rest, trailing_comma); let lpar = lpar.map(|l| vec![l]).unwrap_or_default(); @@ -2191,7 +2225,10 @@ fn make_tuple<'a>( } } -fn make_tuple_from_elements<'a>(first: Element<'a>, mut rest: Vec>) -> Tuple<'a> { +fn make_tuple_from_elements<'r, 'a>( + first: Element<'r, 'a>, + mut rest: Vec>, +) -> Tuple<'r, 'a> { rest.insert(0, first); Tuple { elements: rest, @@ -2200,7 +2237,11 @@ fn make_tuple_from_elements<'a>(first: Element<'a>, mut rest: Vec>) } } -fn make_kwarg<'a>(name: Name<'a>, eq: TokenRef<'a>, value: Expression<'a>) -> Arg<'a> { +fn make_kwarg<'r, 'a>( + name: Name<'r, 'a>, + eq: TokenRef<'r, 'a>, + value: Expression<'r, 'a>, +) -> Arg<'r, 'a> { let equal = Some(make_assign_equal(eq)); let keyword = Some(name); Arg { @@ -2215,7 +2256,7 @@ fn make_kwarg<'a>(name: Name<'a>, eq: TokenRef<'a>, value: Expression<'a>) -> Ar } } -fn make_star_arg<'a>(star: TokenRef<'a>, expr: Expression<'a>) -> Arg<'a> { +fn make_star_arg<'r, 'a>(star: TokenRef<'r, 'a>, expr: Expression<'r, 'a>) -> Arg<'r, 'a> { let str = star.string; Arg { value: expr, @@ -2229,12 +2270,12 @@ fn make_star_arg<'a>(star: TokenRef<'a>, expr: Expression<'a>) -> Arg<'a> { } } -fn make_call<'a>( - func: Expression<'a>, - lpar_tok: TokenRef<'a>, - args: Vec>, - rpar_tok: TokenRef<'a>, -) -> Call<'a> { +fn make_call<'r, 'a>( + func: Expression<'r, 'a>, + lpar_tok: TokenRef<'r, 'a>, + args: Vec>, + rpar_tok: TokenRef<'r, 'a>, +) -> Call<'r, 'a> { let lpar = vec![]; let rpar = vec![]; let func = Box::new(func); @@ -2251,7 +2292,10 @@ fn make_call<'a>( } } -fn make_genexp_call<'a>(func: Expression<'a>, mut genexp: GeneratorExp<'a>) -> Call<'a> { +fn make_genexp_call<'r, 'a>( + func: Expression<'r, 'a>, + mut genexp: GeneratorExp<'r, 'a>, +) -> Call<'r, 'a> { // func ( (genexp) ) // ^ // lpar_tok @@ -2287,7 +2331,7 @@ fn make_genexp_call<'a>(func: Expression<'a>, mut genexp: GeneratorExp<'a>) -> C } } -fn make_arg(expr: Expression) -> Arg { +fn make_arg<'r, 'a>(expr: Expression<'r, 'a>) -> Arg<'r, 'a> { Arg { value: expr, keyword: Default::default(), @@ -2300,7 +2344,7 @@ fn make_arg(expr: Expression) -> Arg { } } -fn make_comp_if<'a>(if_tok: TokenRef<'a>, test: Expression<'a>) -> CompIf<'a> { +fn make_comp_if<'r, 'a>(if_tok: TokenRef<'r, 'a>, test: Expression<'r, 'a>) -> CompIf<'r, 'a> { CompIf { test, whitespace_before: Default::default(), @@ -2309,14 +2353,14 @@ fn make_comp_if<'a>(if_tok: TokenRef<'a>, test: Expression<'a>) -> CompIf<'a> { } } -fn make_for_if<'a>( - async_tok: Option>, - for_tok: TokenRef<'a>, - target: AssignTargetExpression<'a>, - in_tok: TokenRef<'a>, - iter: Expression<'a>, - ifs: Vec>, -) -> CompFor<'a> { +fn make_for_if<'r, 'a>( + async_tok: Option>, + for_tok: TokenRef<'r, 'a>, + target: AssignTargetExpression<'r, 'a>, + in_tok: TokenRef<'r, 'a>, + iter: Expression<'r, 'a>, + ifs: Vec>, +) -> CompFor<'r, 'a> { let inner_for_in = None; let asynchronous = async_tok.as_ref().map(|_| Asynchronous { whitespace_after: Default::default(), @@ -2338,7 +2382,10 @@ fn make_for_if<'a>( } } -fn make_bare_genexp<'a>(elt: Expression<'a>, for_in: CompFor<'a>) -> GeneratorExp<'a> { +fn make_bare_genexp<'r, 'a>( + elt: Expression<'r, 'a>, + for_in: CompFor<'r, 'a>, +) -> GeneratorExp<'r, 'a> { GeneratorExp { elt: Box::new(elt), for_in: Box::new(for_in), @@ -2347,7 +2394,7 @@ fn make_bare_genexp<'a>(elt: Expression<'a>, for_in: CompFor<'a>) -> GeneratorEx } } -fn merge_comp_fors(comp_fors: Vec) -> CompFor { +fn merge_comp_fors<'r, 'a>(comp_fors: Vec>) -> CompFor<'r, 'a> { let mut it = comp_fors.into_iter().rev(); let first = it.next().expect("cant merge empty comp_fors"); @@ -2357,40 +2404,40 @@ fn merge_comp_fors(comp_fors: Vec) -> CompFor { }) } -fn make_left_bracket(tok: TokenRef) -> LeftSquareBracket { +fn make_left_bracket<'r, 'a>(tok: TokenRef<'r, 'a>) -> LeftSquareBracket<'r, 'a> { LeftSquareBracket { whitespace_after: Default::default(), tok, } } -fn make_right_bracket(tok: TokenRef) -> RightSquareBracket { +fn make_right_bracket<'r, 'a>(tok: TokenRef<'r, 'a>) -> RightSquareBracket<'r, 'a> { RightSquareBracket { whitespace_before: Default::default(), tok, } } -fn make_left_brace(tok: TokenRef) -> LeftCurlyBrace { +fn make_left_brace<'r, 'a>(tok: TokenRef<'r, 'a>) -> LeftCurlyBrace<'r, 'a> { LeftCurlyBrace { whitespace_after: Default::default(), tok, } } -fn make_right_brace(tok: TokenRef) -> RightCurlyBrace { +fn make_right_brace<'r, 'a>(tok: TokenRef<'r, 'a>) -> RightCurlyBrace<'r, 'a> { RightCurlyBrace { whitespace_before: Default::default(), tok, } } -fn make_list_comp<'a>( - lbracket: LeftSquareBracket<'a>, - elt: Expression<'a>, - for_in: CompFor<'a>, - rbracket: RightSquareBracket<'a>, -) -> ListComp<'a> { +fn make_list_comp<'r, 'a>( + lbracket: LeftSquareBracket<'r, 'a>, + elt: Expression<'r, 'a>, + for_in: CompFor<'r, 'a>, + rbracket: RightSquareBracket<'r, 'a>, +) -> ListComp<'r, 'a> { ListComp { elt: Box::new(elt), for_in: Box::new(for_in), @@ -2401,12 +2448,12 @@ fn make_list_comp<'a>( } } -fn make_set_comp<'a>( - lbrace: LeftCurlyBrace<'a>, - elt: Expression<'a>, - for_in: CompFor<'a>, - rbrace: RightCurlyBrace<'a>, -) -> SetComp<'a> { +fn make_set_comp<'r, 'a>( + lbrace: LeftCurlyBrace<'r, 'a>, + elt: Expression<'r, 'a>, + for_in: CompFor<'r, 'a>, + rbrace: RightCurlyBrace<'r, 'a>, +) -> SetComp<'r, 'a> { SetComp { elt: Box::new(elt), for_in: Box::new(for_in), @@ -2417,12 +2464,12 @@ fn make_set_comp<'a>( } } -fn make_dict_comp<'a>( - lbrace: LeftCurlyBrace<'a>, - kvpair: (Expression<'a>, TokenRef<'a>, Expression<'a>), - for_in: CompFor<'a>, - rbrace: RightCurlyBrace<'a>, -) -> DictComp<'a> { +fn make_dict_comp<'r, 'a>( + lbrace: LeftCurlyBrace<'r, 'a>, + kvpair: (Expression<'r, 'a>, TokenRef<'r, 'a>, Expression<'r, 'a>), + for_in: CompFor<'r, 'a>, + rbrace: RightCurlyBrace<'r, 'a>, +) -> DictComp<'r, 'a> { let (key, colon_tok, value) = kvpair; DictComp { @@ -2439,11 +2486,11 @@ fn make_dict_comp<'a>( } } -fn make_list<'a>( - lbracket: LeftSquareBracket<'a>, - elements: Vec>, - rbracket: RightSquareBracket<'a>, -) -> List<'a> { +fn make_list<'r, 'a>( + lbracket: LeftSquareBracket<'r, 'a>, + elements: Vec>, + rbracket: RightSquareBracket<'r, 'a>, +) -> List<'r, 'a> { List { elements, lbracket, @@ -2453,11 +2500,11 @@ fn make_list<'a>( } } -fn make_set<'a>( - lbrace: LeftCurlyBrace<'a>, - elements: Vec>, - rbrace: RightCurlyBrace<'a>, -) -> Set<'a> { +fn make_set<'r, 'a>( + lbrace: LeftCurlyBrace<'r, 'a>, + elements: Vec>, + rbrace: RightCurlyBrace<'r, 'a>, +) -> Set<'r, 'a> { Set { elements, lbrace, @@ -2467,13 +2514,13 @@ fn make_set<'a>( } } -fn comma_separate<'a, T>( +fn comma_separate<'r, 'a, T>( first: T, - rest: Vec<(Comma<'a>, T)>, - trailing_comma: Option>, + rest: Vec<(Comma<'r, 'a>, T)>, + trailing_comma: Option>, ) -> Vec where - T: WithComma<'a>, + T: WithComma<'r, 'a>, { let mut elements = vec![]; let mut current = first; @@ -2488,11 +2535,11 @@ where elements } -fn make_dict<'a>( - lbrace: LeftCurlyBrace<'a>, - elements: Vec>, - rbrace: RightCurlyBrace<'a>, -) -> Dict<'a> { +fn make_dict<'r, 'a>( + lbrace: LeftCurlyBrace<'r, 'a>, + elements: Vec>, + rbrace: RightCurlyBrace<'r, 'a>, +) -> Dict<'r, 'a> { Dict { elements, lbrace, @@ -2502,11 +2549,11 @@ fn make_dict<'a>( } } -fn make_double_starred_keypairs<'a>( - first: DictElement<'a>, - rest: Vec<(Comma<'a>, DictElement<'a>)>, - trailing_comma: Option>, -) -> Vec> { +fn make_double_starred_keypairs<'r, 'a>( + first: DictElement<'r, 'a>, + rest: Vec<(Comma<'r, 'a>, DictElement<'r, 'a>)>, + trailing_comma: Option>, +) -> Vec> { let mut elements = vec![]; let mut current = first; for (comma, next) in rest { @@ -2522,7 +2569,9 @@ fn make_double_starred_keypairs<'a>( elements } -fn make_dict_element<'a>(el: (Expression<'a>, TokenRef<'a>, Expression<'a>)) -> DictElement<'a> { +fn make_dict_element<'r, 'a>( + el: (Expression<'r, 'a>, TokenRef<'r, 'a>, Expression<'r, 'a>), +) -> DictElement<'r, 'a> { let (key, colon_tok, value) = el; DictElement::Simple { key, @@ -2534,10 +2583,10 @@ fn make_dict_element<'a>(el: (Expression<'a>, TokenRef<'a>, Expression<'a>)) -> } } -fn make_double_starred_element<'a>( - star_tok: TokenRef<'a>, - value: Expression<'a>, -) -> StarredDictElement<'a> { +fn make_double_starred_element<'r, 'a>( + star_tok: TokenRef<'r, 'a>, + value: Expression<'r, 'a>, +) -> StarredDictElement<'r, 'a> { StarredDictElement { value, comma: Default::default(), @@ -2546,11 +2595,11 @@ fn make_double_starred_element<'a>( } } -fn make_index(value: Expression) -> BaseSlice { +fn make_index<'r, 'a>(value: Expression<'r, 'a>) -> BaseSlice<'r, 'a> { BaseSlice::Index(Index { value }) } -fn make_colon(tok: TokenRef) -> Colon { +fn make_colon<'r, 'a>(tok: TokenRef<'r, 'a>) -> Colon<'r, 'a> { let whitespace_before = Default::default(); let whitespace_after = Default::default(); Colon { @@ -2560,12 +2609,12 @@ fn make_colon(tok: TokenRef) -> Colon { } } -fn make_slice<'a>( - lower: Option>, - first_colon: TokenRef<'a>, - upper: Option>, - rest: Option<(TokenRef<'a>, Option>)>, -) -> BaseSlice<'a> { +fn make_slice<'r, 'a>( + lower: Option>, + first_colon: TokenRef<'r, 'a>, + upper: Option>, + rest: Option<(TokenRef<'r, 'a>, Option>)>, +) -> BaseSlice<'r, 'a> { let first_colon = make_colon(first_colon); let (second_colon, step) = if let Some((tok, step)) = rest { (Some(make_colon(tok)), step) @@ -2581,11 +2630,11 @@ fn make_slice<'a>( }) } -fn make_slices<'a>( - first: BaseSlice<'a>, - rest: Vec<(Comma<'a>, BaseSlice<'a>)>, - trailing_comma: Option>, -) -> Vec> { +fn make_slices<'r, 'a>( + first: BaseSlice<'r, 'a>, + rest: Vec<(Comma<'r, 'a>, BaseSlice<'r, 'a>)>, + trailing_comma: Option>, +) -> Vec> { let mut elements = vec![]; let mut current = first; for (comma, next) in rest { @@ -2602,13 +2651,13 @@ fn make_slices<'a>( elements } -fn make_subscript<'a>( - value: Expression<'a>, - lbracket: LeftSquareBracket<'a>, - slice: Vec>, - rbracket: RightSquareBracket<'a>, -) -> Subscript<'a> { - let lbracket_tok = lbracket.tok.clone(); +fn make_subscript<'r, 'a>( + value: Expression<'r, 'a>, + lbracket: LeftSquareBracket<'r, 'a>, + slice: Vec>, + rbracket: RightSquareBracket<'r, 'a>, +) -> Subscript<'r, 'a> { + let lbracket_tok = lbracket.tok; Subscript { value: Box::new(value), slice, @@ -2621,13 +2670,13 @@ fn make_subscript<'a>( } } -fn make_ifexp<'a>( - body: Expression<'a>, - if_tok: TokenRef<'a>, - test: Expression<'a>, - else_tok: TokenRef<'a>, - orelse: Expression<'a>, -) -> IfExp<'a> { +fn make_ifexp<'r, 'a>( + body: Expression<'r, 'a>, + if_tok: TokenRef<'r, 'a>, + test: Expression<'r, 'a>, + else_tok: TokenRef<'r, 'a>, + orelse: Expression<'r, 'a>, +) -> IfExp<'r, 'a> { IfExp { test: Box::new(test), body: Box::new(body), @@ -2643,10 +2692,10 @@ fn make_ifexp<'a>( } } -fn add_arguments_trailing_comma<'a>( - mut args: Vec>, - trailing_comma: Option>, -) -> Vec> { +fn add_arguments_trailing_comma<'r, 'a>( + mut args: Vec>, + trailing_comma: Option>, +) -> Vec> { if let Some(comma) = trailing_comma { let last = args.pop().unwrap(); args.push(last.with_comma(comma)); @@ -2654,12 +2703,12 @@ fn add_arguments_trailing_comma<'a>( args } -fn make_lambda<'a>( - lambda_tok: TokenRef<'a>, - params: Parameters<'a>, - colon_tok: TokenRef<'a>, - expr: Expression<'a>, -) -> Lambda<'a> { +fn make_lambda<'r, 'a>( + lambda_tok: TokenRef<'r, 'a>, + params: Parameters<'r, 'a>, + colon_tok: TokenRef<'r, 'a>, + expr: Expression<'r, 'a>, +) -> Lambda<'r, 'a> { let colon = make_colon(colon_tok); Lambda { params: Box::new(params), @@ -2672,7 +2721,7 @@ fn make_lambda<'a>( } } -fn make_annotation<'a>(tok: TokenRef<'a>, ann: Expression<'a>) -> Annotation<'a> { +fn make_annotation<'r, 'a>(tok: TokenRef<'r, 'a>, ann: Expression<'r, 'a>) -> Annotation<'r, 'a> { Annotation { annotation: ann, whitespace_before_indicator: Default::default(), @@ -2681,12 +2730,12 @@ fn make_annotation<'a>(tok: TokenRef<'a>, ann: Expression<'a>) -> Annotation<'a> } } -fn make_ann_assignment<'a>( - target: AssignTargetExpression<'a>, - col: TokenRef<'a>, - ann: Expression<'a>, - rhs: Option<(TokenRef<'a>, Expression<'a>)>, -) -> AnnAssign<'a> { +fn make_ann_assignment<'r, 'a>( + target: AssignTargetExpression<'r, 'a>, + col: TokenRef<'r, 'a>, + ann: Expression<'r, 'a>, + rhs: Option<(TokenRef<'r, 'a>, Expression<'r, 'a>)>, +) -> AnnAssign<'r, 'a> { let annotation = make_annotation(col, ann); let (eq, value) = rhs.map(|(x, y)| (Some(x), Some(y))).unwrap_or((None, None)); let equal = eq.map(make_assign_equal); @@ -2699,11 +2748,11 @@ fn make_ann_assignment<'a>( } } -fn make_yield<'a>( - yield_tok: TokenRef<'a>, - f: Option>, - e: Option>, -) -> Yield<'a> { +fn make_yield<'r, 'a>( + yield_tok: TokenRef<'r, 'a>, + f: Option>, + e: Option>, +) -> Yield<'r, 'a> { let value = match (f, e) { (None, None) => None, (Some(f), Some(e)) => Some(YieldValue::From(make_from(f, e))), @@ -2719,7 +2768,7 @@ fn make_yield<'a>( } } -fn make_from<'a>(tok: TokenRef<'a>, e: Expression<'a>) -> From<'a> { +fn make_from<'r, 'a>(tok: TokenRef<'r, 'a>, e: Expression<'r, 'a>) -> From<'r, 'a> { From { item: e, whitespace_before_from: Default::default(), @@ -2728,7 +2777,10 @@ fn make_from<'a>(tok: TokenRef<'a>, e: Expression<'a>) -> From<'a> { } } -fn make_return<'a>(return_tok: TokenRef<'a>, value: Option>) -> Return<'a> { +fn make_return<'r, 'a>( + return_tok: TokenRef<'r, 'a>, + value: Option>, +) -> Return<'r, 'a> { Return { value, whitespace_after_return: Default::default(), @@ -2737,11 +2789,11 @@ fn make_return<'a>(return_tok: TokenRef<'a>, value: Option>) -> R } } -fn make_assert<'a>( - assert_tok: TokenRef<'a>, - test: Expression<'a>, - rest: Option<(Comma<'a>, Expression<'a>)>, -) -> Assert<'a> { +fn make_assert<'r, 'a>( + assert_tok: TokenRef<'r, 'a>, + test: Expression<'r, 'a>, + rest: Option<(Comma<'r, 'a>, Expression<'r, 'a>)>, +) -> Assert<'r, 'a> { let (comma, msg) = if let Some((c, msg)) = rest { (Some(c), Some(msg)) } else { @@ -2758,11 +2810,11 @@ fn make_assert<'a>( } } -fn make_raise<'a>( - raise_tok: TokenRef<'a>, - exc: Option>, - rest: Option<(TokenRef<'a>, Expression<'a>)>, -) -> Raise<'a> { +fn make_raise<'r, 'a>( + raise_tok: TokenRef<'r, 'a>, + exc: Option>, + rest: Option<(TokenRef<'r, 'a>, Expression<'r, 'a>)>, +) -> Raise<'r, 'a> { let cause = rest.map(|(t, e)| make_from(t, e)); Raise { @@ -2774,12 +2826,12 @@ fn make_raise<'a>( } } -fn make_global<'a>( - tok: TokenRef<'a>, - init: Vec<(Name<'a>, Comma<'a>)>, - last: Name<'a>, -) -> Global<'a> { - let mut names: Vec> = init +fn make_global<'r, 'a>( + tok: TokenRef<'r, 'a>, + init: Vec<(Name<'r, 'a>, Comma<'r, 'a>)>, + last: Name<'r, 'a>, +) -> Global<'r, 'a> { + let mut names: Vec> = init .into_iter() .map(|(name, c)| NameItem { name, @@ -2798,12 +2850,12 @@ fn make_global<'a>( } } -fn make_nonlocal<'a>( - tok: TokenRef<'a>, - init: Vec<(Name<'a>, Comma<'a>)>, - last: Name<'a>, -) -> Nonlocal<'a> { - let mut names: Vec> = init +fn make_nonlocal<'r, 'a>( + tok: TokenRef<'r, 'a>, + init: Vec<(Name<'r, 'a>, Comma<'r, 'a>)>, + last: Name<'r, 'a>, +) -> Nonlocal<'r, 'a> { + let mut names: Vec> = init .into_iter() .map(|(name, c)| NameItem { name, @@ -2823,16 +2875,16 @@ fn make_nonlocal<'a>( } #[allow(clippy::too_many_arguments)] -fn make_for<'a>( - async_tok: Option>, - for_tok: TokenRef<'a>, - target: AssignTargetExpression<'a>, - in_tok: TokenRef<'a>, - iter: Expression<'a>, - colon_tok: TokenRef<'a>, - body: Suite<'a>, - orelse: Option>, -) -> For<'a> { +fn make_for<'r, 'a>( + async_tok: Option>, + for_tok: TokenRef<'r, 'a>, + target: AssignTargetExpression<'r, 'a>, + in_tok: TokenRef<'r, 'a>, + iter: Expression<'r, 'a>, + colon_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, + orelse: Option>, +) -> For<'r, 'a> { let asynchronous = async_tok.as_ref().map(|_| Asynchronous { whitespace_after: Default::default(), }); @@ -2855,13 +2907,13 @@ fn make_for<'a>( } } -fn make_while<'a>( - while_tok: TokenRef<'a>, - test: Expression<'a>, - colon_tok: TokenRef<'a>, - body: Suite<'a>, - orelse: Option>, -) -> While<'a> { +fn make_while<'r, 'a>( + while_tok: TokenRef<'r, 'a>, + test: Expression<'r, 'a>, + colon_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, + orelse: Option>, +) -> While<'r, 'a> { While { test, body, @@ -2874,7 +2926,10 @@ fn make_while<'a>( } } -fn make_await<'a>(await_tok: TokenRef<'a>, expression: Expression<'a>) -> Await<'a> { +fn make_await<'r, 'a>( + await_tok: TokenRef<'r, 'a>, + expression: Expression<'r, 'a>, +) -> Await<'r, 'a> { Await { expression: Box::new(expression), lpar: Default::default(), @@ -2884,13 +2939,17 @@ fn make_await<'a>(await_tok: TokenRef<'a>, expression: Expression<'a>) -> Await< } } -fn make_class_def<'a>( - class_tok: TokenRef<'a>, - name: Name<'a>, - args: Option<(LeftParen<'a>, Option>>, RightParen<'a>)>, - colon_tok: TokenRef<'a>, - body: Suite<'a>, -) -> std::result::Result, &'static str> { +fn make_class_def<'r, 'a>( + class_tok: TokenRef<'r, 'a>, + name: Name<'r, 'a>, + args: Option<( + LeftParen<'r, 'a>, + Option>>, + RightParen<'r, 'a>, + )>, + colon_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, +) -> std::result::Result, &'static str> { let mut bases = vec![]; let mut keywords = vec![]; let mut parens_tok = None; @@ -2898,7 +2957,7 @@ fn make_class_def<'a>( let mut rpar = None; if let Some((lpar_, args, rpar_)) = args { - parens_tok = Some((lpar_.lpar_tok.clone(), rpar_.rpar_tok.clone())); + parens_tok = Some((lpar_.lpar_tok, rpar_.rpar_tok)); lpar = Some(lpar_); rpar = Some(rpar_); if let Some(args) = args { @@ -2938,18 +2997,18 @@ fn make_class_def<'a>( }) } -fn make_string(tok: TokenRef) -> String { +fn make_string<'r, 'a>(tok: TokenRef<'r, 'a>) -> String<'r, 'a> { String::Simple(SimpleString { value: tok.string, ..Default::default() }) } -fn make_strings<'a>(s: Vec<(String<'a>, TokenRef<'a>)>) -> String<'a> { +fn make_strings<'r, 'a>(s: Vec<(String<'r, 'a>, TokenRef<'r, 'a>)>) -> String<'r, 'a> { let mut strings = s.into_iter().rev(); let (first, _) = strings.next().expect("no strings to make a string of"); strings.fold(first, |acc, (str, tok)| { - let ret: String<'a> = String::Concatenated(ConcatenatedString { + let ret: String<'r, 'a> = String::Concatenated(ConcatenatedString { left: Box::new(str), right: Box::new(acc), whitespace_between: Default::default(), @@ -2961,14 +3020,14 @@ fn make_strings<'a>(s: Vec<(String<'a>, TokenRef<'a>)>) -> String<'a> { }) } -fn make_fstring_expression<'a>( - lbrace_tok: TokenRef<'a>, - expression: Expression<'a>, - eq: Option>, - conversion_pair: Option<(TokenRef<'a>, &'a str)>, - format_pair: Option<(TokenRef<'a>, Vec>)>, - rbrace_tok: TokenRef<'a>, -) -> FormattedStringExpression<'a> { +fn make_fstring_expression<'r, 'a>( + lbrace_tok: TokenRef<'r, 'a>, + expression: Expression<'r, 'a>, + eq: Option>, + conversion_pair: Option<(TokenRef<'r, 'a>, &'a str)>, + format_pair: Option<(TokenRef<'r, 'a>, Vec>)>, + rbrace_tok: TokenRef<'r, 'a>, +) -> FormattedStringExpression<'r, 'a> { let equal = eq.map(make_assign_equal); let (conversion_tok, conversion) = if let Some((t, c)) = conversion_pair { (Some(t), Some(c)) @@ -3002,11 +3061,11 @@ fn make_fstring_expression<'a>( } } -fn make_fstring<'a>( +fn make_fstring<'r, 'a>( start: &'a str, - parts: Vec>, + parts: Vec>, end: &'a str, -) -> FormattedString<'a> { +) -> FormattedString<'r, 'a> { FormattedString { start, parts, @@ -3016,11 +3075,11 @@ fn make_fstring<'a>( } } -fn make_finally<'a>( - finally_tok: TokenRef<'a>, - colon_tok: TokenRef<'a>, - body: Suite<'a>, -) -> Finally<'a> { +fn make_finally<'r, 'a>( + finally_tok: TokenRef<'r, 'a>, + colon_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, +) -> Finally<'r, 'a> { Finally { body, leading_lines: Default::default(), @@ -3030,13 +3089,13 @@ fn make_finally<'a>( } } -fn make_except<'a>( - except_tok: TokenRef<'a>, - exp: Option>, - as_: Option<(TokenRef<'a>, Name<'a>)>, - colon_tok: TokenRef<'a>, - body: Suite<'a>, -) -> ExceptHandler<'a> { +fn make_except<'r, 'a>( + except_tok: TokenRef<'r, 'a>, + exp: Option>, + as_: Option<(TokenRef<'r, 'a>, Name<'r, 'a>)>, + colon_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, +) -> ExceptHandler<'r, 'a> { // TODO: AsName should come from outside let name = as_.map(|(x, y)| make_as_name(x, AssignTargetExpression::Name(y))); ExceptHandler { @@ -3051,14 +3110,14 @@ fn make_except<'a>( } } -fn make_except_star<'a>( - except_tok: TokenRef<'a>, - star_tok: TokenRef<'a>, - exp: Expression<'a>, - as_: Option<(TokenRef<'a>, Name<'a>)>, - colon_tok: TokenRef<'a>, - body: Suite<'a>, -) -> ExceptStarHandler<'a> { +fn make_except_star<'r, 'a>( + except_tok: TokenRef<'r, 'a>, + star_tok: TokenRef<'r, 'a>, + exp: Expression<'r, 'a>, + as_: Option<(TokenRef<'r, 'a>, Name<'r, 'a>)>, + colon_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, +) -> ExceptStarHandler<'r, 'a> { // TODO: AsName should come from outside let name = as_.map(|(x, y)| make_as_name(x, AssignTargetExpression::Name(y))); ExceptStarHandler { @@ -3075,13 +3134,13 @@ fn make_except_star<'a>( } } -fn make_try<'a>( - try_tok: TokenRef<'a>, - body: Suite<'a>, - handlers: Vec>, - orelse: Option>, - finalbody: Option>, -) -> Try<'a> { +fn make_try<'r, 'a>( + try_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, + handlers: Vec>, + orelse: Option>, + finalbody: Option>, +) -> Try<'r, 'a> { Try { body, handlers, @@ -3093,13 +3152,13 @@ fn make_try<'a>( } } -fn make_try_star<'a>( - try_tok: TokenRef<'a>, - body: Suite<'a>, - handlers: Vec>, - orelse: Option>, - finalbody: Option>, -) -> TryStar<'a> { +fn make_try_star<'r, 'a>( + try_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, + handlers: Vec>, + orelse: Option>, + finalbody: Option>, +) -> TryStar<'r, 'a> { TryStar { body, handlers, @@ -3111,7 +3170,7 @@ fn make_try_star<'a>( } } -fn make_aug_op(tok: TokenRef) -> Result { +fn make_aug_op<'r, 'a>(tok: TokenRef<'r, 'a>) -> Result<'a, AugOp<'r, 'a>> { let whitespace_before = Default::default(); let whitespace_after = Default::default(); @@ -3185,11 +3244,11 @@ fn make_aug_op(tok: TokenRef) -> Result { }) } -fn make_aug_assign<'a>( - target: AssignTargetExpression<'a>, - operator: AugOp<'a>, - value: Expression<'a>, -) -> AugAssign<'a> { +fn make_aug_assign<'r, 'a>( + target: AssignTargetExpression<'r, 'a>, + operator: AugOp<'r, 'a>, + value: Expression<'r, 'a>, +) -> AugAssign<'r, 'a> { AugAssign { target, operator, @@ -3198,11 +3257,11 @@ fn make_aug_assign<'a>( } } -fn make_with_item<'a>( - item: Expression<'a>, - as_: Option>, - n: Option>, -) -> WithItem<'a> { +fn make_with_item<'r, 'a>( + item: Expression<'r, 'a>, + as_: Option>, + n: Option>, +) -> WithItem<'r, 'a> { let asname = match (as_, n) { (Some(as_), Some(n)) => Some(make_as_name(as_, n)), (None, None) => None, @@ -3215,13 +3274,13 @@ fn make_with_item<'a>( } } -fn make_with<'a>( - async_tok: Option>, - with_tok: TokenRef<'a>, - items: Vec>, - colon_tok: TokenRef<'a>, - body: Suite<'a>, -) -> With<'a> { +fn make_with<'r, 'a>( + async_tok: Option>, + with_tok: TokenRef<'r, 'a>, + items: Vec>, + colon_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, +) -> With<'r, 'a> { let asynchronous = async_tok.as_ref().map(|_| Asynchronous { whitespace_after: Default::default(), }); @@ -3238,7 +3297,7 @@ fn make_with<'a>( } } -fn make_del<'a>(tok: TokenRef<'a>, target: DelTargetExpression<'a>) -> Del<'a> { +fn make_del<'r, 'a>(tok: TokenRef<'r, 'a>, target: DelTargetExpression<'r, 'a>) -> Del<'r, 'a> { Del { target, whitespace_after_del: Default::default(), @@ -3247,11 +3306,11 @@ fn make_del<'a>(tok: TokenRef<'a>, target: DelTargetExpression<'a>) -> Del<'a> { } } -fn make_del_tuple<'a>( - lpar: Option>, - elements: Vec>, - rpar: Option>, -) -> DelTargetExpression<'a> { +fn make_del_tuple<'r, 'a>( + lpar: Option>, + elements: Vec>, + rpar: Option>, +) -> DelTargetExpression<'r, 'a> { DelTargetExpression::Tuple(Tuple { elements, lpar: lpar.map(|x| vec![x]).unwrap_or_default(), @@ -3259,7 +3318,11 @@ fn make_del_tuple<'a>( }) } -fn make_named_expr<'a>(name: Name<'a>, tok: TokenRef<'a>, expr: Expression<'a>) -> NamedExpr<'a> { +fn make_named_expr<'r, 'a>( + name: Name<'r, 'a>, + tok: TokenRef<'r, 'a>, + expr: Expression<'r, 'a>, +) -> NamedExpr<'r, 'a> { NamedExpr { target: Box::new(Expression::Name(name)), value: Box::new(expr), @@ -3271,14 +3334,14 @@ fn make_named_expr<'a>(name: Name<'a>, tok: TokenRef<'a>, expr: Expression<'a>) } } -fn make_match<'a>( - match_tok: TokenRef<'a>, - subject: Expression<'a>, - colon_tok: TokenRef<'a>, - indent_tok: TokenRef<'a>, - cases: Vec>, - dedent_tok: TokenRef<'a>, -) -> Match<'a> { +fn make_match<'r, 'a>( + match_tok: TokenRef<'r, 'a>, + subject: Expression<'r, 'a>, + colon_tok: TokenRef<'r, 'a>, + indent_tok: TokenRef<'r, 'a>, + cases: Vec>, + dedent_tok: TokenRef<'r, 'a>, +) -> Match<'r, 'a> { Match { subject, cases, @@ -3295,13 +3358,13 @@ fn make_match<'a>( } } -fn make_case<'a>( - case_tok: TokenRef<'a>, - pattern: MatchPattern<'a>, - guard: Option<(TokenRef<'a>, Expression<'a>)>, - colon_tok: TokenRef<'a>, - body: Suite<'a>, -) -> MatchCase<'a> { +fn make_case<'r, 'a>( + case_tok: TokenRef<'r, 'a>, + pattern: MatchPattern<'r, 'a>, + guard: Option<(TokenRef<'r, 'a>, Expression<'r, 'a>)>, + colon_tok: TokenRef<'r, 'a>, + body: Suite<'r, 'a>, +) -> MatchCase<'r, 'a> { let (if_tok, guard) = match guard { Some((if_tok, guard)) => (Some(if_tok), Some(guard)), None => (None, None), @@ -3321,19 +3384,19 @@ fn make_case<'a>( } } -fn make_match_value(value: Expression) -> MatchPattern { +fn make_match_value<'r, 'a>(value: Expression<'r, 'a>) -> MatchPattern<'r, 'a> { MatchPattern::Value(MatchValue { value }) } -fn make_match_singleton(value: Name) -> MatchPattern { +fn make_match_singleton<'r, 'a>(value: Name<'r, 'a>) -> MatchPattern<'r, 'a> { MatchPattern::Singleton(MatchSingleton { value }) } -fn make_list_pattern<'a>( - lbracket: Option>, - patterns: Vec>, - rbracket: Option>, -) -> MatchSequence<'a> { +fn make_list_pattern<'r, 'a>( + lbracket: Option>, + patterns: Vec>, + rbracket: Option>, +) -> MatchSequence<'r, 'a> { MatchSequence::MatchList(MatchList { patterns, lbracket, @@ -3343,11 +3406,11 @@ fn make_list_pattern<'a>( }) } -fn make_as_pattern<'a>( - pattern: Option>, - as_tok: Option>, - name: Option>, -) -> MatchPattern<'a> { +fn make_as_pattern<'r, 'a>( + pattern: Option>, + as_tok: Option>, + name: Option>, +) -> MatchPattern<'r, 'a> { MatchPattern::As(Box::new(MatchAs { pattern, name, @@ -3359,7 +3422,7 @@ fn make_as_pattern<'a>( })) } -fn make_bit_or(tok: TokenRef) -> BitOr { +fn make_bit_or<'r, 'a>(tok: TokenRef<'r, 'a>) -> BitOr<'r, 'a> { BitOr { whitespace_before: Default::default(), whitespace_after: Default::default(), @@ -3367,10 +3430,10 @@ fn make_bit_or(tok: TokenRef) -> BitOr { } } -fn make_or_pattern<'a>( - first: MatchPattern<'a>, - rest: Vec<(TokenRef<'a>, MatchPattern<'a>)>, -) -> MatchPattern<'a> { +fn make_or_pattern<'r, 'a>( + first: MatchPattern<'r, 'a>, + rest: Vec<(TokenRef<'r, 'a>, MatchPattern<'r, 'a>)>, +) -> MatchPattern<'r, 'a> { if rest.is_empty() { return first; } @@ -3396,25 +3459,25 @@ fn make_or_pattern<'a>( })) } -fn ensure_real_number(tok: TokenRef) -> GrammarResult { +fn ensure_real_number<'r, 'a>(tok: TokenRef<'r, 'a>) -> GrammarResult> { match make_number(tok) { e @ (Expression::Integer(_) | Expression::Float(_)) => Ok(e), _ => Err("real number"), } } -fn ensure_imaginary_number(tok: TokenRef) -> GrammarResult { +fn ensure_imaginary_number<'r, 'a>(tok: TokenRef<'r, 'a>) -> GrammarResult> { match make_number(tok) { e @ Expression::Imaginary(_) => Ok(e), _ => Err("imaginary number"), } } -fn make_tuple_pattern<'a>( - lpar: LeftParen<'a>, - patterns: Vec>, - rpar: RightParen<'a>, -) -> MatchSequence<'a> { +fn make_tuple_pattern<'r, 'a>( + lpar: LeftParen<'r, 'a>, + patterns: Vec>, + rpar: RightParen<'r, 'a>, +) -> MatchSequence<'r, 'a> { MatchSequence::MatchTuple(MatchTuple { patterns, lpar: vec![lpar], @@ -3422,23 +3485,28 @@ fn make_tuple_pattern<'a>( }) } -fn make_open_sequence_pattern<'a>( - first: StarrableMatchSequenceElement<'a>, - comma: Comma<'a>, - mut rest: Vec>, -) -> Vec> { +fn make_open_sequence_pattern<'r, 'a>( + first: StarrableMatchSequenceElement<'r, 'a>, + comma: Comma<'r, 'a>, + mut rest: Vec>, +) -> Vec> { rest.insert(0, first.with_comma(comma)); rest } -fn make_match_sequence_element(value: MatchPattern) -> MatchSequenceElement { +fn make_match_sequence_element<'r, 'a>( + value: MatchPattern<'r, 'a>, +) -> MatchSequenceElement<'r, 'a> { MatchSequenceElement { value, comma: Default::default(), } } -fn make_match_star<'a>(star_tok: TokenRef<'a>, name: Option>) -> MatchStar<'a> { +fn make_match_star<'r, 'a>( + star_tok: TokenRef<'r, 'a>, + name: Option>, +) -> MatchStar<'r, 'a> { MatchStar { name, comma: Default::default(), @@ -3447,15 +3515,15 @@ fn make_match_star<'a>(star_tok: TokenRef<'a>, name: Option>) -> MatchS } } -fn make_match_mapping<'a>( - lbrace: LeftCurlyBrace<'a>, - mut elements: Vec>, - el_comma: Option>, - star_tok: Option>, - rest: Option>, - trailing_comma: Option>, - rbrace: RightCurlyBrace<'a>, -) -> MatchPattern<'a> { +fn make_match_mapping<'r, 'a>( + lbrace: LeftCurlyBrace<'r, 'a>, + mut elements: Vec>, + el_comma: Option>, + star_tok: Option>, + rest: Option>, + trailing_comma: Option>, + rbrace: RightCurlyBrace<'r, 'a>, +) -> MatchPattern<'r, 'a> { if let Some(c) = el_comma { if let Some(el) = elements.pop() { elements.push(el.with_comma(c)); @@ -3475,11 +3543,11 @@ fn make_match_mapping<'a>( }) } -fn make_match_mapping_element<'a>( - key: Expression<'a>, - colon_tok: TokenRef<'a>, - pattern: MatchPattern<'a>, -) -> MatchMappingElement<'a> { +fn make_match_mapping_element<'r, 'a>( + key: Expression<'r, 'a>, + colon_tok: TokenRef<'r, 'a>, + pattern: MatchPattern<'r, 'a>, +) -> MatchMappingElement<'r, 'a> { MatchMappingElement { key, pattern, @@ -3490,15 +3558,15 @@ fn make_match_mapping_element<'a>( } } -fn make_class_pattern<'a>( - cls: NameOrAttribute<'a>, - lpar_tok: TokenRef<'a>, - mut patterns: Vec>, - pat_comma: Option>, - mut kwds: Vec>, - kwd_comma: Option>, - rpar_tok: TokenRef<'a>, -) -> MatchPattern<'a> { +fn make_class_pattern<'r, 'a>( + cls: NameOrAttribute<'r, 'a>, + lpar_tok: TokenRef<'r, 'a>, + mut patterns: Vec>, + pat_comma: Option>, + mut kwds: Vec>, + kwd_comma: Option>, + rpar_tok: TokenRef<'r, 'a>, +) -> MatchPattern<'r, 'a> { if let Some(c) = pat_comma { if let Some(el) = patterns.pop() { patterns.push(el.with_comma(c)); @@ -3525,11 +3593,11 @@ fn make_class_pattern<'a>( }) } -fn make_match_keyword_element<'a>( - key: Name<'a>, - equal_tok: TokenRef<'a>, - pattern: MatchPattern<'a>, -) -> MatchKeywordElement<'a> { +fn make_match_keyword_element<'r, 'a>( + key: Name<'r, 'a>, + equal_tok: TokenRef<'r, 'a>, + pattern: MatchPattern<'r, 'a>, +) -> MatchKeywordElement<'r, 'a> { MatchKeywordElement { key, pattern, diff --git a/native/libcst/src/parser/mod.rs b/native/libcst/src/parser/mod.rs index 8e6ec8e1..de9a1947 100644 --- a/native/libcst/src/parser/mod.rs +++ b/native/libcst/src/parser/mod.rs @@ -8,4 +8,5 @@ mod grammar; mod numbers; pub use errors::ParserError; +pub(crate) use grammar::TokVec; pub use grammar::{python, Result}; diff --git a/native/libcst/src/tokenizer/whitespace_parser.rs b/native/libcst/src/tokenizer/whitespace_parser.rs index ec463f99..55ad5120 100644 --- a/native/libcst/src/tokenizer/whitespace_parser.rs +++ b/native/libcst/src/tokenizer/whitespace_parser.rs @@ -3,6 +3,8 @@ // This source code is licensed under the MIT license found in the // LICENSE file in the root directory of this source tree +use std::rc::Rc; + use crate::nodes::{ Comment, EmptyLine, Fakeness, Newline, ParenthesizableWhitespace, ParenthesizedWhitespace, SimpleWhitespace, TrailingWhitespace, @@ -65,7 +67,7 @@ pub struct Config<'a> { } impl<'a> Config<'a> { - pub fn new(input: &'a str, tokens: &[Token<'a>]) -> Self { + pub fn new(input: &'a str, tokens: &[Rc>]) -> Self { let mut default_indent = " "; for tok in tokens { if tok.r#type == TokType::Indent { diff --git a/native/libcst_derive/src/codegen.rs b/native/libcst_derive/src/codegen.rs index 4fce05df..aa5515f0 100644 --- a/native/libcst_derive/src/codegen.rs +++ b/native/libcst_derive/src/codegen.rs @@ -56,7 +56,7 @@ fn impl_enum(ast: &DeriveInput, e: &DataEnum) -> TokenStream { let ident = &ast.ident; let generics = &ast.generics; let gen = quote! { - impl<'a> Codegen<'a> for #ident #generics { + impl #generics Codegen<'a> for #ident #generics { fn codegen(&self, state: &mut CodegenState<'a>) { match self { #(Self::#varnames(x) => x.codegen(state),)* diff --git a/native/libcst_derive/src/cstnode.rs b/native/libcst_derive/src/cstnode.rs new file mode 100644 index 00000000..5f8d3bde --- /dev/null +++ b/native/libcst_derive/src/cstnode.rs @@ -0,0 +1,404 @@ +// Copyright (c) Meta Platforms, Inc. and its affiliates. +// +// This source code is licensed under the MIT license found in the +// LICENSE file in the root directory of this source tree + +use proc_macro::{Span, TokenStream}; +use quote::{format_ident, quote, quote_spanned, ToTokens}; +use syn::{ + self, + punctuated::{Pair, Punctuated}, + spanned::Spanned, + token::Comma, + AngleBracketedGenericArguments, Attribute, Data, DataEnum, DataStruct, DeriveInput, Field, + Fields, FieldsNamed, FieldsUnnamed, GenericArgument, GenericParam, Generics, Ident, Lifetime, + LifetimeDef, ParenthesizedGenericArguments, Path, PathArguments, PathSegment, Token, Type, + TypePath, Visibility, +}; + +pub(crate) fn impl_cst_node(ast: DeriveInput) -> TokenStream { + match ast.data { + Data::Enum(e) => impl_enum(ast.attrs, ast.vis, ast.ident, ast.generics, e), + Data::Struct(s) => impl_struct(ast.attrs, ast.vis, ast.ident, ast.generics, s), + Data::Union(u) => quote_spanned! { + u.union_token.span() => + compile_error!("Union type is not supported") + } + .into(), + } +} + +// enum Foo<'a> { +// Variant(Variant<'a>), +// } +// => +// enum Foo<'a> { +// Variant(Variant<'a>), +// } +// enum DeflatedFoo<'r, 'a> { +// Variant(DeflatedVariant<'r, 'a>), +// } + +fn impl_enum( + attrs: Vec, + vis: Visibility, + ident: Ident, + generics: Generics, + mut e: DataEnum, +) -> TokenStream { + let deflated_ident = format_ident!("Deflated{}", &ident); + let mut deflated_generics = generics.clone(); + let mut added_lifetime = false; + let mut deflated_variant_tokens = vec![]; + + for var in e.variants.iter_mut() { + let (inflated_fields, deflated_fields, extra_lifetime) = impl_fields(var.fields.clone()); + added_lifetime |= extra_lifetime; + var.fields = deflated_fields; + deflated_variant_tokens.push(var.to_token_stream()); + var.fields = inflated_fields; + } + if added_lifetime { + deflated_generics.params.insert( + 0, + GenericParam::Lifetime(LifetimeDef::new(Lifetime::new( + "'r", + Span::call_site().into(), + ))), + ); + } + let inflated = DeriveInput { + attrs, + vis, + ident, + generics, + data: Data::Enum(e), + }; + + let gen = quote! { + #inflated + enum #deflated_ident#deflated_generics { + #(#deflated_variant_tokens)* + } + }; + gen.into() +} + +// pub struct Foo<'a> { +// pub bar: Bar<'a>, +// pub value: &'a str, +// pub whitespace_after: SimpleWhitespace<'a>, +// pub(crate) tok: Option, +// } +// => +// pub struct Foo<'a> { +// pub bar: Bar<'a>, +// pub value: &'a str, +// pub whitespace_after: SimpleWhitespace<'a>, +// } +// struct DeflatedFoo<'r, 'a> { +// pub bar: DeflatedBar<'r, 'a>, +// pub value: &'a str, +// pub tok: Option> +// } + +fn impl_struct( + attrs: Vec, + vis: Visibility, + ident: Ident, + generics: Generics, + mut s: DataStruct, +) -> TokenStream { + let deflated_ident = format_ident!("Deflated{}", &ident); + let mut deflated_generics = generics.clone(); + + let (inflated_fields, deflated_fields, added_lifetime) = impl_fields(s.fields); + s.fields = inflated_fields; + if added_lifetime { + deflated_generics.params.insert( + 0, + GenericParam::Lifetime(LifetimeDef::new(Lifetime::new( + "'r", + Span::call_site().into(), + ))), + ); + } + let inflated = DeriveInput { + attrs, + vis, + ident, + generics, + data: Data::Struct(s), + }; + + let gen = quote! { + #inflated + + struct #deflated_ident#deflated_generics + #deflated_fields + + }; + gen.into() +} + +fn impl_fields(fields: Fields) -> (Fields, Fields, bool) { + match &fields { + Fields::Unnamed(fs) => { + let (deflated_fields, added_lifetime) = impl_unnamed_fields(fs.clone()); + (fields, Fields::Unnamed(deflated_fields), added_lifetime) + } + Fields::Named(fs) => impl_named_fields(fs.clone()), + Fields::Unit => (Fields::Unit, Fields::Unit, false), + } +} + +fn impl_unnamed_fields(mut deflated_fields: FieldsUnnamed) -> (FieldsUnnamed, bool) { + let mut added_lifetime = false; + for f in deflated_fields.unnamed.iter_mut() { + if let Type::Path(TypePath { path, .. }) = &mut f.ty { + if let Some(seg) = path.segments.last_mut() { + seg.ident = format_ident!("Deflated{}", seg.ident); + if let PathArguments::AngleBracketed(AngleBracketedGenericArguments { + args, .. + }) = &mut seg.arguments + { + added_lifetime = true; + args.insert( + 0, + GenericArgument::Lifetime(Lifetime::new("'r", Span::call_site().into())), + ); + } + } + } + } + (deflated_fields, added_lifetime) +} + +fn impl_named_fields(mut fields: FieldsNamed) -> (Fields, Fields, bool) { + let mut deflated_fields = fields.clone(); + let mut added_lifetime = false; + let span: Span = Span::call_site(); + // Drop whitespace fields from deflated fields + // And add lifetimes to tokenref fields + deflated_fields.named = deflated_fields + .named + .into_pairs() + .filter(|pair| { + let id = pair.value().ident.as_ref().unwrap(); + !format!("{}", id).starts_with("whitespace_") + }) + .map(|pair| { + added_lifetime = true; + add_lifetimes(pair, span) + }) + .collect(); + + // Drop tokenref fields from inflated fields + fields.named = fields + .named + .into_pairs() + .filter(|pair| !is_token_ref(pair.value())) + .collect(); + ( + Fields::Named(fields), + Fields::Named(deflated_fields), + added_lifetime, + ) +} + +fn is_token_ref(field: &Field) -> bool { + if let Type::Path(path) = &field.ty { + if let Some(id) = path.path.segments.last().map(|seg| &seg.ident) { + return format!("{}", id) == "TokenRef"; + } + } + false +} + +// foo::bar -> foo::bar<'r, 'a> +fn add_lifetimes(mut pair: Pair, span: Span) -> Pair { + if let Some(seg) = rightmost_path_segment_mut(&mut pair.value_mut().ty) { + let lifetime_argument = GenericArgument::Lifetime(Lifetime::new("'r", span.into())); + match seg.arguments { + PathArguments::None => { + let mut generic_args = Punctuated::<_, _>::new(); + generic_args.push(lifetime_argument); + seg.arguments = PathArguments::AngleBracketed(AngleBracketedGenericArguments { + colon2_token: None, + lt_token: Token![<]([span.into()]), + gt_token: Token![>]([span.into()]), + args: generic_args, + }) + } + PathArguments::AngleBracketed(AngleBracketedGenericArguments { + ref mut args, .. + }) => { + args.insert(0, lifetime_argument); + } + _ => todo!(), + } + } + pair +} + +// fn rightmost_path_segment(ty: &Type) -> Option<&PathSegment> { +// if let Type::Path(TypePath { path, .. }) = ty { +// if let Some(seg) = path.segments.last() { +// if let PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. }) = +// &seg.arguments +// { +// if let Some(GenericArgument::Type(t)) = args.last() { +// return rightmost_path_segment(t); +// } +// } +// return Some(seg); +// } +// } +// None +// } + +type Link = Option>; + +struct Node { + next: Link, +} + +struct Recursive { + root: Link, +} + +// fn back(node: &mut Node) -> &mut Link { +// let mut anchor = &mut Some(Box::new(node)); +// loop { +// match { anchor } { +// &mut Some(ref mut node) => anchor = &mut node.next, +// other => return other, +// } +// } +// } + +fn back(start: &mut Link) -> &mut Link { + let mut anchor = start; + + loop { + match { anchor } { + &mut Some(ref mut node) => anchor = &mut node.next, + other => return other, + } + } +} + +// foo::bar::baz> -> baz> +fn get_pathseg(ty: &Type) -> Option<&PathSegment> { + match ty { + Type::Path(TypePath { path, .. }) => path.segments.last(), + _ => None, + } +} + +// foo::bar::baz> -> quux<'a> +fn rightmost_path_segment(ty: &Type) -> Option<&PathSegment> { + let mut candidate = get_pathseg(ty); + loop { + if let Some(pathseg) = candidate { + if let PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. }) = + &pathseg.arguments + { + if let Some(GenericArgument::Type(t)) = args.last() { + candidate = get_pathseg(t); + continue; + } + } + } + break; + } + candidate +} + +fn get_pathseg_mut(ty: &mut Type) -> Option<&mut PathSegment> { + match ty { + Type::Path(TypePath { path, .. }) => path.segments.last_mut(), + _ => None, + } +} + +fn has_more_mut(candidate: &Option<&mut PathSegment>) -> bool { + if let Some(PathArguments::AngleBracketed(AngleBracketedGenericArguments { + ref args, .. + })) = candidate.as_ref().map(|c| &c.arguments) + { + matches!(args.last(), Some(GenericArgument::Type(_))) + } else { + false + } +} + +fn rightmost_path_segment_mut(ty: &mut Type) -> Option<&mut PathSegment> { + let mut candidate = get_pathseg_mut(ty); + + while has_more_mut(&candidate) { + candidate = match candidate.unwrap().arguments { + PathArguments::AngleBracketed(AngleBracketedGenericArguments { + ref mut args, .. + }) => { + if let Some(GenericArgument::Type(t)) = args.last_mut() { + get_pathseg_mut(t) + } else { + unreachable!(); + } + } + _ => unreachable!(), + }; + } + + candidate +} + +// fn rightmost_path_segment_mut(mut ty: &mut Type) -> Option<&mut PathSegment> { +// loop { +// match { &mut *ty } { +// Type::Path(TypePath { path, .. }) => { +// let last_seg = path.segments.last_mut().unwrap(); +// match { &mut *last_seg }.arguments { +// PathArguments::AngleBracketed(AngleBracketedGenericArguments { +// mut args, +// .. +// }) => match args.last_mut().unwrap() { +// GenericArgument::Type(t) => ty = t, +// _ => {} +// }, +// _ => return None, +// } +// } +// _ => return None, +// } +// } +// // let tmp = ret; +// // if let Some(ref mut seg) = *tmp { +// // if let PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. }) = +// // &mut seg.arguments +// // { +// // if let Some(GenericArgument::Type(t)) = args.last_mut() { +// // ty_ = Some(t); +// // continue; +// // } +// // } +// // } +// // ty_ = None; +// // } +// // return ret; + +// // if let Type::Path(TypePath { path, .. }) = ty { +// // if let Some(seg) = { path.segments.last_mut() } { +// // if let PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. }) = +// // &mut { seg }.arguments +// // { +// // if let Some(GenericArgument::Type(t)) = args.last_mut() { +// // return rightmost_path_segment_mut(t); +// // } +// // } +// // return Some(seg); +// // } +// // } +// // None +// } diff --git a/native/libcst_derive/src/inflate.rs b/native/libcst_derive/src/inflate.rs index 323160c1..5205e28b 100644 --- a/native/libcst_derive/src/inflate.rs +++ b/native/libcst_derive/src/inflate.rs @@ -56,7 +56,8 @@ fn impl_inflate_enum(ast: &DeriveInput, e: &DataEnum) -> TokenStream { let ident = &ast.ident; let generics = &ast.generics; let gen = quote! { - impl<'a> Inflate<'a> for #ident #generics { + impl #generics Inflate<'a> for #ident #generics { + type Inflated = Self; fn inflate(mut self, config: & crate::tokenizer::whitespace_parser::Config<'a>) -> std::result::Result { match self { #(Self::#varnames(x) => Ok(Self::#varnames(x.inflate(config)?)),)* diff --git a/native/libcst_derive/src/lib.rs b/native/libcst_derive/src/lib.rs index 97d1e321..c15ef0d8 100644 --- a/native/libcst_derive/src/lib.rs +++ b/native/libcst_derive/src/lib.rs @@ -11,8 +11,11 @@ mod codegen; use codegen::impl_codegen; mod into_py; use into_py::impl_into_py; +mod cstnode; +use cstnode::impl_cst_node; use proc_macro::TokenStream; +use syn::{parse, parse_macro_input, DeriveInput}; #[proc_macro_derive(Inflate)] pub fn inflate_derive(input: TokenStream) -> TokenStream { @@ -34,3 +37,9 @@ pub fn parenthesized_node_codegen(input: TokenStream) -> TokenStream { pub fn into_py(input: TokenStream) -> TokenStream { impl_into_py(&syn::parse(input).unwrap()) } + +#[proc_macro_attribute] +pub fn cst_node(args: TokenStream, input: TokenStream) -> TokenStream { + let _ = parse_macro_input!(args as parse::Nothing); + impl_cst_node(parse_macro_input!(input as DeriveInput)) +} diff --git a/native/libcst_derive/src/parenthesized_node.rs b/native/libcst_derive/src/parenthesized_node.rs index fe716510..fda8e197 100644 --- a/native/libcst_derive/src/parenthesized_node.rs +++ b/native/libcst_derive/src/parenthesized_node.rs @@ -23,14 +23,14 @@ fn impl_struct(ast: &DeriveInput) -> TokenStream { let ident = &ast.ident; let generics = &ast.generics; let gen = quote! { - impl<'a> ParenthesizedNode<'a> for #ident #generics { - fn lpar(&self) -> &Vec> { + impl #generics ParenthesizedNode#generics for #ident #generics { + fn lpar(&self) -> &Vec { &self.lpar } - fn rpar(&self) -> &Vec> { + fn rpar(&self) -> &Vec { &self.rpar } - fn with_parens(self, left: LeftParen<'a>, right: RightParen<'a>) -> Self { + fn with_parens(self, left: LeftParen#generics, right: RightParen#generics) -> Self { let mut lpar = self.lpar; let mut rpar = self.rpar; lpar.insert(0, left); @@ -76,18 +76,18 @@ fn impl_enum(ast: &DeriveInput, e: &DataEnum) -> TokenStream { let ident = &ast.ident; let generics = &ast.generics; let gen = quote! { - impl<'a> ParenthesizedNode<'a> for #ident #generics { - fn lpar(&self) -> &Vec> { + impl #generics ParenthesizedNode#generics for #ident #generics { + fn lpar(&self) -> &Vec { match self { #(Self::#varnames(x) => x.lpar(),)* } } - fn rpar(&self) -> &Vec> { + fn rpar(&self) -> &Vec { match self { #(Self::#varnames(x) => x.rpar(),)* } } - fn with_parens(self, left: LeftParen<'a>, right: RightParen<'a>) -> Self { + fn with_parens(self, left: LeftParen #generics, right: RightParen #generics) -> Self { match self { #(Self::#varnames(x) => Self::#varnames(x.with_parens(left, right)),)* }