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