Initial import from the monolithic Qt.
[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 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
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), majorVersion(-1), minorVersion(-1), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1)
70 {
71 }
72
73 QDeclarativeParser::Object::~Object() 
74
75     if (defaultProperty) defaultProperty->release();
76     if (synthCache) synthCache->release();
77     foreach(Property *prop, properties)
78         prop->release();
79     foreach(Property *prop, valueProperties)
80         prop->release();
81     foreach(Property *prop, signalProperties)
82         prop->release();
83     foreach(Property *prop, attachedProperties)
84         prop->release();
85     foreach(Property *prop, groupedProperties)
86         prop->release();
87     foreach(Property *prop, valueTypeProperties)
88         prop->release();
89     typedef QPair<Property *, int> PropPair;
90     foreach(const PropPair &prop, scriptStringProperties)
91         prop.first->release();
92     foreach(const DynamicProperty &prop, dynamicProperties)
93         if (prop.defaultValue) prop.defaultValue->release();
94 }
95
96 void Object::setBindingBit(int b)
97 {
98     while (bindingBitmask.size() < 4 * (1 + b / 32))
99         bindingBitmask.append(char(0));
100
101     quint32 *bits = (quint32 *)bindingBitmask.data();
102     bits[b / 32] |= (1 << (b % 32));
103 }
104
105 const QMetaObject *Object::metaObject() const
106 {
107     if (!metadata.isEmpty() && metatype)
108         return &extObject;
109     else
110         return metatype;
111 }
112
113 QDeclarativeParser::Property *Object::getDefaultProperty()
114 {
115     if (!defaultProperty) {
116         defaultProperty = new Property;
117         defaultProperty->parent = this;
118     }
119     return defaultProperty;
120 }
121
122 void QDeclarativeParser::Object::addValueProperty(Property *p)
123 {
124     p->addref();
125     valueProperties << p;
126 }
127
128 void QDeclarativeParser::Object::addSignalProperty(Property *p)
129 {
130     p->addref();
131     signalProperties << p;
132 }
133
134 void QDeclarativeParser::Object::addAttachedProperty(Property *p)
135 {
136     p->addref();
137     attachedProperties << p;
138 }
139
140 void QDeclarativeParser::Object::addGroupedProperty(Property *p)
141 {
142     p->addref();
143     groupedProperties << p;
144 }
145
146 void QDeclarativeParser::Object::addValueTypeProperty(Property *p)
147 {
148     p->addref();
149     valueTypeProperties << p;
150 }
151
152 void QDeclarativeParser::Object::addScriptStringProperty(Property *p, int stack)
153 {
154     p->addref();
155     scriptStringProperties << qMakePair(p, stack);
156 }
157
158
159 Property *QDeclarativeParser::Object::getProperty(const QByteArray &name, bool create)
160 {
161     if (!properties.contains(name)) {
162         if (create) {
163             Property *property = new Property(name);
164             property->parent = this;
165             properties.insert(name, property);
166         } else {
167             return 0;
168         }
169     }
170     return properties[name];
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)
195 {
196 }
197
198 QDeclarativeParser::Object::DynamicSlot::DynamicSlot()
199 {
200 }
201
202 QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
203 : name(o.name), body(o.body), parameterNames(o.parameterNames), location(o.location)
204 {
205 }
206
207 QDeclarativeParser::Property::Property()
208 : parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false), 
209   isValueTypeSubProperty(false), isAlias(false)
210 {
211 }
212
213 QDeclarativeParser::Property::Property(const QByteArray &n)
214 : parent(0), type(0), index(-1), value(0), name(n), isDefault(false), 
215   isDeferred(false), isValueTypeSubProperty(false), isAlias(false)
216 {
217 }
218
219 QDeclarativeParser::Property::~Property() 
220
221     foreach(Value *value, values)
222         value->release();
223     foreach(Value *value, onValues)
224         value->release();
225     if (value) value->release(); 
226 }
227
228 QDeclarativeParser::Object *QDeclarativeParser::Property::getValue(const LocationSpan &l)
229 {
230     if (!value) { value = new QDeclarativeParser::Object; value->location = l; }
231     return value;
232 }
233
234 void QDeclarativeParser::Property::addValue(Value *v)
235 {
236     values << v;
237 }
238
239 void QDeclarativeParser::Property::addOnValue(Value *v)
240 {
241     onValues << v;
242 }
243
244 bool QDeclarativeParser::Property::isEmpty() const
245 {
246     return !value && values.isEmpty() && onValues.isEmpty();
247 }
248
249 QDeclarativeParser::Value::Value()
250 : type(Unknown), object(0)
251 {
252 }
253
254 QDeclarativeParser::Value::~Value() 
255
256     if (object) object->release();
257 }
258
259 QDeclarativeParser::Variant::Variant()
260 : t(Invalid) {}
261
262 QDeclarativeParser::Variant::Variant(const Variant &o)
263 : t(o.t), d(o.d), s(o.s)
264 {
265 }
266
267 QDeclarativeParser::Variant::Variant(bool v)
268 : t(Boolean), b(v)
269 {
270 }
271
272 QDeclarativeParser::Variant::Variant(double v, const QString &asWritten)
273 : t(Number), d(v), s(asWritten)
274 {
275 }
276
277 QDeclarativeParser::Variant::Variant(const QString &v)
278 : t(String), s(v)
279 {
280 }
281
282 QDeclarativeParser::Variant::Variant(const QString &v, QDeclarativeJS::AST::Node *n)
283 : t(Script), n(n), s(v)
284 {
285 }
286
287 QDeclarativeParser::Variant &QDeclarativeParser::Variant::operator=(const Variant &o)
288 {
289     t = o.t;
290     d = o.d;
291     s = o.s;
292     return *this;
293 }
294
295 QDeclarativeParser::Variant::Type QDeclarativeParser::Variant::type() const
296 {
297     return t;
298 }
299
300 bool QDeclarativeParser::Variant::asBoolean() const
301 {
302     return b;
303 }
304
305 QString QDeclarativeParser::Variant::asString() const
306 {
307     return s;
308 }
309
310 double QDeclarativeParser::Variant::asNumber() const
311 {
312     return d;
313 }
314
315 //reverse of Lexer::singleEscape()
316 QString escapedString(const QString &string)
317 {
318     QString tmp = QLatin1String("\"");
319     for (int i = 0; i < string.length(); ++i) {
320         const QChar &c = string.at(i);
321         switch(c.unicode()) {
322         case 0x08:
323             tmp += QLatin1String("\\b");
324             break;
325         case 0x09:
326             tmp += QLatin1String("\\t");
327             break;
328         case 0x0A:
329             tmp += QLatin1String("\\n");
330             break;
331         case 0x0B:
332             tmp += QLatin1String("\\v");
333             break;
334         case 0x0C:
335             tmp += QLatin1String("\\f");
336             break;
337         case 0x0D:
338             tmp += QLatin1String("\\r");
339             break;
340         case 0x22:
341             tmp += QLatin1String("\\\"");
342             break;
343         case 0x27:
344             tmp += QLatin1String("\\\'");
345             break;
346         case 0x5C:
347             tmp += QLatin1String("\\\\");
348             break;
349         default:
350             tmp += c;
351             break;
352         }
353     }
354     tmp += QLatin1Char('\"');
355     return tmp;
356 }
357
358 QString QDeclarativeParser::Variant::asScript() const
359 {
360     switch(type()) { 
361     default:
362     case Invalid:
363         return QString();
364     case Boolean:
365         return b?QLatin1String("true"):QLatin1String("false");
366     case Number:
367         if (s.isEmpty())
368             return QString::number(d);
369         else
370             return s;
371     case String:
372         return escapedString(s);
373     case Script:
374         return s;
375     }
376 }
377
378 QDeclarativeJS::AST::Node *QDeclarativeParser::Variant::asAST() const
379 {
380     if (type() == Script)
381         return n;
382     else
383         return 0;
384 }
385
386 bool QDeclarativeParser::Variant::isStringList() const
387 {
388     if (isString())
389         return true;
390
391     if (type() != Script || !n)
392         return false;
393
394     AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
395     if (!array)
396         return false;
397
398     AST::ElementList *elements = array->elements;
399
400     while (elements) {
401
402         if (!AST::cast<AST::StringLiteral *>(elements->expression))
403             return false;
404
405         elements = elements->next;
406     }
407
408     return true;
409 }
410
411 QStringList QDeclarativeParser::Variant::asStringList() const
412 {
413     QStringList rv;
414     if (isString()) {
415         rv << asString();
416         return rv;
417     }
418
419     AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
420     if (!array)
421         return rv;
422
423     AST::ElementList *elements = array->elements;
424     while (elements) {
425
426         AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(elements->expression);
427         if (!string)
428             return QStringList();
429         rv.append(string->value->asString());
430
431         elements = elements->next;
432     }
433
434     return  rv;
435 }
436
437 QT_END_NAMESPACE