From cb79ecf67ceb647fed49839bc68af1e9cddb20fc Mon Sep 17 00:00:00 2001 From: Roberto Raggi Date: Mon, 7 Apr 2025 19:11:56 +0200 Subject: [PATCH] Add keepSpace to improve formatting of the AST printer Signed-off-by: Roberto Raggi --- .../src/gen_ast_pretty_printer_cc.ts | 21 ++++++ .../src/gen_ast_pretty_printer_h.ts | 3 + src/parser/cxx/ast_pretty_printer.cc | 74 ++++++++++++++++++- src/parser/cxx/ast_pretty_printer.h | 3 + tests/api_tests/test_rewriter.cc | 2 +- 5 files changed, 101 insertions(+), 2 deletions(-) diff --git a/packages/cxx-gen-ast/src/gen_ast_pretty_printer_cc.ts b/packages/cxx-gen-ast/src/gen_ast_pretty_printer_cc.ts index c35658b2..af807814 100644 --- a/packages/cxx-gen-ast/src/gen_ast_pretty_printer_cc.ts +++ b/packages/cxx-gen-ast/src/gen_ast_pretty_printer_cc.ts @@ -78,6 +78,7 @@ export function gen_ast_pretty_printer_cc({ emit(`}`); emit(`void space() { accept.space(); }`); emit(`void nospace() { accept.nospace(); }`); + emit(`void keepSpace() { accept.keepSpace(); }`); emit(`void newline() { accept.newline(); }`); emit(`void nonewline() { accept.nonewline(); }`); emit(`void indent() { accept.indent(); }`); @@ -99,6 +100,11 @@ export function gen_ast_pretty_printer_cc({ } break; + case "opLoc": + emit(`space();`); + emit(`keepSpace();`); + break; + case "closeLoc": case "colonLoc": case "dotLoc": @@ -149,6 +155,15 @@ export function gen_ast_pretty_printer_cc({ } break; + case "equalLoc": + emit(`keepSpace();`); + break; + + case "opLoc": + emit(`space();`); + emit(`keepSpace();`); + break; + case "closeLoc": case "lbracketLoc": case "lbracket2Loc": @@ -379,11 +394,17 @@ void ASTPrettyPrinter::space() { } void ASTPrettyPrinter::nospace() { + if (keepSpace_) return; space_ = false; } +void ASTPrettyPrinter::keepSpace() { + keepSpace_ = true; +} + void ASTPrettyPrinter::newline() { space_ = false; + keepSpace_ = false; newline_ = true; } diff --git a/packages/cxx-gen-ast/src/gen_ast_pretty_printer_h.ts b/packages/cxx-gen-ast/src/gen_ast_pretty_printer_h.ts index a0453772..b8a40f91 100644 --- a/packages/cxx-gen-ast/src/gen_ast_pretty_printer_h.ts +++ b/packages/cxx-gen-ast/src/gen_ast_pretty_printer_h.ts @@ -99,6 +99,7 @@ ${code.join("\n")} } newline_ = false; space_ = false; + keepSpace_ = false; std::format_to(output_, fmt, std::forward(args)...); space(); } @@ -107,6 +108,7 @@ ${code.join("\n")} void space(); void nospace(); + void keepSpace(); void newline(); void nonewline(); void indent(); @@ -117,6 +119,7 @@ private: std::ostream_iterator output_; int depth_ = 0; bool space_ = false; + bool keepSpace_ = false; bool newline_ = false; }; diff --git a/src/parser/cxx/ast_pretty_printer.cc b/src/parser/cxx/ast_pretty_printer.cc index 513bf806..117555b5 100644 --- a/src/parser/cxx/ast_pretty_printer.cc +++ b/src/parser/cxx/ast_pretty_printer.cc @@ -34,6 +34,7 @@ struct ASTPrettyPrinter::UnitVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -51,6 +52,7 @@ struct ASTPrettyPrinter::DeclarationVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -122,6 +124,7 @@ struct ASTPrettyPrinter::StatementVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -173,6 +176,7 @@ struct ASTPrettyPrinter::ExpressionVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -304,6 +308,7 @@ struct ASTPrettyPrinter::TemplateParameterVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -325,6 +330,7 @@ struct ASTPrettyPrinter::SpecifierVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -410,6 +416,7 @@ struct ASTPrettyPrinter::PtrOperatorVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -429,6 +436,7 @@ struct ASTPrettyPrinter::CoreDeclaratorVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -450,6 +458,7 @@ struct ASTPrettyPrinter::DeclaratorChunkVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -467,6 +476,7 @@ struct ASTPrettyPrinter::UnqualifiedIdVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -498,6 +508,7 @@ struct ASTPrettyPrinter::NestedNameSpecifierVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -519,6 +530,7 @@ struct ASTPrettyPrinter::FunctionBodyVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -540,6 +552,7 @@ struct ASTPrettyPrinter::TemplateArgumentVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -557,6 +570,7 @@ struct ASTPrettyPrinter::ExceptionSpecifierVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -574,6 +588,7 @@ struct ASTPrettyPrinter::RequirementVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -595,6 +610,7 @@ struct ASTPrettyPrinter::NewInitializerVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -612,6 +628,7 @@ struct ASTPrettyPrinter::MemInitializerVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -629,6 +646,7 @@ struct ASTPrettyPrinter::LambdaCaptureVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -654,6 +672,7 @@ struct ASTPrettyPrinter::ExceptionDeclarationVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -671,6 +690,7 @@ struct ASTPrettyPrinter::AttributeSpecifierVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -694,6 +714,7 @@ struct ASTPrettyPrinter::AttributeTokenVisitor { } void space() { accept.space(); } void nospace() { accept.nospace(); } + void keepSpace() { accept.keepSpace(); } void newline() { accept.newline(); } void nonewline() { accept.nonewline(); } void indent() { accept.indent(); } @@ -993,6 +1014,7 @@ void ASTPrettyPrinter::operator()(EnumeratorAST* ast) { if (ast->equalLoc) { space(); writeToken(ast->equalLoc); + keepSpace(); } operator()(ast->expression); } @@ -1327,6 +1349,7 @@ void ASTPrettyPrinter::DeclarationVisitor::operator()( if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } accept(ast->nestedNameSpecifier); accept(ast->unqualifiedId); @@ -1441,6 +1464,7 @@ void ASTPrettyPrinter::DeclarationVisitor::operator()( if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } for (auto it = ast->gnuAttributeList; it; it = it->next) { @@ -1538,6 +1562,7 @@ void ASTPrettyPrinter::DeclarationVisitor::operator()( if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } accept(ast->expression); if (ast->semicolonLoc) { @@ -1750,6 +1775,7 @@ void ASTPrettyPrinter::DeclarationVisitor::operator()( if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } accept(ast->expression); } @@ -2330,7 +2356,11 @@ void ASTPrettyPrinter::ExpressionVisitor::operator()(FoldExpressionAST* ast) { } accept(ast->leftExpression); if (ast->opLoc) { + space(); + keepSpace(); accept.write("{}", Token::spell(ast->op)); + space(); + keepSpace(); } if (ast->ellipsisLoc) { accept.writeToken(ast->ellipsisLoc); @@ -2354,7 +2384,11 @@ void ASTPrettyPrinter::ExpressionVisitor::operator()( } accept(ast->expression); if (ast->opLoc) { + space(); + keepSpace(); accept.write("{}", Token::spell(ast->op)); + space(); + keepSpace(); } if (ast->ellipsisLoc) { accept.writeToken(ast->ellipsisLoc); @@ -2376,7 +2410,11 @@ void ASTPrettyPrinter::ExpressionVisitor::operator()( accept.writeToken(ast->ellipsisLoc); } if (ast->opLoc) { + space(); + keepSpace(); accept.write("{}", Token::spell(ast->op)); + space(); + keepSpace(); } accept(ast->expression); if (ast->rparenLoc) { @@ -2537,7 +2575,11 @@ void ASTPrettyPrinter::ExpressionVisitor::operator()( PostIncrExpressionAST* ast) { accept(ast->baseExpression); if (ast->opLoc) { + space(); + keepSpace(); accept.write("{}", Token::spell(ast->op)); + space(); + keepSpace(); } } @@ -2688,7 +2730,11 @@ void ASTPrettyPrinter::ExpressionVisitor::operator()( void ASTPrettyPrinter::ExpressionVisitor::operator()(UnaryExpressionAST* ast) { if (ast->opLoc) { + space(); + keepSpace(); accept.write("{}", Token::spell(ast->op)); + space(); + keepSpace(); } accept(ast->expression); } @@ -2859,7 +2905,11 @@ void ASTPrettyPrinter::ExpressionVisitor::operator()( void ASTPrettyPrinter::ExpressionVisitor::operator()(BinaryExpressionAST* ast) { accept(ast->leftExpression); if (ast->opLoc) { + space(); + keepSpace(); accept.write("{}", Token::spell(ast->op)); + space(); + keepSpace(); } accept(ast->rightExpression); } @@ -2896,7 +2946,11 @@ void ASTPrettyPrinter::ExpressionVisitor::operator()( AssignmentExpressionAST* ast) { accept(ast->leftExpression); if (ast->opLoc) { + space(); + keepSpace(); accept.write("{}", Token::spell(ast->op)); + space(); + keepSpace(); } accept(ast->rightExpression); } @@ -2965,6 +3019,7 @@ void ASTPrettyPrinter::ExpressionVisitor::operator()(EqualInitializerAST* ast) { if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } accept(ast->expression); } @@ -3050,6 +3105,7 @@ void ASTPrettyPrinter::TemplateParameterVisitor::operator()( if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } accept(ast->idExpression); } @@ -3073,6 +3129,7 @@ void ASTPrettyPrinter::TemplateParameterVisitor::operator()( if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } accept(ast->typeId); } @@ -3089,6 +3146,7 @@ void ASTPrettyPrinter::TemplateParameterVisitor::operator()( if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } accept(ast->typeId); } @@ -3634,6 +3692,9 @@ void ASTPrettyPrinter::UnqualifiedIdVisitor::operator()( accept.writeToken(ast->operatorLoc); } if (ast->opLoc) { + space(); + keepSpace(); + if (ast->op == TokenKind::T_NEW_ARRAY) { accept.write("new"); } else if (ast->op == TokenKind::T_DELETE_ARRAY) { @@ -3642,6 +3703,9 @@ void ASTPrettyPrinter::UnqualifiedIdVisitor::operator()( ast->op != TokenKind::T_LBRACKET) { accept.write("{}", Token::spell(ast->op)); } + + space(); + keepSpace(); } if (ast->openLoc) { nospace(); @@ -3795,6 +3859,7 @@ void ASTPrettyPrinter::FunctionBodyVisitor::operator()( if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } if (ast->defaultLoc) { accept.writeToken(ast->defaultLoc); @@ -3855,6 +3920,7 @@ void ASTPrettyPrinter::FunctionBodyVisitor::operator()( if (ast->equalLoc) { space(); accept.writeToken(ast->equalLoc); + keepSpace(); } if (ast->deleteLoc) { accept.writeToken(ast->deleteLoc); @@ -4287,10 +4353,16 @@ void ASTPrettyPrinter::space() { space_ = true; } -void ASTPrettyPrinter::nospace() { space_ = false; } +void ASTPrettyPrinter::nospace() { + if (keepSpace_) return; + space_ = false; +} + +void ASTPrettyPrinter::keepSpace() { keepSpace_ = true; } void ASTPrettyPrinter::newline() { space_ = false; + keepSpace_ = false; newline_ = true; } diff --git a/src/parser/cxx/ast_pretty_printer.h b/src/parser/cxx/ast_pretty_printer.h index f71a55cb..d9277b25 100644 --- a/src/parser/cxx/ast_pretty_printer.h +++ b/src/parser/cxx/ast_pretty_printer.h @@ -127,6 +127,7 @@ class ASTPrettyPrinter { } newline_ = false; space_ = false; + keepSpace_ = false; std::format_to(output_, fmt, std::forward(args)...); space(); } @@ -135,6 +136,7 @@ class ASTPrettyPrinter { void space(); void nospace(); + void keepSpace(); void newline(); void nonewline(); void indent(); @@ -145,6 +147,7 @@ class ASTPrettyPrinter { std::ostream_iterator output_; int depth_ = 0; bool space_ = false; + bool keepSpace_ = false; bool newline_ = false; }; diff --git a/tests/api_tests/test_rewriter.cc b/tests/api_tests/test_rewriter.cc index 8ff81297..2cb83fe7 100644 --- a/tests/api_tests/test_rewriter.cc +++ b/tests/api_tests/test_rewriter.cc @@ -246,7 +246,7 @@ const auto N = S<0, 1, 2>; }; ASSERT_EQ(decl_to_string(instance), - "const auto S =(0 * 0) +(1 * 1) +(2 * 2);"); + "const auto S = (0 * 0) + (1 * 1) + (2 * 2);"); auto eq = ast_cast( instance->initDeclaratorList->value->initializer);