Qt 4.8
qdeclarativerewrite.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtDeclarative module 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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "private/qdeclarativerewrite_p.h"
43 
44 #include "private/qdeclarativeglobal_p.h"
45 
46 #include <QtCore/qdebug.h>
47 
49 
50 DEFINE_BOOL_CONFIG_OPTION(rewriteDump, QML_REWRITE_DUMP);
51 
53 
55 {
56  Engine engine;
57  NodePool pool(QString(), &engine);
58  Lexer lexer(&engine);
59  Parser parser(&engine);
60  lexer.setCode(code, 0);
61  parser.parseStatement();
62  if (!parser.statement())
63  return false;
64 
65  return isSharable(parser.statement());
66 }
67 
69 {
70  _sharable = true;
71  AST::Node::acceptChild(node, this);
72  return _sharable;
73 }
74 
75 QString RewriteBinding::operator()(const QString &code, bool *ok, bool *sharable)
76 {
77  Engine engine;
78  NodePool pool(QString(), &engine);
79  Lexer lexer(&engine);
80  Parser parser(&engine);
81  lexer.setCode(code, 0);
82  parser.parseStatement();
83  if (!parser.statement()) {
84  if (ok) *ok = false;
85  return QString();
86  } else {
87  if (ok) *ok = true;
88  if (sharable) {
89  SharedBindingTester tester;
90  *sharable = tester.isSharable(parser.statement());
91  }
92  }
93  return rewrite(code, 0, parser.statement());
94 }
95 
97 {
98  if (!node)
99  return code;
100 
101  if (sharable) {
102  SharedBindingTester tester;
103  *sharable = tester.isSharable(node);
104  }
105 
107  QDeclarativeJS::AST::Statement *statement = node->statementCast();
108  if(!expression && !statement)
109  return code;
110 
111  TextWriter w;
112  _writer = &w;
113  _position = expression ? expression->firstSourceLocation().begin() : statement->firstSourceLocation().begin();
114  _inLoop = 0;
115 
116  accept(node);
117 
118  unsigned startOfStatement = 0;
119  unsigned endOfStatement = (expression ? expression->lastSourceLocation().end() : statement->lastSourceLocation().end()) - _position;
120 
121  QString startString = QLatin1String("(function ") + QString::fromUtf8(_name) + QLatin1String("() { ");
122  if (expression)
123  startString += QLatin1String("return ");
124  _writer->replace(startOfStatement, 0, startString);
125  _writer->replace(endOfStatement, 0, QLatin1String(" })"));
126 
127  if (rewriteDump()) {
128  qWarning() << "=============================================================";
129  qWarning() << "Rewrote:";
130  qWarning() << qPrintable(code);
131  }
132 
133  QString codeCopy = code;
134  w.write(&codeCopy);
135 
136  if (rewriteDump()) {
137  qWarning() << "To:";
138  qWarning() << qPrintable(code);
139  qWarning() << "=============================================================";
140  }
141 
142  return codeCopy;
143 }
144 
146 {
147  AST::Node::acceptChild(node, this);
148 }
149 
151  AST::Statement *node)
152 {
153  TextWriter w;
154  _writer = &w;
155  _position = position;
156  _inLoop = 0;
157 
158  accept(node);
159 
160  unsigned startOfStatement = node->firstSourceLocation().begin() - _position;
161  unsigned endOfStatement = node->lastSourceLocation().end() - _position;
162 
163  _writer->replace(startOfStatement, 0, QLatin1String("(function ") + QString::fromUtf8(_name) + QLatin1String("() { "));
164  _writer->replace(endOfStatement, 0, QLatin1String(" })"));
165 
166  if (rewriteDump()) {
167  qWarning() << "=============================================================";
168  qWarning() << "Rewrote:";
169  qWarning() << qPrintable(code);
170  }
171 
172  w.write(&code);
173 
174  if (rewriteDump()) {
175  qWarning() << "To:";
176  qWarning() << qPrintable(code);
177  qWarning() << "=============================================================";
178  }
179 
180  return code;
181 }
182 
184 {
185  for (AST::StatementList *it = ast->statements; it; it = it->next) {
186  if (! it->next) {
187  // we need to rewrite only the last statement of a block.
188  accept(it->statement);
189  }
190  }
191 
192  return false;
193 }
194 
196 {
197  if (! _inLoop) {
198  unsigned startOfExpressionStatement = ast->firstSourceLocation().begin() - _position;
199  _writer->replace(startOfExpressionStatement, 0, QLatin1String("return "));
200  }
201 
202  return false;
203 }
204 
206 {
207  ++_inLoop;
208  return true;
209 }
210 
212 {
213  --_inLoop;
214 }
215 
217 {
218  ++_inLoop;
219  return true;
220 }
221 
223 {
224  --_inLoop;
225 }
226 
228 {
229  ++_inLoop;
230  return true;
231 }
232 
234 {
235  --_inLoop;
236 }
237 
239 {
240  ++_inLoop;
241  return true;
242 }
243 
245 {
246  --_inLoop;
247 }
248 
250 {
251  ++_inLoop;
252  return true;
253 }
254 
256 {
257  --_inLoop;
258 }
259 
261 {
262  ++_inLoop;
263  return true;
264 }
265 
267 {
268  --_inLoop;
269 }
270 
271 } // namespace QDeclarativeRewrite
272 
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
#define it(className, varName)
DEFINE_BOOL_CONFIG_OPTION(rewriteDump, QML_REWRITE_DUMP)
void write(QString *s)
Definition: textwriter.cpp:179
virtual SourceLocation firstSourceLocation() const =0
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
virtual Statement * statementCast()
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
The QString class provides a Unicode character string.
Definition: qstring.h:83
AST::Statement * statement() const
virtual SourceLocation lastSourceLocation() const =0
virtual SourceLocation firstSourceLocation() const =0
QString rewrite(QString code, unsigned position, AST::Statement *node)
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
virtual SourceLocation lastSourceLocation() const =0
static QString fromUtf8(const char *, int size=-1)
Returns a QString initialized with the first size bytes of the UTF-8 string str.
Definition: qstring.cpp:4302
Q_CORE_EXPORT void qWarning(const char *,...)
virtual bool visit(AST::Block *ast)
virtual ExpressionNode * expressionCast()
QString operator()(const QString &code, bool *ok=0, bool *sharable=0)
virtual void endVisit(AST::DoWhileStatement *ast)
#define qPrintable(string)
Definition: qglobal.h:1750
virtual SourceLocation firstSourceLocation() const
void setCode(const QString &c, int lineno)