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