1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
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
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.
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.
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
42 #include "private/qdeclarativeparser_p.h"
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"
60 #include <QStringBuilder>
65 using namespace QDeclarativeJS;
66 using namespace QDeclarativeParser;
68 QDeclarativeParser::Object::Object()
69 : type(-1), majorVersion(-1), minorVersion(-1), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1)
73 QDeclarativeParser::Object::~Object()
75 if (defaultProperty) defaultProperty->release();
76 if (synthCache) synthCache->release();
77 foreach(Property *prop, properties)
79 foreach(Property *prop, valueProperties)
81 foreach(Property *prop, signalProperties)
83 foreach(Property *prop, attachedProperties)
85 foreach(Property *prop, groupedProperties)
87 foreach(Property *prop, valueTypeProperties)
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();
96 void Object::setBindingBit(int b)
98 while (bindingBitmask.size() < 4 * (1 + b / 32))
99 bindingBitmask.append(char(0));
101 quint32 *bits = (quint32 *)bindingBitmask.data();
102 bits[b / 32] |= (1 << (b % 32));
105 const QMetaObject *Object::metaObject() const
107 if (!metadata.isEmpty() && metatype)
113 QDeclarativeParser::Property *Object::getDefaultProperty()
115 if (!defaultProperty) {
116 defaultProperty = new Property;
117 defaultProperty->parent = this;
119 return defaultProperty;
122 void QDeclarativeParser::Object::addValueProperty(Property *p)
125 valueProperties << p;
128 void QDeclarativeParser::Object::addSignalProperty(Property *p)
131 signalProperties << p;
134 void QDeclarativeParser::Object::addAttachedProperty(Property *p)
137 attachedProperties << p;
140 void QDeclarativeParser::Object::addGroupedProperty(Property *p)
143 groupedProperties << p;
146 void QDeclarativeParser::Object::addValueTypeProperty(Property *p)
149 valueTypeProperties << p;
152 void QDeclarativeParser::Object::addScriptStringProperty(Property *p, int stack)
155 scriptStringProperties << qMakePair(p, stack);
159 Property *QDeclarativeParser::Object::getProperty(const QByteArray &name, bool create)
161 if (!properties.contains(name)) {
163 Property *property = new Property(name);
164 property->parent = this;
165 properties.insert(name, property);
170 return properties[name];
173 QDeclarativeParser::Object::DynamicProperty::DynamicProperty()
174 : isDefaultProperty(false), type(Variant), defaultValue(0)
178 QDeclarativeParser::Object::DynamicProperty::DynamicProperty(const DynamicProperty &o)
179 : isDefaultProperty(o.isDefaultProperty),
181 customType(o.customType),
183 defaultValue(o.defaultValue),
188 QDeclarativeParser::Object::DynamicSignal::DynamicSignal()
192 QDeclarativeParser::Object::DynamicSignal::DynamicSignal(const DynamicSignal &o)
193 : name(o.name), parameterTypes(o.parameterTypes),
194 parameterNames(o.parameterNames)
198 QDeclarativeParser::Object::DynamicSlot::DynamicSlot()
202 QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
203 : name(o.name), body(o.body), parameterNames(o.parameterNames), location(o.location)
207 QDeclarativeParser::Property::Property()
208 : parent(0), type(0), index(-1), value(0), isDefault(true), isDeferred(false),
209 isValueTypeSubProperty(false), isAlias(false)
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)
219 QDeclarativeParser::Property::~Property()
221 foreach(Value *value, values)
223 foreach(Value *value, onValues)
225 if (value) value->release();
228 QDeclarativeParser::Object *QDeclarativeParser::Property::getValue(const LocationSpan &l)
230 if (!value) { value = new QDeclarativeParser::Object; value->location = l; }
234 void QDeclarativeParser::Property::addValue(Value *v)
239 void QDeclarativeParser::Property::addOnValue(Value *v)
244 bool QDeclarativeParser::Property::isEmpty() const
246 return !value && values.isEmpty() && onValues.isEmpty();
249 QDeclarativeParser::Value::Value()
250 : type(Unknown), object(0)
254 QDeclarativeParser::Value::~Value()
256 if (object) object->release();
259 QDeclarativeParser::Variant::Variant()
262 QDeclarativeParser::Variant::Variant(const Variant &o)
263 : t(o.t), d(o.d), s(o.s)
267 QDeclarativeParser::Variant::Variant(bool v)
272 QDeclarativeParser::Variant::Variant(double v, const QString &asWritten)
273 : t(Number), d(v), s(asWritten)
277 QDeclarativeParser::Variant::Variant(const QString &v)
282 QDeclarativeParser::Variant::Variant(const QString &v, QDeclarativeJS::AST::Node *n)
283 : t(Script), n(n), s(v)
287 QDeclarativeParser::Variant &QDeclarativeParser::Variant::operator=(const Variant &o)
295 QDeclarativeParser::Variant::Type QDeclarativeParser::Variant::type() const
300 bool QDeclarativeParser::Variant::asBoolean() const
305 QString QDeclarativeParser::Variant::asString() const
310 double QDeclarativeParser::Variant::asNumber() const
315 //reverse of Lexer::singleEscape()
316 QString escapedString(const QString &string)
318 QString tmp = QLatin1String("\"");
319 for (int i = 0; i < string.length(); ++i) {
320 const QChar &c = string.at(i);
321 switch(c.unicode()) {
323 tmp += QLatin1String("\\b");
326 tmp += QLatin1String("\\t");
329 tmp += QLatin1String("\\n");
332 tmp += QLatin1String("\\v");
335 tmp += QLatin1String("\\f");
338 tmp += QLatin1String("\\r");
341 tmp += QLatin1String("\\\"");
344 tmp += QLatin1String("\\\'");
347 tmp += QLatin1String("\\\\");
354 tmp += QLatin1Char('\"');
358 QString QDeclarativeParser::Variant::asScript() const
365 return b?QLatin1String("true"):QLatin1String("false");
368 return QString::number(d);
372 return escapedString(s);
378 QDeclarativeJS::AST::Node *QDeclarativeParser::Variant::asAST() const
380 if (type() == Script)
386 bool QDeclarativeParser::Variant::isStringList() const
391 if (type() != Script || !n)
394 AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
398 AST::ElementList *elements = array->elements;
402 if (!AST::cast<AST::StringLiteral *>(elements->expression))
405 elements = elements->next;
411 QStringList QDeclarativeParser::Variant::asStringList() const
419 AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
423 AST::ElementList *elements = array->elements;
426 AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(elements->expression);
428 return QStringList();
429 rv.append(string->value->asString());
431 elements = elements->next;