From 0cfa2d617a4a74bb23e9851f01752a7d811d108b Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Fri, 2 Sep 2022 15:34:51 -0400 Subject: [PATCH] Iterate on CST traversal --- src/ast_visitor.rs | 36 +- src/autofix.rs | 14 - src/check_ast.rs | 14 +- src/check_cst.rs | 395 +------------- src/cst_visitor.rs | 1255 +++++++++++++++++++++++++++++++++----------- src/lib.rs | 1 - src/linter.rs | 33 +- 7 files changed, 1016 insertions(+), 732 deletions(-) delete mode 100644 src/autofix.rs diff --git a/src/ast_visitor.rs b/src/ast_visitor.rs index b0fadc8a43..a8f70b51f2 100644 --- a/src/ast_visitor.rs +++ b/src/ast_visitor.rs @@ -4,7 +4,7 @@ use rustpython_parser::ast::{ PatternKind, Stmt, StmtKind, Unaryop, Withitem, }; -pub trait Visitor { +pub trait ASTVisitor { fn visit_stmt(&mut self, stmt: &Stmt) { walk_stmt(self, stmt); } @@ -61,7 +61,7 @@ pub trait Visitor { } } -pub fn walk_stmt(visitor: &mut V, stmt: &Stmt) { +pub fn walk_stmt(visitor: &mut V, stmt: &Stmt) { match &stmt.node { StmtKind::FunctionDef { args, body, .. } => { visitor.visit_arguments(args); @@ -238,7 +238,7 @@ pub fn walk_stmt(visitor: &mut V, stmt: &Stmt) { } } -pub fn walk_expr(visitor: &mut V, expr: &Expr) { +pub fn walk_expr(visitor: &mut V, expr: &Expr) { match &expr.node { ExprKind::BoolOp { op, values } => { visitor.visit_boolop(op); @@ -399,7 +399,7 @@ pub fn walk_expr(visitor: &mut V, expr: &Expr) { } } -pub fn walk_constant(visitor: &mut V, constant: &Constant) { +pub fn walk_constant(visitor: &mut V, constant: &Constant) { if let Constant::Tuple(constants) = constant { for constant in constants { visitor.visit_constant(constant) @@ -407,7 +407,7 @@ pub fn walk_constant(visitor: &mut V, constant: &Constant) } } -pub fn walk_comprehension(visitor: &mut V, comprehension: &Comprehension) { +pub fn walk_comprehension(visitor: &mut V, comprehension: &Comprehension) { visitor.visit_expr(&comprehension.target, None); visitor.visit_expr(&comprehension.iter, None); for expr in &comprehension.ifs { @@ -415,7 +415,7 @@ pub fn walk_comprehension(visitor: &mut V, comprehension: & } } -pub fn walk_excepthandler(visitor: &mut V, excepthandler: &Excepthandler) { +pub fn walk_excepthandler(visitor: &mut V, excepthandler: &Excepthandler) { match &excepthandler.node { ExcepthandlerKind::ExceptHandler { type_, body, .. } => { if let Some(expr) = type_ { @@ -428,7 +428,7 @@ pub fn walk_excepthandler(visitor: &mut V, excepthandler: & } } -pub fn walk_arguments(visitor: &mut V, arguments: &Arguments) { +pub fn walk_arguments(visitor: &mut V, arguments: &Arguments) { for arg in &arguments.posonlyargs { visitor.visit_arg(arg); } @@ -452,24 +452,24 @@ pub fn walk_arguments(visitor: &mut V, arguments: &Argument } } -pub fn walk_arg(visitor: &mut V, arg: &Arg) { +pub fn walk_arg(visitor: &mut V, arg: &Arg) { if let Some(expr) = &arg.node.annotation { visitor.visit_annotation(expr) } } -pub fn walk_keyword(visitor: &mut V, keyword: &Keyword) { +pub fn walk_keyword(visitor: &mut V, keyword: &Keyword) { visitor.visit_expr(&keyword.node.value, None); } -pub fn walk_withitem(visitor: &mut V, withitem: &Withitem) { +pub fn walk_withitem(visitor: &mut V, withitem: &Withitem) { visitor.visit_expr(&withitem.context_expr, None); if let Some(expr) = &withitem.optional_vars { visitor.visit_expr(expr, None); } } -pub fn walk_match_case(visitor: &mut V, match_case: &MatchCase) { +pub fn walk_match_case(visitor: &mut V, match_case: &MatchCase) { visitor.visit_pattern(&match_case.pattern); if let Some(expr) = &match_case.guard { visitor.visit_expr(expr, None); @@ -479,7 +479,7 @@ pub fn walk_match_case(visitor: &mut V, match_case: &MatchC } } -pub fn walk_pattern(visitor: &mut V, pattern: &Pattern) { +pub fn walk_pattern(visitor: &mut V, pattern: &Pattern) { match &pattern.node { PatternKind::MatchValue { value } => visitor.visit_expr(value, None), PatternKind::MatchSingleton { value } => visitor.visit_constant(value), @@ -527,24 +527,24 @@ pub fn walk_pattern(visitor: &mut V, pattern: &Pattern) { #[allow(unused_variables)] #[inline(always)] -pub fn walk_expr_context(visitor: &mut V, expr_context: &ExprContext) {} +pub fn walk_expr_context(visitor: &mut V, expr_context: &ExprContext) {} #[allow(unused_variables)] #[inline(always)] -pub fn walk_boolop(visitor: &mut V, boolop: &Boolop) {} +pub fn walk_boolop(visitor: &mut V, boolop: &Boolop) {} #[allow(unused_variables)] #[inline(always)] -pub fn walk_operator(visitor: &mut V, operator: &Operator) {} +pub fn walk_operator(visitor: &mut V, operator: &Operator) {} #[allow(unused_variables)] #[inline(always)] -pub fn walk_unaryop(visitor: &mut V, unaryop: &Unaryop) {} +pub fn walk_unaryop(visitor: &mut V, unaryop: &Unaryop) {} #[allow(unused_variables)] #[inline(always)] -pub fn walk_cmpop(visitor: &mut V, cmpop: &Cmpop) {} +pub fn walk_cmpop(visitor: &mut V, cmpop: &Cmpop) {} #[allow(unused_variables)] #[inline(always)] -pub fn walk_alias(visitor: &mut V, alias: &Alias) {} +pub fn walk_alias(visitor: &mut V, alias: &Alias) {} diff --git a/src/autofix.rs b/src/autofix.rs deleted file mode 100644 index 51f5713bdf..0000000000 --- a/src/autofix.rs +++ /dev/null @@ -1,14 +0,0 @@ -use crate::message::Message; -use crate::settings::Settings; -use crate::{cache, fs}; -use libcst_native::parse_module; - -pub fn autofix(contents: &str, messages: &[Message]) { - // Parse the module. - let mut m = match parse_module(&contents, None) { - Ok(m) => m, - Err(e) => panic!("foo"), - }; - - m.body -} diff --git a/src/check_ast.rs b/src/check_ast.rs index 98c3fbbc70..7c16db2f09 100644 --- a/src/check_ast.rs +++ b/src/check_ast.rs @@ -7,11 +7,11 @@ use rustpython_parser::ast::{ use rustpython_parser::parser; use crate::ast_ops::{extract_all_names, Binding, BindingKind, Scope, ScopeKind}; +use crate::ast_visitor; +use crate::ast_visitor::{walk_excepthandler, ASTVisitor}; use crate::builtins::{BUILTINS, MAGIC_GLOBALS}; use crate::checks::{Check, CheckCode, CheckKind}; use crate::settings::Settings; -use crate::visitor; -use crate::visitor::{walk_excepthandler, Visitor}; struct Checker<'a> { settings: &'a Settings, @@ -37,7 +37,7 @@ impl Checker<'_> { } } -impl Visitor for Checker<'_> { +impl ASTVisitor for Checker<'_> { fn visit_stmt(&mut self, stmt: &Stmt) { match &stmt.node { StmtKind::Global { names } | StmtKind::Nonlocal { names } => { @@ -255,7 +255,7 @@ impl Visitor for Checker<'_> { _ => {} } - visitor::walk_stmt(self, stmt); + ast_visitor::walk_stmt(self, stmt); match &stmt.node { StmtKind::ClassDef { .. } => { @@ -359,7 +359,7 @@ impl Visitor for Checker<'_> { _ => {} }; - visitor::walk_expr(self, expr); + ast_visitor::walk_expr(self, expr); match &expr.node { ExprKind::GeneratorExp { .. } @@ -466,7 +466,7 @@ impl Visitor for Checker<'_> { } } - visitor::walk_arguments(self, arguments); + ast_visitor::walk_arguments(self, arguments); } fn visit_arg(&mut self, arg: &Arg) { @@ -478,7 +478,7 @@ impl Visitor for Checker<'_> { location: arg.location, }, ); - visitor::walk_arg(self, arg); + ast_visitor::walk_arg(self, arg); } } diff --git a/src/check_cst.rs b/src/check_cst.rs index d556f3c9ff..19dafc2043 100644 --- a/src/check_cst.rs +++ b/src/check_cst.rs @@ -1,14 +1,11 @@ -use std::collections::{BTreeMap, BTreeSet}; -use std::fmt::format; +use std::collections::BTreeMap; -use rustpython_parser::ast::{ - Arg, Arguments, Expr, ExprContext, ExprKind, Location, Stmt, StmtKind, Suite, -}; +use libcst_native::{Expression, If, Module}; +use rustpython_parser::ast::Location; -use crate::ast_visitor; -use crate::ast_visitor::ASTVisitor; -use crate::check_cst::ScopeKind::{Class, Function, Generator, Module}; use crate::checks::{Check, CheckKind}; +use crate::cst_visitor; +use crate::cst_visitor::CSTVisitor; use crate::settings::Settings; enum ScopeKind { @@ -44,9 +41,6 @@ struct Binding { struct Checker<'a> { settings: &'a Settings, checks: Vec, - scopes: Vec, - dead_scopes: Vec, - in_f_string: bool, } impl Checker<'_> { @@ -54,384 +48,27 @@ impl Checker<'_> { Checker { settings, checks: vec![], - scopes: vec![], - dead_scopes: vec![], - in_f_string: false, } } } -impl ASTVisitor for Checker<'_> { - fn visit_stmt(&mut self, stmt: &Stmt) { - match &stmt.node { - StmtKind::FunctionDef { name, .. } => { - self.push_scope(Scope { - kind: Function, - values: BTreeMap::new(), - }); - self.add_binding(Binding { - kind: BindingKind::ClassDefinition, - name: name.clone(), - used: false, - location: stmt.location, - }) - } - StmtKind::AsyncFunctionDef { name, .. } => { - self.push_scope(Scope { - kind: Function, - values: BTreeMap::new(), - }); - self.add_binding(Binding { - kind: BindingKind::ClassDefinition, - name: name.clone(), - used: false, - location: stmt.location, - }) - } - StmtKind::Return { .. } => { - if self - .settings - .select - .contains(CheckKind::ReturnOutsideFunction.code()) - { - if let Some(scope) = self.scopes.last() { - match scope.kind { - Class | Module => { - self.checks.push(Check { - kind: CheckKind::ReturnOutsideFunction, - location: stmt.location, - }); - } - _ => {} - } - } - } - } - StmtKind::ClassDef { .. } => self.push_scope(Scope { - kind: Class, - values: BTreeMap::new(), - }), - StmtKind::Import { names } => { - for alias in names { - if alias.node.name.contains('.') && alias.node.asname.is_none() { - self.add_binding(Binding { - kind: BindingKind::SubmoduleImportation, - name: alias.node.name.clone(), - used: false, - location: stmt.location, - }) - } else { - self.add_binding(Binding { - kind: BindingKind::Importation, - name: alias - .node - .asname - .clone() - .unwrap_or_else(|| alias.node.name.clone()), - used: false, - location: stmt.location, - }) - } - } - } - StmtKind::ImportFrom { names, module, .. } => { - for alias in names { - let name = alias - .node - .asname - .clone() - .unwrap_or_else(|| alias.node.name.clone()); - if module - .clone() - .map(|name| name == "future") - .unwrap_or_default() - { - self.add_binding(Binding { - kind: BindingKind::FutureImportation, - name, - used: true, - location: stmt.location, - }); - } else if alias.node.name == "*" { - self.add_binding(Binding { - kind: BindingKind::StarImportation, - name, - used: false, - location: stmt.location, - }); - - if self - .settings - .select - .contains(CheckKind::ImportStarUsage.code()) - { - self.checks.push(Check { - kind: CheckKind::ImportStarUsage, - location: stmt.location, - }); - } - } else { - self.add_binding(Binding { - kind: BindingKind::Importation, - name: match module { - None => name, - Some(parent) => format!("{}.{}", parent, name), - }, - used: false, - location: stmt.location, - }) - } - } - } - StmtKind::If { test, .. } => { - if self.settings.select.contains(CheckKind::IfTuple.code()) { - if let ExprKind::Tuple { .. } = test.node { - self.checks.push(Check { - kind: CheckKind::IfTuple, - location: stmt.location, - }); - } - } - } - StmtKind::Raise { exc, .. } => { - if self - .settings - .select - .contains(CheckKind::RaiseNotImplemented.code()) - { - if let Some(expr) = exc { - match &expr.node { - ExprKind::Call { func, .. } => { - if let ExprKind::Name { id, .. } = &func.node { - if id == "NotImplemented" { - self.checks.push(Check { - kind: CheckKind::RaiseNotImplemented, - location: stmt.location, - }); - } - } - } - ExprKind::Name { id, .. } => { - if id == "NotImplemented" { - self.checks.push(Check { - kind: CheckKind::RaiseNotImplemented, - location: stmt.location, - }); - } - } - _ => {} - } - } - } - } - StmtKind::AugAssign { target, .. } => { - self.handle_node_load(target); - } - _ => {} - } - - ast_visitor::walk_stmt(self, stmt); - - match &stmt.node { - StmtKind::ClassDef { .. } - | StmtKind::FunctionDef { .. } - | StmtKind::AsyncFunctionDef { .. } => { - self.pop_scope(); - } - _ => {} - }; - - if let StmtKind::ClassDef { name, .. } = &stmt.node { - self.add_binding(Binding { - kind: BindingKind::Definition, - name: name.clone(), - used: false, - location: stmt.location, +impl CSTVisitor for Checker<'_> { + fn visit_If<'a>(&'a mut self, node: &'a If) -> &'a If { + if let Expression::Tuple { .. } = node.test { + self.checks.push(Check { + kind: CheckKind::IfTuple, + location: Default::default(), }); } - } - - fn visit_expr(&mut self, expr: &Expr) { - let initial = self.in_f_string; - match &expr.node { - ExprKind::Name { ctx, .. } => match ctx { - ExprContext::Load => self.handle_node_load(expr), - ExprContext::Store => self.handle_node_store(expr), - ExprContext::Del => {} - }, - ExprKind::GeneratorExp { .. } => self.push_scope(Scope { - kind: Generator, - values: BTreeMap::new(), - }), - ExprKind::Lambda { .. } => self.push_scope(Scope { - kind: Function, - values: BTreeMap::new(), - }), - ExprKind::JoinedStr { values } => { - if !self.in_f_string - && self - .settings - .select - .contains(CheckKind::FStringMissingPlaceholders.code()) - && !values - .iter() - .any(|value| matches!(value.node, ExprKind::FormattedValue { .. })) - { - self.checks.push(Check { - kind: CheckKind::FStringMissingPlaceholders, - location: expr.location, - }); - } - self.in_f_string = true; - } - _ => {} - }; - - ast_visitor::walk_expr(self, expr); - - match &expr.node { - ExprKind::GeneratorExp { .. } | ExprKind::Lambda { .. } => { - if let Some(scope) = self.scopes.pop() { - self.dead_scopes.push(scope); - } - } - ExprKind::JoinedStr { .. } => { - self.in_f_string = initial; - } - _ => {} - }; - } - - fn visit_arguments(&mut self, arguments: &Arguments) { - if self - .settings - .select - .contains(CheckKind::DuplicateArgumentName.code()) - { - // Collect all the arguments into a single vector. - let mut all_arguments: Vec<&Arg> = arguments - .args - .iter() - .chain(arguments.posonlyargs.iter()) - .chain(arguments.kwonlyargs.iter()) - .collect(); - if let Some(arg) = &arguments.vararg { - all_arguments.push(arg); - } - if let Some(arg) = &arguments.kwarg { - all_arguments.push(arg); - } - - // Search for duplicates. - let mut idents: BTreeSet = BTreeSet::new(); - for arg in all_arguments { - let ident = &arg.node.arg; - if idents.contains(ident) { - self.checks.push(Check { - kind: CheckKind::DuplicateArgumentName, - location: arg.location, - }); - break; - } - idents.insert(ident.clone()); - } - } - - ast_visitor::walk_arguments(self, arguments); - } - - fn visit_arg(&mut self, arg: &Arg) { - self.add_binding(Binding { - kind: BindingKind::Argument, - name: arg.node.arg.clone(), - used: false, - location: arg.location, - }); - ast_visitor::walk_arg(self, arg); + cst_visitor::walk_If(self, node); + node } } -impl Checker<'_> { - fn push_scope(&mut self, scope: Scope) { - self.scopes.push(scope); - } - - fn pop_scope(&mut self) { - self.dead_scopes - .push(self.scopes.pop().expect("Attempted to pop without scope.")); - } - - fn add_binding(&mut self, binding: Binding) { - // TODO(charlie): Don't treat annotations as assignments if there is an existing value. - let scope = self.scopes.last_mut().expect("No current scope found."); - scope.values.insert( - binding.name.clone(), - match scope.values.get(&binding.name) { - None => binding, - Some(existing) => Binding { - kind: binding.kind, - name: binding.name, - location: binding.location, - used: existing.used, - }, - }, - ); - } - - fn handle_node_load(&mut self, expr: &Expr) { - if let ExprKind::Name { id, .. } = &expr.node { - for scope in self.scopes.iter_mut().rev() { - if matches!(scope.kind, Class) { - if id == "__class__" { - return; - } else { - continue; - } - } - if let Some(binding) = scope.values.get_mut(id) { - binding.used = true; - } - } - } - } - - fn handle_node_store(&mut self, expr: &Expr) { - if let ExprKind::Name { id, .. } = &expr.node { - // TODO(charlie): Handle alternate binding types (like `Annotation`). - self.add_binding(Binding { - kind: BindingKind::Assignment, - name: id.to_string(), - used: false, - location: expr.location, - }); - } - } - - fn check_dead_scopes(&mut self) { - // TODO(charlie): Handle `__all__`. - for scope in &self.dead_scopes { - for (name, binding) in scope.values.iter().rev() { - if !binding.used && matches!(binding.kind, BindingKind::Importation) { - self.checks.push(Check { - kind: CheckKind::UnusedImport(name.clone()), - location: binding.location, - }); - } - } - } - } -} - -pub fn check_ast(python_ast: &Suite, settings: &Settings) -> Vec { +pub fn check_cst(python_cst: &Module, settings: &Settings) -> Vec { let mut checker = Checker::new(settings); - checker.push_scope(Scope { - kind: Module, - values: BTreeMap::new(), - }); - for stmt in python_ast { - checker.visit_stmt(stmt); + for node in &python_cst.body { + checker.visit_Statement(node); } - checker.pop_scope(); - checker.check_dead_scopes(); checker.checks } diff --git a/src/cst_visitor.rs b/src/cst_visitor.rs index ea7097fd9b..50ad2450e0 100644 --- a/src/cst_visitor.rs +++ b/src/cst_visitor.rs @@ -1,325 +1,978 @@ +#![allow(non_snake_case)] + use libcst_native::{ - AnnAssign, Annotation, Arg, AsName, Assert, Assign, AssignEqual, AssignTarget, Asynchronous, - Attribute, AugAssign, AugOp, Await, BinaryOperation, BitAnd, BitAndAssign, BitInvert, - BitOrAssign, BitXor, BitXorAssign, BooleanOperation, Break, Call, ClassDef, Colon, Comma, - Comment, CompFor, CompIf, Comparison, ComparisonTarget, CompoundStatement, ConcatenatedString, - Continue, Decorator, Del, Dict, DictComp, DictElement, Divide, DivideAssign, Dot, Element, - Ellipsis, Else, EmptyLine, Equal, ExceptHandler, ExceptStarHandler, Expr, Expression, Finally, - Float, FloorDivide, FloorDivideAssign, For, FormattedString, FormattedStringExpression, - FormattedStringText, From, FunctionDef, GeneratorExp, Global, GreaterThan, GreaterThanEqual, - If, IfExp, Imaginary, Import, ImportAlias, ImportFrom, ImportStar, In, IndentedBlock, Index, - Integer, Is, IsNot, Lambda, LeftCurlyBrace, LeftParen, LeftShift, LeftShiftAssign, - LeftSquareBracket, LessThan, LessThanEqual, List, ListComp, Match, MatchAs, MatchCase, - MatchClass, MatchKeywordElement, MatchList, MatchMapping, MatchMappingElement, MatchOr, - MatchOrElement, MatchPattern, MatchSequence, MatchSequenceElement, MatchSingleton, MatchStar, - MatchTuple, MatchValue, MatrixMultiply, MatrixMultiplyAssign, Minus, Module, Modulo, - ModuloAssign, Multiply, MultiplyAssign, Name, NameItem, NamedExpr, Newline, Nonlocal, Not, - NotEqual, NotIn, Or, Param, ParamSlash, ParamStar, Parameters, ParenthesizedWhitespace, Pass, - Plus, Power, PowerAssign, Raise, Return, RightCurlyBrace, RightParen, RightShift, - RightShiftAssign, RightSquareBracket, Semicolon, Set, SetComp, SimpleStatementLine, - SimpleStatementSuite, SimpleString, SimpleWhitespace, Slice, SmallStatement, - StarredDictElement, StarredElement, Statement, Subscript, SubscriptElement, Subtract, - SubtractAssign, TrailingWhitespace, Try, TryStar, Tuple, UnaryOperation, While, With, WithItem, - Yield, + AnnAssign, Annotation, Arg, AsName, Assert, Assign, AssignEqual, AssignTarget, + AssignTargetExpression, Asynchronous, Attribute, AugAssign, Await, BaseSlice, BinaryOp, + BinaryOperation, BooleanOp, BooleanOperation, Break, Call, ClassDef, 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, From, FunctionDef, + GeneratorExp, Global, If, IfExp, Imaginary, Import, ImportAlias, ImportFrom, ImportNames, + ImportStar, IndentedBlock, Index, Integer, Lambda, List, ListComp, Match, Name, NameItem, + NameOrAttribute, NamedExpr, Nonlocal, OrElse, Param, ParamStar, Parameters, Pass, Raise, + Return, Set, SetComp, SimpleStatementLine, SimpleStatementSuite, SimpleString, Slice, + SmallStatement, StarArg, StarredDictElement, StarredElement, Statement, Subscript, + SubscriptElement, Suite, Try, TryStar, Tuple, UnaryOp, UnaryOperation, While, With, WithItem, + Yield, YieldValue, }; pub trait CSTVisitor { - // fn visit_statement(&mut self, statement: &Statement) { - // walk_statement(self, statement); - // } - // fn visit_simple_statement_line(&mut self, simple_statement_line: &SimpleStatementLine) { - // walk_simple_statement_line(self, simple_statement_line); - // } - // fn visit_compound_statement(&mut self, compound_statement: &CompoundStatement) { - // walk_compound_statement(self, compound_statement); - // } - // fn visit_small_statement(&mut self, small_statement: &SmallStatement) { - // walk_small_statement(self, small_statement); - // } - // fn visit_expression(&mut self, expression: &Expression) { - // walk_expression(self, expression); - // } - // fn visit_Add(&mut self, node: &Add) {} - // fn visit_AddAssign(&mut self, node: &AddAssign) {} - // fn visit_And(&mut self, node: &And) {} - fn visit_AnnAssign(&mut self, node: &AnnAssign) {} - fn visit_Annotation(&mut self, node: &Annotation) {} - fn visit_Arg(&mut self, node: &Arg) {} - fn visit_AsName(&mut self, node: &AsName) {} - fn visit_Assert(&mut self, node: &Assert) {} - fn visit_Assign(&mut self, node: &Assign) {} - fn visit_AssignEqual(&mut self, node: &AssignEqual) {} - fn visit_AssignTarget(&mut self, node: &AssignTarget) {} - fn visit_Asynchronous(&mut self, node: &Asynchronous) {} - fn visit_Attribute(&mut self, node: &Attribute) {} - fn visit_AugAssign(&mut self, node: &AugAssign) {} - fn visit_AugOp(&mut self, node: &AugOp) {} - fn visit_Await(&mut self, node: &Await) {} - fn visit_BinaryOperation(&mut self, node: &BinaryOperation) {} - // fn visit_BitAnd(&mut self, node: &BitAnd) {} - // fn visit_BitAndAssign(&mut self, node: &BitAndAssign) {} - // fn visit_BitInvert(&mut self, node: &BitInvert) {} - // fn visit_BitOr(&mut self, node: &BitOr) {} - // fn visit_BitOrAssign(&mut self, node: &BitOrAssign) {} - // fn visit_BitXor(&mut self, node: &BitXor) {} - // fn visit_BitXorAssign(&mut self, node: &BitXorAssign) {} - fn visit_BooleanOperation(&mut self, node: &BooleanOperation) {} - fn visit_Break(&mut self, node: &Break) {} - fn visit_Call(&mut self, node: &Call) {} - fn visit_ClassDef(&mut self, node: &ClassDef) {} - fn visit_Colon(&mut self, node: &Colon) {} - fn visit_Comma(&mut self, node: &Comma) {} - fn visit_Comment(&mut self, node: &Comment) {} - fn visit_CompFor(&mut self, node: &CompFor) {} - fn visit_CompIf(&mut self, node: &CompIf) {} - fn visit_Comparison(&mut self, node: &Comparison) {} - fn visit_ComparisonTarget(&mut self, node: &ComparisonTarget) {} - fn visit_ConcatenatedString(&mut self, node: &ConcatenatedString) {} - fn visit_Continue(&mut self, node: &Continue) {} - fn visit_Decorator(&mut self, node: &Decorator) {} - fn visit_Del(&mut self, node: &Del) {} - fn visit_Dict(&mut self, node: &Dict) {} - fn visit_DictComp(&mut self, node: &DictComp) {} - fn visit_DictElement(&mut self, node: &DictElement) {} - fn visit_Divide(&mut self, node: &Divide) {} - fn visit_DivideAssign(&mut self, node: &DivideAssign) {} - fn visit_Dot(&mut self, node: &Dot) {} - fn visit_Element(&mut self, node: &Element) {} - fn visit_Ellipsis(&mut self, node: &Ellipsis) {} - fn visit_Else(&mut self, node: &Else) {} - fn visit_EmptyLine(&mut self, node: &EmptyLine) {} - fn visit_Equal(&mut self, node: &Equal) {} - fn visit_ExceptHandler(&mut self, node: &ExceptHandler) {} - fn visit_ExceptStarHandler(&mut self, node: &ExceptStarHandler) {} - fn visit_Expr(&mut self, node: &Expr) {} - fn visit_Finally(&mut self, node: &Finally) {} - fn visit_Float(&mut self, node: &Float) {} - fn visit_FloorDivide(&mut self, node: &FloorDivide) {} - fn visit_FloorDivideAssign(&mut self, node: &FloorDivideAssign) {} - fn visit_For(&mut self, node: &For) {} - fn visit_FormattedString(&mut self, node: &FormattedString) {} + fn visit_Statement(&mut self, node: &Statement) { + walk_Statement(self, node); + } + fn visit_SimpleStatementLine(&mut self, node: &SimpleStatementLine) { + walk_SimpleStatementLine(self, node); + } + fn visit_CompoundStatement(&mut self, node: &CompoundStatement) { + walk_CompoundStatement(self, node); + } + fn visit_SmallStatement(&mut self, node: &SmallStatement) { + walk_SmallStatement(self, node); + } + fn visit_Expression(&mut self, node: &Expression) { + walk_Expression(self, node); + } + fn visit_AnnAssign(&mut self, node: &AnnAssign) { + walk_AnnAssign(self, node); + } + fn visit_Annotation(&mut self, node: &Annotation) { + walk_Annotation(self, node); + } + fn visit_Arg(&mut self, node: &Arg) { + walk_Arg(self, node); + } + fn visit_AsName(&mut self, node: &AsName) { + walk_AsName(self, node); + } + fn visit_Assert(&mut self, node: &Assert) { + walk_Assert(self, node); + } + fn visit_Assign(&mut self, node: &Assign) { + walk_Assign(self, node); + } + fn visit_AssignEqual(&mut self, node: &AssignEqual) { + walk_AssignEqual(self, node); + } + fn visit_AssignTarget(&mut self, node: &AssignTarget) { + walk_AssignTarget(self, node); + } + fn visit_AssignTargetExpression(&mut self, node: &AssignTargetExpression) { + walk_AssignTargetExpression(self, node); + } + fn visit_Asynchronous(&mut self, node: &Asynchronous) { + walk_Asynchronous(self, node); + } + fn visit_Attribute(&mut self, node: &Attribute) { + walk_Attribute(self, node); + } + fn visit_AugAssign(&mut self, node: &AugAssign) { + walk_AugAssign(self, node); + } + fn visit_Await(&mut self, node: &Await) { + walk_Await(self, node); + } + fn visit_BinaryOperation(&mut self, node: &BinaryOperation) { + walk_BinaryOperation(self, node); + } + fn visit_BinaryOp(&mut self, node: &BinaryOp) { + walk_BinaryOp(self, node); + } + fn visit_BooleanOperation(&mut self, node: &BooleanOperation) { + walk_BooleanOperation(self, node); + } + fn visit_BooleanOp(&mut self, node: &BooleanOp) { + walk_BooleanOp(self, node); + } + fn visit_Break(&mut self, node: &Break) { + walk_Break(self, node); + } + fn visit_Call(&mut self, node: &Call) { + walk_Call(self, node); + } + fn visit_ClassDef(&mut self, node: &ClassDef) { + walk_ClassDef(self, node); + } + fn visit_CompFor(&mut self, node: &CompFor) { + walk_CompFor(self, node); + } + fn visit_CompIf(&mut self, node: &CompIf) { + walk_CompIf(self, node); + } + fn visit_Comparison(&mut self, node: &Comparison) { + walk_Comparison(self, node); + } + fn visit_ComparisonTarget(&mut self, node: &ComparisonTarget) { + walk_ComparisonTarget(self, node); + } + fn visit_CompOp(&mut self, node: &CompOp) { + walk_CompOp(self, node); + } + fn visit_ConcatenatedString(&mut self, node: &ConcatenatedString) { + walk_ConcatenatedString(self, node); + } + fn visit_Continue(&mut self, node: &Continue) { + walk_Continue(self, node); + } + fn visit_Decorator(&mut self, node: &Decorator) { + walk_Decorator(self, node); + } + fn visit_Del(&mut self, node: &Del) { + walk_Del(self, node); + } + fn visit_DelTargetExpression(&mut self, node: &DelTargetExpression) { + walk_DelTargetExpression(self, node); + } + fn visit_Dict(&mut self, node: &Dict) { + walk_Dict(self, node); + } + fn visit_DictComp(&mut self, node: &DictComp) { + walk_DictComp(self, node); + } + fn visit_DictElement(&mut self, node: &DictElement) { + walk_DictElement(self, node); + } + fn visit_Element(&mut self, node: &Element) { + walk_Element(self, node); + } + fn visit_Ellipsis(&mut self, node: &Ellipsis) { + walk_Ellipsis(self, node); + } + fn visit_Else(&mut self, node: &Else) { + walk_Else(self, node); + } + fn visit_ExceptHandler(&mut self, node: &ExceptHandler) { + walk_ExceptHandler(self, node); + } + fn visit_ExceptStarHandler(&mut self, node: &ExceptStarHandler) { + walk_ExceptStarHandler(self, node); + } + fn visit_Expr(&mut self, node: &Expr) { + walk_Expr(self, node); + } + fn visit_Finally(&mut self, node: &Finally) { + walk_Finally(self, node); + } + fn visit_Float(&mut self, node: &Float) { + walk_Float(self, node); + } + fn visit_For(&mut self, node: &For) { + walk_For(self, node); + } + fn visit_FormattedString(&mut self, node: &FormattedString) { + walk_FormattedString(self, node); + } + fn visit_FormattedStringExpression(&mut self, node: &FormattedStringExpression) { + walk_FormattedStringExpression(self, node); + } + fn visit_FormattedStringText(&mut self, node: &FormattedStringText) { + walk_FormattedStringText(self, node); + } + fn visit_From(&mut self, node: &From) { + walk_From(self, node); + } + fn visit_FunctionDef(&mut self, node: &FunctionDef) { + walk_FunctionDef(self, node); + } + fn visit_GeneratorExp(&mut self, node: &GeneratorExp) { + walk_GeneratorExp(self, node); + } + fn visit_Global(&mut self, node: &Global) { + walk_Global(self, node); + } + fn visit_If<'a>(&'a mut self, node: &'a If) -> &'a If { + walk_If(self, node); + return node; + } + fn visit_IfExp(&mut self, node: &IfExp) { + walk_IfExp(self, node); + } + fn visit_Imaginary(&mut self, node: &Imaginary) { + walk_Imaginary(self, node); + } + fn visit_Import(&mut self, node: &Import) { + walk_Import(self, node); + } + fn visit_ImportAlias(&mut self, node: &ImportAlias) { + walk_ImportAlias(self, node); + } + fn visit_ImportFrom(&mut self, node: &ImportFrom) { + walk_ImportFrom(self, node); + } + fn visit_ImportStar(&mut self, node: &ImportStar) { + walk_ImportStar(self, node); + } + fn visit_IndentedBlock(&mut self, node: &IndentedBlock) { + walk_IndentedBlock(self, node); + } + fn visit_Index(&mut self, node: &Index) { + walk_Index(self, node); + } + fn visit_Integer(&mut self, node: &Integer) { + walk_Integer(self, node); + } + fn visit_Lambda(&mut self, node: &Lambda) { + walk_Lambda(self, node); + } + fn visit_List(&mut self, node: &List) { + walk_List(self, node); + } + fn visit_ListComp(&mut self, node: &ListComp) { + walk_ListComp(self, node); + } + fn visit_Match(&mut self, node: &Match) { + walk_Match(self, node); + } - fn visit_FormattedStringExpression(&mut self, node: &FormattedStringExpression) {} - fn visit_FormattedStringText(&mut self, node: &FormattedStringText) {} - fn visit_From(&mut self, node: &From) {} - fn visit_FunctionDef(&mut self, node: &FunctionDef) {} - fn visit_GeneratorExp(&mut self, node: &GeneratorExp) {} - fn visit_Global(&mut self, node: &Global) {} - fn visit_GreaterThan(&mut self, node: &GreaterThan) {} - fn visit_GreaterThanEqual(&mut self, node: &GreaterThanEqual) {} - fn visit_If(&mut self, node: &If) {} - fn visit_IfExp(&mut self, node: &IfExp) {} - fn visit_Imaginary(&mut self, node: &Imaginary) {} - fn visit_Import(&mut self, node: &Import) {} - fn visit_ImportAlias(&mut self, node: &ImportAlias) {} - fn visit_ImportFrom(&mut self, node: &ImportFrom) {} - fn visit_ImportStar(&mut self, node: &ImportStar) {} - fn visit_In(&mut self, node: &In) {} - fn visit_IndentedBlock(&mut self, node: &IndentedBlock) {} - fn visit_Index(&mut self, node: &Index) {} - fn visit_Integer(&mut self, node: &Integer) {} - fn visit_Is(&mut self, node: &Is) {} - fn visit_IsNot(&mut self, node: &IsNot) {} - fn visit_Lambda(&mut self, node: &Lambda) {} - fn visit_LeftCurlyBrace(&mut self, node: &LeftCurlyBrace) {} - fn visit_LeftParen(&mut self, node: &LeftParen) {} - fn visit_LeftShift(&mut self, node: &LeftShift) {} - fn visit_LeftShiftAssign(&mut self, node: &LeftShiftAssign) {} - fn visit_LeftSquareBracket(&mut self, node: &LeftSquareBracket) {} - fn visit_LessThan(&mut self, node: &LessThan) {} - fn visit_LessThanEqual(&mut self, node: &LessThanEqual) {} - fn visit_List(&mut self, node: &List) {} - fn visit_ListComp(&mut self, node: &ListComp) {} - fn visit_Match(&mut self, node: &Match) {} - fn visit_MatchAs(&mut self, node: &MatchAs) {} - fn visit_MatchCase(&mut self, node: &MatchCase) {} - fn visit_MatchClass(&mut self, node: &MatchClass) {} - fn visit_MatchKeywordElement(&mut self, node: &MatchKeywordElement) {} - fn visit_MatchList(&mut self, node: &MatchList) {} - fn visit_MatchMapping(&mut self, node: &MatchMapping) {} - fn visit_MatchMappingElement(&mut self, node: &MatchMappingElement) {} - fn visit_MatchOr(&mut self, node: &MatchOr) {} - fn visit_MatchOrElement(&mut self, node: &MatchOrElement) {} - fn visit_MatchPattern(&mut self, node: &MatchPattern) {} - fn visit_MatchSequence(&mut self, node: &MatchSequence) {} + // fn visit_MatchAs(&mut self, node: &MatchAs) { walk_MatchAs(self, node); } + // fn visit_MatchCase(&mut self, node: &MatchCase) { walk_MatchCase(self, node); } + // fn visit_MatchClass(&mut self, node: &MatchClass) { walk_MatchClass(self, node); } + // fn visit_MatchKeywordElement(&mut self, node: &MatchKeywordElement) { walk_MatchKeywordElement(self, node); } + // fn visit_MatchList(&mut self, node: &MatchList) { walk_MatchList(self, node); } + // fn visit_MatchMapping(&mut self, node: &MatchMapping) { walk_MatchMapping(self, node); } + // fn visit_MatchMappingElement(&mut self, node: &MatchMappingElement) { walk_MatchMappingElement(self, node); } + // fn visit_MatchOr(&mut self, node: &MatchOr) { walk_MatchOr(self, node); } + // fn visit_MatchOrElement(&mut self, node: &MatchOrElement) { walk_MatchOrElement(self, node); } + // fn visit_MatchPattern(&mut self, node: &MatchPattern) { walk_MatchPattern(self, node); } + // fn visit_MatchSequence(&mut self, node: &MatchSequence) { walk_MatchSequence(self, node); } + // fn visit_MatchSequenceElement(&mut self, node: &MatchSequenceElement) { walk_MatchSequenceElement(self, node); } + // fn visit_MatchSingleton(&mut self, node: &MatchSingleton) { walk_MatchSingleton(self, node); } + // fn visit_MatchStar(&mut self, node: &MatchStar) { walk_MatchStar(self, node); } + // fn visit_MatchTuple(&mut self, node: &MatchTuple) { walk_MatchTuple(self, node); } + // fn visit_MatchValue(&mut self, node: &MatchValue) { walk_MatchValue(self, node); } - fn visit_MatchSequenceElement(&mut self, node: &MatchSequenceElement) {} - fn visit_MatchSingleton(&mut self, node: &MatchSingleton) {} - fn visit_MatchStar(&mut self, node: &MatchStar) {} - fn visit_MatchTuple(&mut self, node: &MatchTuple) {} - fn visit_MatchValue(&mut self, node: &MatchValue) {} - fn visit_MatrixMultiply(&mut self, node: &MatrixMultiply) {} - - fn visit_MatrixMultiplyAssign(&mut self, node: &MatrixMultiplyAssign) {} - fn visit_Minus(&mut self, node: &Minus) {} - fn visit_Module(&mut self, node: &Module) {} - fn visit_Modulo(&mut self, node: &Modulo) {} - fn visit_ModuloAssign(&mut self, node: &ModuloAssign) {} - fn visit_Multiply(&mut self, node: &Multiply) {} - fn visit_MultiplyAssign(&mut self, node: &MultiplyAssign) {} - fn visit_Name(&mut self, node: &Name) {} - fn visit_NameItem(&mut self, node: &NameItem) {} - fn visit_NamedExpr(&mut self, node: &NamedExpr) {} - fn visit_Newline(&mut self, node: &Newline) {} - fn visit_Nonlocal(&mut self, node: &Nonlocal) {} - fn visit_Not(&mut self, node: &Not) {} - fn visit_NotEqual(&mut self, node: &NotEqual) {} - fn visit_NotIn(&mut self, node: &NotIn) {} - fn visit_Or(&mut self, node: &Or) {} - fn visit_Param(&mut self, node: &Param) {} - fn visit_ParamSlash(&mut self, node: &ParamSlash) {} - fn visit_ParamStar(&mut self, node: &ParamStar) {} - fn visit_Parameters(&mut self, node: &Parameters) {} - - fn visit_ParenthesizedWhitespace(&mut self, node: &ParenthesizedWhitespace) {} - fn visit_Pass(&mut self, node: &Pass) {} - fn visit_Plus(&mut self, node: &Plus) {} - fn visit_Power(&mut self, node: &Power) {} - fn visit_PowerAssign(&mut self, node: &PowerAssign) {} - fn visit_Raise(&mut self, node: &Raise) {} - fn visit_Return(&mut self, node: &Return) {} - fn visit_RightCurlyBrace(&mut self, node: &RightCurlyBrace) {} - fn visit_RightParen(&mut self, node: &RightParen) {} - fn visit_RightShift(&mut self, node: &RightShift) {} - fn visit_RightShiftAssign(&mut self, node: &RightShiftAssign) {} - fn visit_RightSquareBracket(&mut self, node: &RightSquareBracket) {} - fn visit_Semicolon(&mut self, node: &Semicolon) {} - fn visit_Set(&mut self, node: &Set) {} - fn visit_SetComp(&mut self, node: &SetComp) {} - fn visit_SimpleStatementLine(&mut self, node: &SimpleStatementLine) {} - - fn visit_SimpleStatementSuite(&mut self, node: &SimpleStatementSuite) {} - fn visit_SimpleString(&mut self, node: &SimpleString) {} - fn visit_SimpleWhitespace(&mut self, node: &SimpleWhitespace) {} - fn visit_Slice(&mut self, node: &Slice) {} - fn visit_StarredDictElement(&mut self, node: &StarredDictElement) {} - fn visit_StarredElement(&mut self, node: &StarredElement) {} - fn visit_Subscript(&mut self, node: &Subscript) {} - fn visit_SubscriptElement(&mut self, node: &SubscriptElement) {} - fn visit_Subtract(&mut self, node: &Subtract) {} - fn visit_SubtractAssign(&mut self, node: &SubtractAssign) {} - fn visit_TrailingWhitespace(&mut self, node: &TrailingWhitespace) {} - fn visit_Try(&mut self, node: &Try) {} - fn visit_TryStar(&mut self, node: &TryStar) {} - fn visit_Tuple(&mut self, node: &Tuple) {} - fn visit_UnaryOperation(&mut self, node: &UnaryOperation) {} - fn visit_While(&mut self, node: &While) {} - fn visit_With(&mut self, node: &With) {} - fn visit_WithItem(&mut self, node: &WithItem) {} - fn visit_Yield(&mut self, node: &Yield) {} -} - -pub fn walk_statement(visitor: &mut V, statement: &Statement) { - match statement { - Statement::Simple(simple_statement_line) => { - visitor.visit_simple_statement_line(simple_statement_line) - } - Statement::Compound(compound_statement) => { - visitor.visit_compound_statement(compound_statement) - } + fn visit_Name(&mut self, node: &Name) { + walk_Name(self, node); + } + fn visit_NameItem(&mut self, node: &NameItem) { + walk_NameItem(self, node); + } + fn visit_NamedExpr(&mut self, node: &NamedExpr) { + walk_NamedExpr(self, node); + } + fn visit_Nonlocal(&mut self, node: &Nonlocal) { + walk_Nonlocal(self, node); + } + fn visit_OrElse(&mut self, node: &OrElse) { + walk_OrElse(self, node); + } + fn visit_Param(&mut self, node: &Param) { + walk_Param(self, node); + } + fn visit_ParamStar(&mut self, node: &ParamStar) { + walk_ParamStar(self, node); + } + fn visit_Parameters(&mut self, node: &Parameters) { + walk_Parameters(self, node); + } + fn visit_Pass(&mut self, node: &Pass) { + walk_Pass(self, node); + } + fn visit_Raise(&mut self, node: &Raise) { + walk_Raise(self, node); + } + fn visit_Return(&mut self, node: &Return) { + walk_Return(self, node); + } + fn visit_Set(&mut self, node: &Set) { + walk_Set(self, node); + } + fn visit_SetComp(&mut self, node: &SetComp) { + walk_SetComp(self, node); + } + fn visit_SimpleStatementSuite(&mut self, node: &SimpleStatementSuite) { + walk_SimpleStatementSuite(self, node); + } + fn visit_SimpleString(&mut self, node: &SimpleString) { + walk_SimpleString(self, node); + } + fn visit_Slice(&mut self, node: &Slice) { + walk_Slice(self, node); + } + fn visit_StarredDictElement(&mut self, node: &StarredDictElement) { + walk_StarredDictElement(self, node); + } + fn visit_StarredElement(&mut self, node: &StarredElement) { + walk_StarredElement(self, node); + } + fn visit_Subscript(&mut self, node: &Subscript) { + walk_Subscript(self, node); + } + fn visit_SubscriptElement(&mut self, node: &SubscriptElement) { + walk_SubscriptElement(self, node); + } + fn visit_Try(&mut self, node: &Try) { + walk_Try(self, node); + } + fn visit_TryStar(&mut self, node: &TryStar) { + walk_TryStar(self, node); + } + fn visit_Tuple(&mut self, node: &Tuple) { + walk_Tuple(self, node); + } + fn visit_UnaryOp(&mut self, node: &UnaryOp) { + walk_UnaryOp(self, node); + } + fn visit_UnaryOperation(&mut self, node: &UnaryOperation) { + walk_UnaryOperation(self, node); + } + fn visit_While(&mut self, node: &While) { + walk_While(self, node); + } + fn visit_With(&mut self, node: &With) { + walk_With(self, node); + } + fn visit_WithItem(&mut self, node: &WithItem) { + walk_WithItem(self, node); + } + fn visit_Yield(&mut self, node: &Yield) { + walk_Yield(self, node); + } + fn visit_YieldValue(&mut self, node: &YieldValue) { + walk_YieldValue(self, node); } } -pub fn walk_simple_statement_line( +pub fn walk_Statement(visitor: &mut V, node: &Statement) { + match node { + Statement::Simple(node) => visitor.visit_SimpleStatementLine(node), + Statement::Compound(node) => visitor.visit_CompoundStatement(node), + } +} + +pub fn walk_SimpleStatementLine( visitor: &mut V, - simple_statement_line: &SimpleStatementLine, + node: &SimpleStatementLine, ) { - for small_statement in &simple_statement_line.body { - visitor.visit_small_statement(small_statement); + for node in &node.body { + visitor.visit_SmallStatement(node); } } -pub fn walk_compound_statement( +pub fn walk_CompoundStatement(visitor: &mut V, node: &CompoundStatement) { + match node { + CompoundStatement::FunctionDef(node) => visitor.visit_FunctionDef(node), + CompoundStatement::If(node) => { + visitor.visit_If(node); + } + CompoundStatement::For(node) => visitor.visit_For(node), + CompoundStatement::While(node) => visitor.visit_While(node), + CompoundStatement::ClassDef(node) => visitor.visit_ClassDef(node), + CompoundStatement::Try(node) => visitor.visit_Try(node), + CompoundStatement::TryStar(node) => visitor.visit_TryStar(node), + CompoundStatement::With(node) => visitor.visit_With(node), + CompoundStatement::Match(node) => visitor.visit_Match(node), + } +} + +pub fn walk_SmallStatement(visitor: &mut V, node: &SmallStatement) { + match node { + SmallStatement::Pass(node) => visitor.visit_Pass(node), + SmallStatement::Break(node) => visitor.visit_Break(node), + SmallStatement::Continue(node) => visitor.visit_Continue(node), + SmallStatement::Return(node) => visitor.visit_Return(node), + SmallStatement::Expr(node) => visitor.visit_Expr(node), + SmallStatement::Assert(node) => visitor.visit_Assert(node), + 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::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) { + match node { + Expression::Name(node) => visitor.visit_Name(node), + Expression::Ellipsis(node) => visitor.visit_Ellipsis(node), + Expression::Integer(node) => visitor.visit_Integer(node), + Expression::Float(node) => visitor.visit_Float(node), + 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::BooleanOperation(node) => visitor.visit_BooleanOperation(node), + Expression::Attribute(node) => visitor.visit_Attribute(node), + Expression::Tuple(node) => visitor.visit_Tuple(node), + Expression::Call(node) => visitor.visit_Call(node), + Expression::GeneratorExp(node) => visitor.visit_GeneratorExp(node), + Expression::ListComp(node) => visitor.visit_ListComp(node), + Expression::SetComp(node) => visitor.visit_SetComp(node), + Expression::DictComp(node) => visitor.visit_DictComp(node), + Expression::List(node) => visitor.visit_List(node), + Expression::Set(node) => visitor.visit_Set(node), + Expression::Dict(node) => visitor.visit_Dict(node), + Expression::Subscript(node) => visitor.visit_Subscript(node), + Expression::StarredElement(node) => visitor.visit_StarredElement(node), + Expression::IfExp(node) => visitor.visit_IfExp(node), + Expression::Lambda(node) => visitor.visit_Lambda(node), + Expression::Yield(node) => visitor.visit_Yield(node), + Expression::Await(node) => visitor.visit_Await(node), + Expression::SimpleString(node) => visitor.visit_SimpleString(node), + Expression::ConcatenatedString(node) => visitor.visit_ConcatenatedString(node), + Expression::FormattedString(node) => visitor.visit_FormattedString(node), + Expression::NamedExpr(node) => visitor.visit_NamedExpr(node), + } +} +pub fn walk_AssignEqual(visitor: &mut V, node: &AssignEqual) { + // Nothing to do. +} +pub fn walk_AssignTarget(visitor: &mut V, node: &AssignTarget) { + visitor.visit_AssignTargetExpression(&node.target); +} +pub fn walk_AssignTargetExpression( visitor: &mut V, - compound_statement: &CompoundStatement, + node: &AssignTargetExpression, ) { - match compound_statement { - CompoundStatement::FunctionDef(_) => {} - CompoundStatement::If(_) => {} - CompoundStatement::For(_) => {} - CompoundStatement::While(_) => {} - CompoundStatement::ClassDef(_) => {} - CompoundStatement::Try(_) => {} - CompoundStatement::TryStar(_) => {} - CompoundStatement::With(_) => {} - CompoundStatement::Match(_) => {} + match &node { + AssignTargetExpression::Name(node) => visitor.visit_Name(node), + AssignTargetExpression::Attribute(node) => visitor.visit_Attribute(node), + AssignTargetExpression::StarredElement(node) => visitor.visit_StarredElement(node), + AssignTargetExpression::Tuple(node) => visitor.visit_Tuple(node), + AssignTargetExpression::List(node) => visitor.visit_List(node), + AssignTargetExpression::Subscript(node) => visitor.visit_Subscript(node), } } - -pub fn walk_small_statement( +pub fn walk_AnnAssign(visitor: &mut V, node: &AnnAssign) { + visitor.visit_AssignTargetExpression(&node.target); + if let Some(expression) = &node.value { + visitor.visit_Expression(expression) + } +} +pub fn walk_Annotation(visitor: &mut V, node: &Annotation) { + visitor.visit_Expression(&node.annotation); +} +pub fn walk_Arg(visitor: &mut V, node: &Arg) { + visitor.visit_Expression(&node.value); + if let Some(node) = &node.keyword { + visitor.visit_Name(node) + } + if let Some(node) = &node.equal { + visitor.visit_AssignEqual(node) + } +} +pub fn walk_AsName(visitor: &mut V, node: &AsName) { + visitor.visit_AssignTargetExpression(&node.name) +} +pub fn walk_Assert(visitor: &mut V, node: &Assert) { + visitor.visit_Expression(&node.test); + if let Some(expression) = &node.msg { + visitor.visit_Expression(expression); + } +} +pub fn walk_Assign(visitor: &mut V, node: &Assign) { + for target in &node.targets { + visitor.visit_AssignTarget(target) + } + 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) +} +pub fn walk_AugAssign(visitor: &mut V, node: &AugAssign) { + visitor.visit_AssignTargetExpression(&node.target); + visitor.visit_Expression(&node.value); +} +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); + visitor.visit_BinaryOp(&node.operator); + visitor.visit_Expression(&node.right); +} +pub fn walk_BinaryOp(visitor: &mut V, node: &BinaryOp) { + // Nothing to do. +} +pub fn walk_BooleanOperation(visitor: &mut V, node: &BooleanOperation) { + visitor.visit_Expression(&node.left); + visitor.visit_BooleanOp(&node.operator); + visitor.visit_Expression(&node.right); +} +pub fn walk_BooleanOp(visitor: &mut V, node: &BooleanOp) { + // Nothing to do. +} +pub fn walk_Break(visitor: &mut V, node: &Break) { + // Nothing to do. +} +pub fn walk_Call(visitor: &mut V, node: &Call) { + for node in &node.args { + visitor.visit_Arg(node) + } + visitor.visit_Expression(&node.func) +} +pub fn walk_ClassDef(visitor: &mut V, node: &ClassDef) { + visitor.visit_Name(&node.name); + for node in &node.bases { + visitor.visit_Arg(node); + } + for node in &node.keywords { + visitor.visit_Arg(node); + } + for node in &node.decorators { + visitor.visit_Decorator(node); + } + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } +} +pub fn walk_CompFor(visitor: &mut V, node: &CompFor) { + if let Some(node) = &node.asynchronous { + visitor.visit_Asynchronous(node); + } + visitor.visit_AssignTargetExpression(&node.target); + visitor.visit_Expression(&node.iter); + for node in &node.ifs { + visitor.visit_CompIf(node); + } + if let Some(node) = &node.inner_for_in { + visitor.visit_CompFor(node); + } +} +pub fn walk_CompIf(visitor: &mut V, node: &CompIf) { + visitor.visit_Expression(&node.test) +} +pub fn walk_Comparison(visitor: &mut V, node: &Comparison) { + visitor.visit_Expression(&node.left); + for node in &node.comparisons { + visitor.visit_ComparisonTarget(node); + } +} +pub fn walk_ComparisonTarget(visitor: &mut V, node: &ComparisonTarget) { + visitor.visit_CompOp(&node.operator); + visitor.visit_Expression(&node.comparator); +} +pub fn walk_CompOp(visitor: &mut V, node: &CompOp) { + // Nothing to do. +} +pub fn walk_ConcatenatedString(visitor: &mut V, node: &ConcatenatedString) { + // Nothing to do. +} +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) +} +pub fn walk_Del(visitor: &mut V, node: &Del) { + visitor.visit_DelTargetExpression(&node.target) +} +pub fn walk_DelTargetExpression( visitor: &mut V, - small_statement: &SmallStatement, + node: &DelTargetExpression, ) { - match small_statement { - SmallStatement::Pass(_) => {} - SmallStatement::Break(_) => {} - SmallStatement::Continue(_) => {} - SmallStatement::Return(inner) => { - if let Some(expression) = &inner.value { - visitor.visit_expression(expression); - } - } - SmallStatement::Expr(inner) => { - visitor.visit_expression(&inner.value); - } - SmallStatement::Assert(inner) => { - visitor.visit_expression(&inner.test); - if let Some(expression) = &inner.msg { - visitor.visit_expression(expression); - } - } - SmallStatement::Import(inner) => { - // Do I really need to recurse here? - for name in &inner.names { - visitor.visit_ImportAlias(name); - } - } - SmallStatement::ImportFrom(inner) => { - // Do I really need to recurse here? - for name in &inner.names { - visitor.visit_Name(name); - } - } - SmallStatement::Assign(_) => {} - SmallStatement::AnnAssign(_) => {} - SmallStatement::Raise(_) => {} - SmallStatement::Global(_) => {} - SmallStatement::Nonlocal(_) => {} - SmallStatement::AugAssign(_) => {} - SmallStatement::Del(_) => {} + match &node { + DelTargetExpression::Name(node) => visitor.visit_Name(node), + DelTargetExpression::Attribute(node) => visitor.visit_Attribute(node), + DelTargetExpression::Tuple(node) => visitor.visit_Tuple(node), + DelTargetExpression::List(node) => visitor.visit_List(node), + DelTargetExpression::Subscript(node) => visitor.visit_Subscript(node), } } - -pub fn walk_expression(visitor: &mut V, expression: &Expression) { - match expression { - Expression::Name(_) => {} - Expression::Ellipsis(_) => {} - Expression::Integer(_) => {} - Expression::Float(_) => {} - Expression::Imaginary(_) => {} - Expression::Comparison(_) => {} - Expression::UnaryOperation(_) => {} - Expression::BinaryOperation(_) => {} - Expression::BooleanOperation(_) => {} - Expression::Attribute(_) => {} - Expression::Tuple(_) => {} - Expression::Call(_) => {} - Expression::GeneratorExp(_) => {} - Expression::ListComp(_) => {} - Expression::SetComp(_) => {} - Expression::DictComp(_) => {} - Expression::List(_) => {} - Expression::Set(_) => {} - Expression::Dict(_) => {} - Expression::Subscript(_) => {} - Expression::StarredElement(_) => {} - Expression::IfExp(_) => {} - Expression::Lambda(_) => {} - Expression::Yield(_) => {} - Expression::Await(_) => {} - Expression::SimpleString(_) => {} - Expression::ConcatenatedString(_) => {} - Expression::FormattedString(_) => {} - Expression::NamedExpr(_) => {} +pub fn walk_Dict(visitor: &mut V, node: &Dict) { + for node in &node.elements { + visitor.visit_DictElement(node) + } +} +pub fn walk_DictComp(visitor: &mut V, node: &DictComp) { + visitor.visit_Expression(&node.key); + visitor.visit_Expression(&node.value); + visitor.visit_CompFor(&node.for_in); +} +pub fn walk_DictElement(visitor: &mut V, node: &DictElement) { + match &node { + DictElement::Simple { key, value, .. } => { + visitor.visit_Expression(key); + visitor.visit_Expression(value); + } + DictElement::Starred(node) => visitor.visit_StarredDictElement(node), + } +} +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), + } +} +pub fn walk_Ellipsis(visitor: &mut V, node: &Ellipsis) { + // Nothing to do. +} +pub fn walk_Else(visitor: &mut V, node: &Else) { + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } +} +pub fn walk_ExceptHandler(visitor: &mut V, node: &ExceptHandler) { + if let Some(node) = &node.r#type { + visitor.visit_Expression(node); + } + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } + if let Some(node) = &node.name { + visitor.visit_AsName(node) + } +} +pub fn walk_ExceptStarHandler(visitor: &mut V, node: &ExceptStarHandler) { + visitor.visit_Expression(&node.r#type); + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } + if let Some(node) = &node.name { + visitor.visit_AsName(node) + } +} +pub fn walk_Expr(visitor: &mut V, node: &Expr) { + visitor.visit_Expression(&node.value) +} +pub fn walk_Finally(visitor: &mut V, node: &Finally) { + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } +} +pub fn walk_Float(visitor: &mut V, node: &Float) { + // Nothing to do. +} +pub fn walk_For(visitor: &mut V, node: &For) { + visitor.visit_AssignTargetExpression(&node.target); + visitor.visit_Expression(&node.iter); + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } + if let Some(node) = &node.orelse { + visitor.visit_Else(node); + } + if let Some(node) = &node.asynchronous { + visitor.visit_Asynchronous(node); + } +} +pub fn walk_FormattedString(visitor: &mut V, node: &FormattedString) { + for node in &node.parts { + match node { + FormattedStringContent::Text(node) => visitor.visit_FormattedStringText(node), + FormattedStringContent::Expression(node) => { + visitor.visit_FormattedStringExpression(node) + } + } + } +} +pub fn walk_FormattedStringExpression( + visitor: &mut V, + node: &FormattedStringExpression, +) { + visitor.visit_Expression(&node.expression); +} +pub fn walk_FormattedStringText( + visitor: &mut V, + node: &FormattedStringText, +) { + // Nothing to do. +} +pub fn walk_From(visitor: &mut V, node: &From) { + visitor.visit_Expression(&node.item) +} +pub fn walk_FunctionDef(visitor: &mut V, node: &FunctionDef) { + visitor.visit_Name(&node.name); + visitor.visit_Parameters(&node.params); + for node in &node.decorators { + visitor.visit_Decorator(node); + } + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } + if let Some(node) = &node.returns { + visitor.visit_Annotation(node); + } + if let Some(node) = &node.asynchronous { + visitor.visit_Asynchronous(node); + } +} +pub fn walk_GeneratorExp(visitor: &mut V, node: &GeneratorExp) { + visitor.visit_Expression(&node.elt); + visitor.visit_CompFor(&node.for_in); +} +pub fn walk_Global(visitor: &mut V, node: &Global) { + for node in &node.names { + visitor.visit_NameItem(&node) + } +} +pub fn walk_If(visitor: &mut V, node: &If) { + visitor.visit_Expression(&node.test); + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } + if let Some(node) = &node.orelse { + visitor.visit_OrElse(node); + } +} +pub fn walk_IfExp(visitor: &mut V, node: &IfExp) { + visitor.visit_Expression(&node.test); + visitor.visit_Expression(&node.body); + visitor.visit_Expression(&node.orelse); +} +pub fn walk_Imaginary(visitor: &mut V, node: &Imaginary) { + // Nothing to do. +} +pub fn walk_Import(visitor: &mut V, node: &Import) { + for node in &node.names { + visitor.visit_ImportAlias(node) + } +} +pub fn walk_ImportAlias(visitor: &mut V, node: &ImportAlias) { + match &node.name { + NameOrAttribute::N(node) => visitor.visit_Name(node), + NameOrAttribute::A(node) => visitor.visit_Attribute(node), + } + if let Some(node) = &node.asname { + visitor.visit_AsName(node) + } +} +pub fn walk_ImportFrom(visitor: &mut V, node: &ImportFrom) { + match &node.names { + ImportNames::Star(node) => visitor.visit_ImportStar(node), + ImportNames::Aliases(node) => { + for node in node { + visitor.visit_ImportAlias(node) + } + } + } +} +pub fn walk_ImportStar(visitor: &mut V, node: &ImportStar) { + // Nothing to do. +} +pub fn walk_IndentedBlock(visitor: &mut V, node: &IndentedBlock) { + for node in &node.body { + visitor.visit_Statement(node) + } +} +pub fn walk_Index(visitor: &mut V, node: &Index) { + visitor.visit_Expression(&node.value); +} +pub fn walk_Integer(visitor: &mut V, node: &Integer) { + // Nothing to do. +} +pub fn walk_Lambda(visitor: &mut V, node: &Lambda) { + visitor.visit_Parameters(&node.params); + visitor.visit_Expression(&node.body); +} +pub fn walk_List(visitor: &mut V, node: &List) { + for node in &node.elements { + visitor.visit_Element(node) + } +} +pub fn walk_ListComp(visitor: &mut V, node: &ListComp) { + visitor.visit_Expression(&node.elt); + visitor.visit_CompFor(&node.for_in); +} +pub fn walk_Match(visitor: &mut V, node: &Match) { + visitor.visit_Expression(&node.subject); + // TODO + // for node in &node.cases { + // visitor.visit_MatchCase(node); + // } +} +pub fn walk_Name(visitor: &mut V, node: &Name) { + // Nothing to do. +} +pub fn walk_NameItem(visitor: &mut V, node: &NameItem) { + visitor.visit_Name(&node.name); +} +pub fn walk_NamedExpr(visitor: &mut V, node: &NamedExpr) {} +pub fn walk_Nonlocal(visitor: &mut V, node: &Nonlocal) {} +pub fn walk_OrElse(visitor: &mut V, node: &OrElse) { + match node { + OrElse::Elif(node) => { + visitor.visit_If(node); + } + OrElse::Else(node) => visitor.visit_Else(node), + } +} +pub fn walk_Param(visitor: &mut V, node: &Param) { + visitor.visit_Name(&node.name); + if let Some(node) = &node.annotation { + visitor.visit_Annotation(node); + } + if let Some(node) = &node.equal { + visitor.visit_AssignEqual(node); + } + if let Some(node) = &node.default { + visitor.visit_Expression(node); + } +} +pub fn walk_ParamStar(visitor: &mut V, node: &ParamStar) { + // Nothing to do. +} +pub fn walk_Parameters(visitor: &mut V, node: &Parameters) { + for node in &node.posonly_params { + visitor.visit_Param(node); + } + for node in &node.params { + visitor.visit_Param(node); + } + if let Some(node) = &node.star_kwarg { + visitor.visit_Param(node); + } + for node in &node.kwonly_params { + visitor.visit_Param(node); + } + if let Some(node) = &node.star_arg { + match &node { + StarArg::Star(node) => visitor.visit_ParamStar(node), + StarArg::Param(node) => visitor.visit_Param(node), + } + } +} +pub fn walk_Pass(visitor: &mut V, node: &Pass) { + // Nothing to do. +} +pub fn walk_Raise(visitor: &mut V, node: &Raise) {} +pub fn walk_Return(visitor: &mut V, node: &Return) { + if let Some(expression) = &node.value { + visitor.visit_Expression(expression); + } +} +pub fn walk_Set(visitor: &mut V, node: &Set) { + for node in &node.elements { + visitor.visit_Element(node) + } +} +pub fn walk_SetComp(visitor: &mut V, node: &SetComp) { + visitor.visit_Expression(&node.elt); + visitor.visit_CompFor(&node.for_in); +} +pub fn walk_SimpleString(visitor: &mut V, node: &SimpleString) { + // Nothing to do. +} +pub fn walk_SimpleStatementSuite( + visitor: &mut V, + node: &SimpleStatementSuite, +) { + for node in &node.body { + visitor.visit_SmallStatement(node) + } +} +pub fn walk_Slice(visitor: &mut V, node: &Slice) { + if let Some(node) = &node.lower { + visitor.visit_Expression(node) + } + if let Some(node) = &node.upper { + visitor.visit_Expression(node) + } + if let Some(node) = &node.step { + visitor.visit_Expression(node) + } +} +pub fn walk_StarredDictElement(visitor: &mut V, node: &StarredDictElement) { + visitor.visit_Expression(&node.value) +} +pub fn walk_StarredElement(visitor: &mut V, node: &StarredElement) { + visitor.visit_Expression(&node.value) +} +pub fn walk_Subscript(visitor: &mut V, node: &Subscript) { + visitor.visit_Expression(&node.value); + for node in &node.slice { + visitor.visit_SubscriptElement(node) + } +} +pub fn walk_SubscriptElement(visitor: &mut V, node: &SubscriptElement) { + match &node.slice { + BaseSlice::Index(node) => visitor.visit_Index(node), + BaseSlice::Slice(node) => visitor.visit_Slice(node), + } +} +pub fn walk_Try(visitor: &mut V, node: &Try) { + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } + for node in &node.handlers { + visitor.visit_ExceptHandler(node) + } + if let Some(node) = &node.orelse { + visitor.visit_Else(node) + } + if let Some(node) = &node.finalbody { + visitor.visit_Finally(node) + } +} +pub fn walk_TryStar(visitor: &mut V, node: &TryStar) { + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } + for node in &node.handlers { + visitor.visit_ExceptStarHandler(node) + } + if let Some(node) = &node.orelse { + visitor.visit_Else(node) + } + if let Some(node) = &node.finalbody { + visitor.visit_Finally(node) + } +} +pub fn walk_Tuple(visitor: &mut V, node: &Tuple) { + for node in &node.elements { + visitor.visit_Element(node) + } +} +pub fn walk_UnaryOp(visitor: &mut V, node: &UnaryOp) { + // Nothing to do. +} +pub fn walk_UnaryOperation(visitor: &mut V, node: &UnaryOperation) { + visitor.visit_UnaryOp(&node.operator); + visitor.visit_Expression(&node.expression); +} +pub fn walk_While(visitor: &mut V, node: &While) { + visitor.visit_Expression(&node.test); + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } + if let Some(node) = &node.orelse { + visitor.visit_Else(node) + } +} +pub fn walk_With(visitor: &mut V, node: &With) { + if let Some(node) = &node.asynchronous { + visitor.visit_Asynchronous(node); + } + for node in &node.items { + visitor.visit_WithItem(node) + } + match &node.body { + Suite::IndentedBlock(node) => visitor.visit_IndentedBlock(node), + Suite::SimpleStatementSuite(node) => visitor.visit_SimpleStatementSuite(node), + } +} +pub fn walk_WithItem(visitor: &mut V, node: &WithItem) { + visitor.visit_Expression(&node.item); + if let Some(node) = &node.asname { + visitor.visit_AsName(node) + } +} +pub fn walk_Yield(visitor: &mut V, node: &Yield) { + if let Some(node) = &node.value { + visitor.visit_YieldValue(node); + } +} +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), } } diff --git a/src/lib.rs b/src/lib.rs index de19f99264..f5ffc88c14 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,5 @@ mod ast_ops; mod ast_visitor; -mod autofix; mod builtins; mod cache; pub mod check_ast; diff --git a/src/linter.rs b/src/linter.rs index a1e9bef9c5..5792bd5949 100644 --- a/src/linter.rs +++ b/src/linter.rs @@ -5,6 +5,7 @@ use log::debug; use rustpython_parser::parser; use crate::check_ast::check_ast; +use crate::check_cst::check_cst; use crate::check_lines::check_lines; use crate::checks::{Check, LintSource}; use crate::message::Message; @@ -24,19 +25,26 @@ pub fn check_path(path: &Path, settings: &Settings, mode: &cache::Mode) -> Resul // Aggregate all checks. let mut checks: Vec = vec![]; - // Run the AST-based checks. - if settings - .select - .iter() - .any(|check_code| matches!(check_code.lint_source(), LintSource::AST)) - { - let path = path.to_string_lossy(); - let python_ast = parser::parse_program(&contents, &path)?; - checks.extend(check_ast(&python_ast, settings, &path)); - } + // Run the CST-based checks. + let python_cst = match libcst_native::parse_module(&contents, None) { + Ok(m) => m, + Err(e) => panic!("Failed to parse CST."), + }; + checks.extend(check_cst(&python_cst, settings)); - // Run the lines-based checks. - check_lines(&mut checks, &contents, settings); + // // Run the AST-based checks. + // if settings + // .select + // .iter() + // .any(|check_code| matches!(check_code.lint_source(), LintSource::AST)) + // { + // let path = path.to_string_lossy(); + // let python_ast = parser::parse_program(&contents, &path)?; + // checks.extend(check_ast(&python_ast, settings, &path)); + // } + // + // // Run the lines-based checks. + // check_lines(&mut checks, &contents, settings); // Convert to messages. let messages: Vec = checks @@ -47,6 +55,7 @@ pub fn check_path(path: &Path, settings: &Settings, mode: &cache::Mode) -> Resul filename: path.to_string_lossy().to_string(), }) .collect(); + cache::set(path, settings, &messages, mode); Ok(messages)