1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "qmlmarkupvisitor.h"
5
6#include <QtCore/qglobal.h>
7#include <QtCore/qstringlist.h>
8
9#include <private/qqmljsast_p.h>
10#include <private/qqmljsengine_p.h>
11
12QT_BEGIN_NAMESPACE
13
14QmlMarkupVisitor::QmlMarkupVisitor(const QString &source,
15 const QList<QQmlJS::SourceLocation> &pragmas,
16 QQmlJS::Engine *engine)
17{
18 this->m_source = source;
19 this->m_engine = engine;
20
21 m_cursor = 0;
22 m_extraIndex = 0;
23
24 // Merge the lists of locations of pragmas and comments in the source code.
25 int i = 0;
26 int j = 0;
27 const QList<QQmlJS::SourceLocation> comments = engine->comments();
28 while (i < comments.size() && j < pragmas.size()) {
29 if (comments[i].offset < pragmas[j].offset) {
30 m_extraTypes.append(t: Comment);
31 m_extraLocations.append(t: comments[i]);
32 ++i;
33 } else {
34 m_extraTypes.append(t: Pragma);
35 m_extraLocations.append(t: comments[j]);
36 ++j;
37 }
38 }
39
40 while (i < comments.size()) {
41 m_extraTypes.append(t: Comment);
42 m_extraLocations.append(t: comments[i]);
43 ++i;
44 }
45
46 while (j < pragmas.size()) {
47 m_extraTypes.append(t: Pragma);
48 m_extraLocations.append(t: pragmas[j]);
49 ++j;
50 }
51}
52
53QString QmlMarkupVisitor::markedUpCode()
54{
55 if (int(m_cursor) < m_source.size())
56 addExtra(start: m_cursor, finish: m_source.size());
57
58 return m_output;
59}
60
61bool QmlMarkupVisitor::hasError() const
62{
63 return m_hasRecursionDepthError;
64}
65
66void QmlMarkupVisitor::addExtra(quint32 start, quint32 finish)
67{
68 if (m_extraIndex >= m_extraLocations.size()) {
69 QString extra = m_source.mid(position: start, n: finish - start);
70 if (extra.trimmed().isEmpty())
71 m_output += extra;
72 else
73 m_output += Utilities::protect(string: extra); // text that should probably have been caught by the parser
74
75 m_cursor = finish;
76 return;
77 }
78
79 while (m_extraIndex < m_extraLocations.size()) {
80 if (m_extraTypes[m_extraIndex] == Comment) {
81 if (m_extraLocations[m_extraIndex].offset - 2 >= start)
82 break;
83 } else {
84 if (m_extraLocations[m_extraIndex].offset >= start)
85 break;
86 }
87 m_extraIndex++;
88 }
89
90 quint32 i = start;
91 while (i < finish && m_extraIndex < m_extraLocations.size()) {
92 quint32 j = m_extraLocations[m_extraIndex].offset - 2;
93 if (i <= j && j < finish) {
94 if (i < j)
95 m_output += Utilities::protect(string: m_source.mid(position: i, n: j - i));
96
97 quint32 l = m_extraLocations[m_extraIndex].length;
98 if (m_extraTypes[m_extraIndex] == Comment) {
99 if (m_source.mid(position: j, n: 2) == QLatin1String("/*"))
100 l += 4;
101 else
102 l += 2;
103 m_output += QLatin1String("<@comment>");
104 m_output += Utilities::protect(string: m_source.mid(position: j, n: l));
105 m_output += QLatin1String("</@comment>");
106 } else
107 m_output += Utilities::protect(string: m_source.mid(position: j, n: l));
108
109 m_extraIndex++;
110 i = j + l;
111 } else
112 break;
113 }
114
115 QString extra = m_source.mid(position: i, n: finish - i);
116 if (extra.trimmed().isEmpty())
117 m_output += extra;
118 else
119 m_output += Utilities::protect(string: extra); // text that should probably have been caught by the parser
120
121 m_cursor = finish;
122}
123
124void QmlMarkupVisitor::addMarkedUpToken(QQmlJS::SourceLocation &location,
125 const QString &tagName,
126 const QHash<QString, QString> &attributes)
127{
128 if (!location.isValid())
129 return;
130
131 if (m_cursor < location.offset)
132 addExtra(start: m_cursor, finish: location.offset);
133 else if (m_cursor > location.offset)
134 return;
135
136 m_output += QString(QLatin1String("<@%1")).arg(a: tagName);
137 for (const auto &key : attributes)
138 m_output += QString(QLatin1String(" %1=\"%2\"")).arg(args: key, args: attributes[key]);
139 m_output += QString(QLatin1String(">%2</@%3>")).arg(args: Utilities::protect(string: sourceText(location)), args: tagName);
140 m_cursor += location.length;
141}
142
143QString QmlMarkupVisitor::sourceText(QQmlJS::SourceLocation &location)
144{
145 return m_source.mid(position: location.offset, n: location.length);
146}
147
148void QmlMarkupVisitor::addVerbatim(QQmlJS::SourceLocation first,
149 QQmlJS::SourceLocation last)
150{
151 if (!first.isValid())
152 return;
153
154 quint32 start = first.begin();
155 quint32 finish;
156 if (last.isValid())
157 finish = last.end();
158 else
159 finish = first.end();
160
161 if (m_cursor < start)
162 addExtra(start: m_cursor, finish: start);
163 else if (m_cursor > start)
164 return;
165
166 QString text = m_source.mid(position: start, n: finish - start);
167 m_output += Utilities::protect(string: text);
168 m_cursor = finish;
169}
170
171bool QmlMarkupVisitor::visit(QQmlJS::AST::UiImport *uiimport)
172{
173 addVerbatim(first: uiimport->importToken);
174 if (!uiimport->importUri)
175 addMarkedUpToken(location&: uiimport->fileNameToken, tagName: QLatin1String("headerfile"));
176 return false;
177}
178
179void QmlMarkupVisitor::endVisit(QQmlJS::AST::UiImport *uiimport)
180{
181 if (uiimport->version)
182 addVerbatim(first: uiimport->version->firstSourceLocation(),
183 last: uiimport->version->lastSourceLocation());
184 addVerbatim(first: uiimport->asToken);
185 addMarkedUpToken(location&: uiimport->importIdToken, tagName: QLatin1String("headerfile"));
186 addVerbatim(first: uiimport->semicolonToken);
187}
188
189bool QmlMarkupVisitor::visit(QQmlJS::AST::UiPublicMember *member)
190{
191 if (member->type == QQmlJS::AST::UiPublicMember::Property) {
192 addVerbatim(first: member->defaultToken());
193 addVerbatim(first: member->readonlyToken());
194 addVerbatim(first: member->propertyToken());
195 addVerbatim(first: member->typeModifierToken);
196 addMarkedUpToken(location&: member->typeToken, tagName: QLatin1String("type"));
197 addMarkedUpToken(location&: member->identifierToken, tagName: QLatin1String("name"));
198 addVerbatim(first: member->colonToken);
199 if (member->binding)
200 QQmlJS::AST::Node::accept(node: member->binding, visitor: this);
201 else if (member->statement)
202 QQmlJS::AST::Node::accept(node: member->statement, visitor: this);
203 } else {
204 addVerbatim(first: member->propertyToken());
205 addVerbatim(first: member->typeModifierToken);
206 addMarkedUpToken(location&: member->typeToken, tagName: QLatin1String("type"));
207 // addVerbatim(member->identifierToken());
208 QQmlJS::AST::Node::accept(node: member->parameters, visitor: this);
209 }
210 addVerbatim(first: member->semicolonToken);
211 return false;
212}
213
214bool QmlMarkupVisitor::visit(QQmlJS::AST::UiObjectInitializer *initializer)
215{
216 addVerbatim(first: initializer->lbraceToken, last: initializer->lbraceToken);
217 return true;
218}
219
220void QmlMarkupVisitor::endVisit(QQmlJS::AST::UiObjectInitializer *initializer)
221{
222 addVerbatim(first: initializer->rbraceToken, last: initializer->rbraceToken);
223}
224
225bool QmlMarkupVisitor::visit(QQmlJS::AST::UiObjectBinding *binding)
226{
227 QQmlJS::AST::Node::accept(node: binding->qualifiedId, visitor: this);
228 addVerbatim(first: binding->colonToken);
229 QQmlJS::AST::Node::accept(node: binding->qualifiedTypeNameId, visitor: this);
230 QQmlJS::AST::Node::accept(node: binding->initializer, visitor: this);
231 return false;
232}
233
234bool QmlMarkupVisitor::visit(QQmlJS::AST::UiScriptBinding *binding)
235{
236 QQmlJS::AST::Node::accept(node: binding->qualifiedId, visitor: this);
237 addVerbatim(first: binding->colonToken);
238 QQmlJS::AST::Node::accept(node: binding->statement, visitor: this);
239 return false;
240}
241
242bool QmlMarkupVisitor::visit(QQmlJS::AST::UiArrayBinding *binding)
243{
244 QQmlJS::AST::Node::accept(node: binding->qualifiedId, visitor: this);
245 addVerbatim(first: binding->colonToken);
246 addVerbatim(first: binding->lbracketToken);
247 QQmlJS::AST::Node::accept(node: binding->members, visitor: this);
248 addVerbatim(first: binding->rbracketToken);
249 return false;
250}
251
252bool QmlMarkupVisitor::visit(QQmlJS::AST::UiArrayMemberList *list)
253{
254 for (QQmlJS::AST::UiArrayMemberList *it = list; it; it = it->next) {
255 QQmlJS::AST::Node::accept(node: it->member, visitor: this);
256 // addVerbatim(it->commaToken);
257 }
258 return false;
259}
260
261bool QmlMarkupVisitor::visit(QQmlJS::AST::UiQualifiedId *id)
262{
263 addMarkedUpToken(location&: id->identifierToken, tagName: QLatin1String("name"));
264 return false;
265}
266
267bool QmlMarkupVisitor::visit(QQmlJS::AST::ThisExpression *expression)
268{
269 addVerbatim(first: expression->thisToken);
270 return true;
271}
272
273bool QmlMarkupVisitor::visit(QQmlJS::AST::IdentifierExpression *identifier)
274{
275 addMarkedUpToken(location&: identifier->identifierToken, tagName: QLatin1String("name"));
276 return false;
277}
278
279bool QmlMarkupVisitor::visit(QQmlJS::AST::NullExpression *null)
280{
281 addMarkedUpToken(location&: null->nullToken, tagName: QLatin1String("number"));
282 return true;
283}
284
285bool QmlMarkupVisitor::visit(QQmlJS::AST::TrueLiteral *literal)
286{
287 addMarkedUpToken(location&: literal->trueToken, tagName: QLatin1String("number"));
288 return true;
289}
290
291bool QmlMarkupVisitor::visit(QQmlJS::AST::FalseLiteral *literal)
292{
293 addMarkedUpToken(location&: literal->falseToken, tagName: QLatin1String("number"));
294 return true;
295}
296
297bool QmlMarkupVisitor::visit(QQmlJS::AST::NumericLiteral *literal)
298{
299 addMarkedUpToken(location&: literal->literalToken, tagName: QLatin1String("number"));
300 return false;
301}
302
303bool QmlMarkupVisitor::visit(QQmlJS::AST::StringLiteral *literal)
304{
305 addMarkedUpToken(location&: literal->literalToken, tagName: QLatin1String("string"));
306 return true;
307}
308
309bool QmlMarkupVisitor::visit(QQmlJS::AST::RegExpLiteral *literal)
310{
311 addVerbatim(first: literal->literalToken);
312 return true;
313}
314
315bool QmlMarkupVisitor::visit(QQmlJS::AST::ArrayPattern *literal)
316{
317 addVerbatim(first: literal->lbracketToken);
318 QQmlJS::AST::Node::accept(node: literal->elements, visitor: this);
319 addVerbatim(first: literal->rbracketToken);
320 return false;
321}
322
323bool QmlMarkupVisitor::visit(QQmlJS::AST::ObjectPattern *literal)
324{
325 addVerbatim(first: literal->lbraceToken);
326 return true;
327}
328
329void QmlMarkupVisitor::endVisit(QQmlJS::AST::ObjectPattern *literal)
330{
331 addVerbatim(first: literal->rbraceToken);
332}
333
334bool QmlMarkupVisitor::visit(QQmlJS::AST::PatternElementList *list)
335{
336 for (QQmlJS::AST::PatternElementList *it = list; it; it = it->next) {
337 QQmlJS::AST::Node::accept(node: it->element, visitor: this);
338 // addVerbatim(it->commaToken);
339 }
340 QQmlJS::AST::Node::accept(node: list->elision, visitor: this);
341 return false;
342}
343
344bool QmlMarkupVisitor::visit(QQmlJS::AST::Elision *elision)
345{
346 addVerbatim(first: elision->commaToken, last: elision->commaToken);
347 return true;
348}
349
350bool QmlMarkupVisitor::visit(QQmlJS::AST::PatternProperty *list)
351{
352 QQmlJS::AST::Node::accept(node: list->name, visitor: this);
353 addVerbatim(first: list->colonToken, last: list->colonToken);
354 QQmlJS::AST::Node::accept(node: list->initializer, visitor: this);
355 // addVerbatim(list->commaToken, list->commaToken);
356 return false;
357}
358
359bool QmlMarkupVisitor::visit(QQmlJS::AST::ArrayMemberExpression *expression)
360{
361 QQmlJS::AST::Node::accept(node: expression->base, visitor: this);
362 addVerbatim(first: expression->lbracketToken);
363 QQmlJS::AST::Node::accept(node: expression->expression, visitor: this);
364 addVerbatim(first: expression->rbracketToken);
365 return false;
366}
367
368bool QmlMarkupVisitor::visit(QQmlJS::AST::FieldMemberExpression *expression)
369{
370 QQmlJS::AST::Node::accept(node: expression->base, visitor: this);
371 addVerbatim(first: expression->dotToken);
372 addMarkedUpToken(location&: expression->identifierToken, tagName: QLatin1String("name"));
373 return false;
374}
375
376bool QmlMarkupVisitor::visit(QQmlJS::AST::NewMemberExpression *expression)
377{
378 addVerbatim(first: expression->newToken);
379 QQmlJS::AST::Node::accept(node: expression->base, visitor: this);
380 addVerbatim(first: expression->lparenToken);
381 QQmlJS::AST::Node::accept(node: expression->arguments, visitor: this);
382 addVerbatim(first: expression->rparenToken);
383 return false;
384}
385
386bool QmlMarkupVisitor::visit(QQmlJS::AST::NewExpression *expression)
387{
388 addVerbatim(first: expression->newToken);
389 return true;
390}
391
392bool QmlMarkupVisitor::visit(QQmlJS::AST::ArgumentList *list)
393{
394 addVerbatim(first: list->commaToken, last: list->commaToken);
395 return true;
396}
397
398bool QmlMarkupVisitor::visit(QQmlJS::AST::PostIncrementExpression *expression)
399{
400 addVerbatim(first: expression->incrementToken);
401 return true;
402}
403
404bool QmlMarkupVisitor::visit(QQmlJS::AST::PostDecrementExpression *expression)
405{
406 addVerbatim(first: expression->decrementToken);
407 return true;
408}
409
410bool QmlMarkupVisitor::visit(QQmlJS::AST::DeleteExpression *expression)
411{
412 addVerbatim(first: expression->deleteToken);
413 return true;
414}
415
416bool QmlMarkupVisitor::visit(QQmlJS::AST::VoidExpression *expression)
417{
418 addVerbatim(first: expression->voidToken);
419 return true;
420}
421
422bool QmlMarkupVisitor::visit(QQmlJS::AST::TypeOfExpression *expression)
423{
424 addVerbatim(first: expression->typeofToken);
425 return true;
426}
427
428bool QmlMarkupVisitor::visit(QQmlJS::AST::PreIncrementExpression *expression)
429{
430 addVerbatim(first: expression->incrementToken);
431 return true;
432}
433
434bool QmlMarkupVisitor::visit(QQmlJS::AST::PreDecrementExpression *expression)
435{
436 addVerbatim(first: expression->decrementToken);
437 return true;
438}
439
440bool QmlMarkupVisitor::visit(QQmlJS::AST::UnaryPlusExpression *expression)
441{
442 addVerbatim(first: expression->plusToken);
443 return true;
444}
445
446bool QmlMarkupVisitor::visit(QQmlJS::AST::UnaryMinusExpression *expression)
447{
448 addVerbatim(first: expression->minusToken);
449 return true;
450}
451
452bool QmlMarkupVisitor::visit(QQmlJS::AST::TildeExpression *expression)
453{
454 addVerbatim(first: expression->tildeToken);
455 return true;
456}
457
458bool QmlMarkupVisitor::visit(QQmlJS::AST::NotExpression *expression)
459{
460 addVerbatim(first: expression->notToken);
461 return true;
462}
463
464bool QmlMarkupVisitor::visit(QQmlJS::AST::BinaryExpression *expression)
465{
466 QQmlJS::AST::Node::accept(node: expression->left, visitor: this);
467 addMarkedUpToken(location&: expression->operatorToken, tagName: QLatin1String("op"));
468 QQmlJS::AST::Node::accept(node: expression->right, visitor: this);
469 return false;
470}
471
472bool QmlMarkupVisitor::visit(QQmlJS::AST::ConditionalExpression *expression)
473{
474 QQmlJS::AST::Node::accept(node: expression->expression, visitor: this);
475 addVerbatim(first: expression->questionToken);
476 QQmlJS::AST::Node::accept(node: expression->ok, visitor: this);
477 addVerbatim(first: expression->colonToken);
478 QQmlJS::AST::Node::accept(node: expression->ko, visitor: this);
479 return false;
480}
481
482bool QmlMarkupVisitor::visit(QQmlJS::AST::CommaExpression *expression)
483{
484 QQmlJS::AST::Node::accept(node: expression->left, visitor: this);
485 addVerbatim(first: expression->commaToken);
486 QQmlJS::AST::Node::accept(node: expression->right, visitor: this);
487 return false;
488}
489
490bool QmlMarkupVisitor::visit(QQmlJS::AST::Block *block)
491{
492 addVerbatim(first: block->lbraceToken);
493 return true;
494}
495
496void QmlMarkupVisitor::endVisit(QQmlJS::AST::Block *block)
497{
498 addVerbatim(first: block->rbraceToken);
499}
500
501bool QmlMarkupVisitor::visit(QQmlJS::AST::VariableStatement *statement)
502{
503 addVerbatim(first: statement->declarationKindToken);
504 QQmlJS::AST::Node::accept(node: statement->declarations, visitor: this);
505 // addVerbatim(statement->semicolonToken);
506 return false;
507}
508
509bool QmlMarkupVisitor::visit(QQmlJS::AST::VariableDeclarationList *list)
510{
511 for (QQmlJS::AST::VariableDeclarationList *it = list; it; it = it->next) {
512 QQmlJS::AST::Node::accept(node: it->declaration, visitor: this);
513 addVerbatim(first: it->commaToken);
514 }
515 return false;
516}
517
518bool QmlMarkupVisitor::visit(QQmlJS::AST::EmptyStatement *statement)
519{
520 addVerbatim(first: statement->semicolonToken);
521 return true;
522}
523
524bool QmlMarkupVisitor::visit(QQmlJS::AST::ExpressionStatement *statement)
525{
526 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
527 addVerbatim(first: statement->semicolonToken);
528 return false;
529}
530
531bool QmlMarkupVisitor::visit(QQmlJS::AST::IfStatement *statement)
532{
533 addMarkedUpToken(location&: statement->ifToken, tagName: QLatin1String("keyword"));
534 addVerbatim(first: statement->lparenToken);
535 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
536 addVerbatim(first: statement->rparenToken);
537 QQmlJS::AST::Node::accept(node: statement->ok, visitor: this);
538 if (statement->ko) {
539 addMarkedUpToken(location&: statement->elseToken, tagName: QLatin1String("keyword"));
540 QQmlJS::AST::Node::accept(node: statement->ko, visitor: this);
541 }
542 return false;
543}
544
545bool QmlMarkupVisitor::visit(QQmlJS::AST::DoWhileStatement *statement)
546{
547 addMarkedUpToken(location&: statement->doToken, tagName: QLatin1String("keyword"));
548 QQmlJS::AST::Node::accept(node: statement->statement, visitor: this);
549 addMarkedUpToken(location&: statement->whileToken, tagName: QLatin1String("keyword"));
550 addVerbatim(first: statement->lparenToken);
551 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
552 addVerbatim(first: statement->rparenToken);
553 addVerbatim(first: statement->semicolonToken);
554 return false;
555}
556
557bool QmlMarkupVisitor::visit(QQmlJS::AST::WhileStatement *statement)
558{
559 addMarkedUpToken(location&: statement->whileToken, tagName: QLatin1String("keyword"));
560 addVerbatim(first: statement->lparenToken);
561 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
562 addVerbatim(first: statement->rparenToken);
563 QQmlJS::AST::Node::accept(node: statement->statement, visitor: this);
564 return false;
565}
566
567bool QmlMarkupVisitor::visit(QQmlJS::AST::ForStatement *statement)
568{
569 addMarkedUpToken(location&: statement->forToken, tagName: QLatin1String("keyword"));
570 addVerbatim(first: statement->lparenToken);
571 QQmlJS::AST::Node::accept(node: statement->initialiser, visitor: this);
572 addVerbatim(first: statement->firstSemicolonToken);
573 QQmlJS::AST::Node::accept(node: statement->condition, visitor: this);
574 addVerbatim(first: statement->secondSemicolonToken);
575 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
576 addVerbatim(first: statement->rparenToken);
577 QQmlJS::AST::Node::accept(node: statement->statement, visitor: this);
578 return false;
579}
580
581bool QmlMarkupVisitor::visit(QQmlJS::AST::ForEachStatement *statement)
582{
583 addMarkedUpToken(location&: statement->forToken, tagName: QLatin1String("keyword"));
584 addVerbatim(first: statement->lparenToken);
585 QQmlJS::AST::Node::accept(node: statement->lhs, visitor: this);
586 addVerbatim(first: statement->inOfToken);
587 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
588 addVerbatim(first: statement->rparenToken);
589 QQmlJS::AST::Node::accept(node: statement->statement, visitor: this);
590 return false;
591}
592
593bool QmlMarkupVisitor::visit(QQmlJS::AST::ContinueStatement *statement)
594{
595 addMarkedUpToken(location&: statement->continueToken, tagName: QLatin1String("keyword"));
596 addMarkedUpToken(location&: statement->identifierToken, tagName: QLatin1String("name"));
597 addVerbatim(first: statement->semicolonToken);
598 return false;
599}
600
601bool QmlMarkupVisitor::visit(QQmlJS::AST::BreakStatement *statement)
602{
603 addMarkedUpToken(location&: statement->breakToken, tagName: QLatin1String("keyword"));
604 addMarkedUpToken(location&: statement->identifierToken, tagName: QLatin1String("name"));
605 addVerbatim(first: statement->semicolonToken);
606 return false;
607}
608
609bool QmlMarkupVisitor::visit(QQmlJS::AST::ReturnStatement *statement)
610{
611 addMarkedUpToken(location&: statement->returnToken, tagName: QLatin1String("keyword"));
612 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
613 addVerbatim(first: statement->semicolonToken);
614 return false;
615}
616
617bool QmlMarkupVisitor::visit(QQmlJS::AST::WithStatement *statement)
618{
619 addMarkedUpToken(location&: statement->withToken, tagName: QLatin1String("keyword"));
620 addVerbatim(first: statement->lparenToken);
621 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
622 addVerbatim(first: statement->rparenToken);
623 QQmlJS::AST::Node::accept(node: statement->statement, visitor: this);
624 return false;
625}
626
627bool QmlMarkupVisitor::visit(QQmlJS::AST::CaseBlock *block)
628{
629 addVerbatim(first: block->lbraceToken);
630 return true;
631}
632
633void QmlMarkupVisitor::endVisit(QQmlJS::AST::CaseBlock *block)
634{
635 addVerbatim(first: block->rbraceToken, last: block->rbraceToken);
636}
637
638bool QmlMarkupVisitor::visit(QQmlJS::AST::SwitchStatement *statement)
639{
640 addMarkedUpToken(location&: statement->switchToken, tagName: QLatin1String("keyword"));
641 addVerbatim(first: statement->lparenToken);
642 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
643 addVerbatim(first: statement->rparenToken);
644 QQmlJS::AST::Node::accept(node: statement->block, visitor: this);
645 return false;
646}
647
648bool QmlMarkupVisitor::visit(QQmlJS::AST::CaseClause *clause)
649{
650 addMarkedUpToken(location&: clause->caseToken, tagName: QLatin1String("keyword"));
651 QQmlJS::AST::Node::accept(node: clause->expression, visitor: this);
652 addVerbatim(first: clause->colonToken);
653 QQmlJS::AST::Node::accept(node: clause->statements, visitor: this);
654 return false;
655}
656
657bool QmlMarkupVisitor::visit(QQmlJS::AST::DefaultClause *clause)
658{
659 addMarkedUpToken(location&: clause->defaultToken, tagName: QLatin1String("keyword"));
660 addVerbatim(first: clause->colonToken, last: clause->colonToken);
661 return true;
662}
663
664bool QmlMarkupVisitor::visit(QQmlJS::AST::LabelledStatement *statement)
665{
666 addMarkedUpToken(location&: statement->identifierToken, tagName: QLatin1String("name"));
667 addVerbatim(first: statement->colonToken);
668 QQmlJS::AST::Node::accept(node: statement->statement, visitor: this);
669 return false;
670}
671
672bool QmlMarkupVisitor::visit(QQmlJS::AST::ThrowStatement *statement)
673{
674 addMarkedUpToken(location&: statement->throwToken, tagName: QLatin1String("keyword"));
675 QQmlJS::AST::Node::accept(node: statement->expression, visitor: this);
676 addVerbatim(first: statement->semicolonToken);
677 return false;
678}
679
680bool QmlMarkupVisitor::visit(QQmlJS::AST::Catch *c)
681{
682 addMarkedUpToken(location&: c->catchToken, tagName: QLatin1String("keyword"));
683 addVerbatim(first: c->lparenToken);
684 addMarkedUpToken(location&: c->identifierToken, tagName: QLatin1String("name"));
685 addVerbatim(first: c->rparenToken);
686 return false;
687}
688
689bool QmlMarkupVisitor::visit(QQmlJS::AST::Finally *f)
690{
691 addMarkedUpToken(location&: f->finallyToken, tagName: QLatin1String("keyword"));
692 QQmlJS::AST::Node::accept(node: f->statement, visitor: this);
693 return false;
694}
695
696bool QmlMarkupVisitor::visit(QQmlJS::AST::TryStatement *statement)
697{
698 addMarkedUpToken(location&: statement->tryToken, tagName: QLatin1String("keyword"));
699 QQmlJS::AST::Node::accept(node: statement->statement, visitor: this);
700 QQmlJS::AST::Node::accept(node: statement->catchExpression, visitor: this);
701 QQmlJS::AST::Node::accept(node: statement->finallyExpression, visitor: this);
702 return false;
703}
704
705bool QmlMarkupVisitor::visit(QQmlJS::AST::FunctionExpression *expression)
706{
707 addMarkedUpToken(location&: expression->functionToken, tagName: QLatin1String("keyword"));
708 addMarkedUpToken(location&: expression->identifierToken, tagName: QLatin1String("name"));
709 addVerbatim(first: expression->lparenToken);
710 QQmlJS::AST::Node::accept(node: expression->formals, visitor: this);
711 addVerbatim(first: expression->rparenToken);
712 addVerbatim(first: expression->lbraceToken);
713 QQmlJS::AST::Node::accept(node: expression->body, visitor: this);
714 addVerbatim(first: expression->rbraceToken);
715 return false;
716}
717
718bool QmlMarkupVisitor::visit(QQmlJS::AST::FunctionDeclaration *declaration)
719{
720 addMarkedUpToken(location&: declaration->functionToken, tagName: QLatin1String("keyword"));
721 addMarkedUpToken(location&: declaration->identifierToken, tagName: QLatin1String("name"));
722 addVerbatim(first: declaration->lparenToken);
723 QQmlJS::AST::Node::accept(node: declaration->formals, visitor: this);
724 addVerbatim(first: declaration->rparenToken);
725 addVerbatim(first: declaration->lbraceToken);
726 QQmlJS::AST::Node::accept(node: declaration->body, visitor: this);
727 addVerbatim(first: declaration->rbraceToken);
728 return false;
729}
730
731bool QmlMarkupVisitor::visit(QQmlJS::AST::FormalParameterList *list)
732{
733 // addVerbatim(list->commaToken);
734 QQmlJS::AST::Node::accept(node: list->element, visitor: this);
735 // addMarkedUpToken(list->identifierToken, QLatin1String("name"));
736 return false;
737}
738
739bool QmlMarkupVisitor::visit(QQmlJS::AST::DebuggerStatement *statement)
740{
741 addVerbatim(first: statement->debuggerToken);
742 addVerbatim(first: statement->semicolonToken);
743 return true;
744}
745
746// Elements and items are represented by UiObjectDefinition nodes.
747
748bool QmlMarkupVisitor::visit(QQmlJS::AST::UiObjectDefinition *definition)
749{
750 addMarkedUpToken(location&: definition->qualifiedTypeNameId->identifierToken, tagName: QLatin1String("type"));
751 QQmlJS::AST::Node::accept(node: definition->initializer, visitor: this);
752 return false;
753}
754
755void QmlMarkupVisitor::throwRecursionDepthError()
756{
757 m_hasRecursionDepthError = true;
758}
759
760QT_END_NAMESPACE
761

source code of qttools/src/qdoc/qdoc/src/qdoc/qmlmarkupvisitor.cpp