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->typeToken, "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->typeToken, "type"_L1);
249 // addVerbatim(member->identifierToken());
250 QQmlJS::AST::Node::accept(member->parameters, this);
251 }
252 addVerbatim(member->semicolonToken);
253 return false;
254}
255
256bool QmlMarkupVisitor::visit(QQmlJS::AST::UiObjectInitializer *initializer)
257{
258 addVerbatim(initializer->lbraceToken, initializer->lbraceToken);
259 return true;
260}
261
262void QmlMarkupVisitor::endVisit(QQmlJS::AST::UiObjectInitializer *initializer)
263{
264 addVerbatim(initializer->rbraceToken, initializer->rbraceToken);
265}
266
267bool QmlMarkupVisitor::visit(QQmlJS::AST::UiObjectBinding *binding)
268{
269 QQmlJS::AST::Node::accept(binding->qualifiedId, this);
270 addVerbatim(binding->colonToken);
271 if (auto fullLocation = getFullyQualifiedLocation(binding->qualifiedTypeNameId))
272 addMarkedUpToken(fullLocation.value(), "type"_L1);
273 else
274 QQmlJS::AST::Node::accept(binding->qualifiedTypeNameId, this);
275
276 QQmlJS::AST::Node::accept(binding->initializer, this);
277 return false;
278}
279
280bool QmlMarkupVisitor::visit(QQmlJS::AST::UiScriptBinding *binding)
281{
282 QQmlJS::AST::Node::accept(binding->qualifiedId, this);
283 addVerbatim(binding->colonToken);
284 QQmlJS::AST::Node::accept(binding->statement, this);
285 return false;
286}
287
288bool QmlMarkupVisitor::visit(QQmlJS::AST::UiArrayBinding *binding)
289{
290 QQmlJS::AST::Node::accept(binding->qualifiedId, this);
291 addVerbatim(binding->colonToken);
292 addVerbatim(binding->lbracketToken);
293 QQmlJS::AST::Node::accept(binding->members, this);
294 addVerbatim(binding->rbracketToken);
295 return false;
296}
297
298bool QmlMarkupVisitor::visit(QQmlJS::AST::UiArrayMemberList *list)
299{
300 for (QQmlJS::AST::UiArrayMemberList *it = list; it; it = it->next) {
301 QQmlJS::AST::Node::accept(it->member, this);
302 // addVerbatim(it->commaToken);
303 }
304 return false;
305}
306
307bool QmlMarkupVisitor::visit(QQmlJS::AST::UiQualifiedId *id)
308{
309 addMarkedUpToken(getLocationForMarkup(id), "name"_L1);
310 return false;
311}
312
313bool QmlMarkupVisitor::visit(QQmlJS::AST::ThisExpression *expression)
314{
315 addVerbatim(expression->thisToken);
316 return true;
317}
318
319bool QmlMarkupVisitor::visit(QQmlJS::AST::IdentifierExpression *identifier)
320{
321 addMarkedUpToken(identifier->identifierToken, "name"_L1);
322 return false;
323}
324
325bool QmlMarkupVisitor::visit(QQmlJS::AST::NullExpression *null)
326{
327 addMarkedUpToken(null->nullToken, "number"_L1);
328 return true;
329}
330
331bool QmlMarkupVisitor::visit(QQmlJS::AST::TrueLiteral *literal)
332{
333 addMarkedUpToken(literal->trueToken, "number"_L1);
334 return true;
335}
336
337bool QmlMarkupVisitor::visit(QQmlJS::AST::FalseLiteral *literal)
338{
339 addMarkedUpToken(literal->falseToken, "number"_L1);
340 return true;
341}
342
343bool QmlMarkupVisitor::visit(QQmlJS::AST::NumericLiteral *literal)
344{
345 addMarkedUpToken(literal->literalToken, "number"_L1);
346 return false;
347}
348
349bool QmlMarkupVisitor::visit(QQmlJS::AST::StringLiteral *literal)
350{
351 addMarkedUpToken(literal->literalToken, "string"_L1);
352 return true;
353}
354
355bool QmlMarkupVisitor::visit(QQmlJS::AST::RegExpLiteral *literal)
356{
357 addVerbatim(literal->literalToken);
358 return true;
359}
360
361bool QmlMarkupVisitor::visit(QQmlJS::AST::ArrayPattern *literal)
362{
363 addVerbatim(literal->lbracketToken);
364 QQmlJS::AST::Node::accept(literal->elements, this);
365 addVerbatim(literal->rbracketToken);
366 return false;
367}
368
369bool QmlMarkupVisitor::visit(QQmlJS::AST::ObjectPattern *literal)
370{
371 addVerbatim(literal->lbraceToken);
372 return true;
373}
374
375void QmlMarkupVisitor::endVisit(QQmlJS::AST::ObjectPattern *literal)
376{
377 addVerbatim(literal->rbraceToken);
378}
379
380bool QmlMarkupVisitor::visit(QQmlJS::AST::PatternElementList *list)
381{
382 for (QQmlJS::AST::PatternElementList *it = list; it; it = it->next) {
383 QQmlJS::AST::Node::accept(it->element, this);
384 // addVerbatim(it->commaToken);
385 }
386 QQmlJS::AST::Node::accept(list->elision, this);
387 return false;
388}
389
390bool QmlMarkupVisitor::visit(QQmlJS::AST::Elision *elision)
391{
392 addVerbatim(elision->commaToken, elision->commaToken);
393 return true;
394}
395
396bool QmlMarkupVisitor::visit(QQmlJS::AST::PatternProperty *list)
397{
398 QQmlJS::AST::Node::accept(list->name, this);
399 addVerbatim(list->colonToken, list->colonToken);
400 QQmlJS::AST::Node::accept(list->initializer, this);
401 // addVerbatim(list->commaToken, list->commaToken);
402 return false;
403}
404
405bool QmlMarkupVisitor::visit(QQmlJS::AST::ArrayMemberExpression *expression)
406{
407 QQmlJS::AST::Node::accept(expression->base, this);
408 addVerbatim(expression->lbracketToken);
409 QQmlJS::AST::Node::accept(expression->expression, this);
410 addVerbatim(expression->rbracketToken);
411 return false;
412}
413
414bool QmlMarkupVisitor::visit(QQmlJS::AST::FieldMemberExpression *expression)
415{
416 QQmlJS::AST::Node::accept(expression->base, this);
417 addVerbatim(expression->dotToken);
418 addMarkedUpToken(expression->identifierToken, "name"_L1);
419 return false;
420}
421
422bool QmlMarkupVisitor::visit(QQmlJS::AST::NewMemberExpression *expression)
423{
424 addVerbatim(expression->newToken);
425 QQmlJS::AST::Node::accept(expression->base, this);
426 addVerbatim(expression->lparenToken);
427 QQmlJS::AST::Node::accept(expression->arguments, this);
428 addVerbatim(expression->rparenToken);
429 return false;
430}
431
432bool QmlMarkupVisitor::visit(QQmlJS::AST::NewExpression *expression)
433{
434 addVerbatim(expression->newToken);
435 return true;
436}
437
438bool QmlMarkupVisitor::visit(QQmlJS::AST::ArgumentList *list)
439{
440 addVerbatim(list->commaToken, list->commaToken);
441 return true;
442}
443
444bool QmlMarkupVisitor::visit(QQmlJS::AST::PostIncrementExpression *expression)
445{
446 addVerbatim(expression->incrementToken);
447 return true;
448}
449
450bool QmlMarkupVisitor::visit(QQmlJS::AST::PostDecrementExpression *expression)
451{
452 addVerbatim(expression->decrementToken);
453 return true;
454}
455
456bool QmlMarkupVisitor::visit(QQmlJS::AST::DeleteExpression *expression)
457{
458 addVerbatim(expression->deleteToken);
459 return true;
460}
461
462bool QmlMarkupVisitor::visit(QQmlJS::AST::VoidExpression *expression)
463{
464 addVerbatim(expression->voidToken);
465 return true;
466}
467
468bool QmlMarkupVisitor::visit(QQmlJS::AST::TypeOfExpression *expression)
469{
470 addVerbatim(expression->typeofToken);
471 return true;
472}
473
474bool QmlMarkupVisitor::visit(QQmlJS::AST::PreIncrementExpression *expression)
475{
476 addVerbatim(expression->incrementToken);
477 return true;
478}
479
480bool QmlMarkupVisitor::visit(QQmlJS::AST::PreDecrementExpression *expression)
481{
482 addVerbatim(expression->decrementToken);
483 return true;
484}
485
486bool QmlMarkupVisitor::visit(QQmlJS::AST::UnaryPlusExpression *expression)
487{
488 addVerbatim(expression->plusToken);
489 return true;
490}
491
492bool QmlMarkupVisitor::visit(QQmlJS::AST::UnaryMinusExpression *expression)
493{
494 addVerbatim(expression->minusToken);
495 return true;
496}
497
498bool QmlMarkupVisitor::visit(QQmlJS::AST::TildeExpression *expression)
499{
500 addVerbatim(expression->tildeToken);
501 return true;
502}
503
504bool QmlMarkupVisitor::visit(QQmlJS::AST::NotExpression *expression)
505{
506 addVerbatim(expression->notToken);
507 return true;
508}
509
510bool QmlMarkupVisitor::visit(QQmlJS::AST::BinaryExpression *expression)
511{
512 QQmlJS::AST::Node::accept(expression->left, this);
513 addMarkedUpToken(expression->operatorToken, "op"_L1);
514 QQmlJS::AST::Node::accept(expression->right, this);
515 return false;
516}
517
518bool QmlMarkupVisitor::visit(QQmlJS::AST::ConditionalExpression *expression)
519{
520 QQmlJS::AST::Node::accept(expression->expression, this);
521 addVerbatim(expression->questionToken);
522 QQmlJS::AST::Node::accept(expression->ok, this);
523 addVerbatim(expression->colonToken);
524 QQmlJS::AST::Node::accept(expression->ko, this);
525 return false;
526}
527
528bool QmlMarkupVisitor::visit(QQmlJS::AST::CommaExpression *expression)
529{
530 QQmlJS::AST::Node::accept(expression->left, this);
531 addVerbatim(expression->commaToken);
532 QQmlJS::AST::Node::accept(expression->right, this);
533 return false;
534}
535
536bool QmlMarkupVisitor::visit(QQmlJS::AST::Block *block)
537{
538 addVerbatim(block->lbraceToken);
539 return true;
540}
541
542void QmlMarkupVisitor::endVisit(QQmlJS::AST::Block *block)
543{
544 addVerbatim(block->rbraceToken);
545}
546
547bool QmlMarkupVisitor::visit(QQmlJS::AST::VariableStatement *statement)
548{
549 addVerbatim(statement->declarationKindToken);
550 QQmlJS::AST::Node::accept(statement->declarations, this);
551 // addVerbatim(statement->semicolonToken);
552 return false;
553}
554
555bool QmlMarkupVisitor::visit(QQmlJS::AST::VariableDeclarationList *list)
556{
557 for (QQmlJS::AST::VariableDeclarationList *it = list; it; it = it->next) {
558 QQmlJS::AST::Node::accept(it->declaration, this);
559 addVerbatim(it->commaToken);
560 }
561 return false;
562}
563
564bool QmlMarkupVisitor::visit(QQmlJS::AST::EmptyStatement *statement)
565{
566 addVerbatim(statement->semicolonToken);
567 return true;
568}
569
570bool QmlMarkupVisitor::visit(QQmlJS::AST::ExpressionStatement *statement)
571{
572 QQmlJS::AST::Node::accept(statement->expression, this);
573 addVerbatim(statement->semicolonToken);
574 return false;
575}
576
577bool QmlMarkupVisitor::visit(QQmlJS::AST::IfStatement *statement)
578{
579 addMarkedUpToken(statement->ifToken, "keyword"_L1);
580 addVerbatim(statement->lparenToken);
581 QQmlJS::AST::Node::accept(statement->expression, this);
582 addVerbatim(statement->rparenToken);
583 QQmlJS::AST::Node::accept(statement->ok, this);
584 if (statement->ko) {
585 addMarkedUpToken(statement->elseToken, "keyword"_L1);
586 QQmlJS::AST::Node::accept(statement->ko, this);
587 }
588 return false;
589}
590
591bool QmlMarkupVisitor::visit(QQmlJS::AST::DoWhileStatement *statement)
592{
593 addMarkedUpToken(statement->doToken, "keyword"_L1);
594 QQmlJS::AST::Node::accept(statement->statement, this);
595 addMarkedUpToken(statement->whileToken, "keyword"_L1);
596 addVerbatim(statement->lparenToken);
597 QQmlJS::AST::Node::accept(statement->expression, this);
598 addVerbatim(statement->rparenToken);
599 addVerbatim(statement->semicolonToken);
600 return false;
601}
602
603bool QmlMarkupVisitor::visit(QQmlJS::AST::WhileStatement *statement)
604{
605 addMarkedUpToken(statement->whileToken, "keyword"_L1);
606 addVerbatim(statement->lparenToken);
607 QQmlJS::AST::Node::accept(statement->expression, this);
608 addVerbatim(statement->rparenToken);
609 QQmlJS::AST::Node::accept(statement->statement, this);
610 return false;
611}
612
613bool QmlMarkupVisitor::visit(QQmlJS::AST::ForStatement *statement)
614{
615 addMarkedUpToken(statement->forToken, "keyword"_L1);
616 addVerbatim(statement->lparenToken);
617 QQmlJS::AST::Node::accept(statement->initialiser, this);
618 addVerbatim(statement->firstSemicolonToken);
619 QQmlJS::AST::Node::accept(statement->condition, this);
620 addVerbatim(statement->secondSemicolonToken);
621 QQmlJS::AST::Node::accept(statement->expression, this);
622 addVerbatim(statement->rparenToken);
623 QQmlJS::AST::Node::accept(statement->statement, this);
624 return false;
625}
626
627bool QmlMarkupVisitor::visit(QQmlJS::AST::ForEachStatement *statement)
628{
629 addMarkedUpToken(statement->forToken, "keyword"_L1);
630 addVerbatim(statement->lparenToken);
631 QQmlJS::AST::Node::accept(statement->lhs, this);
632 addVerbatim(statement->inOfToken);
633 QQmlJS::AST::Node::accept(statement->expression, this);
634 addVerbatim(statement->rparenToken);
635 QQmlJS::AST::Node::accept(statement->statement, this);
636 return false;
637}
638
639bool QmlMarkupVisitor::visit(QQmlJS::AST::ContinueStatement *statement)
640{
641 addMarkedUpToken(statement->continueToken, "keyword"_L1);
642 addMarkedUpToken(statement->identifierToken, "name"_L1);
643 addVerbatim(statement->semicolonToken);
644 return false;
645}
646
647bool QmlMarkupVisitor::visit(QQmlJS::AST::BreakStatement *statement)
648{
649 addMarkedUpToken(statement->breakToken, "keyword"_L1);
650 addMarkedUpToken(statement->identifierToken, "name"_L1);
651 addVerbatim(statement->semicolonToken);
652 return false;
653}
654
655bool QmlMarkupVisitor::visit(QQmlJS::AST::ReturnStatement *statement)
656{
657 addMarkedUpToken(statement->returnToken, "keyword"_L1);
658 QQmlJS::AST::Node::accept(statement->expression, this);
659 addVerbatim(statement->semicolonToken);
660 return false;
661}
662
663bool QmlMarkupVisitor::visit(QQmlJS::AST::WithStatement *statement)
664{
665 addMarkedUpToken(statement->withToken, "keyword"_L1);
666 addVerbatim(statement->lparenToken);
667 QQmlJS::AST::Node::accept(statement->expression, this);
668 addVerbatim(statement->rparenToken);
669 QQmlJS::AST::Node::accept(statement->statement, this);
670 return false;
671}
672
673bool QmlMarkupVisitor::visit(QQmlJS::AST::CaseBlock *block)
674{
675 addVerbatim(block->lbraceToken);
676 return true;
677}
678
679void QmlMarkupVisitor::endVisit(QQmlJS::AST::CaseBlock *block)
680{
681 addVerbatim(block->rbraceToken, block->rbraceToken);
682}
683
684bool QmlMarkupVisitor::visit(QQmlJS::AST::SwitchStatement *statement)
685{
686 addMarkedUpToken(statement->switchToken, "keyword"_L1);
687 addVerbatim(statement->lparenToken);
688 QQmlJS::AST::Node::accept(statement->expression, this);
689 addVerbatim(statement->rparenToken);
690 QQmlJS::AST::Node::accept(statement->block, this);
691 return false;
692}
693
694bool QmlMarkupVisitor::visit(QQmlJS::AST::CaseClause *clause)
695{
696 addMarkedUpToken(clause->caseToken, "keyword"_L1);
697 QQmlJS::AST::Node::accept(clause->expression, this);
698 addVerbatim(clause->colonToken);
699 QQmlJS::AST::Node::accept(clause->statements, this);
700 return false;
701}
702
703bool QmlMarkupVisitor::visit(QQmlJS::AST::DefaultClause *clause)
704{
705 addMarkedUpToken(clause->defaultToken, "keyword"_L1);
706 addVerbatim(clause->colonToken, clause->colonToken);
707 return true;
708}
709
710bool QmlMarkupVisitor::visit(QQmlJS::AST::LabelledStatement *statement)
711{
712 addMarkedUpToken(statement->identifierToken, "name"_L1);
713 addVerbatim(statement->colonToken);
714 QQmlJS::AST::Node::accept(statement->statement, this);
715 return false;
716}
717
718bool QmlMarkupVisitor::visit(QQmlJS::AST::ThrowStatement *statement)
719{
720 addMarkedUpToken(statement->throwToken, "keyword"_L1);
721 QQmlJS::AST::Node::accept(statement->expression, this);
722 addVerbatim(statement->semicolonToken);
723 return false;
724}
725
726bool QmlMarkupVisitor::visit(QQmlJS::AST::Catch *c)
727{
728 addMarkedUpToken(c->catchToken, "keyword"_L1);
729 addVerbatim(c->lparenToken);
730 addMarkedUpToken(c->identifierToken, "name"_L1);
731 addVerbatim(c->rparenToken);
732 return false;
733}
734
735bool QmlMarkupVisitor::visit(QQmlJS::AST::Finally *f)
736{
737 addMarkedUpToken(f->finallyToken, "keyword"_L1);
738 QQmlJS::AST::Node::accept(f->statement, this);
739 return false;
740}
741
742bool QmlMarkupVisitor::visit(QQmlJS::AST::TryStatement *statement)
743{
744 addMarkedUpToken(statement->tryToken, "keyword"_L1);
745 QQmlJS::AST::Node::accept(statement->statement, this);
746 QQmlJS::AST::Node::accept(statement->catchExpression, this);
747 QQmlJS::AST::Node::accept(statement->finallyExpression, this);
748 return false;
749}
750
751bool QmlMarkupVisitor::visit(QQmlJS::AST::FunctionExpression *expression)
752{
753 addMarkedUpToken(expression->functionToken, "keyword"_L1);
754 addMarkedUpToken(expression->identifierToken, "name"_L1);
755 addVerbatim(expression->lparenToken);
756 QQmlJS::AST::Node::accept(expression->formals, this);
757 addVerbatim(expression->rparenToken);
758 addVerbatim(expression->lbraceToken);
759 QQmlJS::AST::Node::accept(expression->body, this);
760 addVerbatim(expression->rbraceToken);
761 return false;
762}
763
764bool QmlMarkupVisitor::visit(QQmlJS::AST::FunctionDeclaration *declaration)
765{
766 addMarkedUpToken(declaration->functionToken, "keyword"_L1);
767 addMarkedUpToken(declaration->identifierToken, "name"_L1);
768 addVerbatim(declaration->lparenToken);
769 QQmlJS::AST::Node::accept(declaration->formals, this);
770 addVerbatim(declaration->rparenToken);
771 addVerbatim(declaration->lbraceToken);
772 QQmlJS::AST::Node::accept(declaration->body, this);
773 addVerbatim(declaration->rbraceToken);
774 return false;
775}
776
777bool QmlMarkupVisitor::visit(QQmlJS::AST::FormalParameterList *list)
778{
779 QQmlJS::AST::Node::accept(list->element, this);
780 return false;
781}
782
783bool QmlMarkupVisitor::visit(QQmlJS::AST::DebuggerStatement *statement)
784{
785 addVerbatim(statement->debuggerToken);
786 addVerbatim(statement->semicolonToken);
787 return true;
788}
789
790// Elements and items are represented by UiObjectDefinition nodes.
791
792bool QmlMarkupVisitor::visit(QQmlJS::AST::UiObjectDefinition *definition)
793{
794 if (auto fullLocation = getFullyQualifiedLocation(definition->qualifiedTypeNameId))
795 addMarkedUpToken(fullLocation.value(), "type"_L1);
796 else
797 QQmlJS::AST::Node::accept(definition->qualifiedTypeNameId, this);
798
799 QQmlJS::AST::Node::accept(definition->initializer, this);
800 return false;
801}
802
804{
805 m_hasRecursionDepthError = true;
806}
807
808QT_END_NAMESPACE
void throwRecursionDepthError() final
void endVisit(QQmlJS::AST::UiImport *) override
bool visit(QQmlJS::AST::UiImport *) override