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