1// Copyright (C) 2020 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#include "qqmldomastdumper_p.h"
5#include "qqmldomerrormessage_p.h"
6#include <QtQml/private/qqmljsast_p.h>
7#include <QtCore/QDebug>
8#include <QtCore/QString>
9#include <QtCore/QTextStream>
10
11QT_BEGIN_NAMESPACE
12
13namespace QQmlJS {
14namespace Dom {
15using namespace AST;
16/*!
17\internal
18\enum QQmlJS::AstDumperOption
19
20This enum type specifies the options for the AstDumper.
21The values can be combined with the '|' operator, and checked using the '&' operator.
22
23\value None
24 Default dumping options
25\value NoLocations
26 Does not dump SourceLocations, allowing one to compare equivalent AST
27 generated by code formatted differently
28\value NoAnnotations
29 Does not dump annotations
30\value DumpNode
31 Does dump a <Node></Node> in preVisit/postVisit
32*/
33
34/*!
35\internal
36\class QQmlJS::AstDumper
37\brief Dumps or compares AST in an xml like format, mostly for testing/debugging
38
39Initialize it with a lambda that dumps a string, and configure it with .setX methods.
40If \l{indent} is set to a non zero value the xml is indented by that amount, and
41\l{baseIndent} is the initial indent.
42If \l{emitNode} is true the node tag is emitted in the preVisit/postVisit.
43If \l{emitLocation} is true the SourceLocations are emitted.
44If \l{emitAnnotations} is true annotations are emitted
45
46The implementation has unnecessary roundtrips to QString, but it is supposed to be used
47for debugging purposes...
48
49Probably you will not use the visitor at all but rather the static method diff or
50the qDebug() and ostream operator << that use the visitor...
51
52\fn AstDumper::diff(AST::Node *n1, AST::Node *n2, int nContext, AstDumperOptions opt, int indent)
53
54\brief compares the two AST::Node n1 and n2 and returns a string describing their first difference
55
56If there are no differences the empty string is returned, so .isEmpty() can be use to check
57for no differences.
58\l{nContext} decides how much context is printed out.
59
60*/
61
62// no export, just a supporting class...
63class AstDumper: public AST::BaseVisitor
64{
65public:
66 AstDumper(const std::function<void(QStringView)> &dumper,
67 AstDumperOptions options = AstDumperOption::None, int indent = 1, int baseIndent = 0,
68 function_ref<QStringView(SourceLocation)> loc2str = &noStr)
69 : dumper(dumper), options(options), indent(indent), baseIndent(baseIndent), loc2str(loc2str)
70 {
71 }
72
73private:
74 void start(QStringView str) {
75 dumper(QString::fromLatin1(ba: " ").repeated(times: baseIndent));
76 dumper(u"<");
77 dumper(str);
78 dumper(u">\n");
79 baseIndent += indent;
80 }
81
82 void stop(QStringView str) {
83 baseIndent -= indent;
84 dumper(QString::fromLatin1(ba: " ").repeated(times: baseIndent));
85 dumper(u"</");
86 dumper(str);
87 dumper(u">\n");
88 }
89
90 QString quotedString(const QString &s) {
91 QString res(s);
92 return QStringLiteral(u"\"") + res
93 .replace(before: QLatin1String("\\"), after: QLatin1String("\\\\"))
94 .replace(before: QLatin1String("\""), after: QLatin1String("\\\"")) + QLatin1String("\"");
95 }
96
97 QString quotedString(QStringView s) {
98 return quotedString(s: s.toString());
99 }
100
101 QString loc(const SourceLocation &s, bool trim = false) {
102 QString tokenStr;
103 if (s.length > 0)
104 tokenStr = loc2str(s).toString()
105 .replace(before: QLatin1String("\\"), after: QLatin1String("\\\\"))
106 .replace(before: QLatin1String("\""),after: QLatin1String("\\\""));
107 if (trim)
108 tokenStr = tokenStr.trimmed();
109 if (noLocations() || s == SourceLocation())
110 return QLatin1String("\"%1\"").arg(args&: tokenStr);
111 else {
112 return QLatin1String("\"off:%1 len:%2 l:%3 c:%4 %5\"").arg(args: QString::number(s.offset), args: QString::number(s.length), args: QString::number(s.startLine), args: QString::number(s.startColumn), args&: tokenStr);
113 }
114 }
115
116 QString semicolonToken(const SourceLocation &s)
117 {
118 if (options & AstDumperOption::SloppyCompare)
119 return QString();
120 return QLatin1String(" semicolonToken=") + loc(s);
121 }
122
123 QString boolStr(bool v) { return (v ? quotedString(s: u"true"): quotedString(s: u"false")); }
124public:
125 bool preVisit(Node *) override { if (dumpNode()) start(str: u"Node"); return true; }
126 void postVisit(Node *) override { if (dumpNode()) stop(str: u"Node"); }
127
128 // Ui
129 bool visit(UiProgram *) override { start(str: u"UiProgram"); return true; }
130 void endVisit(AST::UiProgram *) override { stop(str: u"UiProgram"); }
131
132 bool visit(UiHeaderItemList *) override { start(str: u"UiHeaderItemList"); return true; }
133 void endVisit(AST::UiHeaderItemList *) override { stop(str: u"UiHeaderItemList"); }
134
135#if QT_VERSION >= QT_VERSION_CHECK(6, 6, 0)
136 bool visit(UiPragmaValueList *el) override {
137 start(str: QLatin1String("UiPragmaValueList value=%1").arg(args&: el->value));
138 return true;
139 }
140 void endVisit(AST::UiPragmaValueList *) override { stop(str: u"UiPragmaValueList"); }
141#endif
142
143 bool visit(UiPragma *el) override {
144 start(str: QLatin1String("UiPragma name=%1 pragmaToken=%2%3")
145 .arg(args: quotedString(s: el->name), args: loc(s: el->pragmaToken),
146 args: semicolonToken(s: el->semicolonToken)));
147 return true;
148 }
149 void endVisit(AST::UiPragma *) override { stop(str: u"UiPragma"); }
150
151 bool visit(UiImport *el) override {
152 start(str: QLatin1String("UiImport fileName=%1 importId=%2 importToken=%3 fileNameToken=%4 "
153 "asToken=%5 importIdToken=%6%7")
154 .arg(args: quotedString(s: el->fileName), args: quotedString(s: el->importId),
155 args: loc(s: el->importToken), args: loc(s: el->fileNameToken), args: loc(s: el->asToken),
156 args: loc(s: el->importIdToken), args: semicolonToken(s: el->semicolonToken)));
157 return true;
158 }
159 void endVisit(AST::UiImport *el) override {
160 Node::accept(node: el->version, visitor: this);
161 stop(str: u"UiImport");
162 }
163
164 bool visit(UiPublicMember *el) override {
165 QString typeStr = ((el->type == UiPublicMember::Signal) ? QLatin1String("Signal") :
166 (el->type == UiPublicMember::Property) ? QLatin1String("Property") : QLatin1String("Unexpected(%1)").arg(args: QString::number(el->type)));
167 start(str: QLatin1String("UiPublicMember type=%1 typeModifier=%2 name=%3 isDefaultMember=%4 "
168 "isReadonlyMember=%5 isRequired=%6 "
169 "defaultToken=%7 readonlyToken=%8 propertyToken=%9 requiredToken=%10 "
170 "typeModifierToken=%11 typeToken=%12 "
171 "identifierToken=%13 colonToken=%14%15")
172 .arg(args: quotedString(s: typeStr), args: quotedString(s: el->typeModifier),
173 args: quotedString(s: el->name), args: boolStr(v: el->isDefaultMember()),
174 args: boolStr(v: el->isReadonly()), args: boolStr(v: el->isRequired()),
175 args: loc(s: el->defaultToken()), args: loc(s: el->readonlyToken()),
176 args: loc(s: el->propertyToken()), args: loc(s: el->requiredToken()),
177 args: loc(s: el->typeModifierToken), args: loc(s: el->typeToken),
178 args: loc(s: el->identifierToken), args: loc(s: el->colonToken),
179 args: semicolonToken(s: el->semicolonToken)));
180 if (!noAnnotations()) // put annotations inside the node they refer to
181 Node::accept(node: el->annotations, visitor: this);
182 Node::accept(node: el->memberType, visitor: this);
183 return true;
184 }
185 void endVisit(AST::UiPublicMember *el) override {
186 Node::accept(node: el->parameters, visitor: this);
187 stop(str: u"UiPublicMember");
188 }
189
190 bool visit(AST::UiSourceElement *el) override {
191 start(str: u"UiSourceElement");
192 if (!noAnnotations()) // put annotations inside the node they refer to
193 Node::accept(node: el->annotations, visitor: this);
194 return true;
195 }
196 void endVisit(AST::UiSourceElement *) override { stop(str: u"UiSourceElement"); }
197
198 bool visit(AST::UiObjectDefinition *el) override {
199 start(str: u"UiObjectDefinition");
200 if (!noAnnotations()) // put annotations inside the node they refer to
201 Node::accept(node: el->annotations, visitor: this);
202 return true;
203 }
204 void endVisit(AST::UiObjectDefinition *) override { stop(str: u"UiObjectDefinition"); }
205
206 bool visit(AST::UiObjectInitializer *el) override {
207 start(str: QLatin1String("UiObjectInitializer lbraceToken=%1 rbraceToken=%2")
208 .arg(args: loc(s: el->lbraceToken), args: loc(s: el->rbraceToken)));
209 return true;
210 }
211 void endVisit(AST::UiObjectInitializer *) override { stop(str: u"UiObjectInitializer"); }
212
213 bool visit(AST::UiObjectBinding *el) override {
214 start(str: QLatin1String("UiObjectBinding colonToken=%1 hasOnToken=%2")
215 .arg(args: loc(s: el->colonToken), args: boolStr(v: el->hasOnToken)));
216 if (!noAnnotations()) // put annotations inside the node they refer to
217 Node::accept(node: el->annotations, visitor: this);
218 return true;
219 }
220 void endVisit(AST::UiObjectBinding *) override { stop(str: u"UiObjectBinding"); }
221
222 bool visit(AST::UiScriptBinding *el) override {
223 start(str: QLatin1String("UiScriptBinding colonToken=%1")
224 .arg(args: loc(s: el->colonToken)));
225 if (!noAnnotations()) // put annotations inside the node they refer to
226 Node::accept(node: el->annotations, visitor: this);
227 return true;
228 }
229 void endVisit(AST::UiScriptBinding *) override { stop(str: u"UiScriptBinding"); }
230
231 bool visit(AST::UiArrayBinding *el) override {
232 start(str: QLatin1String("UiArrayBinding colonToken=%1 lbracketToken=%2 rbracketToken=%3")
233 .arg(args: loc(s: el->colonToken), args: loc(s: el->lbracketToken), args: loc(s: el->rbracketToken)));
234 if (!noAnnotations()) // put annotations inside the node they refer to
235 Node::accept(node: el->annotations, visitor: this);
236 return true;
237 }
238 void endVisit(AST::UiArrayBinding *) override { stop(str: u"UiArrayBinding"); }
239
240 bool visit(AST::UiParameterList *el) override {
241 start(str: QLatin1String("UiParameterList name=%1 commaToken=%2 propertyTypeToken=%3 identifierToken=%4 colonToken=%5")
242 .arg(args: quotedString(s: el->name), args: loc(s: el->commaToken), args: loc(s: el->propertyTypeToken), args: loc(s: el->identifierToken), args: loc(s: el->colonToken)));
243 Node::accept(node: el->type, visitor: this);
244 return true;
245 }
246 void endVisit(AST::UiParameterList *el) override {
247 stop(str: u"UiParameterList");
248 Node::accept(node: el->next, visitor: this); // put other args at the same level as this one...
249 }
250
251 bool visit(AST::UiObjectMemberList *) override { start(str: u"UiObjectMemberList"); return true; }
252 void endVisit(AST::UiObjectMemberList *) override { stop(str: u"UiObjectMemberList"); }
253
254 bool visit(AST::UiArrayMemberList *el) override {
255 start(str: QLatin1String("UiArrayMemberList commaToken=%1")
256 .arg(args: loc(s: el->commaToken)));
257 return true;
258 }
259 void endVisit(AST::UiArrayMemberList *) override { stop(str: u"UiArrayMemberList"); }
260
261 bool visit(AST::UiQualifiedId *el) override {
262 start(str: QLatin1String("UiQualifiedId name=%1 identifierToken=%2")
263 .arg(args: quotedString(s: el->name), args: loc(s: el->identifierToken)));
264 Node::accept(node: el->next, visitor: this);
265 return true;
266 }
267 void endVisit(AST::UiQualifiedId *) override { stop(str: u"UiQualifiedId"); }
268
269 bool visit(AST::UiEnumDeclaration *el) override {
270 start(str: QLatin1String("UiEnumDeclaration enumToken=%1 rbraceToken=%2 name=%3")
271 .arg(args: loc(s: el->enumToken), args: loc(s: el->rbraceToken), args: quotedString(s: el->name)));
272 if (!noAnnotations()) // put annotations inside the node they refer to
273 Node::accept(node: el->annotations, visitor: this);
274 return true;
275 }
276 void endVisit(AST::UiEnumDeclaration *) override { stop(str: u"UiEnumDeclaration"); }
277
278 bool visit(AST::UiEnumMemberList *el) override {
279 start(str: QLatin1String("UiEnumMemberList member=%1 value=%2 memberToken=%3 valueToken=%4")
280 .arg(args: quotedString(s: el->member), args: quotedString(s: QString::number(el->value)), args: loc(s: el->memberToken), args: loc(s: el->valueToken)));
281 return true;
282 }
283 void endVisit(AST::UiEnumMemberList *el) override {
284 stop(str: u"UiEnumMemberList");
285 Node::accept(node: el->next, visitor: this); // put other enum members at the same level as this one...
286 }
287
288 bool visit(AST::UiVersionSpecifier *el) override {
289 start(str: QLatin1String("UiVersionSpecifier majorVersion=%1 minorVersion=%2 majorToken=%3 minorToken=%4")
290 .arg(args: quotedString(s: QString::number(el->version.majorVersion())),
291 args: quotedString(s: QString::number(el->version.minorVersion())),
292 args: loc(s: el->majorToken), args: loc(s: el->minorToken)));
293 return true;
294 }
295 void endVisit(AST::UiVersionSpecifier *) override { stop(str: u"UiVersionSpecifier"); }
296
297 bool visit(AST::UiInlineComponent *el) override {
298 start(str: QLatin1String("UiInlineComponent name=%1 componentToken=%2")
299 .arg(args: quotedString(s: el->name), args: loc(s: el->componentToken)));
300 if (!noAnnotations()) // put annotations inside the node they refer to
301 Node::accept(node: el->annotations, visitor: this);
302 return true;
303 }
304 void endVisit(AST::UiInlineComponent *) override { stop(str: u"UiInlineComponent"); }
305
306 bool visit(UiRequired *el) override {
307 start(str: QLatin1String("UiRequired name=%1 requiredToken=%2%3")
308 .arg(args: quotedString(s: el->name), args: loc(s: el->requiredToken),
309 args: semicolonToken(s: el->semicolonToken)));
310 return true;
311 }
312 void endVisit(UiRequired *) override { stop(str: u"UiRequired"); }
313
314 bool visit(UiAnnotation *) override {
315 start(str: u"UiAnnotation");
316 return true;
317 }
318 void endVisit(UiAnnotation *) override { stop(str: u"UiAnnotation"); }
319
320 bool visit(UiAnnotationList *) override {
321 start(str: u"UiAnnotationList");
322 return true;
323 }
324 void endVisit(UiAnnotationList *) override { stop(str: u"UiAnnotationList"); }
325
326 // QQmlJS
327 bool visit(AST::TypeExpression *) override {
328 start(str: u"TypeExpression");
329 return true;
330 }
331 void endVisit(AST::TypeExpression *) override { stop(str: u"TypeExpression"); }
332
333 bool visit(AST::ThisExpression *el) override {
334 start(str: QLatin1String("ThisExpression thisToken=%1")
335 .arg(args: loc(s: el->thisToken)));
336 return true;
337 }
338 void endVisit(AST::ThisExpression *) override { stop(str: u"ThisExpression"); }
339
340 bool visit(AST::IdentifierExpression *el) override {
341 start(str: QLatin1String("IdentifierExpression name=%1 identifierToken=%2")
342 .arg(args: quotedString(s: el->name), args: loc(s: el->identifierToken)));
343 return true;
344 }
345 void endVisit(AST::IdentifierExpression *) override { stop(str: u"IdentifierExpression"); }
346
347 bool visit(AST::NullExpression *el) override {
348 start(str: QLatin1String("NullExpression nullToken=%1")
349 .arg(args: loc(s: el->nullToken)));
350 return true;
351 }
352 void endVisit(AST::NullExpression *) override { stop(str: u"NullExpression"); }
353
354 bool visit(AST::TrueLiteral *el) override {
355 start(str: QLatin1String("TrueLiteral trueToken=%1")
356 .arg(args: loc(s: el->trueToken)));
357 return true;
358 }
359 void endVisit(AST::TrueLiteral *) override { stop(str: u"TrueLiteral"); }
360
361 bool visit(AST::FalseLiteral *el) override {
362 start(str: QLatin1String("FalseLiteral falseToken=%1")
363 .arg(args: loc(s: el->falseToken)));
364 return true;
365 }
366 void endVisit(AST::FalseLiteral *) override { stop(str: u"FalseLiteral"); }
367
368 bool visit(AST::SuperLiteral *el) override {
369 start(str: QLatin1String("SuperLiteral superToken=%1")
370 .arg(args: loc(s: el->superToken)));
371 return true;
372 }
373 void endVisit(AST::SuperLiteral *) override { stop(str: u"SuperLiteral"); }
374
375 bool visit(AST::StringLiteral *el) override {
376 start(str: QLatin1String("StringLiteral value=%1 literalToken=%2")
377 .arg(args: quotedString(s: el->value), args: loc(s: el->literalToken)));
378 return true;
379 }
380 void endVisit(AST::StringLiteral *) override { stop(str: u"StringLiteral"); }
381
382 bool visit(AST::TemplateLiteral *el) override {
383 start(str: QLatin1String("TemplateLiteral value=%1 rawValue=%2 literalToken=%3")
384 .arg(args: quotedString(s: el->value), args: quotedString(s: el->rawValue), args: loc(s: el->literalToken)));
385 Node::accept(node: el->expression, visitor: this);
386 return true;
387 }
388 void endVisit(AST::TemplateLiteral *) override { stop(str: u"TemplateLiteral"); }
389
390 bool visit(AST::NumericLiteral *el) override {
391 start(str: QLatin1String("NumericLiteral value=%1 literalToken=%2")
392 .arg(args: quotedString(s: QString::number(el->value)), args: loc(s: el->literalToken)));
393 return true;
394 }
395 void endVisit(AST::NumericLiteral *) override { stop(str: u"NumericLiteral"); }
396
397 bool visit(AST::RegExpLiteral *el) override {
398 start(str: QLatin1String("RegExpLiteral pattern=%1 flags=%2 literalToken=%3")
399 .arg(args: quotedString(s: el->pattern), args: quotedString(s: QString::number(el->flags, base: 16)), args: loc(s: el->literalToken)));
400 return true;
401 }
402 void endVisit(AST::RegExpLiteral *) override { stop(str: u"RegExpLiteral"); }
403
404 bool visit(AST::ArrayPattern *el) override {
405 start(str: QLatin1String("ArrayPattern lbracketToken=%1 commaToken=%2 rbracketToken=%3 parseMode=%4")
406 .arg(args: loc(s: el->lbracketToken),args: loc(s: el->commaToken),args: loc(s: el->rbracketToken), args: quotedString(s: QString::number(el->parseMode, base: 16))));
407 return true;
408 }
409 void endVisit(AST::ArrayPattern *) override { stop(str: u"ArrayPattern"); }
410
411 bool visit(AST::ObjectPattern *el) override {
412 start(str: QLatin1String("ObjectPattern lbraceToken=%1 rbraceToken=%2 parseMode=%3")
413 .arg(args: loc(s: el->lbraceToken), args: loc(s: el->rbraceToken), args: quotedString(s: QString::number(el->parseMode, base: 16))));
414 return true;
415 }
416 void endVisit(AST::ObjectPattern *) override { stop(str: u"ObjectPattern"); }
417
418 bool visit(AST::PatternElementList *) override { start(str: u"PatternElementList"); return true; }
419 void endVisit(AST::PatternElementList *) override { stop(str: u"PatternElementList"); }
420
421 bool visit(AST::PatternPropertyList *) override { start(str: u"PatternPropertyList"); return true; }
422 void endVisit(AST::PatternPropertyList *) override { stop(str: u"PatternPropertyList"); }
423
424 bool visit(AST::PatternElement *el) override {
425 start(str: QLatin1String("PatternElement identifierToken=%1 bindingIdentifier=%2 type=%3 scope=%4 isForDeclaration=%5")
426 .arg(args: loc(s: el->identifierToken), args: quotedString(s: el->bindingIdentifier), args: quotedString(s: QString::number(el->type, base: 16)),
427 args: quotedString(s: QString::number(static_cast<int>(el->scope), base: 16)), args: boolStr(v: el->isForDeclaration)));
428 return true;
429 }
430 void endVisit(AST::PatternElement *) override { stop(str: u"PatternElement"); }
431
432 bool visit(AST::PatternProperty *el) override {
433 start(str: QLatin1String("PatternProperty identifierToken=%1 bindingIdentifier=%2 type=%3 scope=%4 isForDeclaration=%5 colonToken=%6")
434 .arg(args: loc(s: el->identifierToken), args: quotedString(s: el->bindingIdentifier), args: quotedString(s: QString::number(el->type, base: 16)),
435 args: quotedString(s: QString::number(static_cast<int>(el->scope), base: 16)), args: boolStr(v: el->isForDeclaration), args: loc(s: el->colonToken)));
436 return true;
437 }
438 void endVisit(AST::PatternProperty *) override { stop(str: u"PatternProperty"); }
439
440 bool visit(AST::Elision *el) override {
441 start(str: QLatin1String("Elision commaToken=%1")
442 .arg(args: loc(s: el->commaToken)));
443 return true;
444 }
445 void endVisit(AST::Elision *el) override {
446 stop(str: u"Elision");
447 Node::accept(node: el->next, visitor: this); // emit other elisions at the same level
448 }
449
450 bool visit(AST::NestedExpression *el) override {
451 start(str: QLatin1String("NestedExpression lparenToken=%1 rparenToken=%2")
452 .arg(args: loc(s: el->lparenToken), args: loc(s: el->rparenToken)));
453 return true;
454 }
455 void endVisit(AST::NestedExpression *) override { stop(str: u"NestedExpression"); }
456
457 bool visit(AST::IdentifierPropertyName *el) override {
458 if (options & AstDumperOption::SloppyCompare)
459 start(str: QLatin1String("StringLiteralOrIdentifierPropertyName id=%1")
460 .arg(args: quotedString(s: el->id)));
461 else
462 start(str: QLatin1String("IdentifierPropertyName id=%1 propertyNameToken=%2")
463 .arg(args: quotedString(s: el->id), args: loc(s: el->propertyNameToken)));
464 return true;
465 }
466 void endVisit(AST::IdentifierPropertyName *) override {
467 if (options & AstDumperOption::SloppyCompare)
468 stop(str: u"StringLiteralOrIdentifierPropertyName");
469 else
470 stop(str: u"IdentifierPropertyName");
471 }
472
473 bool visit(AST::StringLiteralPropertyName *el) override {
474 if (options & AstDumperOption::SloppyCompare)
475 start(str: QLatin1String("StringLiteralOrIdentifierPropertyName id=%1")
476 .arg(args: quotedString(s: el->id)));
477 else
478 start(str: QLatin1String("StringLiteralPropertyName id=%1 propertyNameToken=%2")
479 .arg(args: quotedString(s: el->id), args: loc(s: el->propertyNameToken)));
480 return true;
481 }
482 void endVisit(AST::StringLiteralPropertyName *) override {
483 if (options & AstDumperOption::SloppyCompare)
484 stop(str: u"StringLiteralOrIdentifierPropertyName");
485 else
486 stop(str: u"StringLiteralPropertyName");
487 }
488
489 bool visit(AST::NumericLiteralPropertyName *el) override {
490 start(str: QLatin1String("NumericLiteralPropertyName id=%1 propertyNameToken=%2")
491 .arg(args: quotedString(s: QString::number(el->id)),args: loc(s: el->propertyNameToken)));
492 return true;
493 }
494 void endVisit(AST::NumericLiteralPropertyName *) override { stop(str: u"NumericLiteralPropertyName"); }
495
496 bool visit(AST::ComputedPropertyName *) override {
497 start(str: u"ComputedPropertyName");
498 return true;
499 }
500 void endVisit(AST::ComputedPropertyName *) override { stop(str: u"ComputedPropertyName"); }
501
502 bool visit(AST::ArrayMemberExpression *el) override {
503 start(str: QLatin1String("ArrayMemberExpression lbraketToken=%1 rbraketToken=%2")
504 .arg(args: loc(s: el->lbracketToken), args: loc(s: el->rbracketToken)));
505 return true;
506 }
507 void endVisit(AST::ArrayMemberExpression *) override { stop(str: u"ArrayMemberExpression"); }
508
509 bool visit(AST::FieldMemberExpression *el) override {
510 start(str: QLatin1String("FieldMemberExpression name=%1 dotToken=%2 identifierToken=%3")
511 .arg(args: quotedString(s: el->name), args: loc(s: el->dotToken), args: loc(s: el->identifierToken)));
512 return true;
513 }
514 void endVisit(AST::FieldMemberExpression *) override { stop(str: u"FieldMemberExpression"); }
515
516 bool visit(AST::TaggedTemplate *) override {
517 start(str: u"TaggedTemplate");
518 return true;
519 }
520 void endVisit(AST::TaggedTemplate *) override { stop(str: u"TaggedTemplate"); }
521
522 bool visit(AST::NewMemberExpression *el) override {
523 start(str: QLatin1String("NewMemberExpression newToken=%1 lparenToken=%2 rparenToken=%3")
524 .arg(args: loc(s: el->newToken), args: loc(s: el->lparenToken), args: loc(s: el->rparenToken)));
525 return true;
526 }
527 void endVisit(AST::NewMemberExpression *) override { stop(str: u"NewMemberExpression"); }
528
529 bool visit(AST::NewExpression *el) override {
530 start(str: QLatin1String("NewExpression newToken=%1")
531 .arg(args: loc(s: el->newToken)));
532 return true;
533 }
534 void endVisit(AST::NewExpression *) override { stop(str: u"NewExpression"); }
535
536 bool visit(AST::CallExpression *el) override {
537 start(str: QLatin1String("CallExpression lparenToken=%1 rparenToken=%2")
538 .arg(args: loc(s: el->lparenToken), args: loc(s: el->rparenToken)));
539 return true;
540 }
541 void endVisit(AST::CallExpression *) override { stop(str: u"CallExpression"); }
542
543 bool visit(AST::ArgumentList *el) override {
544 start(str: QLatin1String("ArgumentList commaToken=%1 isSpreadElement=%2")
545 .arg(args: loc(s: el->commaToken), args: boolStr(v: el->isSpreadElement)));
546 return true;
547 }
548 void endVisit(AST::ArgumentList *) override { stop(str: u"ArgumentList"); }
549
550 bool visit(AST::PostIncrementExpression *el) override {
551 start(str: QLatin1String("PostIncrementExpression incrementToken=%1")
552 .arg(args: loc(s: el->incrementToken)));
553 return true;
554 }
555 void endVisit(AST::PostIncrementExpression *) override { stop(str: u"PostIncrementExpression"); }
556
557 bool visit(AST::PostDecrementExpression *el) override {
558 start(str: QLatin1String("PostDecrementExpression decrementToken=%1")
559 .arg(args: loc(s: el->decrementToken)));
560 return true;
561 }
562 void endVisit(AST::PostDecrementExpression *) override { stop(str: u"PostDecrementExpression"); }
563
564 bool visit(AST::DeleteExpression *el) override {
565 start(str: QLatin1String("DeleteExpression deleteToken=%1")
566 .arg(args: loc(s: el->deleteToken)));
567 return true;
568 }
569 void endVisit(AST::DeleteExpression *) override { stop(str: u"DeleteExpression"); }
570
571 bool visit(AST::VoidExpression *el) override {
572 start(str: QLatin1String("VoidExpression voidToken=%1")
573 .arg(args: loc(s: el->voidToken)));
574 return true;
575 }
576 void endVisit(AST::VoidExpression *) override { stop(str: u"VoidExpression"); }
577
578 bool visit(AST::TypeOfExpression *el) override {
579 start(str: QLatin1String("TypeOfExpression typeofToken=%1")
580 .arg(args: loc(s: el->typeofToken)));
581 return true;
582 }
583 void endVisit(AST::TypeOfExpression *) override { stop(str: u"TypeOfExpression"); }
584
585 bool visit(AST::PreIncrementExpression *el) override {
586 start(str: QLatin1String("PreIncrementExpression incrementToken=%1")
587 .arg(args: loc(s: el->incrementToken)));
588 return true;
589 }
590 void endVisit(AST::PreIncrementExpression *) override { stop(str: u"PreIncrementExpression"); }
591
592 bool visit(AST::PreDecrementExpression *el) override {
593 start(str: QLatin1String("PreDecrementExpression decrementToken=%1")
594 .arg(args: loc(s: el->decrementToken)));
595 return true;
596 }
597 void endVisit(AST::PreDecrementExpression *) override { stop(str: u"PreDecrementExpression"); }
598
599 bool visit(AST::UnaryPlusExpression *el) override {
600 start(str: QLatin1String("UnaryPlusExpression plusToken=%1")
601 .arg(args: loc(s: el->plusToken)));
602 return true;
603 }
604 void endVisit(AST::UnaryPlusExpression *) override { stop(str: u"UnaryPlusExpression"); }
605
606 bool visit(AST::UnaryMinusExpression *el) override {
607 start(str: QLatin1String("UnaryMinusExpression minusToken=%1")
608 .arg(args: loc(s: el->minusToken)));
609 return true;
610 }
611 void endVisit(AST::UnaryMinusExpression *) override { stop(str: u"UnaryMinusExpression"); }
612
613 bool visit(AST::TildeExpression *el) override {
614 start(str: QLatin1String("TildeExpression tildeToken=%1")
615 .arg(args: loc(s: el->tildeToken)));
616 return true;
617 }
618 void endVisit(AST::TildeExpression *) override { stop(str: u"TildeExpression"); }
619
620 bool visit(AST::NotExpression *el) override {
621 start(str: QLatin1String("NotExpression notToken=%1")
622 .arg(args: loc(s: el->notToken)));
623 return true;
624 }
625 void endVisit(AST::NotExpression *) override { stop(str: u"NotExpression"); }
626
627 bool visit(AST::BinaryExpression *el) override {
628 start(str: QLatin1String("BinaryExpression op=%1 operatorToken=%2")
629 .arg(args: quotedString(s: QString::number(el->op,base: 16)), args: loc(s: el->operatorToken)));
630 return true;
631 }
632 void endVisit(AST::BinaryExpression *) override { stop(str: u"BinaryExpression"); }
633
634 bool visit(AST::ConditionalExpression *el) override {
635 start(str: QLatin1String("ConditionalExpression questionToken=%1 colonToken=%2")
636 .arg(args: loc(s: el->questionToken), args: loc(s: el->colonToken)));
637 return true;
638 }
639 void endVisit(AST::ConditionalExpression *) override { stop(str: u"ConditionalExpression"); }
640
641 bool visit(AST::Expression *el) override {
642 start(str: QLatin1String("Expression commaToken=%1")
643 .arg(args: loc(s: el->commaToken)));
644 return true;
645 }
646 void endVisit(AST::Expression *) override { stop(str: u"Expression"); }
647
648 bool visit(AST::Block *el) override {
649 start(str: QLatin1String("Block lbraceToken=%1 rbraceToken=%2")
650 .arg(args: loc(s: el->lbraceToken), args: loc(s: el->rbraceToken)));
651 return true;
652 }
653 void endVisit(AST::Block *) override { stop(str: u"Block"); }
654
655 bool visit(AST::StatementList *) override {
656 start(str: u"StatementList");
657 return true;
658 }
659 void endVisit(AST::StatementList *) override { stop(str: u"StatementList"); }
660
661 bool visit(AST::VariableStatement *el) override {
662 start(str: QLatin1String("VariableStatement declarationKindToken=%1")
663 .arg(args: loc(s: el->declarationKindToken)));
664 return true;
665 }
666 void endVisit(AST::VariableStatement *) override { stop(str: u"VariableStatement"); }
667
668 bool visit(AST::VariableDeclarationList *el) override {
669 start(str: QLatin1String("VariableDeclarationList commaToken=%1")
670 .arg(args: loc(s: el->commaToken)));
671 return true;
672 }
673 void endVisit(AST::VariableDeclarationList *) override { stop(str: u"VariableDeclarationList"); }
674
675 bool visit(AST::EmptyStatement *el) override {
676 start(str: QLatin1String("EmptyStatement%1").arg(args: semicolonToken(s: el->semicolonToken)));
677 return true;
678 }
679 void endVisit(AST::EmptyStatement *) override { stop(str: u"EmptyStatement"); }
680
681 bool visit(AST::ExpressionStatement *el) override {
682 if (options & AstDumperOption::SloppyCompare)
683 start(str: u"ExpressionStatement");
684 else
685 start(str: QLatin1String("ExpressionStatement%1").arg(args: semicolonToken(s: el->semicolonToken)));
686 return true;
687 }
688 void endVisit(AST::ExpressionStatement *) override { stop(str: u"ExpressionStatement"); }
689
690 bool visit(AST::IfStatement *el) override {
691 start(str: QLatin1String("IfStatement ifToken=%1 lparenToken=%2 rparenToken=%3 elseToken=%4")
692 .arg(args: loc(s: el->ifToken), args: loc(s: el->lparenToken), args: loc(s: el->rparenToken), args: loc(s: el->elseToken)));
693 return true;
694 }
695 void endVisit(AST::IfStatement *) override { stop(str: u"IfStatement"); }
696
697 bool visit(AST::DoWhileStatement *el) override {
698 start(str: QLatin1String(
699 "DoWhileStatement doToken=%1 whileToken=%2 lparenToken=%3 rparenToken=%4%5")
700 .arg(args: loc(s: el->doToken), args: loc(s: el->whileToken), args: loc(s: el->lparenToken),
701 args: loc(s: el->rparenToken), args: semicolonToken(s: el->semicolonToken)));
702 return true;
703 }
704 void endVisit(AST::DoWhileStatement *) override { stop(str: u"DoWhileStatement"); }
705
706 bool visit(AST::WhileStatement *el) override {
707 start(str: QLatin1String("WhileStatement whileToken=%1 lparenToken=%2 rparenToken=%3")
708 .arg(args: loc(s: el->whileToken), args: loc(s: el->lparenToken), args: loc(s: el->rparenToken)));
709 return true;
710 }
711 void endVisit(AST::WhileStatement *) override { stop(str: u"WhileStatement"); }
712
713 bool visit(AST::ForStatement *el) override {
714 if (options & AstDumperOption::SloppyCompare)
715 start(str: QLatin1String("ForStatement forToken=%1 lparenToken=%2 rparenToken=%5")
716 .arg(args: loc(s: el->forToken), args: loc(s: el->lparenToken), args: loc(s: el->rparenToken)));
717 else
718 start(str: QLatin1String("ForStatement forToken=%1 lparenToken=%2 firstSemicolonToken=%3 "
719 "secondSemicolonToken=%4 rparenToken=%5")
720 .arg(args: loc(s: el->forToken), args: loc(s: el->lparenToken),
721 args: loc(s: el->firstSemicolonToken), args: loc(s: el->secondSemicolonToken),
722 args: loc(s: el->rparenToken)));
723 return true;
724 }
725 void endVisit(AST::ForStatement *) override { stop(str: u"ForStatement"); }
726
727 bool visit(AST::ForEachStatement *el) override {
728 start(str: QLatin1String("ForEachStatement forToken=%1 lparenToken=%2 inOfToken=%3 rparenToken=%4 type=%5")
729 .arg(args: loc(s: el->forToken), args: loc(s: el->lparenToken), args: loc(s: el->inOfToken), args: loc(s: el->rparenToken), args: quotedString(s: QString::number(static_cast<int>(el->type), base: 16))));
730 return true;
731 }
732 void endVisit(AST::ForEachStatement *) override { stop(str: u"ForEachStatement"); }
733
734 bool visit(AST::ContinueStatement *el) override {
735 start(str: QLatin1String("ContinueStatement label=%1 continueToken=%2 identifierToken=%3%4")
736 .arg(args: quotedString(s: el->label), args: loc(s: el->continueToken),
737 args: loc(s: el->identifierToken), args: semicolonToken(s: el->semicolonToken)));
738 return true;
739 }
740 void endVisit(AST::ContinueStatement *) override { stop(str: u"ContinueStatement"); }
741
742 bool visit(AST::BreakStatement *el) override {
743 start(str: QLatin1String("BreakStatement label=%1 breakToken=%2 identifierToken=%3%4")
744 .arg(args: quotedString(s: el->label), args: loc(s: el->breakToken), args: loc(s: el->identifierToken),
745 args: semicolonToken(s: el->semicolonToken)));
746 return true;
747 }
748 void endVisit(AST::BreakStatement *) override { stop(str: u"BreakStatement"); }
749
750 bool visit(AST::ReturnStatement *el) override {
751 start(str: QLatin1String("ReturnStatement returnToken=%1%2")
752 .arg(args: loc(s: el->returnToken), args: semicolonToken(s: el->semicolonToken)));
753 return true;
754 }
755 void endVisit(AST::ReturnStatement *) override { stop(str: u"ReturnStatement"); }
756
757 bool visit(AST::YieldExpression *el) override {
758 start(str: QLatin1String("YieldExpression isYieldStar=%1 yieldToken=%2")
759 .arg(args: boolStr(v: el->isYieldStar), args: loc(s: el->yieldToken)));
760 return true;
761 }
762 void endVisit(AST::YieldExpression *) override { stop(str: u"YieldExpression"); }
763
764 bool visit(AST::WithStatement *el) override {
765 start(str: QLatin1String("WithStatement withToken=%1 lparenToken=%2 rparenToken=%3")
766 .arg(args: loc(s: el->withToken), args: loc(s: el->lparenToken), args: loc(s: el->rparenToken)));
767 return true;
768 }
769 void endVisit(AST::WithStatement *) override { stop(str: u"WithStatement"); }
770
771 bool visit(AST::SwitchStatement *el) override {
772 start(str: QLatin1String("SwitchStatement switchToken=%1 lparenToken=%2 rparenToken=%3")
773 .arg(args: loc(s: el->switchToken), args: loc(s: el->lparenToken), args: loc(s: el->rparenToken)));
774 return true;
775 }
776 void endVisit(AST::SwitchStatement *) override { stop(str: u"SwitchStatement"); }
777
778 bool visit(AST::CaseBlock *el) override {
779 start(str: QLatin1String("CaseBlock lbraceToken=%1 rbraceToken=%2")
780 .arg(args: loc(s: el->lbraceToken), args: loc(s: el->rbraceToken)));
781 return true;
782 }
783 void endVisit(AST::CaseBlock *) override { stop(str: u"CaseBlock"); }
784
785 bool visit(AST::CaseClauses *) override {
786 start(str: u"CaseClauses");
787 return true;
788 }
789 void endVisit(AST::CaseClauses *) override { stop(str: u"CaseClauses"); }
790
791 bool visit(AST::CaseClause *el) override {
792 start(str: QLatin1String("CaseClause caseToken=%1 colonToken=%2")
793 .arg(args: loc(s: el->caseToken), args: loc(s: el->colonToken)));
794 return true;
795 }
796 void endVisit(AST::CaseClause *) override { stop(str: u"CaseClause"); }
797
798 bool visit(AST::DefaultClause *el) override {
799 start(str: QLatin1String("DefaultClause defaultToken=%1 colonToken=%2")
800 .arg(args: loc(s: el->defaultToken), args: loc(s: el->colonToken)));
801 return true;
802 }
803 void endVisit(AST::DefaultClause *) override { stop(str: u"DefaultClause"); }
804
805 bool visit(AST::LabelledStatement *el) override {
806 start(str: QLatin1String("LabelledStatement label=%1 identifierToken=%2 colonToken=%3")
807 .arg(args: quotedString(s: el->label), args: loc(s: el->identifierToken), args: loc(s: el->colonToken)));
808 return true;
809 }
810 void endVisit(AST::LabelledStatement *) override { stop(str: u"LabelledStatement"); }
811
812 bool visit(AST::ThrowStatement *el) override {
813 start(str: QLatin1String("ThrowStatement throwToken=%1%2")
814 .arg(args: loc(s: el->throwToken), args: semicolonToken(s: el->semicolonToken)));
815 return true;
816 }
817 void endVisit(AST::ThrowStatement *) override { stop(str: u"ThrowStatement"); }
818
819 bool visit(AST::TryStatement *el) override {
820 start(str: QLatin1String("TryStatement tryToken=%1")
821 .arg(args: loc(s: el->tryToken)));
822 return true;
823 }
824 void endVisit(AST::TryStatement *) override { stop(str: u"TryStatement"); }
825
826 bool visit(AST::Catch *el) override {
827 start(str: QLatin1String("Catch catchToken=%1 lparenToken=%2 identifierToken=%3 rparenToken=%4")
828 .arg(args: loc(s: el->catchToken), args: loc(s: el->lparenToken), args: loc(s: el->identifierToken), args: loc(s: el->rparenToken)));
829 return true;
830 }
831 void endVisit(AST::Catch *) override { stop(str: u"Catch"); }
832
833 bool visit(AST::Finally *el) override {
834 start(str: QLatin1String("Finally finallyToken=%1")
835 .arg(args: loc(s: el->finallyToken)));
836 return true;
837 }
838 void endVisit(AST::Finally *) override { stop(str: u"Finally"); }
839
840 bool visit(AST::FunctionDeclaration *el) override {
841 start(str: QLatin1String("FunctionDeclaration name=%1 isArrowFunction=%2 isGenerator=%3 functionToken=%4 "
842 "identifierToken=%5 lparenToken=%6 rparenToken=%7 lbraceToken=%8 rbraceToken=%9")
843 .arg(args: quotedString(s: el->name), args: boolStr(v: el->isArrowFunction), args: boolStr(v: el->isGenerator),
844 args: loc(s: el->functionToken, trim: options & AstDumperOption::SloppyCompare),
845 args: loc(s: el->identifierToken), args: loc(s: el->lparenToken), args: loc(s: el->rparenToken), args: loc(s: el->lbraceToken),
846 args: loc(s: el->rbraceToken)));
847 return true;
848 }
849 void endVisit(AST::FunctionDeclaration *) override { stop(str: u"FunctionDeclaration"); }
850
851 bool visit(AST::FunctionExpression *el) override {
852 start(str: QLatin1String("FunctionExpression name=%1 isArrowFunction=%2 isGenerator=%3 "
853 "functionToken=%4 "
854 "identifierToken=%5 lparenToken=%6 rparenToken=%7 lbraceToken=%8 "
855 "rbraceToken=%9")
856 .arg(args: quotedString(s: el->name), args: boolStr(v: el->isArrowFunction),
857 args: boolStr(v: el->isGenerator),
858 args: loc(s: el->functionToken, trim: options & AstDumperOption::SloppyCompare),
859 args: loc(s: el->identifierToken), args: loc(s: el->lparenToken), args: loc(s: el->rparenToken),
860 args: loc(s: el->lbraceToken), args: loc(s: el->rbraceToken)));
861 return true;
862 }
863 void endVisit(AST::FunctionExpression *) override { stop(str: u"FunctionExpression"); }
864
865 bool visit(AST::FormalParameterList *) override {
866 start(str: u"FormalParameterList");
867 return true;
868 }
869 void endVisit(AST::FormalParameterList *) override { stop(str: u"FormalParameterList"); }
870
871 bool visit(AST::ClassExpression *el) override {
872 start(str: QLatin1String("ClassExpression name=%1 classToken=%2 identifierToken=%3 lbraceToken=%4 rbraceToken=%5")
873 .arg(args: quotedString(s: el->name), args: loc(s: el->classToken), args: loc(s: el->identifierToken), args: loc(s: el->lbraceToken), args: loc(s: el->rbraceToken)));
874 return true;
875 }
876 void endVisit(AST::ClassExpression *) override { stop(str: u"ClassExpression"); }
877
878 bool visit(AST::ClassDeclaration *el) override {
879 start(str: QLatin1String("ClassDeclaration name=%1 classToken=%2 identifierToken=%3 lbraceToken=%4 rbraceToken=%5")
880 .arg(args: quotedString(s: el->name), args: loc(s: el->classToken), args: loc(s: el->identifierToken), args: loc(s: el->lbraceToken), args: loc(s: el->rbraceToken)));
881 return true;
882 }
883 void endVisit(AST::ClassDeclaration *) override { stop(str: u"ClassDeclaration"); }
884
885 bool visit(AST::ClassElementList *el) override {
886 start(str: QLatin1String("ClassElementList isStatic=%1")
887 .arg(args: boolStr(v: el->isStatic)));
888 return true;
889 }
890 void endVisit(AST::ClassElementList *) override { stop(str: u"ClassElementList"); }
891
892 bool visit(AST::Program *) override {
893 start(str: u"Program");
894 return true;
895 }
896 void endVisit(AST::Program *) override { stop(str: u"Program"); }
897
898 bool visit(AST::NameSpaceImport *el) override {
899 start(str: QLatin1String("NameSpaceImport starToken=%1 importedBindingToken=%2 importedBinding=%3")
900 .arg(args: loc(s: el->starToken), args: loc(s: el->importedBindingToken), args: quotedString(s: el->importedBinding)));
901 return true;
902 }
903 void endVisit(AST::NameSpaceImport *) override { stop(str: u"NameSpaceImport"); }
904
905 bool visit(AST::ImportSpecifier *el) override {
906 start(str: QLatin1String("ImportSpecifier identifierToken=%1 importedBindingToken=%2 identifier=%3 importedBinding=%4")
907 .arg(args: loc(s: el->identifierToken), args: loc(s: el->importedBindingToken), args: quotedString(s: el->identifier), args: quotedString(s: el->importedBinding)));
908 return true;
909 }
910 void endVisit(AST::ImportSpecifier *) override { stop(str: u"ImportSpecifier"); }
911
912 bool visit(AST::ImportsList *el) override {
913 start(str: QLatin1String("ImportsList importSpecifierToken=%1")
914 .arg(args: loc(s: el->importSpecifierToken)));
915 return true;
916 }
917 void endVisit(AST::ImportsList *) override { stop(str: u"ImportsList"); }
918
919 bool visit(AST::NamedImports *el) override {
920 start(str: QLatin1String("NamedImports leftBraceToken=%1 rightBraceToken=%2")
921 .arg(args: loc(s: el->leftBraceToken), args: loc(s: el->rightBraceToken)));
922 return true;
923 }
924 void endVisit(AST::NamedImports *) override { stop(str: u"NamedImports"); }
925
926 bool visit(AST::FromClause *el) override {
927 start(str: QLatin1String("FromClause fromToken=%1 moduleSpecifierToken=%2 moduleSpecifier=%3")
928 .arg(args: loc(s: el->fromToken), args: loc(s: el->moduleSpecifierToken), args: quotedString(s: el->moduleSpecifier)));
929 return true;
930 }
931 void endVisit(AST::FromClause *) override { stop(str: u"FromClause"); }
932
933 bool visit(AST::ImportClause *el) override {
934 start(str: QLatin1String("ImportClause importedDefaultBindingToken=%1 importedDefaultBinding=%2")
935 .arg(args: loc(s: el->importedDefaultBindingToken), args: quotedString(s: el->importedDefaultBinding)));
936 return true;
937 }
938 void endVisit(AST::ImportClause *) override { stop(str: u"ImportClause"); }
939
940 bool visit(AST::ImportDeclaration *el) override {
941 start(str: QLatin1String("ImportDeclaration importToken=%1 moduleSpecifierToken=%2 moduleSpecifier=%3")
942 .arg(args: loc(s: el->importToken), args: loc(s: el->moduleSpecifierToken), args: quotedString(s: el->moduleSpecifier)));
943 return true;
944 }
945 void endVisit(AST::ImportDeclaration *) override { stop(str: u"ImportDeclaration"); }
946
947 bool visit(AST::ExportSpecifier *el) override {
948 start(str: QLatin1String("ExportSpecifier identifierToken=%1 exportedIdentifierToken=%2 identifier=%3 exportedIdentifier=%4")
949 .arg(args: loc(s: el->identifierToken), args: loc(s: el->exportedIdentifierToken), args: quotedString(s: el->identifier), args: quotedString(s: el->exportedIdentifier)));
950 return true;
951 }
952 void endVisit(AST::ExportSpecifier *) override { stop(str: u"ExportSpecifier"); }
953
954 bool visit(AST::ExportsList *) override {
955 start(str: u"ExportsList");
956 return true;
957 }
958 void endVisit(AST::ExportsList *) override { stop(str: u"ExportsList"); }
959
960 bool visit(AST::ExportClause *el) override {
961 start(str: QLatin1String("ExportClause leftBraceToken=%1 rightBraceToken=%2")
962 .arg(args: loc(s: el->leftBraceToken), args: loc(s: el->rightBraceToken)));
963 return true;
964 }
965 void endVisit(AST::ExportClause *) override { stop(str: u"ExportClause"); }
966
967 bool visit(AST::ExportDeclaration *el) override {
968 start(str: QLatin1String("ExportDeclaration exportToken=%1 exportDefault=%3")
969 .arg(args: loc(s: el->exportToken), args: boolStr(v: el->exportDefault)));
970 return true;
971 }
972 void endVisit(AST::ExportDeclaration *) override { stop(str: u"ExportDeclaration"); }
973
974 bool visit(AST::ESModule *) override {
975 start(str: u"ESModule");
976 return true;
977 }
978 void endVisit(AST::ESModule *) override { stop(str: u"ESModule"); }
979
980 bool visit(AST::DebuggerStatement *el) override {
981 start(str: QLatin1String("DebuggerStatement debuggerToken=%1%2")
982 .arg(args: loc(s: el->debuggerToken), args: semicolonToken(s: el->semicolonToken)));
983 return true;
984 }
985 void endVisit(AST::DebuggerStatement *) override { stop(str: u"DebuggerStatement"); }
986
987 bool visit(AST::Type *) override {
988 start(str: u"Type");
989 return true;
990 }
991 void endVisit(AST::Type *) override { stop(str: u"Type"); }
992
993 bool visit(AST::TypeAnnotation *el) override {
994 start(str: QLatin1String("TypeAnnotation colonToken=%1")
995 .arg(args: loc(s: el->colonToken)));
996 return true;
997 }
998 void endVisit(AST::TypeAnnotation *) override { stop(str: u"TypeAnnotation"); }
999
1000 void throwRecursionDepthError() override {
1001 qCWarning(domLog) << "Maximum statement or expression depth exceeded in AstDumper";
1002 }
1003
1004private:
1005 // attributes
1006 std::function <void (QStringView)> dumper;
1007 AstDumperOptions options = AstDumperOption::None;
1008 int indent = 0;
1009 int baseIndent = 0;
1010 function_ref<QStringView(SourceLocation)> loc2str;
1011 bool dumpNode(){
1012 return options & AstDumperOption::DumpNode;
1013 }
1014 bool noLocations() {
1015 return options & AstDumperOption::NoLocations;
1016 }
1017 bool noAnnotations() {
1018 return options & AstDumperOption::NoAnnotations;
1019 }
1020};
1021
1022QDebug operator<<(QDebug d, AST::Node *n) {
1023 QDebug noQuote = d.noquote().nospace();
1024 AstDumper visitor([&noQuote](QStringView s){ noQuote << s; });
1025 Node::accept(node: n, visitor: &visitor);
1026 return d;
1027}
1028
1029QString lineDiff(QString s1, QString s2, int nContext) {
1030 QTextStream d1(&s1), d2(&s2);
1031 QList<QString> preLines(nContext);
1032 int nLine = 0;
1033 bool same = true;
1034 QString l1, l2;
1035 while (same && !d1.atEnd() && !d2.atEnd()) {
1036 l1=d1.readLine();
1037 l2=d2.readLine();
1038 if (l1 == l2)
1039 preLines[nLine++ % nContext] = l1;
1040 else
1041 same = false;
1042 }
1043 QString res;
1044 QTextStream ss(&res);
1045 if (!same || !d1.atEnd() || !d2.atEnd()) {
1046 for (int iline = qMin(a: nLine, b: nContext); iline > 0; --iline) {
1047 ss << QLatin1String(" ") << preLines[(nLine - iline) % nContext] << QLatin1String("\n");
1048 }
1049 int iline = 0;
1050 if (!same) {
1051 ss << QLatin1String("-") << l1 << QLatin1String("\n");
1052 ++iline;
1053 }
1054 if (same && nContext == 0)
1055 nContext = 1;
1056 for (;iline < nContext && !d1.atEnd(); iline ++) {
1057 l1 = d1.readLine();
1058 ss << QLatin1String("-") << l1 << QLatin1String("\n");
1059 }
1060 iline = 0;
1061 if (!same) {
1062 ss << QLatin1String("+") << l2 << QLatin1String("\n");
1063 ++iline;
1064 }
1065 for (;iline < nContext && !d2.atEnd(); iline ++) {
1066 l2 = d2.readLine();
1067 ss << QLatin1String("+") << l2 << QLatin1String("\n");
1068 }
1069 }
1070 return res;
1071}
1072
1073QString astNodeDiff(AST::Node *n1, AST::Node *n2, int nContext, AstDumperOptions opt, int indent,
1074 function_ref<QStringView(SourceLocation)>loc2str1,
1075 function_ref<QStringView(SourceLocation)>loc2str2) {
1076 QString s1, s2;
1077 QTextStream d1(&s1), d2(&s2);
1078 AstDumper visitor1=AstDumper([&d1](QStringView s){ d1 << s; }, opt, indent, 0, loc2str1);
1079 AstDumper visitor2=AstDumper([&d2](QStringView s){ d2 << s; }, opt, indent, 0, loc2str2);
1080 Node::accept(node: n1, visitor: &visitor1);
1081 Node::accept(node: n2, visitor: &visitor2);
1082 d1.flush();
1083 d2.flush();
1084 return lineDiff(s1, s2, nContext);
1085}
1086
1087void astNodeDumper(Sink s, Node *n, AstDumperOptions opt, int indent, int baseIndent,
1088 function_ref<QStringView(SourceLocation)>loc2str)
1089{
1090 AstDumper visitor=AstDumper(s, opt, indent, baseIndent, loc2str);
1091 Node::accept(node: n, visitor: &visitor);
1092}
1093
1094QString astNodeDump(Node *n, AstDumperOptions opt, int indent, int baseIndent,
1095 function_ref<QStringView(SourceLocation)>loc2str)
1096{
1097 return dumperToString(writer: [n, opt, indent, baseIndent, loc2str](Sink s) { astNodeDumper(s, n, opt, indent, baseIndent, loc2str); });
1098}
1099
1100} // end namespace Dom
1101} // end namespace QQmlJS
1102
1103QT_END_NAMESPACE
1104

source code of qtdeclarative/src/qmldom/qqmldomastdumper.cpp