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