aboutsummaryrefslogtreecommitdiffstats
path: root/tools/qmlformat/dumpastvisitor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/qmlformat/dumpastvisitor.cpp')
-rw-r--r--tools/qmlformat/dumpastvisitor.cpp1433
1 files changed, 0 insertions, 1433 deletions
diff --git a/tools/qmlformat/dumpastvisitor.cpp b/tools/qmlformat/dumpastvisitor.cpp
deleted file mode 100644
index 723be4e445..0000000000
--- a/tools/qmlformat/dumpastvisitor.cpp
+++ /dev/null
@@ -1,1433 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2019 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the tools applications of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:GPL-EXCEPT$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3 as published by the Free Software
-** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "dumpastvisitor.h"
-
-#include <QtQml/private/qqmljslexer_p.h>
-
-DumpAstVisitor::DumpAstVisitor(QQmlJS::Engine *engine, Node *rootNode, CommentAstVisitor *comment,
- int indentWidth, DumpAstVisitor::Indentation indentation)
- : m_engine(engine), m_comment(comment), m_indentWidth(indentWidth), m_indentation(indentation)
-{
- // Add all completely orphaned comments
- m_result += getOrphanedComments(nullptr);
-
- m_scope_properties.push(ScopeProperties {});
-
- rootNode->accept(this);
-
- // We need to get rid of one new-line so our output doesn't append an empty line
- m_result.chop(1);
-
- // Remove trailing whitespace
- QStringList lines = m_result.split("\n");
- for (QString& line : lines) {
- while (line.endsWith(" "))
- line.chop(1);
- }
-
- m_result = lines.join("\n");
-}
-
-bool DumpAstVisitor::preVisit(Node *el)
-{
- UiObjectMember *m = el->uiObjectMemberCast();
- if (m != 0)
- Node::accept(m->annotations, this);
- return true;
-}
-
-static QString parseUiQualifiedId(UiQualifiedId *id)
-{
- QString name = id->name.toString();
- for (auto *item = id->next; item != nullptr; item = item->next) {
- name += "." + item->name;
- }
-
- return name;
-}
-
-static QString operatorToString(int op)
-{
- switch (op)
- {
- case QSOperator::Add: return "+";
- case QSOperator::And: return "&&";
- case QSOperator::InplaceAnd: return "&=";
- case QSOperator::Assign: return "=";
- case QSOperator::BitAnd: return "&";
- case QSOperator::BitOr: return "|";
- case QSOperator::BitXor: return "^";
- case QSOperator::InplaceSub: return "-=";
- case QSOperator::Div: return "/";
- case QSOperator::InplaceDiv: return "/=";
- case QSOperator::Equal: return "==";
- case QSOperator::Exp: return "**";
- case QSOperator::InplaceExp: return "**=";
- case QSOperator::Ge: return ">=";
- case QSOperator::Gt: return ">";
- case QSOperator::In: return "in";
- case QSOperator::InplaceAdd: return "+=";
- case QSOperator::InstanceOf: return "instanceof";
- case QSOperator::Le: return "<=";
- case QSOperator::LShift: return "<<";
- case QSOperator::InplaceLeftShift: return "<<=";
- case QSOperator::Lt: return "<";
- case QSOperator::Mod: return "%";
- case QSOperator::InplaceMod: return "%=";
- case QSOperator::Mul: return "*";
- case QSOperator::InplaceMul: return "*=";
- case QSOperator::NotEqual: return "!=";
- case QSOperator::Or: return "||";
- case QSOperator::InplaceOr: return "|=";
- case QSOperator::RShift: return ">>";
- case QSOperator::InplaceRightShift: return ">>=";
- case QSOperator::StrictEqual: return "===";
- case QSOperator::StrictNotEqual: return "!==";
- case QSOperator::Sub: return "-";
- case QSOperator::URShift: return ">>>";
- case QSOperator::InplaceURightShift: return ">>>=";
- case QSOperator::InplaceXor: return "^=";
- case QSOperator::As: return "as";
- case QSOperator::Coalesce: return "??";
- case QSOperator::Invalid:
- default:
- return "INVALID";
- }
-}
-
-QString DumpAstVisitor::formatComment(const Comment &comment) const
-{
- QString result;
-
- bool useMultilineComment = comment.isMultiline() && !comment.isSyntheticMultiline();
-
- if (useMultilineComment)
- result += "/*";
- else if (!comment.hasSheBang())
- result += "//";
-
- result += comment.m_text;
-
- if (comment.isSyntheticMultiline())
- result = result.replace("\n","\n" + formatLine("//", false));
-
- if (comment.m_location == Comment::Location::Back_Inline)
- result.prepend(" ");
-
- if (useMultilineComment)
- result += "*/";
-
- return result;
-}
-
-QString DumpAstVisitor::getComment(Node *node, Comment::Location location) const
-{
- const auto& comments = m_comment->attachedComments();
- if (!comments.contains(node))
- return "";
-
- auto comment = comments[node];
-
- if (comment.m_location != location)
- return "";
-
- return formatComment(comment);
-}
-
-QString DumpAstVisitor::getListItemComment(SourceLocation srcLocation,
- Comment::Location location) const {
- const auto& comments = m_comment->listComments();
-
- if (!comments.contains(srcLocation.begin()))
- return "";
-
- auto comment = comments[srcLocation.begin()];
-
- if (comment.m_location != location)
- return "";
-
- return formatComment(comment);
-}
-
-QString DumpAstVisitor::getOrphanedComments(Node *node) const {
- const auto& orphans = m_comment->orphanComments()[node];
-
- if (orphans.size() == 0)
- return "";
-
- QString result = "";
-
- for (const Comment& orphan : orphans) {
- result += formatLine(formatComment(orphan));
- }
-
- result += "\n";
-
- return result;
-}
-
-QString DumpAstVisitor::parseArgumentList(ArgumentList *list)
-{
- QString result = "";
-
- for (auto *item = list; item != nullptr; item = item->next)
- result += parseExpression(item->expression) + (item->next != nullptr ? ", " : "");
-
- return result;
-}
-
-QString DumpAstVisitor::parseUiParameterList(UiParameterList *list) {
- QString result = "";
-
- for (auto *item = list; item != nullptr; item = item->next)
- result += parseUiQualifiedId(item->type) + " " + item->name + (item->next != nullptr ? ", " : "");
-
- return result;
-}
-
-QString DumpAstVisitor::parsePatternElement(PatternElement *element, bool scope)
-{
- switch (element->type)
- {
- case PatternElement::Literal:
- return parseExpression(element->initializer);
- case PatternElement::Binding: {
- QString result = "";
- QString expr = parseExpression(element->initializer);
-
- if (scope) {
- switch (element->scope) {
- case VariableScope::NoScope:
- break;
- case VariableScope::Let:
- result = "let ";
- break;
- case VariableScope::Const:
- result = "const ";
- break;
- case VariableScope::Var:
- result = "var ";
- break;
- }
- }
-
- if (element->bindingIdentifier.isEmpty())
- result += parseExpression(element->bindingTarget);
- else
- result += element->bindingIdentifier.toString();
-
- if (element->typeAnnotation != nullptr)
- result += ": " + parseType(element->typeAnnotation->type);
-
- if (!expr.isEmpty())
- result += " = "+expr;
-
- return result;
- }
- default:
- m_error = true;
- return "pe_unknown";
- }
-}
-
-static QString escapeString(QString string)
-{
- // Handle escape sequences
- string = string.replace("\r", "\\r").replace("\n", "\\n").replace("\t", "\\t")
- .replace("\b","\\b").replace("\v", "\\v").replace("\f", "\\f");
-
- // Escape backslash
- string = string.replace("\\", "\\\\");
-
- // Escape "
- string = string.replace("\"", "\\\"");
-
- return "\"" + string + "\"";
-}
-
-QString DumpAstVisitor::parsePatternElementList(PatternElementList *list)
-{
- QString result = "";
-
- for (auto *item = list; item != nullptr; item = item->next)
- result += parsePatternElement(item->element) + (item->next != nullptr ? ", " : "");
-
- return result;
-}
-
-QString DumpAstVisitor::parseFormalParameterList(FormalParameterList *list)
-{
- QString result = "";
-
- for (auto *item = list; item != nullptr; item = item->next)
- result += parsePatternElement(item->element) + (item->next != nullptr ? ", " : "");
-
- return result;
-}
-
-QString DumpAstVisitor::parsePatternProperty(PatternProperty *property)
-{
- switch (property->type) {
- case PatternElement::Getter:
- return "get "+parseFunctionExpression(cast<FunctionExpression *>(property->initializer), true);
- case PatternElement::Setter:
- return "set "+parseFunctionExpression(cast<FunctionExpression *>(property->initializer), true);
- default:
- if (property->name->kind == Node::Kind_ComputedPropertyName) {
- return "["+parseExpression(cast<ComputedPropertyName *>(property->name)->expression)+"]: "+parsePatternElement(property, false);
- } else {
- return escapeString(property->name->asString())+": "+parsePatternElement(property, false);
- }
- }
-}
-
-QString DumpAstVisitor::parsePatternPropertyList(PatternPropertyList *list)
-{
- QString result = "";
-
- for (auto *item = list; item != nullptr; item = item->next) {
- result += formatLine(parsePatternProperty(item->property) + (item->next != nullptr ? "," : ""));
- }
-
- return result;
-}
-
-QString DumpAstVisitor::parseFunctionExpression(FunctionExpression *functExpr, bool omitFunction)
-{
- m_indentLevel++;
- QString result;
- bool hasBraces = true;
-
- if (!functExpr->isArrowFunction) {
- result += omitFunction ? "" : "function";
-
- if (functExpr->isGenerator)
- result += "*";
-
- if (!functExpr->name.isEmpty())
- result += (omitFunction ? "" : " ") + functExpr->name;
-
- result += "("+parseFormalParameterList(functExpr->formals)+")";
-
- if (functExpr->typeAnnotation != nullptr)
- result += " : " + parseType(functExpr->typeAnnotation->type);
-
- result += " {\n" + parseStatementList(functExpr->body);
- } else {
- result += "("+parseFormalParameterList(functExpr->formals)+")";
-
- if (functExpr->typeAnnotation != nullptr)
- result += " : " + parseType(functExpr->typeAnnotation->type);
-
- result += " => ";
-
- if (functExpr->body == nullptr) {
- result += "{}";
- } else if (functExpr->body->next == nullptr && functExpr->body->statement->kind == Node::Kind_ReturnStatement) {
- m_indentLevel--;
- result += parseExpression(cast<ReturnStatement *>(functExpr->body->statement)->expression);
- hasBraces = false;
- } else {
- result += "{\n" + parseStatementList(functExpr->body);
- }
- }
-
- if (hasBraces) {
- m_indentLevel--;
- result += formatLine("}", false);
- }
-
- return result;
-
-}
-
-QString DumpAstVisitor::parseType(Type *type) {
- QString result = parseUiQualifiedId(type->typeId);
-
- if (type->typeArguments != nullptr) {
- TypeArgumentList *list = cast<TypeArgumentList *>(type->typeArguments);
-
- result += "<";
-
- for (auto *item = list; item != nullptr; item = item->next) {
- result += parseType(item->typeId) + (item->next != nullptr ? ", " : "");
- }
-
- result += ">";
- }
-
- return result;
-}
-
-QString DumpAstVisitor::parseExpression(ExpressionNode *expression)
-{
- if (expression == nullptr)
- return "";
-
- switch (expression->kind)
- {
- case Node::Kind_ArrayPattern:
- return "["+parsePatternElementList(cast<ArrayPattern *>(expression)->elements)+"]";
- case Node::Kind_IdentifierExpression:
- return cast<IdentifierExpression*>(expression)->name.toString();
- case Node::Kind_FieldMemberExpression: {
- auto *fieldMemberExpr = cast<FieldMemberExpression *>(expression);
- QString result = parseExpression(fieldMemberExpr->base);
-
- // If we're operating on a numeric literal, always put it in braces
- if (fieldMemberExpr->base->kind == Node::Kind_NumericLiteral)
- result = "(" + result + ")";
-
- result += "." + fieldMemberExpr->name.toString();
-
- return result;
- }
- case Node::Kind_ArrayMemberExpression: {
- auto *arrayMemberExpr = cast<ArrayMemberExpression *>(expression);
- return parseExpression(arrayMemberExpr->base)
- + "[" + parseExpression(arrayMemberExpr->expression) + "]";
- }
- case Node::Kind_NestedExpression:
- return "("+parseExpression(cast<NestedExpression *>(expression)->expression)+")";
- case Node::Kind_TrueLiteral:
- return "true";
- case Node::Kind_FalseLiteral:
- return "false";
- case Node::Kind_FunctionExpression:
- {
- auto *functExpr = cast<FunctionExpression *>(expression);
- return parseFunctionExpression(functExpr);
- }
- case Node::Kind_NullExpression:
- return "null";
- case Node::Kind_ThisExpression:
- return "this";
- case Node::Kind_PostIncrementExpression:
- return parseExpression(cast<PostIncrementExpression *>(expression)->base)+"++";
- case Node::Kind_PreIncrementExpression:
- return "++"+parseExpression(cast<PreIncrementExpression *>(expression)->expression);
- case Node::Kind_PostDecrementExpression:
- return parseExpression(cast<PostDecrementExpression *>(expression)->base)+"--";
- case Node::Kind_PreDecrementExpression:
- return "--"+parseExpression(cast<PreDecrementExpression *>(expression)->expression);
- case Node::Kind_NumericLiteral:
- return QString::number(cast<NumericLiteral *>(expression)->value);
- case Node::Kind_TemplateLiteral: {
- auto firstSrcLoc = cast<TemplateLiteral *>(expression)->firstSourceLocation();
- auto lastSrcLoc = cast<TemplateLiteral *>(expression)->lastSourceLocation();
- return m_engine->code().mid(static_cast<int>(firstSrcLoc.begin()),
- static_cast<int>(lastSrcLoc.end() - firstSrcLoc.begin()));
- }
- case Node::Kind_StringLiteral: {
- auto srcLoc = cast<StringLiteral *>(expression)->firstSourceLocation();
- return m_engine->code().mid(static_cast<int>(srcLoc.begin()),
- static_cast<int>(srcLoc.end() - srcLoc.begin()));
- }
- case Node::Kind_BinaryExpression: {
- auto *binExpr = expression->binaryExpressionCast();
- return parseExpression(binExpr->left) + " " + operatorToString(binExpr->op)
- + " " + parseExpression(binExpr->right);
- }
- case Node::Kind_CallExpression: {
- auto *callExpr = cast<CallExpression *>(expression);
-
- return parseExpression(callExpr->base) + "(" + parseArgumentList(callExpr->arguments) + ")";
- }
- case Node::Kind_NewExpression:
- return "new "+parseExpression(cast<NewExpression *>(expression)->expression);
- case Node::Kind_NewMemberExpression: {
- auto *newMemberExpression = cast<NewMemberExpression *>(expression);
- return "new "+parseExpression(newMemberExpression->base)
- + "(" +parseArgumentList(newMemberExpression->arguments)+")";
- }
- case Node::Kind_DeleteExpression:
- return "delete " + parseExpression(cast<DeleteExpression *>(expression)->expression);
- case Node::Kind_VoidExpression:
- return "void " + parseExpression(cast<VoidExpression *>(expression)->expression);
- case Node::Kind_TypeOfExpression:
- return "typeof " + parseExpression(cast<TypeOfExpression *>(expression)->expression);
- case Node::Kind_UnaryPlusExpression:
- return "+" + parseExpression(cast<UnaryPlusExpression *>(expression)->expression);
- case Node::Kind_UnaryMinusExpression:
- return "-" + parseExpression(cast<UnaryMinusExpression *>(expression)->expression);
- case Node::Kind_NotExpression:
- return "!" + parseExpression(cast<NotExpression *>(expression)->expression);
- case Node::Kind_TildeExpression:
- return "~" + parseExpression(cast<TildeExpression *>(expression)->expression);
- case Node::Kind_ConditionalExpression: {
- auto *condExpr = cast<ConditionalExpression *>(expression);
-
- QString result = "";
-
- result += parseExpression(condExpr->expression) + " ? ";
- result += parseExpression(condExpr->ok) + " : ";
- result += parseExpression(condExpr->ko);
-
- return result;
- }
- case Node::Kind_YieldExpression: {
- auto *yieldExpr = cast<YieldExpression*>(expression);
-
- QString result = "yield";
-
- if (yieldExpr->isYieldStar)
- result += "*";
-
- if (yieldExpr->expression)
- result += " " + parseExpression(yieldExpr->expression);
-
- return result;
- }
- case Node::Kind_ObjectPattern: {
- auto *objectPattern = cast<ObjectPattern*>(expression);
-
- if (objectPattern->properties == nullptr)
- return "{}";
-
- QString result = "{\n";
-
- m_indentLevel++;
- result += parsePatternPropertyList(objectPattern->properties);
- m_indentLevel--;
-
- result += formatLine("}", false);
-
- return result;
- }
- case Node::Kind_Expression: {
- auto* expr = cast<Expression*>(expression);
- return parseExpression(expr->left)+", "+parseExpression(expr->right);
- }
- case Node::Kind_TypeExpression: {
- auto* type = cast<TypeExpression*>(expression);
- return parseType(type->m_type);
- }
- case Node::Kind_RegExpLiteral: {
- auto* regexpLiteral = cast<RegExpLiteral*>(expression);
- QString result = "/"+regexpLiteral->pattern+"/";
-
- if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_Unicode)
- result += "u";
- if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_Global)
- result += "g";
- if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_Multiline)
- result += "m";
- if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_Sticky)
- result += "y";
- if (regexpLiteral->flags & QQmlJS::Lexer::RegExp_IgnoreCase)
- result += "i";
-
- return result;
- }
- default:
- m_error = true;
- return "unknown_expression_"+QString::number(expression->kind);
- }
-}
-
-QString DumpAstVisitor::parseVariableDeclarationList(VariableDeclarationList *list)
-{
- QString result = "";
-
- for (auto *item = list; item != nullptr; item = item->next) {
- result += parsePatternElement(item->declaration, (item == list))
- + (item->next != nullptr ? ", " : "");
- }
-
- return result;
-}
-
-QString DumpAstVisitor::parseCaseBlock(CaseBlock *block)
-{
- QString result = "{\n";
-
- for (auto *item = block->clauses; item != nullptr; item = item->next) {
- result += formatLine("case "+parseExpression(item->clause->expression)+":");
- m_indentLevel++;
- result += parseStatementList(item->clause->statements);
- m_indentLevel--;
- }
-
- if (block->defaultClause) {
- result += formatLine("default:");
- m_indentLevel++;
- result += parseStatementList(block->defaultClause->statements);
- m_indentLevel--;
- }
-
- result += formatLine("}", false);
-
- return result;
-}
-
-QString DumpAstVisitor::parseExportSpecifier(ExportSpecifier *specifier)
-{
- QString result = specifier->identifier.toString();
-
- if (!specifier->exportedIdentifier.isEmpty())
- result += " as " + specifier->exportedIdentifier;
-
- return result;
-}
-
-QString DumpAstVisitor::parseExportsList(ExportsList *list)
-{
- QString result = "";
-
- for (auto *item = list; item != nullptr; item = item->next) {
- result += formatLine(parseExportSpecifier(item->exportSpecifier)
- + (item->next != nullptr ? "," : ""));
- }
-
- return result;
-}
-
-static bool needsSemicolon(int kind)
-{
- switch (kind) {
- case Node::Kind_ForStatement:
- case Node::Kind_ForEachStatement:
- case Node::Kind_IfStatement:
- case Node::Kind_SwitchStatement:
- case Node::Kind_WhileStatement:
- case Node::Kind_DoWhileStatement:
- case Node::Kind_TryStatement:
- case Node::Kind_WithStatement:
- return false;
- default:
- return true;
- }
-}
-
-QString DumpAstVisitor::parseBlock(Block *block, bool hasNext, bool allowBraceless)
-{
- bool hasOneLine =
- (block->statements != nullptr && block->statements->next == nullptr) && allowBraceless;
-
- QString result = hasOneLine ? "\n" : "{\n";
- m_indentLevel++;
- result += parseStatementList(block->statements);
- m_indentLevel--;
-
- if (hasNext)
- result += formatLine(hasOneLine ? "" : "} ", false);
-
- if (!hasNext && !hasOneLine)
- result += formatLine("}", false);
-
- if (block->statements) {
- m_blockNeededBraces |= !needsSemicolon(block->statements->statement->kind)
- || (block->statements->next != nullptr);
- } else {
- m_blockNeededBraces = true;
- }
-
- return result;
-}
-
-static bool endsWithSemicolon(const QStringView s)
-{
- return s.trimmed().endsWith(';');
-}
-
-QString DumpAstVisitor::parseStatement(Statement *statement, bool blockHasNext,
- bool blockAllowBraceless)
-{
- if (statement == nullptr)
- return "";
-
- switch (statement->kind)
- {
- case Node::Kind_EmptyStatement:
- return "";
- case Node::Kind_ExpressionStatement:
- return parseExpression(cast<ExpressionStatement *>(statement)->expression);
- case Node::Kind_VariableStatement:
- return parseVariableDeclarationList(cast<VariableStatement *>(statement)->declarations);
- case Node::Kind_ReturnStatement:
- return "return "+parseExpression(cast<ReturnStatement *>(statement)->expression);
- case Node::Kind_ContinueStatement:
- return "continue";
- case Node::Kind_BreakStatement:
- return "break";
- case Node::Kind_SwitchStatement: {
- auto *switchStatement = cast<SwitchStatement *>(statement);
-
- QString result = "switch ("+parseExpression(switchStatement->expression)+") ";
-
- result += parseCaseBlock(switchStatement->block);
-
- return result;
- }
- case Node::Kind_IfStatement: {
- auto *ifStatement = cast<IfStatement *>(statement);
-
- m_blockNeededBraces = !blockAllowBraceless;
-
- QString ifFalse = parseStatement(ifStatement->ko, false, true);
- QString ifTrue = parseStatement(ifStatement->ok, !ifFalse.isEmpty(), true);
-
- bool ifTrueBlock = ifStatement->ok->kind == Node::Kind_Block;
- bool ifFalseBlock = ifStatement->ko
- ? (ifStatement->ko->kind == Node::Kind_Block || ifStatement->ko->kind == Node::Kind_IfStatement)
- : false;
-
- if (m_blockNeededBraces) {
- ifFalse = parseStatement(ifStatement->ko, false, false);
- ifTrue = parseStatement(ifStatement->ok, !ifFalse.isEmpty(), false);
- }
-
- if (ifStatement->ok->kind != Node::Kind_Block && !endsWithSemicolon(ifTrue))
- ifTrue += ";";
-
- if (ifStatement->ko && ifStatement->ko->kind != Node::Kind_Block
- && ifStatement->ko->kind != Node::Kind_IfStatement && !endsWithSemicolon(ifFalse))
- ifFalse += ";";
-
- QString result = "if (" + parseExpression(ifStatement->expression) + ")";
-
- if (m_blockNeededBraces) {
- if (ifStatement->ok->kind != Node::Kind_Block) {
- QString result = "{\n";
- m_indentLevel++;
- result += formatLine(ifTrue);
- m_indentLevel--;
- result += formatLine("} ", false);
- ifTrue = result;
- ifTrueBlock = true;
- }
-
- if (ifStatement->ko && ifStatement->ko->kind != Node::Kind_Block && ifStatement->ko->kind != Node::Kind_IfStatement) {
- QString result = "{\n";
- m_indentLevel++;
- result += formatLine(ifFalse);
- m_indentLevel--;
- result += formatLine("} ", false);
- ifFalse = result;
- ifFalseBlock = true;
- }
- }
-
- if (ifTrueBlock) {
- result += " " + ifTrue;
- } else {
- result += "\n";
- m_indentLevel++;
- result += formatPartlyFormatedLines(ifTrue);
- m_indentLevel--;
- }
-
- if (!ifFalse.isEmpty())
- {
- if (ifTrueBlock)
- result += "else";
- else
- result += formatLine("else", false);
-
- if (ifFalseBlock) {
- // Blocks generate an extra newline that we don't want here.
- if (!m_blockNeededBraces && ifFalse.endsWith(QLatin1String("\n")))
- ifFalse.chop(1);
-
- result += " " + ifFalse;
- } else {
- result += "\n";
- m_indentLevel++;
- result += formatPartlyFormatedLines(ifFalse, false);
- m_indentLevel--;
- }
- }
-
- return result;
- }
- case Node::Kind_ForStatement: {
- auto *forStatement = cast<ForStatement *>(statement);
-
- QString expr = parseExpression(forStatement->expression);
- QString result = "for (";
-
- result += parseVariableDeclarationList(forStatement->declarations);
-
- result += "; ";
-
- result += parseExpression(forStatement->condition) + "; ";
- result += parseExpression(forStatement->expression)+")";
-
- const QString statement = parseStatement(forStatement->statement);
-
- if (!statement.isEmpty())
- result += " "+statement;
- else
- result += ";";
-
- return result;
- }
- case Node::Kind_ForEachStatement: {
- auto *forEachStatement = cast<ForEachStatement *>(statement);
-
- QString result = "for (";
-
- PatternElement *patternElement = cast<PatternElement *>(forEachStatement->lhs);
-
- if (patternElement != nullptr)
- result += parsePatternElement(patternElement);
- else
- result += parseExpression(forEachStatement->lhs->expressionCast());
-
- switch (forEachStatement->type)
- {
- case ForEachType::In:
- result += " in ";
- break;
- case ForEachType::Of:
- result += " of ";
- break;
- }
-
- result += parseExpression(forEachStatement->expression) + ")";
-
- const QString statement = parseStatement(forEachStatement->statement);
-
- if (!statement.isEmpty())
- result += " "+statement;
- else
- result += ";";
-
- return result;
- }
- case Node::Kind_WhileStatement: {
- auto *whileStatement = cast<WhileStatement *>(statement);
-
- m_blockNeededBraces = false;
-
- auto statement = parseStatement(whileStatement->statement, false, true);
-
- QString result = "while ("+parseExpression(whileStatement->expression) + ")";
-
- if (!statement.isEmpty())
- result += (m_blockNeededBraces ? " " : "") + statement;
- else
- result += ";";
-
- return result;
- }
- case Node::Kind_DoWhileStatement: {
- auto *doWhileStatement = cast<DoWhileStatement *>(statement);
- return "do " + parseBlock(cast<Block *>(doWhileStatement->statement), true, false)
- + "while (" + parseExpression(doWhileStatement->expression) + ")";
- }
- case Node::Kind_TryStatement: {
- auto *tryStatement = cast<TryStatement *>(statement);
-
- Catch *catchExpr = tryStatement->catchExpression;
- Finally *finallyExpr = tryStatement->finallyExpression;
-
- QString result;
-
- result += "try " + parseBlock(cast<Block *>(tryStatement->statement), true, false);
-
- result += "catch (" + parsePatternElement(catchExpr->patternElement, false) + ") "
- + parseBlock(cast<Block *>(catchExpr->statement), finallyExpr, false);
-
- if (finallyExpr) {
- result += "finally " + parseBlock(cast<Block *>(tryStatement->statement), false, false);
- }
-
- return result;
- }
- case Node::Kind_Block: {
- return parseBlock(cast<Block *>(statement), blockHasNext, blockAllowBraceless);
- }
- case Node::Kind_ThrowStatement:
- return "throw "+parseExpression(cast<ThrowStatement *>(statement)->expression);
- case Node::Kind_LabelledStatement: {
- auto *labelledStatement = cast<LabelledStatement *>(statement);
- QString result = labelledStatement->label+":\n";
- result += formatLine(parseStatement(labelledStatement->statement), false);
-
- return result;
- }
- case Node::Kind_WithStatement: {
- auto *withStatement = cast<WithStatement *>(statement);
- return "with (" + parseExpression(withStatement->expression) + ") "
- + parseStatement(withStatement->statement);
- }
- case Node::Kind_DebuggerStatement: {
- return "debugger";
- }
- case Node::Kind_ExportDeclaration:
- m_error = true;
- return "export_decl_unsupported";
- case Node::Kind_ImportDeclaration:
- m_error = true;
- return "import_decl_unsupported";
- default:
- m_error = true;
- return "unknown_statement_"+QString::number(statement->kind);
- }
-}
-
-QString DumpAstVisitor::parseStatementList(StatementList *list)
-{
- QString result = "";
-
- if (list == nullptr)
- return "";
-
- result += getOrphanedComments(list);
-
- for (auto *item = list; item != nullptr; item = item->next) {
- QString statement = parseStatement(item->statement->statementCast(), false, true);
- if (statement.isEmpty())
- continue;
-
- QString commentFront = getComment(item->statement, Comment::Location::Front);
- QString commentBackInline = getComment(item->statement, Comment::Location::Back_Inline);
-
- if (!commentFront.isEmpty())
- result += formatLine(commentFront);
-
- result += formatLine(statement + (needsSemicolon(item->statement->kind) ? ";" : "")
- + commentBackInline);
- }
-
- return result;
-}
-
-bool DumpAstVisitor::visit(UiPublicMember *node) {
-
- QString commentFront = getComment(node, Comment::Location::Front);
- QString commentBackInline = getComment(node, Comment::Location::Back_Inline);
-
- switch (node->type)
- {
- case UiPublicMember::Signal:
- if (scope().m_firstSignal) {
- if (scope().m_firstOfAll)
- scope().m_firstOfAll = false;
- else
- addNewLine();
-
- scope().m_firstSignal = false;
- }
-
- addLine(commentFront);
- addLine("signal "+node->name.toString()+"("+parseUiParameterList(node->parameters) + ")"
- + commentBackInline);
- break;
- case UiPublicMember::Property: {
- if (scope().m_firstProperty) {
- if (scope().m_firstOfAll)
- scope().m_firstOfAll = false;
- else
- addNewLine();
-
- scope().m_firstProperty = false;
- }
-
- const bool is_required = node->requiredToken.isValid();
- const bool is_default = node->defaultToken.isValid();
- const bool is_readonly = node->readonlyToken.isValid();
- const bool has_type_modifier = node->typeModifierToken.isValid();
-
- QString prefix = "";
- QString statement = parseStatement(node->statement);
-
- if (!statement.isEmpty())
- statement.prepend(": ");
-
- if (is_required)
- prefix += "required ";
-
- if (is_default)
- prefix += "default ";
-
- if (is_readonly)
- prefix += "readonly ";
-
- QString member_type = parseUiQualifiedId(node->memberType);
-
- if (has_type_modifier)
- member_type = node->typeModifier + "<" + member_type + ">";
-
- addLine(commentFront);
- if (is_readonly && statement.isEmpty()
- && scope().m_bindings.contains(node->name.toString())) {
- m_result += formatLine(prefix + "property " + member_type + " ", false);
-
- scope().m_pendingBinding = true;
- } else {
- addLine(prefix + "property " + member_type + " "
- + node->name+statement + commentBackInline);
- }
- break;
- }
- }
-
- return true;
-}
-
-QString DumpAstVisitor::generateIndent(int indentLevel) const
-{
- return QString(m_indentWidth * indentLevel, m_indentation == Indentation::Tabs ? '\t' : ' ');
-}
-
-QString DumpAstVisitor::formatLine(QString line, bool newline) const
-{
- QString result = generateIndent(m_indentLevel) + line;
- if (newline)
- result += "\n";
-
- return result;
-}
-
-QString DumpAstVisitor::formatPartlyFormatedLines(QString line, bool newline) const
-{
- QString result;
-
- const auto lines = QStringView { line }.split('\n');
- auto it = lines.cbegin();
- const auto endi = lines.cend();
- if (it != endi) {
- result += generateIndent(m_indentLevel) + *it;
- ++it;
- const QString addonIdent = generateIndent(1);
- for (; it != endi; ++it) {
- result += '\n';
- result += addonIdent + *it;
- }
- }
-
- if (newline)
- result += "\n";
-
- return result;
-}
-
-void DumpAstVisitor::addNewLine(bool always) {
- if (!always && m_result.endsWith("\n\n"))
- return;
-
- m_result += "\n";
-}
-
-void DumpAstVisitor::addLine(QString line) {
- // addLine does not support empty lines, use addNewLine(true) for that
- if (line.isEmpty())
- return;
-
- m_result += formatLine(line);
-}
-
-QHash<QString, UiObjectMember*> findBindings(UiObjectMemberList *list) {
- QHash<QString, UiObjectMember*> bindings;
-
- // This relies on RestructureASTVisitor having run beforehand
-
- for (auto *item = list; item != nullptr; item = item->next) {
- switch (item->member->kind) {
- case Node::Kind_UiPublicMember: {
- UiPublicMember *member = cast<UiPublicMember *>(item->member);
-
- if (member->type != UiPublicMember::Property)
- continue;
-
- bindings[member->name.toString()] = nullptr;
-
- break;
- }
- case Node::Kind_UiObjectBinding: {
- UiObjectBinding *binding = cast<UiObjectBinding *>(item->member);
-
- const QString name = parseUiQualifiedId(binding->qualifiedId);
-
- if (bindings.contains(name))
- bindings[name] = binding;
-
- break;
- }
- case Node::Kind_UiArrayBinding: {
- UiArrayBinding *binding = cast<UiArrayBinding *>(item->member);
-
- const QString name = parseUiQualifiedId(binding->qualifiedId);
-
- if (bindings.contains(name))
- bindings[name] = binding;
-
- break;
- }
- case Node::Kind_UiScriptBinding:
- // We can ignore UiScriptBindings since those are actually properly attached to the property
- break;
- }
- }
-
- return bindings;
-}
-
-bool DumpAstVisitor::visit(UiInlineComponent *node)
-{
- m_component_name = node->name.toString();
- return true;
-}
-
-bool DumpAstVisitor::visit(UiObjectDefinition *node) {
- if (scope().m_firstObject) {
- if (scope().m_firstOfAll)
- scope().m_firstOfAll = false;
- else
- addNewLine();
-
- scope().m_firstObject = false;
- }
-
- addLine(getComment(node, Comment::Location::Front));
- addLine(getComment(node, Comment::Location::Front_Inline));
-
- QString component = "";
-
- if (!m_component_name.isEmpty()) {
- component = "component "+m_component_name+": ";
- m_component_name = "";
- }
-
- addLine(component + parseUiQualifiedId(node->qualifiedTypeNameId) + " {");
-
- m_indentLevel++;
-
- ScopeProperties props;
- props.m_bindings = findBindings(node->initializer->members);
- m_scope_properties.push(props);
-
- m_result += getOrphanedComments(node);
-
- return true;
-}
-
-void DumpAstVisitor::endVisit(UiObjectDefinition *node) {
- m_indentLevel--;
-
- m_scope_properties.pop();
-
- bool need_comma = scope().m_inArrayBinding && scope().m_lastInArrayBinding != node;
-
- addLine(need_comma ? "}," : "}");
- addLine(getComment(node, Comment::Location::Back));
- if (!scope().m_inArrayBinding)
- addNewLine();
-}
-
-bool DumpAstVisitor::visit(UiEnumDeclaration *node) {
-
- addNewLine();
-
- addLine(getComment(node, Comment::Location::Front));
- addLine("enum " + node->name + " {");
- m_indentLevel++;
- m_result += getOrphanedComments(node);
-
- return true;
-}
-
-void DumpAstVisitor::endVisit(UiEnumDeclaration *) {
- m_indentLevel--;
- addLine("}");
-
- addNewLine();
-}
-
-bool DumpAstVisitor::visit(UiEnumMemberList *node) {
- for (auto *members = node; members != nullptr; members = members->next) {
-
- addLine(getListItemComment(members->memberToken, Comment::Location::Front));
-
- QString line = members->member.toString();
-
- if (members->valueToken.isValid())
- line += " = "+QString::number(members->value);
-
- if (members->next != nullptr)
- line += ",";
-
- line += getListItemComment(members->memberToken, Comment::Location::Back_Inline);
-
- addLine(line);
- }
-
- return true;
-}
-
-bool DumpAstVisitor::visit(UiScriptBinding *node) {
- if (scope().m_firstBinding) {
- if (scope().m_firstOfAll)
- scope().m_firstOfAll = false;
- else
- addNewLine();
-
- if (parseUiQualifiedId(node->qualifiedId) != "id")
- scope().m_firstBinding = false;
- }
-
- addLine(getComment(node, Comment::Location::Front));
-
- bool multiline = !needsSemicolon(node->statement->kind);
-
- if (multiline) {
- m_indentLevel++;
- }
-
- QString statement = parseStatement(node->statement);
-
- if (multiline) {
- statement = "{\n" + formatLine(statement);
- m_indentLevel--;
- statement += formatLine("}", false);
- }
-
- QString result = parseUiQualifiedId(node->qualifiedId) + ":";
-
- if (!statement.isEmpty())
- result += " "+statement;
- else
- result += ";";
-
- result += getComment(node, Comment::Location::Back_Inline);
-
- addLine(result);
-
- return true;
-}
-
-bool DumpAstVisitor::visit(UiArrayBinding *node) {
- if (!scope().m_pendingBinding && scope().m_firstBinding) {
- if (scope().m_firstOfAll)
- scope().m_firstOfAll = false;
- else
- addNewLine();
-
- scope().m_firstBinding = false;
- }
-
- if (scope().m_pendingBinding) {
- m_result += parseUiQualifiedId(node->qualifiedId)+ ": [\n";
- scope().m_pendingBinding = false;
- } else {
- addLine(getComment(node, Comment::Location::Front));
- addLine(parseUiQualifiedId(node->qualifiedId)+ ": [");
- }
-
- m_indentLevel++;
-
- ScopeProperties props;
- props.m_inArrayBinding = true;
-
- for (auto *item = node->members; item != nullptr; item = item->next) {
- if (item->next == nullptr)
- props.m_lastInArrayBinding = item->member;
- }
-
- m_scope_properties.push(props);
-
- m_result += getOrphanedComments(node);
-
- return true;
-}
-
-void DumpAstVisitor::endVisit(UiArrayBinding *) {
- m_indentLevel--;
- m_scope_properties.pop();
- addLine("]");
-}
-
-bool DumpAstVisitor::visit(FunctionDeclaration *node) {
- if (scope().m_firstFunction) {
- if (scope().m_firstOfAll)
- scope().m_firstOfAll = false;
- else
- addNewLine();
-
- scope().m_firstFunction = false;
- }
-
- addLine(getComment(node, Comment::Location::Front));
-
- QString head = "function";
-
- if (node->isGenerator)
- head += "*";
-
- head += " "+node->name+"("+parseFormalParameterList(node->formals)+")";
-
- if (node->typeAnnotation != nullptr)
- head += " : " + parseType(node->typeAnnotation->type);
-
- head += " {";
-
- addLine(head);
- m_indentLevel++;
-
- return true;
-}
-
-void DumpAstVisitor::endVisit(FunctionDeclaration *node)
-{
- m_result += parseStatementList(node->body);
- m_indentLevel--;
- addLine("}");
- addNewLine();
-}
-
-bool DumpAstVisitor::visit(UiObjectBinding *node) {
- if (!scope().m_pendingBinding && scope().m_firstObject) {
- if (scope().m_firstOfAll)
- scope().m_firstOfAll = false;
- else
- addNewLine();
-
- scope().m_firstObject = false;
- }
-
- QString name = parseUiQualifiedId(node->qualifiedTypeNameId);
-
- QString result = name;
-
- ScopeProperties props;
- props.m_bindings = findBindings(node->initializer->members);
- m_scope_properties.push(props);
-
- if (node->hasOnToken)
- result += " on "+parseUiQualifiedId(node->qualifiedId);
- else
- result.prepend(parseUiQualifiedId(node->qualifiedId) + ": ");
-
- if (scope().m_pendingBinding) {
- m_result += result + " {\n";
-
- scope().m_pendingBinding = false;
- } else {
- addNewLine();
- addLine(getComment(node, Comment::Location::Front));
- addLine(getComment(node, Comment::Location::Front_Inline));
- addLine(result + " {");
- }
-
- m_indentLevel++;
-
- return true;
-}
-
-void DumpAstVisitor::endVisit(UiObjectBinding *node) {
- m_indentLevel--;
- m_scope_properties.pop();
-
- addLine("}");
- addLine(getComment(node, Comment::Location::Back));
-
- addNewLine();
-}
-
-bool DumpAstVisitor::visit(UiImport *node) {
- scope().m_firstOfAll = false;
-
- addLine(getComment(node, Comment::Location::Front));
-
- QString result = "import ";
-
- if (!node->fileName.isEmpty())
- result += escapeString(node->fileName.toString());
- else
- result += parseUiQualifiedId(node->importUri);
-
- if (node->version) {
- const auto version = node->version->version;
-
- if (version.hasMajorVersion()) {
- result += " " + QString::number(version.majorVersion());
-
- if (version.hasMinorVersion())
- result += "." + QString::number(version.minorVersion());
- }
- }
-
- if (node->asToken.isValid()) {
- result +=" as " + node->importId;
- }
-
- result += getComment(node, Comment::Location::Back_Inline);
-
- addLine(result);
-
- return true;
-}
-
-bool DumpAstVisitor::visit(UiPragma *node) {
- scope().m_firstOfAll = false;
-
- addLine(getComment(node, Comment::Location::Front));
- QString result = "pragma "+ node->name;
- result += getComment(node, Comment::Location::Back_Inline);
-
- addLine(result);
-
- return true;
-}
-
-bool DumpAstVisitor::visit(UiAnnotation *node)
-{
- if (scope().m_firstObject) {
- if (scope().m_firstOfAll)
- scope().m_firstOfAll = false;
- else
- addNewLine();
-
- scope().m_firstObject = false;
- }
-
- addLine(getComment(node, Comment::Location::Front));
- addLine(QLatin1String("@") + parseUiQualifiedId(node->qualifiedTypeNameId) + " {");
-
- m_indentLevel++;
-
- ScopeProperties props;
- props.m_bindings = findBindings(node->initializer->members);
- m_scope_properties.push(props);
-
- m_result += getOrphanedComments(node);
-
- return true;
-}
-
-void DumpAstVisitor::endVisit(UiAnnotation *node) {
- m_indentLevel--;
-
- m_scope_properties.pop();
-
- addLine("}");
- addLine(getComment(node, Comment::Location::Back));
-}