diff options
Diffstat (limited to 'src/qmldom/qqmldomreformatter.cpp')
-rw-r--r-- | src/qmldom/qqmldomreformatter.cpp | 1980 |
1 files changed, 957 insertions, 1023 deletions
diff --git a/src/qmldom/qqmldomreformatter.cpp b/src/qmldom/qqmldomreformatter.cpp index 9114f39c3e..95533b61ac 100644 --- a/src/qmldom/qqmldomreformatter.cpp +++ b/src/qmldom/qqmldomreformatter.cpp @@ -11,6 +11,7 @@ #include <QString> +#include <algorithm> #include <limits> QT_BEGIN_NAMESPACE @@ -19,1170 +20,1103 @@ namespace Dom { using namespace AST; -class Rewriter : protected BaseVisitor +bool ScriptFormatter::preVisit(Node *n) { - OutWriter &lw; - std::shared_ptr<AstComments> comments; - std::function<QStringView(SourceLocation)> loc2Str; - QHash<Node *, QList<std::function<void()>>> postOps; - int expressionDepth = 0; - - bool addSemicolons() const { return expressionDepth > 0; } - -public: - Rewriter(OutWriter &lw, std::shared_ptr<AstComments> comments, - std::function<QStringView(SourceLocation)> loc2Str, Node *node) - : lw(lw), comments(comments), loc2Str(loc2Str) - { - accept(node); + if (CommentedElement *c = comments->commentForNode(n)) { + c->writePre(lw); + postOps[n].append([c, this]() { c->writePost(lw); }); } - -protected: - bool preVisit(Node *n) override - { - if (CommentedElement *c = comments->commentForNode(n)) { - c->writePre(lw); - postOps[n].append([c, this]() { c->writePost(lw); }); - } - return true; - } - void postVisit(Node *n) override - { - for (auto &op : postOps[n]) { - op(); - } - postOps.remove(n); + return true; +} +void ScriptFormatter::postVisit(Node *n) +{ + for (auto &op : postOps[n]) { + op(); } + postOps.remove(n); +} - void accept(Node *node) { Node::accept(node, this); } +void ScriptFormatter::lnAcceptIndented(Node *node) +{ + int indent = lw.increaseIndent(1); + lw.ensureNewline(); + accept(node); + lw.decreaseIndent(1, indent); +} - void lnAcceptIndented(Node *node) - { - int indent = lw.increaseIndent(1); - lw.ensureNewline(); - accept(node); - lw.decreaseIndent(1, indent); +bool ScriptFormatter::acceptBlockOrIndented(Node *ast, bool finishWithSpaceOrNewline) +{ + if (cast<Block *>(ast)) { + out(" "); + accept(ast); + if (finishWithSpaceOrNewline) + out(" "); + return true; + } else { + if (finishWithSpaceOrNewline) + postOps[ast].append([this]() { this->newLine(); }); + lnAcceptIndented(ast); + return false; } +} - void out(const char *str) { lw.write(QString::fromLatin1(str)); } - - void out(QStringView str) { lw.write(str); } +bool ScriptFormatter::visit(ThisExpression *ast) +{ + out(ast->thisToken); + return true; +} - void out(const SourceLocation &loc) - { - if (loc.length != 0) - out(loc2Str(loc)); - } +bool ScriptFormatter::visit(NullExpression *ast) +{ + out(ast->nullToken); + return true; +} +bool ScriptFormatter::visit(TrueLiteral *ast) +{ + out(ast->trueToken); + return true; +} +bool ScriptFormatter::visit(FalseLiteral *ast) +{ + out(ast->falseToken); + return true; +} - void newLine() { lw.ensureNewline(); } +bool ScriptFormatter::visit(IdentifierExpression *ast) +{ + out(ast->identifierToken); + return true; +} +bool ScriptFormatter::visit(StringLiteral *ast) +{ + // correctly handle multiline literals + if (ast->literalToken.length == 0) + return true; + QStringView str = loc2Str(ast->literalToken); + if (lw.indentNextlines && str.contains(QLatin1Char('\n'))) { + out(str.mid(0, 1)); + lw.indentNextlines = false; + out(str.mid(1)); + lw.indentNextlines = true; + } else { + out(str); + } + return true; +} +bool ScriptFormatter::visit(NumericLiteral *ast) +{ + out(ast->literalToken); + return true; +} +bool ScriptFormatter::visit(RegExpLiteral *ast) +{ + out(ast->literalToken); + return true; +} - bool acceptBlockOrIndented(Node *ast, bool finishWithSpaceOrNewline = false) - { - if (cast<Block *>(ast)) { - out(" "); - accept(ast); - if (finishWithSpaceOrNewline) - out(" "); - return true; - } else { - if (finishWithSpaceOrNewline) - postOps[ast].append([this]() { this->newLine(); }); - lnAcceptIndented(ast); - return false; +bool ScriptFormatter::visit(ArrayPattern *ast) +{ + out(ast->lbracketToken); + int baseIndent = lw.increaseIndent(1); + if (ast->elements) { + accept(ast->elements); + out(ast->commaToken); + auto lastElement = lastListElement(ast->elements); + if (lastElement->element && cast<ObjectPattern *>(lastElement->element->initializer)) { + newLine(); } + } else { + out(ast->commaToken); } + lw.decreaseIndent(1, baseIndent); + out(ast->rbracketToken); + return false; +} - // we are not supposed to handle the ui - bool visit(UiPragma *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiEnumDeclaration *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiEnumMemberList *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiImport *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiObjectDefinition *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiObjectInitializer *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiParameterList *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiPublicMember *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiObjectBinding *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiScriptBinding *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiArrayBinding *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiHeaderItemList *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiObjectMemberList *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiArrayMemberList *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiQualifiedId *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiProgram *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiSourceElement *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiVersionSpecifier *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiInlineComponent *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiAnnotation *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiAnnotationList *) override - { - Q_ASSERT(false); - return false; - } - bool visit(UiRequired *) override - { - Q_ASSERT(false); - return false; +bool ScriptFormatter::visit(ObjectPattern *ast) +{ + out(ast->lbraceToken); + ++expressionDepth; + if (ast->properties) { + lnAcceptIndented(ast->properties); + newLine(); } + --expressionDepth; + out(ast->rbraceToken); + return false; +} - bool visit(ThisExpression *ast) override - { - out(ast->thisToken); - return true; - } - bool visit(NullExpression *ast) override - { - out(ast->nullToken); - return true; - } - bool visit(TrueLiteral *ast) override - { - out(ast->trueToken); - return true; - } - bool visit(FalseLiteral *ast) override - { - out(ast->falseToken); - return true; - } - bool visit(IdentifierExpression *ast) override - { - out(ast->identifierToken); - return true; - } - bool visit(StringLiteral *ast) override - { - // correctly handle multiline literals - if (ast->literalToken.length == 0) - return true; - QStringView str = loc2Str(ast->literalToken); - if (lw.indentNextlines && str.contains(QLatin1Char('\n'))) { - out(str.mid(0, 1)); - lw.indentNextlines = false; - out(str.mid(1)); - lw.indentNextlines = true; - } else { - out(str); - } - return true; - } - bool visit(NumericLiteral *ast) override - { - out(ast->literalToken); - return true; - } - bool visit(RegExpLiteral *ast) override - { - out(ast->literalToken); - return true; - } +bool ScriptFormatter::visit(PatternElementList *ast) +{ + for (PatternElementList *it = ast; it; it = it->next) { + const bool isObjectInitializer = + it->element && cast<ObjectPattern *>(it->element->initializer); + if (isObjectInitializer) + newLine(); - bool visit(ArrayPattern *ast) override - { - out(ast->lbracketToken); - int baseIndent = lw.increaseIndent(1); - if (ast->elements) - accept(ast->elements); - out(ast->commaToken); - lw.decreaseIndent(1, baseIndent); - out(ast->rbracketToken); - return false; + if (it->elision) + accept(it->elision); + if (it->elision && it->element) + out(", "); + if (it->element) + accept(it->element); + if (it->next) { + out(", "); + if (isObjectInitializer) + newLine(); + } } + return false; +} - bool visit(ObjectPattern *ast) override - { - out(ast->lbraceToken); - ++expressionDepth; - if (ast->properties) { - lnAcceptIndented(ast->properties); +bool ScriptFormatter::visit(PatternPropertyList *ast) +{ + for (PatternPropertyList *it = ast; it; it = it->next) { + accept(it->property); + if (it->next) { + out(","); newLine(); } - --expressionDepth; - out(ast->rbraceToken); - return false; } + return false; +} - bool visit(PatternElementList *ast) override - { - for (PatternElementList *it = ast; it; it = it->next) { - if (it->elision) - accept(it->elision); - if (it->elision && it->element) - out(", "); - if (it->element) - accept(it->element); - if (it->next) - out(", "); +// https://262.ecma-international.org/7.0/#prod-PropertyDefinition +bool ScriptFormatter::visit(AST::PatternProperty *property) +{ + if (property->type == PatternElement::Getter || property->type == PatternElement::Setter + || property->type == PatternElement::Method) { + // note that MethodDefinitions and FunctionDeclarations have different syntax + // https://262.ecma-international.org/7.0/#prod-MethodDefinition + // https://262.ecma-international.org/7.0/#prod-FunctionDeclaration + // hence visit(FunctionDeclaration*) is not quite appropriate here + if (property->type == PatternProperty::Getter) + out("get "); + else if (property->type == PatternProperty::Setter) + out("set "); + FunctionExpression *f = AST::cast<FunctionExpression *>(property->initializer); + if (f->isGenerator) { + out("*"); } - return false; - } - - bool visit(PatternPropertyList *ast) override - { - for (PatternPropertyList *it = ast; it; it = it->next) { - PatternProperty *assignment = AST::cast<PatternProperty *>(it->property); - if (assignment) { - preVisit(assignment); - bool isStringLike = AST::cast<StringLiteralPropertyName *>(assignment->name) - || cast<IdentifierPropertyName *>(assignment->name); - if (isStringLike) - out("\""); - accept(assignment->name); - if (isStringLike) - out("\""); - out(": "); // assignment->colonToken - if (it->next) - postOps[assignment->initializer].append([this] { - out(","); // always invalid? - }); - accept(assignment->initializer); - if (it->next) - newLine(); - postVisit(assignment); - continue; - } - PatternPropertyList *getterSetter = AST::cast<PatternPropertyList *>(it->next); - if (getterSetter->property) { - switch (getterSetter->property->type) { - case PatternElement::Getter: - out("get"); - break; - case PatternElement::Setter: - out("set"); - break; - default: - break; - } - - accept(getterSetter->property->name); - out("("); - // accept(getterSetter->formals); // TODO - out(")"); - out(" {"); - // accept(getterSetter->functionBody); // TODO - out(" }"); + accept(property->name); + out(f->lparenToken); + accept(f->formals); + out(f->rparenToken); + out(f->lbraceToken); + const bool scoped = f->lbraceToken.isValid(); + if (scoped) + ++expressionDepth; + if (f->body) { + if (f->body->next || scoped) { + lnAcceptIndented(f->body); + lw.newline(); + } else { + auto baseIndent = lw.increaseIndent(1); + accept(f->body); + lw.decreaseIndent(1, baseIndent); } } + if (scoped) + --expressionDepth; + out(f->rbraceToken); return false; } - bool visit(NestedExpression *ast) override - { - out(ast->lparenToken); - int baseIndent = lw.increaseIndent(1); - accept(ast->expression); - lw.decreaseIndent(1, baseIndent); - out(ast->rparenToken); - return false; + // IdentifierReference[?Yield] + accept(property->name); + bool useInitializer = false; + const bool bindingIdentifierExist = !property->bindingIdentifier.isEmpty(); + if (property->colonToken.isValid()) { + // PropertyName[?Yield] : AssignmentExpression[In, ?Yield] + out(": "); + useInitializer = true; + if (bindingIdentifierExist) + out(property->bindingIdentifier); + if (property->bindingTarget) + accept(property->bindingTarget); } - bool visit(IdentifierPropertyName *ast) override - { - out(ast->id.toString()); - return true; - } - bool visit(StringLiteralPropertyName *ast) override - { - out(ast->id.toString()); - return true; - } - bool visit(NumericLiteralPropertyName *ast) override - { - out(QString::number(ast->id)); - return true; + if (property->initializer) { + // CoverInitializedName[?Yield] + if (bindingIdentifierExist) { + out(" = "); + useInitializer = true; + } + if (useInitializer) + accept(property->initializer); } + return false; +} - bool visit(TemplateLiteral *ast) override - { - // correctly handle multiline literals - if (ast->literalToken.length != 0) { - QStringView str = loc2Str(ast->literalToken); - if (lw.indentNextlines && str.contains(QLatin1Char('\n'))) { - out(str.mid(0, 1)); - lw.indentNextlines = false; - out(str.mid(1)); - lw.indentNextlines = true; - } else { - out(str); - } +bool ScriptFormatter::visit(NestedExpression *ast) +{ + out(ast->lparenToken); + int baseIndent = lw.increaseIndent(1); + accept(ast->expression); + lw.decreaseIndent(1, baseIndent); + out(ast->rparenToken); + return false; +} + +bool ScriptFormatter::visit(IdentifierPropertyName *ast) +{ + out(ast->id.toString()); + return true; +} +bool ScriptFormatter::visit(StringLiteralPropertyName *ast) +{ + out(ast->propertyNameToken); + return true; +} +bool ScriptFormatter::visit(NumericLiteralPropertyName *ast) +{ + out(QString::number(ast->id)); + return true; +} + +bool ScriptFormatter::visit(TemplateLiteral *ast) +{ + // correctly handle multiline literals + if (ast->literalToken.length != 0) { + QStringView str = loc2Str(ast->literalToken); + if (lw.indentNextlines && str.contains(QLatin1Char('\n'))) { + out(str.mid(0, 1)); + lw.indentNextlines = false; + out(str.mid(1)); + lw.indentNextlines = true; + } else { + out(str); } - accept(ast->expression); - return true; } + accept(ast->expression); + return true; +} - bool visit(ArrayMemberExpression *ast) override - { - accept(ast->base); - out(ast->lbracketToken); - int indent = lw.increaseIndent(1); - accept(ast->expression); - lw.decreaseIndent(1, indent); - out(ast->rbracketToken); - return false; - } +bool ScriptFormatter::visit(ArrayMemberExpression *ast) +{ + accept(ast->base); + out(ast->lbracketToken); + int indent = lw.increaseIndent(1); + accept(ast->expression); + lw.decreaseIndent(1, indent); + out(ast->rbracketToken); + return false; +} - bool visit(FieldMemberExpression *ast) override - { - accept(ast->base); - out(ast->dotToken); - out(ast->identifierToken); - return false; - } +bool ScriptFormatter::visit(FieldMemberExpression *ast) +{ + accept(ast->base); + out(ast->dotToken); + out(ast->identifierToken); + return false; +} - bool visit(NewMemberExpression *ast) override - { - out("new "); // ast->newToken - accept(ast->base); - out(ast->lparenToken); - accept(ast->arguments); - out(ast->rparenToken); - return false; - } +bool ScriptFormatter::visit(NewMemberExpression *ast) +{ + out("new "); // ast->newToken + accept(ast->base); + out(ast->lparenToken); + accept(ast->arguments); + out(ast->rparenToken); + return false; +} - bool visit(NewExpression *ast) override - { - out("new "); // ast->newToken - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(NewExpression *ast) +{ + out("new "); // ast->newToken + accept(ast->expression); + return false; +} - bool visit(CallExpression *ast) override - { - accept(ast->base); - out(ast->lparenToken); - int baseIndent = lw.increaseIndent(1); - accept(ast->arguments); - lw.decreaseIndent(1, baseIndent); - out(ast->rparenToken); - return false; - } +bool ScriptFormatter::visit(CallExpression *ast) +{ + accept(ast->base); + out(ast->lparenToken); + accept(ast->arguments); + out(ast->rparenToken); + return false; +} - bool visit(PostIncrementExpression *ast) override - { - accept(ast->base); - out(ast->incrementToken); - return false; - } +bool ScriptFormatter::visit(PostIncrementExpression *ast) +{ + accept(ast->base); + out(ast->incrementToken); + return false; +} - bool visit(PostDecrementExpression *ast) override - { - accept(ast->base); - out(ast->decrementToken); - return false; - } +bool ScriptFormatter::visit(PostDecrementExpression *ast) +{ + accept(ast->base); + out(ast->decrementToken); + return false; +} - bool visit(PreIncrementExpression *ast) override - { - out(ast->incrementToken); - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(PreIncrementExpression *ast) +{ + out(ast->incrementToken); + accept(ast->expression); + return false; +} - bool visit(PreDecrementExpression *ast) override - { - out(ast->decrementToken); - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(PreDecrementExpression *ast) +{ + out(ast->decrementToken); + accept(ast->expression); + return false; +} - bool visit(DeleteExpression *ast) override - { - out("delete "); // ast->deleteToken - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(DeleteExpression *ast) +{ + out("delete "); // ast->deleteToken + accept(ast->expression); + return false; +} - bool visit(VoidExpression *ast) override - { - out("void "); // ast->voidToken - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(VoidExpression *ast) +{ + out("void "); // ast->voidToken + accept(ast->expression); + return false; +} - bool visit(TypeOfExpression *ast) override - { - out("typeof "); // ast->typeofToken - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(TypeOfExpression *ast) +{ + out("typeof "); // ast->typeofToken + accept(ast->expression); + return false; +} - bool visit(UnaryPlusExpression *ast) override - { - out(ast->plusToken); - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(UnaryPlusExpression *ast) +{ + out(ast->plusToken); + accept(ast->expression); + return false; +} - bool visit(UnaryMinusExpression *ast) override - { - out(ast->minusToken); - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(UnaryMinusExpression *ast) +{ + out(ast->minusToken); + accept(ast->expression); + return false; +} - bool visit(TildeExpression *ast) override - { - out(ast->tildeToken); - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(TildeExpression *ast) +{ + out(ast->tildeToken); + accept(ast->expression); + return false; +} - bool visit(NotExpression *ast) override - { - out(ast->notToken); - accept(ast->expression); - return false; - } +bool ScriptFormatter::visit(NotExpression *ast) +{ + out(ast->notToken); + accept(ast->expression); + return false; +} - bool visit(BinaryExpression *ast) override - { - accept(ast->left); - out(" "); - out(ast->operatorToken); - out(" "); - accept(ast->right); - return false; - } +bool ScriptFormatter::visit(BinaryExpression *ast) +{ + accept(ast->left); + out(" "); + out(ast->operatorToken); + out(" "); + accept(ast->right); + return false; +} - bool visit(ConditionalExpression *ast) override - { - accept(ast->expression); - out(" ? "); // ast->questionToken - accept(ast->ok); - out(" : "); // ast->colonToken - accept(ast->ko); - return false; - } +bool ScriptFormatter::visit(ConditionalExpression *ast) +{ + accept(ast->expression); + out(" ? "); // ast->questionToken + accept(ast->ok); + out(" : "); // ast->colonToken + accept(ast->ko); + return false; +} - bool visit(Block *ast) override - { - out(ast->lbraceToken); +bool ScriptFormatter::visit(Block *ast) +{ + out(ast->lbraceToken); + if (ast->statements) { ++expressionDepth; lnAcceptIndented(ast->statements); newLine(); --expressionDepth; - out(ast->rbraceToken); - return false; } + out(ast->rbraceToken); + return false; +} - bool visit(VariableStatement *ast) override - { - out(ast->declarationKindToken); - out(" "); - accept(ast->declarations); - if (addSemicolons()) - out(";"); - return false; +bool ScriptFormatter::visit(VariableStatement *ast) +{ + out(ast->declarationKindToken); + out(" "); + accept(ast->declarations); + if (addSemicolons()) + out(";"); + return false; +} + +bool ScriptFormatter::visit(PatternElement *ast) +{ + switch (ast->type) { + case PatternElement::Literal: + case PatternElement::Method: + case PatternElement::Binding: + break; + case PatternElement::Getter: + out("get "); + break; + case PatternElement::Setter: + out("set "); + break; + case PatternElement::SpreadElement: + out("..."); + break; + } + + accept(ast->bindingTarget); + if (!ast->destructuringPattern()) + out(ast->identifierToken); + if (ast->initializer) { + if (ast->isVariableDeclaration() || ast->type == AST::PatternElement::Binding) + out(" = "); + accept(ast->initializer); } + return false; +} +bool ScriptFormatter::visit(EmptyStatement *ast) +{ + out(ast->semicolonToken); + return false; +} - void outputScope(VariableScope scope) { - switch (scope) { - case VariableScope::Const: - out("const "); - break; - case VariableScope::Let: - out("let "); - break; - case VariableScope::Var: - out("var "); - break; - default: - break; +bool ScriptFormatter::visit(IfStatement *ast) +{ + out(ast->ifToken); + out(" "); + out(ast->lparenToken); + preVisit(ast->expression); + ast->expression->accept0(this); + out(ast->rparenToken); + postVisit(ast->expression); + acceptBlockOrIndented(ast->ok, ast->ko); + if (ast->ko) { + out(ast->elseToken); + if (cast<Block *>(ast->ko) || cast<IfStatement *>(ast->ko)) { + out(" "); + accept(ast->ko); + } else { + lnAcceptIndented(ast->ko); } } + return false; +} - bool visit(PatternElement *ast) override - { - if (ast->isForDeclaration) { - outputScope(ast->scope); - } - accept(ast->bindingTarget); - switch (ast->type) { - case PatternElement::Literal: - case PatternElement::Method: - case PatternElement::Binding: - break; - case PatternElement::Getter: - out("get "); - break; - case PatternElement::Setter: - out("set "); - break; - case PatternElement::SpreadElement: - out("..."); - break; +bool ScriptFormatter::visit(DoWhileStatement *ast) +{ + out(ast->doToken); + acceptBlockOrIndented(ast->statement, true); + out(ast->whileToken); + out(" "); + out(ast->lparenToken); + accept(ast->expression); + out(ast->rparenToken); + return false; +} + +bool ScriptFormatter::visit(WhileStatement *ast) +{ + out(ast->whileToken); + out(" "); + out(ast->lparenToken); + accept(ast->expression); + out(ast->rparenToken); + acceptBlockOrIndented(ast->statement); + return false; +} + +bool ScriptFormatter::visit(ForStatement *ast) +{ + out(ast->forToken); + out(" "); + out(ast->lparenToken); + if (ast->initialiser) { + accept(ast->initialiser); + } else if (ast->declarations) { + if (auto pe = ast->declarations->declaration) { + out(pe->declarationKindToken); + out(" "); } - out(ast->identifierToken); - if (ast->initializer) { - if (ast->isVariableDeclaration()) - out(" = "); - accept(ast->initializer); + for (VariableDeclarationList *it = ast->declarations; it; it = it->next) { + accept(it->declaration); } - return false; } + out("; "); // ast->firstSemicolonToken + accept(ast->condition); + out("; "); // ast->secondSemicolonToken + accept(ast->expression); + out(ast->rparenToken); + acceptBlockOrIndented(ast->statement); + return false; +} - bool visit(EmptyStatement *ast) override - { - out(ast->semicolonToken); - return false; +bool ScriptFormatter::visit(ForEachStatement *ast) +{ + out(ast->forToken); + out(" "); + out(ast->lparenToken); + if (auto pe = AST::cast<PatternElement *>(ast->lhs)) { + out(pe->declarationKindToken); + out(" "); } + accept(ast->lhs); + out(" "); + out(ast->inOfToken); + out(" "); + accept(ast->expression); + out(ast->rparenToken); + acceptBlockOrIndented(ast->statement); + return false; +} - bool visit(IfStatement *ast) override - { - out(ast->ifToken); +bool ScriptFormatter::visit(ContinueStatement *ast) +{ + out(ast->continueToken); + if (!ast->label.isNull()) { out(" "); - out(ast->lparenToken); - preVisit(ast->expression); - ast->expression->accept0(this); - out(ast->rparenToken); - postVisit(ast->expression); - acceptBlockOrIndented(ast->ok, ast->ko); - if (ast->ko) { - out(ast->elseToken); - if (cast<Block *>(ast->ko) || cast<IfStatement *>(ast->ko)) { - out(" "); - accept(ast->ko); - } else { - lnAcceptIndented(ast->ko); - } - } - return false; + out(ast->identifierToken); } + if (addSemicolons()) + out(";"); + return false; +} - bool visit(DoWhileStatement *ast) override - { - out(ast->doToken); - acceptBlockOrIndented(ast->statement, true); - out(ast->whileToken); +bool ScriptFormatter::visit(BreakStatement *ast) +{ + out(ast->breakToken); + if (!ast->label.isNull()) { out(" "); - out(ast->lparenToken); - accept(ast->expression); - out(ast->rparenToken); - return false; + out(ast->identifierToken); } + if (addSemicolons()) + out(";"); + return false; +} - bool visit(WhileStatement *ast) override - { - out(ast->whileToken); - out(" "); - out(ast->lparenToken); +bool ScriptFormatter::visit(ReturnStatement *ast) +{ + out(ast->returnToken); + if (ast->expression) { + if (ast->returnToken.length != 0) + out(" "); accept(ast->expression); - out(ast->rparenToken); - acceptBlockOrIndented(ast->statement); - return false; } + if (ast->returnToken.length > 0 && addSemicolons()) + out(";"); + return false; +} - bool visit(ForStatement *ast) override - { - out(ast->forToken); +bool ScriptFormatter::visit(ThrowStatement *ast) +{ + out(ast->throwToken); + if (ast->expression) { out(" "); - out(ast->lparenToken); - if (ast->initialiser) { - accept(ast->initialiser); - } else if (ast->declarations) { - outputScope(ast->declarations->declaration->scope); - accept(ast->declarations); - } - out("; "); // ast->firstSemicolonToken - accept(ast->condition); - out("; "); // ast->secondSemicolonToken accept(ast->expression); - out(ast->rparenToken); - acceptBlockOrIndented(ast->statement); - return false; } + if (addSemicolons()) + out(";"); + return false; +} - bool visit(ForEachStatement *ast) override - { - out(ast->forToken); - out(" "); - out(ast->lparenToken); - accept(ast->lhs); +bool ScriptFormatter::visit(WithStatement *ast) +{ + out(ast->withToken); + out(" "); + out(ast->lparenToken); + accept(ast->expression); + out(ast->rparenToken); + acceptBlockOrIndented(ast->statement); + return false; +} + +bool ScriptFormatter::visit(SwitchStatement *ast) +{ + out(ast->switchToken); + out(" "); + out(ast->lparenToken); + accept(ast->expression); + out(ast->rparenToken); + out(" "); + accept(ast->block); + return false; +} + +bool ScriptFormatter::visit(CaseBlock *ast) +{ + out(ast->lbraceToken); + ++expressionDepth; + newLine(); + accept(ast->clauses); + if (ast->clauses && ast->defaultClause) + newLine(); + accept(ast->defaultClause); + if (ast->moreClauses) + newLine(); + accept(ast->moreClauses); + newLine(); + --expressionDepth; + out(ast->rbraceToken); + return false; +} + +bool ScriptFormatter::visit(CaseClause *ast) +{ + out("case "); // ast->caseToken + accept(ast->expression); + out(ast->colonToken); + if (ast->statements) + lnAcceptIndented(ast->statements); + return false; +} + +bool ScriptFormatter::visit(DefaultClause *ast) +{ + out(ast->defaultToken); + out(ast->colonToken); + lnAcceptIndented(ast->statements); + return false; +} + +bool ScriptFormatter::visit(LabelledStatement *ast) +{ + out(ast->identifierToken); + out(": "); // ast->colonToken + accept(ast->statement); + return false; +} + +bool ScriptFormatter::visit(TryStatement *ast) +{ + out("try "); // ast->tryToken + accept(ast->statement); + if (ast->catchExpression) { out(" "); - out(ast->inOfToken); + accept(ast->catchExpression); + } + if (ast->finallyExpression) { out(" "); - accept(ast->expression); - out(ast->rparenToken); - acceptBlockOrIndented(ast->statement); - return false; + accept(ast->finallyExpression); } + return false; +} - bool visit(ContinueStatement *ast) override - { - out(ast->continueToken); - if (!ast->label.isNull()) { - out(" "); +bool ScriptFormatter::visit(Catch *ast) +{ + out(ast->catchToken); + out(" "); + out(ast->lparenToken); + out(ast->identifierToken); + out(") "); // ast->rparenToken + accept(ast->statement); + return false; +} + +bool ScriptFormatter::visit(Finally *ast) +{ + out("finally "); // ast->finallyToken + accept(ast->statement); + return false; +} + +bool ScriptFormatter::visit(FunctionDeclaration *ast) +{ + return ScriptFormatter::visit(static_cast<FunctionExpression *>(ast)); +} + +bool ScriptFormatter::visit(FunctionExpression *ast) +{ + if (!ast->isArrowFunction) { + if (ast->isGenerator) { + out("function* "); + } else { + out("function "); + } + if (!ast->name.isNull()) out(ast->identifierToken); + } + out(ast->lparenToken); + const bool needParentheses = ast->formals + && (ast->formals->next + || (ast->formals->element && ast->formals->element->bindingTarget)); + if (ast->isArrowFunction && needParentheses) + out("("); + int baseIndent = lw.increaseIndent(1); + accept(ast->formals); + lw.decreaseIndent(1, baseIndent); + if (ast->isArrowFunction && needParentheses) + out(")"); + out(ast->rparenToken); + if (ast->isArrowFunction && !ast->formals) + out("()"); + out(" "); + if (ast->isArrowFunction) + out("=> "); + out(ast->lbraceToken); + if (ast->lbraceToken.length != 0) + ++expressionDepth; + if (ast->body) { + if (ast->body->next || ast->lbraceToken.length != 0) { + lnAcceptIndented(ast->body); + newLine(); + } else { + // print a single statement in one line. E.g. x => x * 2 + baseIndent = lw.increaseIndent(1); + accept(ast->body); + lw.decreaseIndent(1, baseIndent); } - if (addSemicolons()) - out(";"); - return false; } + if (ast->lbraceToken.length != 0) + --expressionDepth; + out(ast->rbraceToken); + return false; +} - bool visit(BreakStatement *ast) override - { - out(ast->breakToken); - if (!ast->label.isNull()) { - out(" "); - out(ast->identifierToken); - } - if (addSemicolons()) - out(";"); - return false; +bool ScriptFormatter::visit(Elision *ast) +{ + for (Elision *it = ast; it; it = it->next) { + if (it->next) + out(", "); // ast->commaToken } + return false; +} - bool visit(ReturnStatement *ast) override - { - out(ast->returnToken); - if (ast->expression) { - if (ast->returnToken.length != 0) - out(" "); - accept(ast->expression); +bool ScriptFormatter::visit(ArgumentList *ast) +{ + for (ArgumentList *it = ast; it; it = it->next) { + if (it->isSpreadElement) + out("..."); + accept(it->expression); + if (it->next) { + out(", "); // it->commaToken } - if (ast->returnToken.length > 0 && addSemicolons()) - out(";"); - return false; } + return false; +} - bool visit(ThrowStatement *ast) override - { - out(ast->throwToken); - if (ast->expression) { - out(" "); - accept(ast->expression); +bool ScriptFormatter::visit(StatementList *ast) +{ + ++expressionDepth; + for (StatementList *it = ast; it; it = it->next) { + // ### work around parser bug: skip empty statements with wrong tokens + if (EmptyStatement *emptyStatement = cast<EmptyStatement *>(it->statement)) { + if (loc2Str(emptyStatement->semicolonToken) != QLatin1String(";")) + continue; } - if (addSemicolons()) - out(";"); - return false; - } - bool visit(WithStatement *ast) override - { - out(ast->withToken); - out(" "); - out(ast->lparenToken); - accept(ast->expression); - out(ast->rparenToken); - acceptBlockOrIndented(ast->statement); - return false; + accept(it->statement); + if (it->next) { + // There might be a post-comment attached to the current + // statement or a pre-comment attached to the next + // statmente or both. + // If any of those are present they will take care of + // handling the spacing between the statements so we + // don't need to push any newline. + auto *commentForCurrentStatement = comments->commentForNode(it->statement); + auto *commentForNextStatement = comments->commentForNode(it->next->statement); + + if ( + (commentForCurrentStatement && !commentForCurrentStatement->postComments().empty()) + || (commentForNextStatement && !commentForNextStatement->preComments().empty()) + ) continue; + + quint32 lineDelta = it->next->firstSourceLocation().startLine + - it->statement->lastSourceLocation().startLine; + lineDelta = std::clamp(lineDelta, quint32{ 1 }, quint32{ 2 }); + + newLine(lineDelta); + } } + --expressionDepth; + return false; +} - bool visit(SwitchStatement *ast) override - { - out(ast->switchToken); - out(" "); - out(ast->lparenToken); - accept(ast->expression); - out(ast->rparenToken); - out(" "); - accept(ast->block); - return false; +bool ScriptFormatter::visit(VariableDeclarationList *ast) +{ + for (VariableDeclarationList *it = ast; it; it = it->next) { + accept(it->declaration); + if (it->next) + out(", "); // it->commaToken } + return false; +} - bool visit(CaseBlock *ast) override - { - out(ast->lbraceToken); - ++expressionDepth; - newLine(); - accept(ast->clauses); - if (ast->clauses && ast->defaultClause) - newLine(); - accept(ast->defaultClause); - if (ast->moreClauses) +bool ScriptFormatter::visit(CaseClauses *ast) +{ + for (CaseClauses *it = ast; it; it = it->next) { + accept(it->clause); + if (it->next) newLine(); - accept(ast->moreClauses); - newLine(); - --expressionDepth; - out(ast->rbraceToken); - return false; } + return false; +} - bool visit(CaseClause *ast) override - { - out("case "); // ast->caseToken - accept(ast->expression); - out(ast->colonToken); - if (ast->statements) - lnAcceptIndented(ast->statements); - return false; - } +bool ScriptFormatter::visit(FormalParameterList *ast) +{ + for (FormalParameterList *it = ast; it; it = it->next) { + // compare FormalParameterList::finish + if (auto id = it->element->bindingIdentifier.toString(); !id.isEmpty()) + out(id); + if (it->element->bindingTarget) + accept(it->element->bindingTarget); + if (it->next) + out(", "); + } + return false; +} - bool visit(DefaultClause *ast) override - { - out(ast->defaultToken); - out(ast->colonToken); - lnAcceptIndented(ast->statements); - return false; - } +// to check +bool ScriptFormatter::visit(SuperLiteral *) +{ + out("super"); + return true; +} +bool ScriptFormatter::visit(ComputedPropertyName *) +{ + out("["); + return true; +} +bool ScriptFormatter::visit(Expression *el) +{ + accept(el->left); + out(", "); + accept(el->right); + return false; +} +bool ScriptFormatter::visit(ExpressionStatement *el) +{ + if (addSemicolons()) + postOps[el->expression].append([this]() { out(";"); }); + return true; +} - bool visit(LabelledStatement *ast) override - { - out(ast->identifierToken); - out(": "); // ast->colonToken - accept(ast->statement); - return false; - } +// Return false because we want to omit default function calls in accept0 implementation. +bool ScriptFormatter::visit(ClassDeclaration *ast) +{ + preVisit(ast); + out(ast->classToken); + out(" "); + out(ast->name); + if (ast->heritage) { + out(" extends "); + accept(ast->heritage); + } + out(" {"); + int baseIndent = lw.increaseIndent(); + for (ClassElementList *it = ast->elements; it; it = it->next) { + lw.newline(); + if (it->isStatic) + out("static "); + accept(it->property); + lw.newline(); + } + lw.decreaseIndent(1, baseIndent); + out("}"); + postVisit(ast); + return false; +} - bool visit(TryStatement *ast) override - { - out("try "); // ast->tryToken - accept(ast->statement); - if (ast->catchExpression) { - out(" "); - accept(ast->catchExpression); - } - if (ast->finallyExpression) { - out(" "); - accept(ast->finallyExpression); - } - return false; +bool ScriptFormatter::visit(AST::ImportDeclaration *ast) +{ + out(ast->importToken); + lw.space(); + if (!ast->moduleSpecifier.isNull()) { + out(ast->moduleSpecifierToken); } + return true; +} - bool visit(Catch *ast) override - { - out(ast->catchToken); - out(" "); - out(ast->lparenToken); +bool ScriptFormatter::visit(AST::ImportSpecifier *ast) +{ + if (!ast->identifier.isNull()) { out(ast->identifierToken); - out(") "); // ast->rparenToken - accept(ast->statement); - return false; + lw.space(); + out("as"); + lw.space(); } + out(ast->importedBindingToken); + return true; +} - bool visit(Finally *ast) override - { - out("finally "); // ast->finallyToken - accept(ast->statement); - return false; - } +bool ScriptFormatter::visit(AST::NameSpaceImport *ast) +{ + out(ast->starToken); + lw.space(); + out("as"); + lw.space(); + out(ast->importedBindingToken); + return true; +} - bool visit(FunctionDeclaration *ast) override - { - return visit(static_cast<FunctionExpression *>(ast)); +bool ScriptFormatter::visit(AST::ImportsList *ast) +{ + for (ImportsList *it = ast; it; it = it->next) { + accept(it->importSpecifier); + if (it->next) { + out(","); + lw.space(); + } + } + return false; +} +bool ScriptFormatter::visit(AST::NamedImports *ast) +{ + out(ast->leftBraceToken); + if (ast->importsList) { + lw.space(); } + return true; +} - bool visit(FunctionExpression *ast) override - { - if (!ast->isArrowFunction) { - out("function "); // ast->functionToken - if (!ast->name.isNull()) - out(ast->identifierToken); - } - out(ast->lparenToken); - if (ast->isArrowFunction && ast->formals && ast->formals->next) - out("("); - int baseIndent = lw.increaseIndent(1); - accept(ast->formals); - lw.decreaseIndent(1, baseIndent); - if (ast->isArrowFunction && ast->formals && ast->formals->next) - out(")"); - out(ast->rparenToken); - if (ast->isArrowFunction && !ast->formals) - out("()"); - out(" "); - if (ast->isArrowFunction) - out("=> "); - out(ast->lbraceToken); - if (ast->lbraceToken.length != 0) - ++expressionDepth; - if (ast->body) { - if (ast->body->next || ast->lbraceToken.length != 0) { - lnAcceptIndented(ast->body); - newLine(); - } else { - // print a single statement in one line. E.g. x => x * 2 - baseIndent = lw.increaseIndent(1); - accept(ast->body); - lw.decreaseIndent(1, baseIndent); - } +bool ScriptFormatter::visit(AST::ImportClause *ast) +{ + if (!ast->importedDefaultBinding.isNull()) { + out(ast->importedDefaultBindingToken); + if (ast->nameSpaceImport || ast->namedImports) { + out(","); + lw.space(); } - if (ast->lbraceToken.length != 0) - --expressionDepth; - out(ast->rbraceToken); - return false; } + return true; +} - bool visit(Elision *ast) override - { - for (Elision *it = ast; it; it = it->next) { - if (it->next) - out(", "); // ast->commaToken - } - return false; +bool ScriptFormatter::visit(AST::ExportDeclaration *ast) +{ + out(ast->exportToken); + lw.space(); + if (ast->exportDefault) { + out("default"); + lw.space(); + } + if (ast->exportsAll()) { + out("*"); } + return true; +} - bool visit(ArgumentList *ast) override - { - for (ArgumentList *it = ast; it; it = it->next) { - if (it->isSpreadElement) - out("..."); - accept(it->expression); - if (it->next) { - out(", "); // it->commaToken - } - } - return false; +bool ScriptFormatter::visit(AST::ExportClause *ast) +{ + out(ast->leftBraceToken); + if (ast->exportsList) { + lw.space(); } + return true; +} - bool visit(StatementList *ast) override - { - ++expressionDepth; - for (StatementList *it = ast; it; it = it->next) { - // ### work around parser bug: skip empty statements with wrong tokens - if (EmptyStatement *emptyStatement = cast<EmptyStatement *>(it->statement)) { - if (loc2Str(emptyStatement->semicolonToken) != QLatin1String(";")) - continue; - } +bool ScriptFormatter::visit(AST::ExportSpecifier *ast) +{ + out(ast->identifier); + if (ast->exportedIdentifierToken.isValid()) { + lw.space(); + out("as"); + lw.space(); + out(ast->exportedIdentifier); + } + return true; +} - accept(it->statement); - if (it->next) - newLine(); +bool ScriptFormatter::visit(AST::ExportsList *ast) +{ + for (ExportsList *it = ast; it; it = it->next) { + accept(it->exportSpecifier); + if (it->next) { + out(","); + lw.space(); } - --expressionDepth; - return false; } + return false; +} - bool visit(VariableDeclarationList *ast) override - { - for (VariableDeclarationList *it = ast; it; it = it->next) { - accept(it->declaration); - if (it->next) - out(", "); // it->commaToken - } - return false; - } +bool ScriptFormatter::visit(AST::FromClause *ast) +{ + lw.space(); + out(ast->fromToken); + lw.space(); + out(ast->moduleSpecifierToken); + return true; +} - bool visit(CaseClauses *ast) override - { - for (CaseClauses *it = ast; it; it = it->next) { - accept(it->clause); - if (it->next) - newLine(); - } - return false; - } +void ScriptFormatter::endVisit(ComputedPropertyName *) +{ + out("]"); +} - bool visit(FormalParameterList *ast) override - { - for (FormalParameterList *it = ast; it; it = it->next) { - out(it->element->bindingIdentifier.toString()); // TODO - if (it->next) - out(", "); - } - return false; +void ScriptFormatter::endVisit(AST::ExportDeclaration *ast) +{ + // add a semicolon at the end of the following expressions + // export * FromClause ; + // export ExportClause FromClause ; + if (ast->fromClause) { + out(";"); } - // to check - bool visit(TypeExpression *) override { return true; } - bool visit(SuperLiteral *) override - { - out("super"); - return true; - } - bool visit(PatternProperty *) override { return true; } - bool visit(ComputedPropertyName *) override - { - out("["); - return true; - } - bool visit(TaggedTemplate *) override { return true; } - bool visit(Expression *el) override - { - accept(el->left); - out(", "); - accept(el->right); - return false; - } - bool visit(ExpressionStatement *el) override - { - if (addSemicolons()) - postOps[el->expression].append([this]() { out(";"); }); - return true; + // add a semicolon at the end of the following expressions + // export ExportClause ; + if (ast->exportClause && !ast->fromClause) { + out(";"); } - bool visit(YieldExpression *) override { return true; } - bool visit(ClassExpression *) override { return true; } - - // Return false because we want to omit default function calls in accept0 implementation. - bool visit(ClassDeclaration *ast) override - { - preVisit(ast); - out(ast->classToken); - out(" "); - out(ast->name); - if (ast->heritage) { - out(" extends "); - accept(ast->heritage); + + // add a semicolon at the end of the following expressions + // export default [lookahead ∉ { function, class }] AssignmentExpression; + if (ast->exportDefault && ast->variableStatementOrDeclaration) { + // lookahead ∉ { function, class } + if (!(ast->variableStatementOrDeclaration->kind == Node::Kind_FunctionDeclaration + || ast->variableStatementOrDeclaration->kind == Node::Kind_ClassDeclaration)) { + out(";"); } - out(" {"); - int baseIndent = lw.increaseIndent(); - for (ClassElementList *it = ast->elements; it; it = it->next) { - PatternProperty *property = it->property; - lw.newline(); - preVisit(property); - if (it->isStatic) - out("static "); - if (property->type == PatternProperty::Getter) - out("get "); - else if (property->type == PatternProperty::Setter) - out("set "); - FunctionExpression *f = AST::cast<FunctionExpression *>(property->initializer); - const bool scoped = f->lbraceToken.length != 0; - out(f->functionToken); - out(f->lparenToken); - accept(f->formals); - out(f->rparenToken); - out(f->lbraceToken); - if (scoped) - ++expressionDepth; - if (f->body) { - if (f->body->next || scoped) { - lnAcceptIndented(f->body); - lw.newline(); - } else { - baseIndent = lw.increaseIndent(1); - accept(f->body); - lw.decreaseIndent(1, baseIndent); - } - } - if (scoped) - --expressionDepth; - out(f->rbraceToken); - lw.newline(); - postVisit(property); + // ArrowFunction in QQmlJS::AST is handled with the help of FunctionDeclaration + // and not as part of AssignmentExpression (as per ECMA + // https://262.ecma-international.org/7.0/#prod-AssignmentExpression) + if (ast->variableStatementOrDeclaration->kind == Node::Kind_FunctionDeclaration + && static_cast<AST::FunctionDeclaration *>(ast->variableStatementOrDeclaration) + ->isArrowFunction) { + out(";"); } - lw.decreaseIndent(1, baseIndent); - out("}"); - postVisit(ast); - return false; } +} + +void ScriptFormatter::endVisit(AST::ExportClause *ast) +{ + if (ast->exportsList) { + lw.space(); + } + out(ast->rightBraceToken); +} - bool visit(ClassElementList *) override { return true; } - bool visit(Program *) override { return true; } - bool visit(NameSpaceImport *) override { return true; } - bool visit(ImportSpecifier *) override { return true; } - bool visit(ImportsList *) override { return true; } - bool visit(NamedImports *) override { return true; } - bool visit(FromClause *) override { return true; } - bool visit(ImportClause *) override { return true; } - bool visit(ImportDeclaration *) override { return true; } - bool visit(ExportSpecifier *) override { return true; } - bool visit(ExportsList *) override { return true; } - bool visit(ExportClause *) override { return true; } - bool visit(ExportDeclaration *) override { return true; } - bool visit(ESModule *) override { return true; } - bool visit(DebuggerStatement *) override { return true; } - bool visit(Type *) override { return true; } - bool visit(TypeArgument *) override { return true; } - bool visit(TypeAnnotation *) override { return true; } - - // overridden to use BasicVisitor (and ensure warnings about new added AST) - void endVisit(UiProgram *) override { } - void endVisit(UiImport *) override { } - void endVisit(UiHeaderItemList *) override { } - void endVisit(UiPragma *) override { } - void endVisit(UiPublicMember *) override { } - void endVisit(UiSourceElement *) override { } - void endVisit(UiObjectDefinition *) override { } - void endVisit(UiObjectInitializer *) override { } - void endVisit(UiObjectBinding *) override { } - void endVisit(UiScriptBinding *) override { } - void endVisit(UiArrayBinding *) override { } - void endVisit(UiParameterList *) override { } - void endVisit(UiObjectMemberList *) override { } - void endVisit(UiArrayMemberList *) override { } - void endVisit(UiQualifiedId *) override { } - void endVisit(UiEnumDeclaration *) override { } - void endVisit(UiEnumMemberList *) override { } - void endVisit(UiVersionSpecifier *) override { } - void endVisit(UiInlineComponent *) override { } - void endVisit(UiAnnotation *) override { } - void endVisit(UiAnnotationList *) override { } - void endVisit(UiRequired *) override { } - void endVisit(TypeExpression *) override { } - void endVisit(ThisExpression *) override { } - void endVisit(IdentifierExpression *) override { } - void endVisit(NullExpression *) override { } - void endVisit(TrueLiteral *) override { } - void endVisit(FalseLiteral *) override { } - void endVisit(SuperLiteral *) override { } - void endVisit(StringLiteral *) override { } - void endVisit(TemplateLiteral *) override { } - void endVisit(NumericLiteral *) override { } - void endVisit(RegExpLiteral *) override { } - void endVisit(ArrayPattern *) override { } - void endVisit(ObjectPattern *) override { } - void endVisit(PatternElementList *) override { } - void endVisit(PatternPropertyList *) override { } - void endVisit(PatternElement *) override { } - void endVisit(PatternProperty *) override { } - void endVisit(Elision *) override { } - void endVisit(NestedExpression *) override { } - void endVisit(IdentifierPropertyName *) override { } - void endVisit(StringLiteralPropertyName *) override { } - void endVisit(NumericLiteralPropertyName *) override { } - void endVisit(ComputedPropertyName *) override { out("]"); } - void endVisit(ArrayMemberExpression *) override { } - void endVisit(FieldMemberExpression *) override { } - void endVisit(TaggedTemplate *) override { } - void endVisit(NewMemberExpression *) override { } - void endVisit(NewExpression *) override { } - void endVisit(CallExpression *) override { } - void endVisit(ArgumentList *) override { } - void endVisit(PostIncrementExpression *) override { } - void endVisit(PostDecrementExpression *) override { } - void endVisit(DeleteExpression *) override { } - void endVisit(VoidExpression *) override { } - void endVisit(TypeOfExpression *) override { } - void endVisit(PreIncrementExpression *) override { } - void endVisit(PreDecrementExpression *) override { } - void endVisit(UnaryPlusExpression *) override { } - void endVisit(UnaryMinusExpression *) override { } - void endVisit(TildeExpression *) override { } - void endVisit(NotExpression *) override { } - void endVisit(BinaryExpression *) override { } - void endVisit(ConditionalExpression *) override { } - void endVisit(Expression *) override { } - void endVisit(Block *) override { } - void endVisit(StatementList *) override { } - void endVisit(VariableStatement *) override { } - void endVisit(VariableDeclarationList *) override { } - void endVisit(EmptyStatement *) override { } - void endVisit(ExpressionStatement *) override { } - void endVisit(IfStatement *) override { } - void endVisit(DoWhileStatement *) override { } - void endVisit(WhileStatement *) override { } - void endVisit(ForStatement *) override { } - void endVisit(ForEachStatement *) override { } - void endVisit(ContinueStatement *) override { } - void endVisit(BreakStatement *) override { } - void endVisit(ReturnStatement *) override { } - void endVisit(YieldExpression *) override { } - void endVisit(WithStatement *) override { } - void endVisit(SwitchStatement *) override { } - void endVisit(CaseBlock *) override { } - void endVisit(CaseClauses *) override { } - void endVisit(CaseClause *) override { } - void endVisit(DefaultClause *) override { } - void endVisit(LabelledStatement *) override { } - void endVisit(ThrowStatement *) override { } - void endVisit(TryStatement *) override { } - void endVisit(Catch *) override { } - void endVisit(Finally *) override { } - void endVisit(FunctionDeclaration *) override { } - void endVisit(FunctionExpression *) override { } - void endVisit(FormalParameterList *) override { } - void endVisit(ClassExpression *) override { } - void endVisit(ClassDeclaration *) override { } - void endVisit(ClassElementList *) override { } - void endVisit(Program *) override { } - void endVisit(NameSpaceImport *) override { } - void endVisit(ImportSpecifier *) override { } - void endVisit(ImportsList *) override { } - void endVisit(NamedImports *) override { } - void endVisit(FromClause *) override { } - void endVisit(ImportClause *) override { } - void endVisit(ImportDeclaration *) override { } - void endVisit(ExportSpecifier *) override { } - void endVisit(ExportsList *) override { } - void endVisit(ExportClause *) override { } - void endVisit(ExportDeclaration *) override { } - void endVisit(ESModule *) override { } - void endVisit(DebuggerStatement *) override { } - void endVisit(Type *) override { } - void endVisit(TypeArgument *) override { } - void endVisit(TypeAnnotation *) override { } - - void throwRecursionDepthError() override - { - out("/* ERROR: Hit recursion limit visiting AST, rewrite failed */"); +void ScriptFormatter::endVisit(AST::NamedImports *ast) +{ + if (ast->importsList) { + lw.space(); } -}; + out(ast->rightBraceToken); +} + +void ScriptFormatter::endVisit(AST::ImportDeclaration *) +{ + out(";"); +} + +void ScriptFormatter::throwRecursionDepthError() +{ + out("/* ERROR: Hit recursion limit ScriptFormatter::visiting AST, rewrite failed */"); +} -void reformatAst(OutWriter &lw, std::shared_ptr<AstComments> comments, - const std::function<QStringView(SourceLocation)> loc2Str, AST::Node *n) +void reformatAst(OutWriter &lw, const std::shared_ptr<AstComments> &comments, + const std::function<QStringView(SourceLocation)> &loc2Str, AST::Node *n) { if (n) { - Rewriter rewriter(lw, comments, loc2Str, n); + ScriptFormatter formatter(lw, comments, loc2Str, n); } } |