From d1759a75baf49773ff4401c226b5915abd3fbede Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Tue, 13 Jun 2023 11:24:34 -0400 Subject: [PATCH] Try to get this to work --- crates/ruff/src/checkers/ast/mod.rs | 14 +- .../rules/collection_literal_concatenation.rs | 76 ++- crates/ruff_python_ast/src/source_code/mod.rs | 1 + .../src/source_code/verbatim_generator.rs | 15 +- crates/ruff_python_ast/src/verbatim_ast.rs | 512 +----------------- 5 files changed, 67 insertions(+), 551 deletions(-) diff --git a/crates/ruff/src/checkers/ast/mod.rs b/crates/ruff/src/checkers/ast/mod.rs index acce1cdd4c..539148ae2c 100644 --- a/crates/ruff/src/checkers/ast/mod.rs +++ b/crates/ruff/src/checkers/ast/mod.rs @@ -12,7 +12,9 @@ use rustpython_parser::ast::{ use ruff_diagnostics::{Diagnostic, IsolationLevel}; use ruff_python_ast::all::{extract_all_names, AllNamesFlags}; use ruff_python_ast::helpers::{extract_handled_exceptions, to_module_path}; -use ruff_python_ast::source_code::{Generator, Indexer, Locator, Quote, Stylist}; +use ruff_python_ast::source_code::{ + Generator, Indexer, Locator, Quote, Stylist, VerbatimGenerator, +}; use ruff_python_ast::str::trailing_quote; use ruff_python_ast::types::Node; use ruff_python_ast::typing::{parse_type_annotation, AnnotationKind}; @@ -144,6 +146,16 @@ impl<'a> Checker<'a> { ) } + /// Create a [`Generator`] to generate source code based on the current AST state. + pub(crate) fn verbatim_generator(&self) -> VerbatimGenerator { + VerbatimGenerator::new( + self.locator, + self.stylist.indentation(), + self.f_string_quote_style().unwrap_or(self.stylist.quote()), + self.stylist.line_ending(), + ) + } + /// Returns the appropriate quoting for f-string by reversing the one used outside of /// the f-string. /// diff --git a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs index 752c7ae487..5fc9ec180e 100644 --- a/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs +++ b/crates/ruff/src/rules/ruff/rules/collection_literal_concatenation.rs @@ -31,7 +31,7 @@ impl Violation for CollectionLiteralConcatenation { } fn make_splat_elts( - splat_element: &Expr, + splat_element: verbatim_ast::Expr, other_elements: &[Expr], splat_at_left: bool, ) -> Vec { @@ -39,16 +39,10 @@ fn make_splat_elts( .iter() .map(|e| verbatim_ast::Expr::Verbatim(verbatim_ast::ExprVerbatim { range: e.range() })) .collect_vec(); - let splat_elt = verbatim_ast::Expr::Starred(verbatim_ast::ExprStarred { - value: Box::from(verbatim_ast::Expr::Verbatim(verbatim_ast::ExprVerbatim { - range: splat_element.range(), - })), - ctx: verbatim_ast::ExprContext::Load, - }); if splat_at_left { - new_elts.insert(0, splat_elt); + new_elts.insert(0, splat_element); } else { - new_elts.push(splat_elt); + new_elts.push(splat_element); } new_elts } @@ -68,37 +62,49 @@ fn concatenate_expressions(expr: &Expr) -> Option<(verbatim_ast::Expr, Type)> { let new_left = match left.as_ref() { Expr::BinOp(ast::ExprBinOp { .. }) => match concatenate_expressions(left) { Some((new_left, _)) => new_left, - None => *left.clone(), + None => verbatim_ast::Expr::from(left), }, - _ => *left.clone(), + _ => verbatim_ast::Expr::from(left), }; let new_right = match right.as_ref() { Expr::BinOp(ast::ExprBinOp { .. }) => match concatenate_expressions(right) { Some((new_right, _)) => new_right, - None => *right.clone(), + None => verbatim_ast::Expr::from(right), }, - _ => *right.clone(), + _ => verbatim_ast::Expr::from(right), }; // Figure out which way the splat is, and the type of the collection. let (type_, splat_element, other_elements, splat_at_left) = match (&new_left, &new_right) { - (Expr::List(ast::ExprList { elts: l_elts, .. }), _) => { - (Type::List, &new_right, l_elts, false) - } - (Expr::Tuple(ast::ExprTuple { elts: l_elts, .. }), _) => { - (Type::Tuple, &new_right, l_elts, false) - } - (_, Expr::List(ast::ExprList { elts: r_elts, .. })) => { - (Type::List, &new_left, r_elts, true) - } - (_, Expr::Tuple(ast::ExprTuple { elts: r_elts, .. })) => { - (Type::Tuple, &new_left, r_elts, true) - } + (Expr::List(ast::ExprList { elts: l_elts, .. }), _) => ( + Type::List, + new_right, + l_elts.iter().map(verbatim_ast::Expr::from).collect(), + false, + ), + (Expr::Tuple(ast::ExprTuple { elts: l_elts, .. }), _) => ( + Type::Tuple, + new_right, + l_elts.iter().map(verbatim_ast::Expr::from).collect(), + false, + ), + (_, Expr::List(ast::ExprList { elts: r_elts, .. })) => ( + Type::List, + new_left, + r_elts.iter().map(verbatim_ast::Expr::from).collect(), + true, + ), + (_, Expr::Tuple(ast::ExprTuple { elts: r_elts, .. })) => ( + Type::Tuple, + new_left, + r_elts.iter().map(verbatim_ast::Expr::from).collect(), + true, + ), _ => return None, }; - let new_elts = match splat_element { + let new_elts = match &splat_element { // We'll be a bit conservative here; only calls, names and attribute accesses // will be considered as splat elements. Expr::Call(_) | Expr::Attribute(_) | Expr::Name(_) => { @@ -115,18 +121,8 @@ fn concatenate_expressions(expr: &Expr) -> Option<(verbatim_ast::Expr, Type)> { }; let new_expr = match type_ { - Type::List => ast::ExprList { - elts: new_elts, - ctx: ExprContext::Load, - range: TextRange::default(), - } - .into(), - Type::Tuple => ast::ExprTuple { - elts: new_elts, - ctx: ExprContext::Load, - range: TextRange::default(), - } - .into(), + Type::List => verbatim_ast::Expr::List(verbatim_ast::ExprList { elts: new_elts }), + Type::Tuple => verbatim_ast::Expr::Tuple(verbatim_ast::ExprTuple { elts: new_elts }), }; Some((new_expr, type_)) @@ -151,8 +147,8 @@ pub(crate) fn collection_literal_concatenation(checker: &mut Checker, expr: &Exp let contents = match type_ { // Wrap the new expression in parentheses if it was a tuple. - Type::Tuple => format!("({})", checker.generator().expr(&new_expr)), - Type::List => checker.generator().expr(&new_expr), + Type::Tuple => format!("({})", checker.verbatim_generator().expr(&new_expr)), + Type::List => checker.verbatim_generator().expr(&new_expr), }; let mut diagnostic = Diagnostic::new( CollectionLiteralConcatenation { diff --git a/crates/ruff_python_ast/src/source_code/mod.rs b/crates/ruff_python_ast/src/source_code/mod.rs index 72abe433f3..5ab68d5b44 100644 --- a/crates/ruff_python_ast/src/source_code/mod.rs +++ b/crates/ruff_python_ast/src/source_code/mod.rs @@ -12,6 +12,7 @@ pub use generator::Generator; pub use indexer::Indexer; pub use locator::Locator; pub use stylist::{Quote, Stylist}; +pub use verbatim_generator::VerbatimGenerator; pub use crate::source_code::line_index::{LineIndex, OneIndexed}; diff --git a/crates/ruff_python_ast/src/source_code/verbatim_generator.rs b/crates/ruff_python_ast/src/source_code/verbatim_generator.rs index d9f5ca944c..9df3a54c14 100644 --- a/crates/ruff_python_ast/src/source_code/verbatim_generator.rs +++ b/crates/ruff_python_ast/src/source_code/verbatim_generator.rs @@ -60,7 +60,7 @@ mod precedence { pub(crate) const MAX: u8 = 63; } -pub struct Generator<'a> { +pub struct VerbatimGenerator<'a> { /// The locator to use for source code positions. locator: &'a Locator<'a>, /// The indentation style to use. @@ -75,7 +75,7 @@ pub struct Generator<'a> { initial: bool, } -impl<'a> Generator<'a> { +impl<'a> VerbatimGenerator<'a> { pub const fn new( locator: &'a Locator<'a>, indent: &'a Indentation, @@ -1199,7 +1199,8 @@ impl<'a> Generator<'a> { conversion: rustpython_ast::ConversionFlag, spec: Option<&Expr>, ) { - let mut generator = Generator::new(self.locator, self.indent, self.quote, self.line_ending); + let mut generator = + VerbatimGenerator::new(self.locator, self.indent, self.quote, self.line_ending); generator.unparse_expr(val, precedence::FORMATTED_VALUE); let brace = if generator.buffer.starts_with('{') { // put a space to avoid escaping the bracket @@ -1255,7 +1256,7 @@ impl<'a> Generator<'a> { self.unparse_fstring_body(values, is_spec); } else { self.p("f"); - let mut generator = Generator::new( + let mut generator = VerbatimGenerator::new( self.locator, self.indent, match self.quote { @@ -1295,14 +1296,14 @@ mod tests { use ruff_python_whitespace::LineEnding; use crate::source_code::stylist::{Indentation, Quote}; - use crate::source_code::Generator; + use crate::source_code::VerbatimGenerator; fn round_trip(contents: &str) -> String { let indentation = Indentation::default(); let quote = Quote::default(); let line_ending = LineEnding::default(); let stmt = Stmt::parse(contents, "").unwrap(); - let mut generator = Generator::new(&indentation, quote, line_ending); + let mut generator = VerbatimGenerator::new(&indentation, quote, line_ending); generator.unparse_stmt(&stmt); generator.generate() } @@ -1314,7 +1315,7 @@ mod tests { contents: &str, ) -> String { let stmt = Stmt::parse(contents, "").unwrap(); - let mut generator = Generator::new(indentation, quote, line_ending); + let mut generator = VerbatimGenerator::new(indentation, quote, line_ending); generator.unparse_stmt(&stmt); generator.generate() } diff --git a/crates/ruff_python_ast/src/verbatim_ast.rs b/crates/ruff_python_ast/src/verbatim_ast.rs index d61e8b8fbb..74ac871b02 100644 --- a/crates/ruff_python_ast/src/verbatim_ast.rs +++ b/crates/ruff_python_ast/src/verbatim_ast.rs @@ -3,25 +3,9 @@ use num_bigint::BigInt; use ruff_text_size::TextRange; +use rustpython_ast::Ranged; use rustpython_parser::ast; -#[derive(Debug, Copy, Clone)] -pub enum ExprContext { - Load, - Store, - Del, -} - -impl From<&ast::ExprContext> for ExprContext { - fn from(ctx: &ast::ExprContext) -> Self { - match ctx { - ast::ExprContext::Load => Self::Load, - ast::ExprContext::Store => Self::Store, - ast::ExprContext::Del => Self::Del, - } - } -} - #[derive(Debug, Copy, Clone)] pub enum Boolop { And, @@ -579,38 +563,32 @@ pub struct ExprConstant<'a> { pub struct ExprAttribute<'a> { pub value: Box>, pub attr: &'a str, - pub ctx: ExprContext, } #[derive(Debug)] pub struct ExprSubscript<'a> { pub value: Box>, pub slice: Box>, - pub ctx: ExprContext, } #[derive(Debug)] pub struct ExprStarred<'a> { pub value: Box>, - pub ctx: ExprContext, } #[derive(Debug)] pub struct ExprName<'a> { pub id: &'a str, - pub ctx: ExprContext, } #[derive(Debug)] pub struct ExprList<'a> { pub elts: Vec>, - pub ctx: ExprContext, } #[derive(Debug)] pub struct ExprTuple<'a> { pub elts: Vec>, - pub ctx: ExprContext, } #[derive(Debug)] @@ -621,13 +599,13 @@ pub struct ExprSlice<'a> { } #[derive(Debug)] -pub struct ExprVerbatim { - pub range: TextRange, +pub struct ExprVerbatim<'a> { + pub expr: &'a ast::Expr, } #[derive(Debug)] pub enum Expr<'a> { - Verbatim(ExprVerbatim), + Verbatim(ExprVerbatim<'a>), BoolOp(ExprBoolOp<'a>), NamedExpr(ExprNamedExpr<'a>), BinOp(ExprBinOp<'a>), @@ -671,235 +649,7 @@ impl<'a> From<&'a Box> for Expr<'a> { impl<'a> From<&'a ast::Expr> for Expr<'a> { fn from(expr: &'a ast::Expr) -> Self { - match expr { - ast::Expr::BoolOp(ast::ExprBoolOp { - op, - values, - range: _range, - }) => Self::BoolOp(ExprBoolOp { - op: op.into(), - values: values.iter().map(Into::into).collect(), - }), - ast::Expr::NamedExpr(ast::ExprNamedExpr { - target, - value, - range: _range, - }) => Self::NamedExpr(ExprNamedExpr { - target: target.into(), - value: value.into(), - }), - ast::Expr::BinOp(ast::ExprBinOp { - left, - op, - right, - range: _range, - }) => Self::BinOp(ExprBinOp { - left: left.into(), - op: op.into(), - right: right.into(), - }), - ast::Expr::UnaryOp(ast::ExprUnaryOp { - op, - operand, - range: _range, - }) => Self::UnaryOp(ExprUnaryOp { - op: op.into(), - operand: operand.into(), - }), - ast::Expr::Lambda(ast::ExprLambda { - args, - body, - range: _range, - }) => Self::Lambda(ExprLambda { - args: (&**args).into(), - body: body.into(), - }), - ast::Expr::IfExp(ast::ExprIfExp { - test, - body, - orelse, - range: _range, - }) => Self::IfExp(ExprIfExp { - test: test.into(), - body: body.into(), - orelse: orelse.into(), - }), - ast::Expr::Dict(ast::ExprDict { - keys, - values, - range: _range, - }) => Self::Dict(ExprDict { - keys: keys - .iter() - .map(|expr| expr.as_ref().map(Into::into)) - .collect(), - values: values.iter().map(Into::into).collect(), - }), - ast::Expr::Set(ast::ExprSet { - elts, - range: _range, - }) => Self::Set(ExprSet { - elts: elts.iter().map(Into::into).collect(), - }), - ast::Expr::ListComp(ast::ExprListComp { - elt, - generators, - range: _range, - }) => Self::ListComp(ExprListComp { - elt: elt.into(), - generators: generators.iter().map(Into::into).collect(), - }), - ast::Expr::SetComp(ast::ExprSetComp { - elt, - generators, - range: _range, - }) => Self::SetComp(ExprSetComp { - elt: elt.into(), - generators: generators.iter().map(Into::into).collect(), - }), - ast::Expr::DictComp(ast::ExprDictComp { - key, - value, - generators, - range: _range, - }) => Self::DictComp(ExprDictComp { - key: key.into(), - value: value.into(), - generators: generators.iter().map(Into::into).collect(), - }), - ast::Expr::GeneratorExp(ast::ExprGeneratorExp { - elt, - generators, - range: _range, - }) => Self::GeneratorExp(ExprGeneratorExp { - elt: elt.into(), - generators: generators.iter().map(Into::into).collect(), - }), - ast::Expr::Await(ast::ExprAwait { - value, - range: _range, - }) => Self::Await(ExprAwait { - value: value.into(), - }), - ast::Expr::Yield(ast::ExprYield { - value, - range: _range, - }) => Self::Yield(ExprYield { - value: value.as_ref().map(Into::into), - }), - ast::Expr::YieldFrom(ast::ExprYieldFrom { - value, - range: _range, - }) => Self::YieldFrom(ExprYieldFrom { - value: value.into(), - }), - ast::Expr::Compare(ast::ExprCompare { - left, - ops, - comparators, - range: _range, - }) => Self::Compare(ExprCompare { - left: left.into(), - ops: ops.iter().map(Into::into).collect(), - comparators: comparators.iter().map(Into::into).collect(), - }), - ast::Expr::Call(ast::ExprCall { - func, - args, - keywords, - range: _range, - }) => Self::Call(ExprCall { - func: func.into(), - args: args.iter().map(Into::into).collect(), - keywords: keywords.iter().map(Into::into).collect(), - }), - ast::Expr::FormattedValue(ast::ExprFormattedValue { - value, - conversion, - format_spec, - range: _range, - }) => Self::FormattedValue(ExprFormattedValue { - value: value.into(), - conversion: *conversion, - format_spec: format_spec.as_ref().map(Into::into), - }), - ast::Expr::JoinedStr(ast::ExprJoinedStr { - values, - range: _range, - }) => Self::JoinedStr(ExprJoinedStr { - values: values.iter().map(Into::into).collect(), - }), - ast::Expr::Constant(ast::ExprConstant { - value, - kind, - range: _range, - }) => Self::Constant(ExprConstant { - value: value.into(), - kind: kind.as_ref().map(String::as_str), - }), - ast::Expr::Attribute(ast::ExprAttribute { - value, - attr, - ctx, - range: _range, - }) => Self::Attribute(ExprAttribute { - value: value.into(), - attr: attr.as_str(), - ctx: ctx.into(), - }), - ast::Expr::Subscript(ast::ExprSubscript { - value, - slice, - ctx, - range: _range, - }) => Self::Subscript(ExprSubscript { - value: value.into(), - slice: slice.into(), - ctx: ctx.into(), - }), - ast::Expr::Starred(ast::ExprStarred { - value, - ctx, - range: _range, - }) => Self::Starred(ExprStarred { - value: value.into(), - ctx: ctx.into(), - }), - ast::Expr::Name(ast::ExprName { - id, - ctx, - range: _range, - }) => Self::Name(ExprName { - id: id.as_str(), - ctx: ctx.into(), - }), - ast::Expr::List(ast::ExprList { - elts, - ctx, - range: _range, - }) => Self::List(ExprList { - elts: elts.iter().map(Into::into).collect(), - ctx: ctx.into(), - }), - ast::Expr::Tuple(ast::ExprTuple { - elts, - ctx, - range: _range, - }) => Self::Tuple(ExprTuple { - elts: elts.iter().map(Into::into).collect(), - ctx: ctx.into(), - }), - ast::Expr::Slice(ast::ExprSlice { - lower, - upper, - step, - range: _range, - }) => Self::Slice(ExprSlice { - lower: lower.as_ref().map(Into::into), - upper: upper.as_ref().map(Into::into), - step: step.as_ref().map(Into::into), - }), - } + Self::Verbatim(ExprVerbatim { expr }) } } @@ -1072,13 +822,13 @@ pub struct StmtExpr<'a> { } #[derive(Debug)] -pub struct StmtVerbatim { - pub range: TextRange, +pub struct StmtVerbatim<'a> { + pub stmt: &'a ast::Stmt, } #[derive(Debug)] pub enum Stmt<'a> { - Verbatim(StmtVerbatim), + Verbatim(StmtVerbatim<'a>), FunctionDef(StmtFunctionDef<'a>), AsyncFunctionDef(StmtAsyncFunctionDef<'a>), ClassDef(StmtClassDef<'a>), @@ -1110,250 +860,6 @@ pub enum Stmt<'a> { impl<'a> From<&'a ast::Stmt> for Stmt<'a> { fn from(stmt: &'a ast::Stmt) -> Self { - match stmt { - ast::Stmt::FunctionDef(ast::StmtFunctionDef { - name, - args, - body, - decorator_list, - returns, - type_comment, - range: _range, - }) => Self::FunctionDef(StmtFunctionDef { - name: name.as_str(), - args: args.into(), - body: body.iter().map(Into::into).collect(), - decorator_list: decorator_list.iter().map(Into::into).collect(), - returns: returns.as_ref().map(Into::into), - type_comment: type_comment.as_ref().map(String::as_str), - }), - ast::Stmt::AsyncFunctionDef(ast::StmtAsyncFunctionDef { - name, - args, - body, - decorator_list, - returns, - type_comment, - range: _range, - }) => Self::AsyncFunctionDef(StmtAsyncFunctionDef { - name: name.as_str(), - args: args.into(), - body: body.iter().map(Into::into).collect(), - decorator_list: decorator_list.iter().map(Into::into).collect(), - returns: returns.as_ref().map(Into::into), - type_comment: type_comment.as_ref().map(String::as_str), - }), - ast::Stmt::ClassDef(ast::StmtClassDef { - name, - bases, - keywords, - body, - decorator_list, - range: _range, - }) => Self::ClassDef(StmtClassDef { - name: name.as_str(), - bases: bases.iter().map(Into::into).collect(), - keywords: keywords.iter().map(Into::into).collect(), - body: body.iter().map(Into::into).collect(), - decorator_list: decorator_list.iter().map(Into::into).collect(), - }), - ast::Stmt::Return(ast::StmtReturn { - value, - range: _range, - }) => Self::Return(StmtReturn { - value: value.as_ref().map(Into::into), - }), - ast::Stmt::Delete(ast::StmtDelete { - targets, - range: _range, - }) => Self::Delete(StmtDelete { - targets: targets.iter().map(Into::into).collect(), - }), - ast::Stmt::Assign(ast::StmtAssign { - targets, - value, - type_comment, - range: _range, - }) => Self::Assign(StmtAssign { - targets: targets.iter().map(Into::into).collect(), - value: value.into(), - type_comment: type_comment.as_ref().map(String::as_str), - }), - ast::Stmt::AugAssign(ast::StmtAugAssign { - target, - op, - value, - range: _range, - }) => Self::AugAssign(StmtAugAssign { - target: target.into(), - op: op.into(), - value: value.into(), - }), - ast::Stmt::AnnAssign(ast::StmtAnnAssign { - target, - annotation, - value, - simple, - range: _range, - }) => Self::AnnAssign(StmtAnnAssign { - target: target.into(), - annotation: annotation.into(), - value: value.as_ref().map(Into::into), - simple: *simple, - }), - ast::Stmt::For(ast::StmtFor { - target, - iter, - body, - orelse, - type_comment, - range: _range, - }) => Self::For(StmtFor { - target: target.into(), - iter: iter.into(), - body: body.iter().map(Into::into).collect(), - orelse: orelse.iter().map(Into::into).collect(), - type_comment: type_comment.as_ref().map(String::as_str), - }), - ast::Stmt::AsyncFor(ast::StmtAsyncFor { - target, - iter, - body, - orelse, - type_comment, - range: _range, - }) => Self::AsyncFor(StmtAsyncFor { - target: target.into(), - iter: iter.into(), - body: body.iter().map(Into::into).collect(), - orelse: orelse.iter().map(Into::into).collect(), - type_comment: type_comment.as_ref().map(String::as_str), - }), - ast::Stmt::While(ast::StmtWhile { - test, - body, - orelse, - range: _range, - }) => Self::While(StmtWhile { - test: test.into(), - body: body.iter().map(Into::into).collect(), - orelse: orelse.iter().map(Into::into).collect(), - }), - ast::Stmt::If(ast::StmtIf { - test, - body, - orelse, - range: _range, - }) => Self::If(StmtIf { - test: test.into(), - body: body.iter().map(Into::into).collect(), - orelse: orelse.iter().map(Into::into).collect(), - }), - ast::Stmt::With(ast::StmtWith { - items, - body, - type_comment, - range: _range, - }) => Self::With(StmtWith { - items: items.iter().map(Into::into).collect(), - body: body.iter().map(Into::into).collect(), - type_comment: type_comment.as_ref().map(String::as_str), - }), - ast::Stmt::AsyncWith(ast::StmtAsyncWith { - items, - body, - type_comment, - range: _range, - }) => Self::AsyncWith(StmtAsyncWith { - items: items.iter().map(Into::into).collect(), - body: body.iter().map(Into::into).collect(), - type_comment: type_comment.as_ref().map(String::as_str), - }), - ast::Stmt::Match(ast::StmtMatch { - subject, - cases, - range: _range, - }) => Self::Match(StmtMatch { - subject: subject.into(), - cases: cases.iter().map(Into::into).collect(), - }), - ast::Stmt::Raise(ast::StmtRaise { - exc, - cause, - range: _range, - }) => Self::Raise(StmtRaise { - exc: exc.as_ref().map(Into::into), - cause: cause.as_ref().map(Into::into), - }), - ast::Stmt::Try(ast::StmtTry { - body, - handlers, - orelse, - finalbody, - range: _range, - }) => Self::Try(StmtTry { - body: body.iter().map(Into::into).collect(), - handlers: handlers.iter().map(Into::into).collect(), - orelse: orelse.iter().map(Into::into).collect(), - finalbody: finalbody.iter().map(Into::into).collect(), - }), - ast::Stmt::TryStar(ast::StmtTryStar { - body, - handlers, - orelse, - finalbody, - range: _range, - }) => Self::TryStar(StmtTryStar { - body: body.iter().map(Into::into).collect(), - handlers: handlers.iter().map(Into::into).collect(), - orelse: orelse.iter().map(Into::into).collect(), - finalbody: finalbody.iter().map(Into::into).collect(), - }), - ast::Stmt::Assert(ast::StmtAssert { - test, - msg, - range: _range, - }) => Self::Assert(StmtAssert { - test: test.into(), - msg: msg.as_ref().map(Into::into), - }), - ast::Stmt::Import(ast::StmtImport { - names, - range: _range, - }) => Self::Import(StmtImport { - names: names.iter().map(Into::into).collect(), - }), - ast::Stmt::ImportFrom(ast::StmtImportFrom { - module, - names, - level, - range: _range, - }) => Self::ImportFrom(StmtImportFrom { - module: module.as_deref(), - names: names.iter().map(Into::into).collect(), - level: *level, - }), - ast::Stmt::Global(ast::StmtGlobal { - names, - range: _range, - }) => Self::Global(StmtGlobal { - names: names.iter().map(ast::Identifier::as_str).collect(), - }), - ast::Stmt::Nonlocal(ast::StmtNonlocal { - names, - range: _range, - }) => Self::Nonlocal(StmtNonlocal { - names: names.iter().map(ast::Identifier::as_str).collect(), - }), - ast::Stmt::Expr(ast::StmtExpr { - value, - range: _range, - }) => Self::Expr(StmtExpr { - value: value.into(), - }), - ast::Stmt::Pass(_) => Self::Pass, - ast::Stmt::Break(_) => Self::Break, - ast::Stmt::Continue(_) => Self::Continue, - } + Self::Verbatim(StmtVerbatim { stmt }) } }