1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#ifndef QQMLDOMREFORMATTER_P
5#define QQMLDOMREFORMATTER_P
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include "qqmldom_global.h"
19
20#include "qqmldomoutwriter_p.h"
21#include "qqmldom_fwd_p.h"
22#include "qqmldomcomments_p.h"
23#include "qqmldomelements_p.h"
24
25#include <QtQml/private/qqmljsast_p.h>
26
27QT_BEGIN_NAMESPACE
28namespace QQmlJS {
29namespace Dom {
30
31class ScriptFormatter final : protected AST::JSVisitor
32{
33public:
34 // TODO QTBUG-121988
35 ScriptFormatter(OutWriter &lw, const ScriptExpression *const script) : lw(lw), m_script(script)
36 {
37 if (m_script) {
38 comments = m_script->astComments();
39 accept(node: m_script->ast());
40 }
41 }
42
43protected:
44 inline void out(const char *str) { lw.write(v: QString::fromLatin1(ba: str)); }
45 inline void out(QStringView str) { lw.write(v: str); }
46 inline void out(const SourceLocation &loc)
47 {
48 if (loc.length != 0)
49 out(str: m_script->loc2Str(loc));
50 }
51 enum CommentOption { NoSpace, SpaceBeforePostComment, OnlyComments };
52 void outWithComments(const SourceLocation &loc, AST::Node *node, CommentOption option = NoSpace)
53 {
54 if (!loc.isValid())
55 return;
56 const CommentedElement *c = comments->commentForNode(n: node, location: CommentAnchor::from(sl: loc));
57 if (c)
58 c->writePre(lw);
59 if (option != OnlyComments)
60 out(loc);
61 if (option == SpaceBeforePostComment)
62 lw.ensureSpace();
63 if (c)
64 c->writePost(lw);
65 }
66 inline void newLine(quint32 count = 1) { lw.ensureNewline(nNewlines: count); }
67
68 inline void accept(AST::Node *node) { AST::Node::accept(node, visitor: this); }
69 void lnAcceptIndented(AST::Node *node);
70 bool acceptBlockOrIndented(AST::Node *ast, bool finishWithSpaceOrNewline = false);
71
72 bool preVisit(AST::Node *n) override;
73 void postVisit(AST::Node *n) override;
74
75 bool visit(AST::ThisExpression *ast) override;
76 bool visit(AST::NullExpression *ast) override;
77 bool visit(AST::TrueLiteral *ast) override;
78 bool visit(AST::FalseLiteral *ast) override;
79 bool visit(AST::IdentifierExpression *ast) override;
80 bool visit(AST::StringLiteral *ast) override;
81 bool visit(AST::NumericLiteral *ast) override;
82 bool visit(AST::RegExpLiteral *ast) override;
83
84 bool visit(AST::ArrayPattern *ast) override;
85
86 bool visit(AST::ObjectPattern *ast) override;
87
88 bool visit(AST::PatternElementList *ast) override;
89
90 bool visit(AST::PatternPropertyList *ast) override;
91 bool visit(AST::PatternProperty *property) override;
92
93 bool visit(AST::NestedExpression *ast) override;
94 bool visit(AST::IdentifierPropertyName *ast) override;
95 bool visit(AST::StringLiteralPropertyName *ast) override;
96 bool visit(AST::NumericLiteralPropertyName *ast) override;
97
98 bool visit(AST::TemplateLiteral *ast) override;
99 bool visit(AST::ArrayMemberExpression *ast) override;
100
101 bool visit(AST::FieldMemberExpression *ast) override;
102
103 bool visit(AST::NewMemberExpression *ast) override;
104
105 bool visit(AST::NewExpression *ast) override;
106
107 bool visit(AST::CallExpression *ast) override;
108
109 bool visit(AST::PostIncrementExpression *ast) override;
110
111 bool visit(AST::PostDecrementExpression *ast) override;
112 bool visit(AST::PreIncrementExpression *ast) override;
113
114 bool visit(AST::PreDecrementExpression *ast) override;
115
116 bool visit(AST::DeleteExpression *ast) override;
117
118 bool visit(AST::VoidExpression *ast) override;
119 bool visit(AST::TypeOfExpression *ast) override;
120
121 bool visit(AST::UnaryPlusExpression *ast) override;
122
123 bool visit(AST::UnaryMinusExpression *ast) override;
124
125 bool visit(AST::TildeExpression *ast) override;
126
127 bool visit(AST::NotExpression *ast) override;
128
129 bool visit(AST::BinaryExpression *ast) override;
130
131 bool visit(AST::ConditionalExpression *ast) override;
132
133 bool visit(AST::Block *ast) override;
134
135 bool visit(AST::VariableStatement *ast) override;
136
137 bool visit(AST::PatternElement *ast) override;
138
139 bool visit(AST::EmptyStatement *ast) override;
140
141 bool visit(AST::IfStatement *ast) override;
142 bool visit(AST::DoWhileStatement *ast) override;
143
144 bool visit(AST::WhileStatement *ast) override;
145
146 bool visit(AST::ForStatement *ast) override;
147
148 bool visit(AST::ForEachStatement *ast) override;
149
150 bool visit(AST::ContinueStatement *ast) override;
151 bool visit(AST::BreakStatement *ast) override;
152
153 bool visit(AST::ReturnStatement *ast) override;
154 bool visit(AST::YieldExpression *ast) override;
155 bool visit(AST::ThrowStatement *ast) override;
156 bool visit(AST::WithStatement *ast) override;
157
158 bool visit(AST::SwitchStatement *ast) override;
159
160 bool visit(AST::CaseBlock *ast) override;
161
162 bool visit(AST::CaseClause *ast) override;
163
164 bool visit(AST::DefaultClause *ast) override;
165
166 bool visit(AST::LabelledStatement *ast) override;
167
168 bool visit(AST::TryStatement *ast) override;
169
170 bool visit(AST::Catch *ast) override;
171
172 bool visit(AST::Finally *ast) override;
173
174 bool visit(AST::FunctionDeclaration *ast) override;
175
176 bool visit(AST::FunctionExpression *ast) override;
177
178 bool visit(AST::Elision *ast) override;
179
180 bool visit(AST::ArgumentList *ast) override;
181
182 bool visit(AST::StatementList *ast) override;
183
184 bool visit(AST::VariableDeclarationList *ast) override;
185
186 bool visit(AST::CaseClauses *ast) override;
187
188 bool visit(AST::FormalParameterList *ast) override;
189
190 bool visit(AST::SuperLiteral *) override;
191 bool visit(AST::ComputedPropertyName *) override;
192 bool visit(AST::CommaExpression *el) override;
193 bool visit(AST::ExpressionStatement *el) override;
194
195 bool visit(AST::ClassDeclaration *ast) override;
196
197 bool visit(AST::ImportDeclaration *ast) override;
198 bool visit(AST::ImportSpecifier *ast) override;
199 bool visit(AST::NameSpaceImport *ast) override;
200 bool visit(AST::ImportsList *ast) override;
201 bool visit(AST::NamedImports *ast) override;
202 bool visit(AST::ImportClause *ast) override;
203
204 bool visit(AST::ExportDeclaration *ast) override;
205 bool visit(AST::ExportClause *ast) override;
206 bool visit(AST::ExportSpecifier *ast) override;
207 bool visit(AST::ExportsList *ast) override;
208
209 bool visit(AST::FromClause *ast) override;
210
211 void endVisit(AST::ComputedPropertyName *) override;
212
213 void endVisit(AST::ExportDeclaration *ast) override;
214 void endVisit(AST::ExportClause *ast) override;
215
216 void endVisit(AST::ImportDeclaration *ast) override;
217 void endVisit(AST::NamedImports *ast) override;
218
219 void throwRecursionDepthError() override;
220
221private:
222 bool addSemicolons() const { return expressionDepth > 0; }
223 bool canRemoveSemicolon(AST::Node *node);
224 OutWriter &writeOutSemicolon(AST::Node *);
225 OutWriter &lw;
226 std::shared_ptr<AstComments> comments;
227 const ScriptExpression *const m_script = nullptr; // outlives this
228 QHash<AST::Node *, QList<std::function<void()>>> postOps;
229 int expressionDepth = 0;
230};
231
232QMLDOM_EXPORT void reformatAst(OutWriter &lw, const QQmlJS::Dom::ScriptExpression *const script);
233
234} // namespace Dom
235} // namespace QQmlJS
236QT_END_NAMESPACE
237
238#endif // QQMLDOMREFORMATTER_P
239

source code of qtdeclarative/src/qmldom/qqmldomreformatter_p.h