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 ** 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.
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.
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.
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.
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), idIndex(-1), metatype(0), synthCache(0), defaultProperty(0), parserStatusCast(-1),
70 componentCompileState(0), nextAliasingObject(0), nextIdObject(0)
74 QDeclarativeParser::Object::~Object()
76 if (synthCache) synthCache->release();
79 void Object::setBindingBit(int b)
81 while (bindingBitmask.size() < 4 * (1 + b / 32))
82 bindingBitmask.append(char(0));
84 quint32 *bits = (quint32 *)bindingBitmask.data();
85 bits[b / 32] |= (1 << (b % 32));
88 const QMetaObject *Object::metaObject() const
90 if (!metadata.isEmpty() && metatype)
96 QDeclarativeParser::Property *Object::getDefaultProperty()
98 if (!defaultProperty) {
99 defaultProperty = pool()->New<Property>();
100 defaultProperty->parent = this;
102 return defaultProperty;
105 void QDeclarativeParser::Object::addValueProperty(Property *p)
107 valueProperties.append(p);
110 void QDeclarativeParser::Object::addSignalProperty(Property *p)
112 signalProperties.append(p);
115 void QDeclarativeParser::Object::addAttachedProperty(Property *p)
117 attachedProperties.append(p);
120 void QDeclarativeParser::Object::addGroupedProperty(Property *p)
122 groupedProperties.append(p);
125 void QDeclarativeParser::Object::addValueTypeProperty(Property *p)
127 valueTypeProperties.append(p);
130 void QDeclarativeParser::Object::addScriptStringProperty(Property *p)
132 scriptStringProperties.append(p);
135 Property *QDeclarativeParser::Object::getProperty(const QStringRef &name, bool create)
137 for (Property *p = properties.first(); p; p = properties.next(p)) {
138 if (p->name() == name)
143 Property *property = pool()->New<Property>();
144 property->parent = this;
145 property->_name = name;
146 property->isDefault = false;
147 properties.prepend(property);
154 Property *QDeclarativeParser::Object::getProperty(const QString &name, bool create)
156 for (Property *p = properties.first(); p; p = properties.next(p)) {
157 if (p->name() == name)
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);
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), location(o.location)
198 int QDeclarativeParser::Object::DynamicSignal::parameterTypesLength() const
201 for (int ii = 0; ii < parameterTypes.count(); ++ii)
202 rv += parameterTypes.at(ii).length();
206 int QDeclarativeParser::Object::DynamicSignal::parameterNamesLength() const
209 for (int ii = 0; ii < parameterNames.count(); ++ii)
210 rv += parameterNames.at(ii).length();
214 QDeclarativeParser::Object::DynamicSlot::DynamicSlot()
218 QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
219 : name(o.name), body(o.body), parameterNames(o.parameterNames), location(o.location)
223 int QDeclarativeParser::Object::DynamicSlot::parameterNamesLength() const
226 for (int ii = 0; ii < parameterNames.count(); ++ii)
227 rv += parameterNames.at(ii).length();
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),
238 QDeclarativeParser::Object *QDeclarativeParser::Property::getValue(const LocationSpan &l)
240 if (!value) { value = pool()->New<Object>(); value->location = l; }
244 void QDeclarativeParser::Property::addValue(Value *v)
249 void QDeclarativeParser::Property::addOnValue(Value *v)
254 bool QDeclarativeParser::Property::isEmpty() const
256 return !value && values.isEmpty() && onValues.isEmpty();
259 QDeclarativeParser::Value::Value()
260 : type(Unknown), object(0), bindingReference(0), signalExpressionContextStack(0), nextValue(0)
264 QDeclarativeParser::Variant::Variant()
269 QDeclarativeParser::Variant::Variant(const Variant &o)
270 : t(o.t), d(o.d), asWritten(o.asWritten)
274 QDeclarativeParser::Variant::Variant(bool v)
279 QDeclarativeParser::Variant::Variant(double v, const QStringRef &asWritten)
280 : t(Number), d(v), asWritten(asWritten)
284 QDeclarativeParser::Variant::Variant(QDeclarativeJS::AST::StringLiteral *v)
289 QDeclarativeParser::Variant::Variant(const QStringRef &asWritten, QDeclarativeJS::AST::Node *n)
290 : t(Script), n(n), asWritten(asWritten)
294 QDeclarativeParser::Variant &QDeclarativeParser::Variant::operator=(const Variant &o)
298 asWritten = o.asWritten;
302 QDeclarativeParser::Variant::Type QDeclarativeParser::Variant::type() const
307 bool QDeclarativeParser::Variant::asBoolean() const
312 QString QDeclarativeParser::Variant::asString() const
316 return l->value.toString();
318 return asWritten.toString();
322 double QDeclarativeParser::Variant::asNumber() const
327 //reverse of Lexer::singleEscape()
328 QString escapedString(const QString &string)
330 QString tmp = QLatin1String("\"");
331 for (int i = 0; i < string.length(); ++i) {
332 const QChar &c = string.at(i);
333 switch(c.unicode()) {
335 tmp += QLatin1String("\\b");
338 tmp += QLatin1String("\\t");
341 tmp += QLatin1String("\\n");
344 tmp += QLatin1String("\\v");
347 tmp += QLatin1String("\\f");
350 tmp += QLatin1String("\\r");
353 tmp += QLatin1String("\\\"");
356 tmp += QLatin1String("\\\'");
359 tmp += QLatin1String("\\\\");
366 tmp += QLatin1Char('\"');
370 QString QDeclarativeParser::Variant::asScript() const
377 return b?QLatin1String("true"):QLatin1String("false");
379 if (asWritten.isEmpty())
380 return QString::number(d);
382 return asWritten.toString();
384 return escapedString(asString());
386 if (AST::IdentifierExpression *i = AST::cast<AST::IdentifierExpression *>(n)) {
388 return i->name.toString();
390 return asWritten.toString();
394 QDeclarativeJS::AST::Node *QDeclarativeParser::Variant::asAST() const
396 if (type() == Script)
402 bool QDeclarativeParser::Variant::isStringList() const
407 if (type() != Script || !n)
410 AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
414 AST::ElementList *elements = array->elements;
418 if (!AST::cast<AST::StringLiteral *>(elements->expression))
421 elements = elements->next;
427 QStringList QDeclarativeParser::Variant::asStringList() const
435 AST::ArrayLiteral *array = AST::cast<AST::ArrayLiteral *>(n);
439 AST::ElementList *elements = array->elements;
442 AST::StringLiteral *string = AST::cast<AST::StringLiteral *>(elements->expression);
444 return QStringList();
445 rv.append(string->value.toString());
447 elements = elements->next;