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

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