From d7412af9965e209a80eff81ad88c9cf7706d1b20 Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 2 Sep 2022 19:50:15 -0400 Subject: [PATCH] Try lifetimes --- remove_redundant_fstring.py | 1 + src/check_cst.rs | 67 +++++++++-- src/cst_visitor.rs | 223 +++++++++++++++++++++++++----------- 3 files changed, 213 insertions(+), 78 deletions(-) create mode 100644 remove_redundant_fstring.py diff --git a/remove_redundant_fstring.py b/remove_redundant_fstring.py new file mode 100644 index 0000000000..675cda8ce6 --- /dev/null +++ b/remove_redundant_fstring.py @@ -0,0 +1 @@ +bad: str = f"bad" + "bad" diff --git a/src/check_cst.rs b/src/check_cst.rs index 2d2fb21610..54832ee292 100644 --- a/src/check_cst.rs +++ b/src/check_cst.rs @@ -1,9 +1,24 @@ +use std::borrow::Borrow; use std::collections::BTreeMap; -use libcst_native::{Arg, ClassDef, Codegen, Expression, If, Module}; -use rustpython_parser::ast::Location; use bat::PrettyPrinter; - +use bumpalo::Bump; +use libcst_native::{ + AnnAssign, Annotation, Arg, AsName, Assert, Assign, AssignEqual, AssignTarget, + AssignTargetExpression, Asynchronous, Attribute, AugAssign, Await, BinaryOp, BinaryOperation, + BooleanOp, BooleanOperation, Break, Call, ClassDef, Codegen, CompFor, CompIf, CompOp, + Comparison, ComparisonTarget, CompoundStatement, ConcatenatedString, Continue, Decorator, Del, + DelTargetExpression, Dict, DictComp, DictElement, Element, Ellipsis, Else, ExceptHandler, + ExceptStarHandler, Expr, Expression, Finally, Float, For, FormattedString, + FormattedStringContent, FormattedStringExpression, FormattedStringText, FunctionDef, + GeneratorExp, Global, If, IfExp, Imaginary, Import, ImportAlias, ImportFrom, ImportStar, + IndentedBlock, Index, Integer, Lambda, List, ListComp, Match, Module, Name, NameItem, + NamedExpr, Nonlocal, OrElse, Param, ParamStar, Parameters, Pass, Raise, Return, Set, SetComp, + SimpleStatementLine, SimpleStatementSuite, SimpleString, Slice, SmallStatement, + StarredDictElement, StarredElement, Statement, Subscript, SubscriptElement, Try, TryStar, + Tuple, UnaryOp, UnaryOperation, While, With, WithItem, Yield, YieldValue, +}; +use rustpython_parser::ast::Location; use crate::checks::{Check, CheckKind}; use crate::cst_visitor; @@ -41,6 +56,7 @@ struct Binding { } struct Checker<'a> { + bump: Bump, settings: &'a Settings, checks: Vec, } @@ -48,6 +64,7 @@ struct Checker<'a> { impl Checker<'_> { pub fn new(settings: &Settings) -> Checker { Checker { + bump: Bump::new(), settings, checks: vec![], } @@ -65,6 +82,32 @@ impl CSTVisitor for Checker<'_> { cst_visitor::walk_If(self, node); } + fn visit_Expression<'a, 'b>(&'b mut self, node: &'a Expression<'a>) -> Expression<'a> + where + 'b: 'a, + { + match node { + Expression::FormattedString(node) => match &node.parts[..] { + [node] => match node { + FormattedStringContent::Text(node) => { + let x = node.value.to_string(); + println!("Found: {:?}", node); + return Expression::SimpleString(Box::new(SimpleString { + value: self.bump.alloc(format!("\"{}\"", x)), + lpar: vec![], + rpar: vec![], + })); + } + _ => {} + }, + _ => {} + }, + _ => {} + } + + cst_visitor::walk_Expression(self, node) + } + fn visit_ClassDef<'a>(&mut self, node: &'a ClassDef<'a>) -> ClassDef<'a> { let mut bases: Vec> = node .bases @@ -107,10 +150,10 @@ pub fn check_cst<'a>(python_cst: &'a Module<'a>, settings: &Settings) -> Vec(python_cst: &'a Module<'a>, settings: &Settings) -> Vec(&mut self, node: &'a Module<'a>) -> Module<'a> { + fn visit_Module<'a, 'b>(&'b mut self, node: &'a Module<'a>) -> Module<'a> + where + 'b: 'a, + { walk_Module(self, node) } - fn visit_Statement<'a>(&mut self, node: &'a Statement<'a>) -> Option> { + fn visit_Statement<'a, 'b>(&'b mut self, node: &'a Statement<'a>) -> Option> + where + 'b: 'a, + { walk_Statement(self, node) } - fn visit_SimpleStatementLine<'a>( - &mut self, + fn visit_SimpleStatementLine<'a, 'b>( + &'b mut self, node: &'a SimpleStatementLine<'a>, - ) -> Option> { + ) -> Option> + where + 'b: 'a, + { walk_SimpleStatementLine(self, node) } - fn visit_CompoundStatement<'a>( - &mut self, + fn visit_CompoundStatement<'a, 'b>( + &'b mut self, node: &'a CompoundStatement<'a>, - ) -> Option> { + ) -> Option> + where + 'b: 'a, + { walk_CompoundStatement(self, node) } - fn visit_SmallStatement(&mut self, node: &SmallStatement) { - walk_SmallStatement(self, node); + fn visit_SmallStatement<'a, 'b>( + &'b mut self, + node: &'a SmallStatement<'a>, + ) -> SmallStatement<'a> + where + 'b: 'a, + { + walk_SmallStatement(self, node) } - fn visit_Expression(&mut self, node: &Expression) { - walk_Expression(self, node); + fn visit_Expression<'a, 'b>(&'b mut self, node: &'a Expression<'a>) -> Expression<'a> + where + 'b: 'a, + { + walk_Expression(self, node) } - fn visit_AnnAssign(&mut self, node: &AnnAssign) { - walk_AnnAssign(self, node); + fn visit_AnnAssign<'a, 'b>(&'b mut self, node: &'a AnnAssign<'a>) -> AnnAssign<'a> + where + 'b: 'a, + { + walk_AnnAssign(self, node) } fn visit_Annotation(&mut self, node: &Annotation) { walk_Annotation(self, node); @@ -81,11 +105,20 @@ pub trait CSTVisitor { fn visit_Await(&mut self, node: &Await) { walk_Await(self, node); } - fn visit_BinaryOperation(&mut self, node: &BinaryOperation) { - walk_BinaryOperation(self, node); + fn visit_BinaryOperation<'a, 'b>( + &'b mut self, + node: &'a BinaryOperation<'a>, + ) -> BinaryOperation<'a> + where + 'b: 'a, + { + walk_BinaryOperation(self, node) } - fn visit_BinaryOp(&mut self, node: &BinaryOp) { - walk_BinaryOp(self, node); + fn visit_BinaryOp<'a, 'b>(&'b mut self, node: &'a BinaryOp<'a>) -> BinaryOp<'a> + where + 'b: 'a, + { + walk_BinaryOp(self, node) } fn visit_BooleanOperation(&mut self, node: &BooleanOperation) { walk_BooleanOperation(self, node); @@ -341,11 +374,14 @@ pub trait CSTVisitor { } } -pub fn walk_Module<'a, V: CSTVisitor + ?Sized>(visitor: &mut V, node: &'a Module<'a>) -> Module<'a> +pub fn walk_Module<'a, 'b, V: CSTVisitor + ?Sized>( + visitor: &'b mut V, + node: &'a Module<'a>, +) -> Module<'a> where - 'a: 'a, + 'b: 'a, { - let mut body: Vec = vec![]; + let mut body: Vec> = vec![]; for node in &node.body { if let Some(node) = visitor.visit_Statement(node) { body.push(node) @@ -356,11 +392,13 @@ where transformed.body = body; transformed } - -pub fn walk_Statement<'a, V: CSTVisitor + ?Sized>( - visitor: &mut V, +pub fn walk_Statement<'a, 'b, V: CSTVisitor + ?Sized>( + visitor: &'b mut V, node: &'a Statement<'a>, -) -> Option> { +) -> Option> +where + 'b: 'a, +{ match node { Statement::Simple(node) => visitor .visit_SimpleStatementLine(node) @@ -370,21 +408,29 @@ pub fn walk_Statement<'a, V: CSTVisitor + ?Sized>( .map(Statement::Compound), } } - -pub fn walk_SimpleStatementLine<'a, V: CSTVisitor + ?Sized>( - visitor: &mut V, +pub fn walk_SimpleStatementLine<'a, 'b, V: CSTVisitor + ?Sized>( + visitor: &'b mut V, node: &'a SimpleStatementLine<'a>, -) -> Option> { +) -> Option> +where + 'b: 'a, +{ + println!("{:?}", node); + let mut body: Vec = vec![]; for node in &node.body { - visitor.visit_SmallStatement(node); + body.push(visitor.visit_SmallStatement(node).clone()); } - Some(node.clone()) + let mut transformed = node.clone(); + transformed.body = body; + Some(transformed) } - -pub fn walk_CompoundStatement<'a, V: CSTVisitor + ?Sized>( - visitor: &mut V, +pub fn walk_CompoundStatement<'a, 'b, V: CSTVisitor + ?Sized>( + visitor: &'b mut V, node: &'a CompoundStatement<'a>, -) -> Option> { +) -> Option> +where + 'b: 'a, +{ match node { CompoundStatement::If(node) => { visitor.visit_If(node); @@ -404,8 +450,13 @@ pub fn walk_CompoundStatement<'a, V: CSTVisitor + ?Sized>( Some(node.clone()) } - -pub fn walk_SmallStatement(visitor: &mut V, node: &SmallStatement) { +pub fn walk_SmallStatement<'a, 'b, V: CSTVisitor + ?Sized>( + visitor: &'b mut V, + node: &'a SmallStatement<'a>, +) -> SmallStatement<'a> +where + 'b: 'a, +{ match node { SmallStatement::Pass(node) => visitor.visit_Pass(node), SmallStatement::Break(node) => visitor.visit_Break(node), @@ -416,16 +467,22 @@ pub fn walk_SmallStatement(visitor: &mut V, node: &Small SmallStatement::Import(node) => visitor.visit_Import(node), SmallStatement::ImportFrom(node) => visitor.visit_ImportFrom(node), SmallStatement::Assign(node) => visitor.visit_Assign(node), - SmallStatement::AnnAssign(node) => visitor.visit_AnnAssign(node), + SmallStatement::AnnAssign(node) => { + return SmallStatement::AnnAssign(visitor.visit_AnnAssign(node)); + } SmallStatement::Raise(node) => visitor.visit_Raise(node), SmallStatement::Global(node) => visitor.visit_Global(node), SmallStatement::Nonlocal(node) => visitor.visit_Nonlocal(node), SmallStatement::AugAssign(node) => visitor.visit_AugAssign(node), SmallStatement::Del(node) => visitor.visit_Del(node), } -} -pub fn walk_Expression(visitor: &mut V, node: &Expression) { + node.clone() +} +pub fn walk_Expression<'a, 'b, V: CSTVisitor + ?Sized>( + visitor: &'b mut V, + node: &'a Expression<'a>, +) -> Expression<'a> { match node { Expression::Name(node) => visitor.visit_Name(node), Expression::Ellipsis(node) => visitor.visit_Ellipsis(node), @@ -434,7 +491,9 @@ pub fn walk_Expression(visitor: &mut V, node: &Expressio Expression::Imaginary(node) => visitor.visit_Imaginary(node), Expression::Comparison(node) => visitor.visit_Comparison(node), Expression::UnaryOperation(node) => visitor.visit_UnaryOperation(node), - Expression::BinaryOperation(node) => visitor.visit_BinaryOperation(node), + Expression::BinaryOperation(node) => { + return Expression::BinaryOperation(Box::new(visitor.visit_BinaryOperation(node))) + } Expression::BooleanOperation(node) => visitor.visit_BooleanOperation(node), Expression::Attribute(node) => visitor.visit_Attribute(node), Expression::Tuple(node) => visitor.visit_Tuple(node), @@ -457,6 +516,8 @@ pub fn walk_Expression(visitor: &mut V, node: &Expressio Expression::FormattedString(node) => visitor.visit_FormattedString(node), Expression::NamedExpr(node) => visitor.visit_NamedExpr(node), } + + node.clone() } pub fn walk_AssignEqual(visitor: &mut V, node: &AssignEqual) { // Nothing to do. @@ -477,11 +538,22 @@ pub fn walk_AssignTargetExpression( AssignTargetExpression::Subscript(node) => visitor.visit_Subscript(node), } } -pub fn walk_AnnAssign(visitor: &mut V, node: &AnnAssign) { +pub fn walk_AnnAssign<'a, 'b, V: CSTVisitor + ?Sized>( + visitor: &'b mut V, + node: &'a AnnAssign<'a>, +) -> AnnAssign<'a> +where + 'b: 'a, +{ + println!("walk_AnnAssign"); + let mut transformed: AnnAssign<'a> = node.clone(); visitor.visit_AssignTargetExpression(&node.target); if let Some(node) = &node.value { - visitor.visit_Expression(node) + println!("Before: {:?}", node); + transformed.value = Some(visitor.visit_Expression(node)); + println!("After: {:?}", transformed.value); } + transformed } pub fn walk_Annotation(visitor: &mut V, node: &Annotation) { visitor.visit_Expression(&node.annotation); @@ -508,13 +580,13 @@ pub fn walk_Assign(visitor: &mut V, node: &Assign) { for target in &node.targets { visitor.visit_AssignTarget(target) } - visitor.visit_Expression(&node.value) + visitor.visit_Expression(&node.value); } pub fn walk_Asynchronous(visitor: &mut V, node: &Asynchronous) { // Nothing to do. } pub fn walk_Attribute(visitor: &mut V, node: &Attribute) { - visitor.visit_Expression(&node.value) + visitor.visit_Expression(&node.value); } pub fn walk_AugAssign(visitor: &mut V, node: &AugAssign) { visitor.visit_AssignTargetExpression(&node.target); @@ -523,13 +595,24 @@ pub fn walk_AugAssign(visitor: &mut V, node: &AugAssign) pub fn walk_Await(visitor: &mut V, node: &Await) { visitor.visit_Expression(&node.expression); } -pub fn walk_BinaryOperation(visitor: &mut V, node: &BinaryOperation) { - visitor.visit_Expression(&node.left); +pub fn walk_BinaryOperation<'a, 'b, V: CSTVisitor + ?Sized>( + visitor: &'b mut V, + node: &'a BinaryOperation<'a>, +) -> BinaryOperation<'a> +where + 'b: 'a, +{ + let mut transformed: BinaryOperation = node.clone(); + + transformed.left = Box::new(visitor.visit_Expression(&node.left)); + transformed.right = Box::new(visitor.visit_Expression(&node.right)); visitor.visit_BinaryOp(&node.operator); - visitor.visit_Expression(&node.right); + + transformed } -pub fn walk_BinaryOp(visitor: &mut V, node: &BinaryOp) { +pub fn walk_BinaryOp<'a, 'b, V: CSTVisitor + ?Sized>(visitor: &'b mut V, node: &'a BinaryOp<'a>) -> BinaryOp<'a> { // Nothing to do. + node.clone() } pub fn walk_BooleanOperation(visitor: &mut V, node: &BooleanOperation) { visitor.visit_Expression(&node.left); @@ -546,7 +629,7 @@ pub fn walk_Call(visitor: &mut V, node: &Call) { for node in &node.args { visitor.visit_Arg(node) } - visitor.visit_Expression(&node.func) + visitor.visit_Expression(&node.func); } pub fn walk_ClassDef<'a, V: CSTVisitor + ?Sized>( visitor: &mut V, @@ -583,7 +666,7 @@ pub fn walk_CompFor(visitor: &mut V, node: &CompFor) { } } pub fn walk_CompIf(visitor: &mut V, node: &CompIf) { - visitor.visit_Expression(&node.test) + visitor.visit_Expression(&node.test); } pub fn walk_Comparison(visitor: &mut V, node: &Comparison) { visitor.visit_Expression(&node.left); @@ -605,7 +688,7 @@ pub fn walk_Continue(visitor: &mut V, node: &Continue) { // Nothing to do. } pub fn walk_Decorator(visitor: &mut V, node: &Decorator) { - visitor.visit_Expression(&node.decorator) + visitor.visit_Expression(&node.decorator); } pub fn walk_Del(visitor: &mut V, node: &Del) { visitor.visit_DelTargetExpression(&node.target) @@ -643,9 +726,13 @@ pub fn walk_DictElement(visitor: &mut V, node: &DictElem } pub fn walk_Element(visitor: &mut V, node: &Element) { match node { - Element::Simple { value: node, .. } => visitor.visit_Expression(node), - Element::Starred(node) => visitor.visit_StarredElement(node), - } + Element::Simple { value: node, .. } => { + visitor.visit_Expression(node); + } + Element::Starred(node) => { + visitor.visit_StarredElement(node); + } + }; } pub fn walk_Ellipsis(visitor: &mut V, node: &Ellipsis) { // Nothing to do. @@ -679,7 +766,7 @@ pub fn walk_ExceptStarHandler(visitor: &mut V, node: &Ex } } pub fn walk_Expr(visitor: &mut V, node: &Expr) { - visitor.visit_Expression(&node.value) + visitor.visit_Expression(&node.value); } pub fn walk_Finally(visitor: &mut V, node: &Finally) { match &node.body { @@ -727,7 +814,7 @@ pub fn walk_FormattedStringText( // Nothing to do. } pub fn walk_From(visitor: &mut V, node: &From) { - visitor.visit_Expression(&node.item) + visitor.visit_Expression(&node.item); } pub fn walk_FunctionDef(visitor: &mut V, node: &FunctionDef) { visitor.visit_Name(&node.name); @@ -908,25 +995,25 @@ pub fn walk_SimpleStatementSuite( node: &SimpleStatementSuite, ) { for node in &node.body { - visitor.visit_SmallStatement(node) + visitor.visit_SmallStatement(node); } } pub fn walk_Slice(visitor: &mut V, node: &Slice) { if let Some(node) = &node.lower { - visitor.visit_Expression(node) + visitor.visit_Expression(node); } if let Some(node) = &node.upper { - visitor.visit_Expression(node) + visitor.visit_Expression(node); } if let Some(node) = &node.step { - visitor.visit_Expression(node) + visitor.visit_Expression(node); } } pub fn walk_StarredDictElement(visitor: &mut V, node: &StarredDictElement) { - visitor.visit_Expression(&node.value) + visitor.visit_Expression(&node.value); } pub fn walk_StarredElement(visitor: &mut V, node: &StarredElement) { - visitor.visit_Expression(&node.value) + visitor.visit_Expression(&node.value); } pub fn walk_Subscript(visitor: &mut V, node: &Subscript) { visitor.visit_Expression(&node.value); @@ -1017,7 +1104,11 @@ pub fn walk_Yield(visitor: &mut V, node: &Yield) { } pub fn walk_YieldValue(visitor: &mut V, node: &YieldValue) { match node { - YieldValue::Expression(node) => visitor.visit_Expression(node), - YieldValue::From(node) => visitor.visit_From(node), - } + YieldValue::Expression(node) => { + visitor.visit_Expression(node); + } + YieldValue::From(node) => { + visitor.visit_From(node); + } + }; }