Compare formatted and unformatted ASTs during formatter tests (#8624)

## Summary

This PR implements validation in the formatter tests to ensure that we
don't modify the AST during formatting. Black has similar logic.

In implementing this, I learned that Black actually _does_ modify the
AST, and their test infrastructure normalizes the AST to wipe away those
differences. Specifically, Black changes the indentation of docstrings,
which _does_ modify the AST; and it also inserts parentheses in `del`
statements, which changes the AST too.

Ruff also does both these things, so we _also_ implement the same
normalization using a new visitor that allows for modifying the AST.

Closes https://github.com/astral-sh/ruff/issues/8184.

## Test Plan

`cargo test`
This commit is contained in:
Charlie Marsh 2023-11-13 09:43:27 -08:00 committed by GitHub
parent 3592f44ade
commit d574fcd1ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 930 additions and 19 deletions

View file

@ -1,6 +1,7 @@
//! AST visitor trait and walk functions.
pub mod preorder;
pub mod transformer;
use crate::{
self as ast, Alias, Arguments, BoolOp, CmpOp, Comprehension, Decorator, ElifElseClause,
@ -14,8 +15,10 @@ use crate::{
/// Prefer [`crate::statement_visitor::StatementVisitor`] for visitors that only need to visit
/// statements.
///
/// Use the [`PreorderVisitor`](self::preorder::PreorderVisitor) if you want to visit the nodes
/// Use the [`PreorderVisitor`](preorder::PreorderVisitor) if you want to visit the nodes
/// in pre-order rather than evaluation order.
///
/// Use the [`Transformer`](transformer::Transformer) if you want to modify the nodes.
pub trait Visitor<'a> {
fn visit_stmt(&mut self, stmt: &'a Stmt) {
walk_stmt(self, stmt);