Add QFastMetaBuilder
[profile/ivi/qtdeclarative.git] / src / declarative / qml / qdeclarativeparser.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 #include "private/qdeclarativeparser_p.h"
43
44 #include "qdeclarativepropertyvaluesource.h"
45 #include "private/qdeclarativevme_p.h"
46 #include "qdeclarative.h"
47 #include "private/qdeclarativecomponent_p.h"
48 #include "qdeclarativecomponent.h"
49 #include "private/qmetaobjectbuilder_p.h"
50 #include "private/qdeclarativevmemetaobject_p.h"
51 #include "private/qdeclarativecompiler_p.h"
52 #include "parser/qdeclarativejsast_p.h"
53 #include "parser/qdeclarativejsengine_p.h"
54
55 #include <QStack>
56 #include <QColor>
57 #include <QPointF>
58 #include <QSizeF>
59 #include <QRectF>
60 #include <QStringBuilder>
61 #include <QtDebug>
62
63 QT_BEGIN_NAMESPACE
64
65 using namespace QDeclarativeJS;
66 using namespace QDeclarativeParser;
67
68 QDeclarativeParser::Object::Object()
69 : type(-1), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1),
70   componentCompileState(0), nextAliasingObject(0), nextIdObject(0)
71 {
72 }
73
74 QDeclarativeParser::Object::~Object() 
75
76     if (synthCache) synthCache->release();
77 }
78
79 void Object::setBindingBit(int b)
80 {
81     while (bindingBitmask.size() < 4 * (1 + b / 32))
82         bindingBitmask.append(char(0));
83
84     quint32 *bits = (quint32 *)bindingBitmask.data();
85     bits[b / 32] |= (1 << (b % 32));
86 }
87
88 const QMetaObject *Object::metaObject() const
89 {
90     if (!metadata.isEmpty() && metatype)
91         return &extObject;
92     else
93         return metatype;
94 }
95
96 QDeclarativeParser::Property *Object::getDefaultProperty()
97 {
98     if (!defaultProperty) {
99         defaultProperty = pool()->New<Property>();
100         defaultProperty->parent = this;
101     }
102     return defaultProperty;
103 }
104
105 void QDeclarativeParser::Object::addValueProperty(Property *p)
106 {
107     valueProperties.append(p);
108 }
109
110 void QDeclarativeParser::Object::addSignalProperty(Property *p)
111 {
112     signalProperties.append(p);
113 }
114
115 void QDeclarativeParser::Object::addAttachedProperty(Property *p)
116 {
117     attachedProperties.append(p);
118 }
119
120 void QDeclarativeParser::Object::addGroupedProperty(Property *p)
121 {
122     groupedProperties.append(p);
123 }
124
125 void QDeclarativeParser::Object::addValueTypeProperty(Property *p)
126 {
127     valueTypeProperties.append(p);
128 }
129
130 void QDeclarativeParser::Object::addScriptStringProperty(Property *p)
131 {
132     scriptStringProperties.append(p);
133 }
134
135 Property *QDeclarativeParser::Object::getProperty(const QStringRef &name, bool create)
136 {
137     for (Property *p = properties.first(); p; p = properties.next(p)) {
138         if (p->name() == name)
139             return p;
140     }
141
142     if (create) {
143         Property *property = pool()->New<Property>();
144         property->parent = this;
145         property->_name = name;
146         property->isDefault = false;
147         properties.prepend(property);
148         return property;
149     } else {
150         return 0;
151     }
152 }
153
154 Property *QDeclarativeParser::Object::getProperty(const QString &name, bool create)
155 {
156     for (Property *p = properties.first(); p; p = properties.next(p)) {
157         if (p->name() == name)
158             return p;
159     }
160
161     if (create) {
162         Property *property = pool()->New<Property>();
163         property->parent = this;
164         property->_name = QStringRef(pool()->NewString(name));
165         property->isDefault = false;
166         properties.prepend(property);
167         return property;
168     } else {
169         return 0;
170     }
171 }
172
173 QDeclarativeParser::Object::DynamicProperty::DynamicProperty()
174 : isDefaultProperty(false), type(Variant), defaultValue(0)
175 {
176 }
177
178 QDeclarativeParser::Object::DynamicProperty::DynamicProperty(const DynamicProperty &o)
179 : isDefaultProperty(o.isDefaultProperty),
180   type(o.type),
181   customType(o.customType),
182   name(o.name),
183   defaultValue(o.defaultValue),
184   location(o.location)
185 {
186 }
187
188 QDeclarativeParser::Object::DynamicSignal::DynamicSignal()
189 {
190 }
191
192 QDeclarativeParser::Object::DynamicSignal::DynamicSignal(const DynamicSignal &o)
193 : name(o.name), parameterTypes(o.parameterTypes), 
194   parameterNames(o.parameterNames), location(o.location)
195 {
196 }
197
198 int QDeclarativeParser::Object::DynamicSignal::parameterTypesLength() const
199 {
200     int rv = 0;
201     for (int ii = 0; ii < parameterTypes.count(); ++ii)
202         rv += parameterTypes.at(ii).length();
203     return rv;
204 }
205
206 int QDeclarativeParser::Object::DynamicSignal::parameterNamesLength() const
207 {
208     int rv = 0;
209     for (int ii = 0; ii < parameterNames.count(); ++ii)
210         rv += parameterNames.at(ii).length();
211     return rv;
212 }
213
214 QDeclarativeParser::Object::DynamicSlot::DynamicSlot()
215 {
216 }
217
218 QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
219 : name(o.name), body(o.body), parameterNames(o.parameterNames), location(o.location)
220 {
221 }
222
223 int QDeclarativeParser::Object::DynamicSlot::parameterNamesLength() const
224 {
225     int rv = 0;
226     for (int ii = 0; ii < parameterNames.count(); ++ii)
227         rv += parameterNames.at(ii).length();
228     return rv;
229 }
230
231 QDeclarativeParser::Property::Property()
232 : parent(0), type(0), index(-1), value(0), _name(0), isDefault(true), isDeferred(false), 
233   isValueTypeSubProperty(false), isAlias(false), scriptStringScope(-1), nextProperty(0), 
234   nextMainProperty(0)
235 {
236 }
237
238 QDeclarativeParser::Object *QDeclarativeParser::Property::getValue(const LocationSpan &l)
239 {
240     if (!value) { value = pool()->New<Object>(); value->location = l; }
241     return value;
242 }
243
244 void QDeclarativeParser::Property::addValue(Value *v)
245 {
246     values.append(v);
247 }
248
249 void QDeclarativeParser::Property::addOnValue(Value *v)
250 {
251     onValues.append(v);
252 }
253
254 bool QDeclarativeParser::Property::isEmpty() const
255 {
256     return !value && values.isEmpty() && onValues.isEmpty();
257 }
258
259 QDeclarativeParser::Value::Value()
260 : type(Unknown), object(0), bindingReference(0), signalExpressionContextStack(0), nextValue(0)
261 {
262 }
263
264 QDeclarativeParser::Variant::Variant()
265 : t(Invalid)
266 {
267 }
268
269 QDeclarativeParser::Variant::Variant(const Variant &o)
270 : t(o.t), d(o.d), asWritten(o.asWritten)
271 {
272 }
273
274 QDeclarativeParser::Variant::Variant(bool v)
275 : t(Boolean), b(v)
276 {
277 }
278
279 QDeclarativeParser::Variant::Variant(double v, const QStringRef &asWritten)
280 : t(Number), d(v), asWritten(asWritten)
281 {
282 }
283
284 QDeclarativeParser::Variant::Variant(QDeclarativeJS::AST::StringLiteral *v)
285 : t(String), l(v)
286 {
287 }
288
289 QDeclarativeParser::Variant::Variant(const QStringRef &asWritten, QDeclarativeJS::AST::Node *n)
290 : t(Script), n(n), asWritten(asWritten)
291 {
292 }
293
294 QDeclarativeParser::Variant &QDeclarativeParser::Variant::operator=(const Variant &o)
295 {
296     t = o.t;
297     d = o.d;
298     asWritten = o.asWritten;
299     return *this;
300 }
301
302 QDeclarativeParser::Variant::Type QDeclarativeParser::Variant::type() const
303 {
304     return t;
305 }
306
307 bool QDeclarativeParser::Variant::asBoolean() const
308 {
309     return b;
310 }
311
312 QString QDeclarativeParser::Variant::asString() const
313 {
314     if (t == String) {
315         // XXX aakenned
316         return l->value.toString();
317     } else {
318         return asWritten.toString();
319     }
320 }
321
322 double QDeclarativeParser::Variant::asNumber() const
323 {
324     return d;
325 }
326
327 //reverse of Lexer::singleEscape()
328 QString escapedString(const QString &string)
329 {
330     QString tmp = QLatin1String("\"");
331     for (int i = 0; i < string.length(); ++i) {
332         const QChar &c = string.at(i);
333         switch(c.unicode()) {
334         case 0x08:
335             tmp += QLatin1String("\\b");
336             break;
337         case 0x09:
338             tmp += QLatin1String("\\t");
339             break;
340         case 0x0A:
341             tmp += QLatin1String("\\n");
342             break;
343         case 0x0B:
344             tmp += QLatin1String("\\v");
345             break;
346         case 0x0C:
347             tmp += QLatin1String("\\f");
348             break;
349         case 0x0D:
350             tmp += QLatin1String("\\r");
351             break;
352         case 0x22:
353             tmp += QLatin1String("\\\"");
354             break;
355         case 0x27:
356             tmp += QLatin1String("\\\'");
357             break;
358         case 0x5C:
359             tmp += QLatin1String("\\\\");
360             break;
361         default:
362             tmp += c;
363             break;
364         }
365     }
366     tmp += QLatin1Char('\"');
367     return tmp;
368 }
369
370 QString QDeclarativeParser::Variant::asScript() const
371 {
372     switch(type()) { 
373     default:
374     case Invalid:
375         return QString();
376     case Boolean:
377         return b?QLatin1String("true"):QLatin1String("false");
378     case Number:
379         if (asWritten.isEmpty())
380             return QString::number(d);
381         else 
382             return asWritten.toString();
383     case String:
384         return escapedString(asString());
385     case Script:
386         if (AST::IdentifierExpression *i = AST::cast<AST::IdentifierExpression *>(n)) {
387             // XXX aakenned
388             return i->name.toString();
389         } else
390             return asWritten.toString();
391     }
392 }
393
394 QDeclarativeJS::AST::Node *QDeclarativeParser::Variant::asAST() const
395 {
396     if (type() == Script)
397         return n;
398     else
399         return 0;
400 }
401
402 bool QDeclarativeParser::Variant::isStringList() const
403 {
404     if (isString())
405         return true;
406
407     if (type() != Script || !n)
408         return false;
409
410     AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
411     if (!array)
412         return false;
413
414     AST::ElementList *elements = array->elements;
415
416     while (elements) {
417
418         if (!AST::cast<AST::StringLiteral *>(elements->expression))
419             return false;
420
421         elements = elements->next;
422     }
423
424     return true;
425 }
426
427 QStringList QDeclarativeParser::Variant::asStringList() const
428 {
429     QStringList rv;
430     if (isString()) {
431         rv << asString();
432         return rv;
433     }
434
435     AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
436     if (!array)
437         return rv;
438
439     AST::ElementList *elements = array->elements;
440     while (elements) {
441
442         AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(elements->expression);
443         if (!string)
444             return QStringList();
445         rv.append(string->value.toString());
446
447         elements = elements->next;
448     }
449
450     return  rv;
451 }
452
453 QT_END_NAMESPACE