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