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