diff options
Diffstat (limited to 'src/qml/qml')
99 files changed, 3054 insertions, 7403 deletions
diff --git a/src/qml/qml/ftw/qhashedstring_p.h b/src/qml/qml/ftw/qhashedstring_p.h index 5fc8443ecd..cdf0717e3a 100644 --- a/src/qml/qml/ftw/qhashedstring_p.h +++ b/src/qml/qml/ftw/qhashedstring_p.h @@ -262,8 +262,9 @@ public: inline uint16_t *utf16Data() const { return (uint16_t *)strData->data(); } inline bool equals(v8::Handle<v8::String> string) const { - return isQString()?string->Equals(utf16Data(), length): - string->Equals(cStrData(), length); + v8::Local<v8::String> data = isQString() ? v8::String::New(utf16Data(), length) + : v8::String::New(cStrData(), length); + return string->Equals(data); } inline bool symbolEquals(const QHashedV8String &string) const { @@ -1183,8 +1184,11 @@ QString QHashedV8String::toString() const QString result; result.reserve(m_hash.length); + v8::String::Value value(m_string); + Q_ASSERT(*value != NULL); + uint16_t* string = *value; for (int i = 0; i < m_hash.length; ++i) - result.append(m_string->GetCharacter(i)); + result.append(string[i]); return result; } diff --git a/src/qml/qml/ftw/qqmlrefcount_p.h b/src/qml/qml/ftw/qqmlrefcount_p.h index 0bc3ea038a..24c3e7a2cc 100644 --- a/src/qml/qml/ftw/qqmlrefcount_p.h +++ b/src/qml/qml/ftw/qqmlrefcount_p.h @@ -56,8 +56,6 @@ #include <QtCore/qglobal.h> #include <QtCore/qatomic.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -193,6 +191,4 @@ QQmlRefPointer<T> &QQmlRefPointer<T>::take(T *other) QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLREFCOUNT_P_H diff --git a/src/qml/qml/parser/qqmljs.g b/src/qml/qml/parser/qqmljs.g index df891da992..ff4f54374b 100644 --- a/src/qml/qml/parser/qqmljs.g +++ b/src/qml/qml/parser/qqmljs.g @@ -24,7 +24,7 @@ %parser QQmlJSGrammar %decl qqmljsparser_p.h %impl qqmljsparser.cpp -%expect 2 +%expect 5 %expect-rr 2 %token T_AND "&" T_AND_AND "&&" T_AND_EQ "&=" @@ -67,6 +67,8 @@ %token T_IMPORT "import" %token T_AS "as" %token T_ON "on" +%token T_GET "get" +%token T_SET "set" %token T_ERROR @@ -79,7 +81,7 @@ %token T_FEED_JS_PROGRAM %nonassoc SHIFT_THERE -%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY +%nonassoc T_IDENTIFIER T_COLON T_SIGNAL T_PROPERTY T_READONLY T_ON T_SET T_GET %nonassoc REDUCE_HERE %start TopLevel @@ -125,16 +127,16 @@ ** ****************************************************************************/ -#include <QtCore/QtDebug> -#include <QtCore/QCoreApplication> - -#include <string.h> - #include "qqmljsengine_p.h" #include "qqmljslexer_p.h" #include "qqmljsast_p.h" #include "qqmljsmemorypool_p.h" +#include <QtCore/qdebug.h> +#include <QtCore/qcoreapplication.h> + +#include <string.h> + ./ /:/**************************************************************************** @@ -210,8 +212,8 @@ #include "qqmljsast_p.h" #include "qqmljsengine_p.h" -#include <QtCore/QList> -#include <QtCore/QString> +#include <QtCore/qlist.h> +#include <QtCore/qstring.h> QT_QML_BEGIN_NAMESPACE @@ -240,7 +242,8 @@ public: AST::FunctionDeclaration *FunctionDeclaration; AST::Node *Node; AST::PropertyName *PropertyName; - AST::PropertyNameAndValueList *PropertyNameAndValueList; + AST::PropertyAssignment *PropertyAssignment; + AST::PropertyAssignmentList *PropertyAssignmentList; AST::SourceElement *SourceElement; AST::SourceElements *SourceElements; AST::Statement *Statement; @@ -388,7 +391,8 @@ protected: /. #include "qqmljsparser_p.h" -#include <QVarLengthArray> + +#include <QtCore/qvarlengtharray.h> // // W A R N I N G @@ -1043,6 +1047,8 @@ JsIdentifier: T_PROPERTY ; JsIdentifier: T_SIGNAL ; JsIdentifier: T_READONLY ; JsIdentifier: T_ON ; +JsIdentifier: T_GET ; +JsIdentifier: T_SET ; -------------------------------------------------------------------------------------------------------- -- Expressions @@ -1219,13 +1225,13 @@ case $rule_number: { -- } break; -- ./ -PrimaryExpression: T_LBRACE PropertyNameAndValueListOpt T_RBRACE ; +PrimaryExpression: T_LBRACE PropertyAssignmentListOpt T_RBRACE ; /. case $rule_number: { AST::ObjectLiteral *node = 0; if (sym(2).Node) node = new (pool) AST::ObjectLiteral( - sym(2).PropertyNameAndValueList->finish ()); + sym(2).PropertyAssignmentList->finish ()); else node = new (pool) AST::ObjectLiteral(); node->lbraceToken = loc(1); @@ -1234,11 +1240,11 @@ case $rule_number: { } break; ./ -PrimaryExpression: T_LBRACE PropertyNameAndValueList T_COMMA T_RBRACE ; +PrimaryExpression: T_LBRACE PropertyAssignmentList T_COMMA T_RBRACE ; /. case $rule_number: { AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral( - sym(2).PropertyNameAndValueList->finish ()); + sym(2).PropertyAssignmentList->finish ()); node->lbraceToken = loc(1); node->rbraceToken = loc(4); sym(1).Node = node; @@ -1330,40 +1336,62 @@ case $rule_number: { } break; ./ -PropertyNameAndValueList: PropertyName T_COLON AssignmentExpression ; +PropertyAssignment: PropertyName T_COLON AssignmentExpression ; /. case $rule_number: { - AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList( + AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue( sym(1).PropertyName, sym(3).Expression); node->colonToken = loc(2); sym(1).Node = node; } break; ./ -PropertyNameAndValueList: PropertyNameAndValueList T_COMMA PropertyName T_COLON AssignmentExpression ; +PropertyAssignment: T_GET PropertyName T_LPAREN T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; /. case $rule_number: { - AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList( - sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression); - node->commaToken = loc(2); - node->colonToken = loc(4); + AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( + sym(2).PropertyName, sym(6).FunctionBody); + node->getSetToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(4); + node->lbraceToken = loc(5); + node->rbraceToken = loc(7); sym(1).Node = node; } break; ./ -PropertyName: T_IDENTIFIER %prec SHIFT_THERE ; +PropertyAssignment: T_SET PropertyName T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; /. case $rule_number: { - AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); + AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( + sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody); + node->getSetToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->lbraceToken = loc(6); + node->rbraceToken = loc(8); sym(1).Node = node; } break; ./ -PropertyName: T_SIGNAL ; -/.case $rule_number:./ +PropertyAssignmentList: PropertyAssignment ; +/. +case $rule_number: { + sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment); +} break; +./ + +PropertyAssignmentList: PropertyAssignmentList T_COMMA PropertyAssignment ; +/. +case $rule_number: { + AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList( + sym(1).PropertyAssignmentList, sym(3).PropertyAssignment); + node->commaToken = loc(2); + sym(1).Node = node; +} break; +./ -PropertyName: T_PROPERTY ; +PropertyName: JsIdentifier %prec SHIFT_THERE ; /. case $rule_number: { AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); @@ -2669,20 +2697,7 @@ case $rule_number: { } break; ./ -LabelledStatement: T_SIGNAL T_COLON Statement ; -/.case $rule_number:./ - -LabelledStatement: T_PROPERTY T_COLON Statement ; -/. -case $rule_number: { - AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement); - node->identifierToken = loc(1); - node->colonToken = loc(2); - sym(1).Node = node; -} break; -./ - -LabelledStatement: T_IDENTIFIER T_COLON Statement ; +LabelledStatement: JsIdentifier T_COLON Statement ; /. case $rule_number: { AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement); @@ -2762,7 +2777,12 @@ case $rule_number: { } break; ./ -FunctionDeclaration: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +-- tell the parser to prefer function declarations to function expressions. +-- That is, the `Function' symbol is used to mark the start of a function +-- declaration. +Function: T_FUNCTION %prec REDUCE_HERE ; + +FunctionDeclaration: Function JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; /. case $rule_number: { AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody); @@ -2776,7 +2796,7 @@ case $rule_number: { } break; ./ -FunctionExpression: T_FUNCTION IdentifierOpt T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +FunctionExpression: T_FUNCTION JsIdentifier T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; /. case $rule_number: { AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody); @@ -2791,6 +2811,19 @@ case $rule_number: { } break; ./ +FunctionExpression: T_FUNCTION T_LPAREN FormalParameterListOpt T_RPAREN T_LBRACE FunctionBodyOpt T_RBRACE ; +/. +case $rule_number: { + AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody); + node->functionToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + node->lbraceToken = loc(5); + node->rbraceToken = loc(7); + sym(1).Node = node; +} break; +./ + FormalParameterList: JsIdentifier ; /. case $rule_number: { @@ -2877,23 +2910,14 @@ case $rule_number: { } break; ./ -IdentifierOpt: ; -/. -case $rule_number: { - stringRef(1) = QStringRef(); -} break; -./ - -IdentifierOpt: JsIdentifier ; - -PropertyNameAndValueListOpt: ; +PropertyAssignmentListOpt: ; /. case $rule_number: { sym(1).Node = 0; } break; ./ -PropertyNameAndValueListOpt: PropertyNameAndValueList ; +PropertyAssignmentListOpt: PropertyAssignmentList ; /. } // switch diff --git a/src/qml/qml/parser/qqmljsast.cpp b/src/qml/qml/parser/qqmljsast.cpp index 6b5ef15352..ea0df4a537 100644 --- a/src/qml/qml/parser/qqmljsast.cpp +++ b/src/qml/qml/parser/qqmljsast.cpp @@ -213,12 +213,32 @@ void Elision::accept0(Visitor *visitor) visitor->endVisit(this); } -void PropertyNameAndValueList::accept0(Visitor *visitor) +void PropertyNameAndValue::accept0(Visitor *visitor) { if (visitor->visit(this)) { - for (PropertyNameAndValueList *it = this; it; it = it->next) { - accept(it->name, visitor); - accept(it->value, visitor); + accept(name, visitor); + accept(value, visitor); + } + + visitor->endVisit(this); +} + +void PropertyGetterSetter::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + accept(name, visitor); + accept(formals, visitor); + accept(functionBody, visitor); + } + + visitor->endVisit(this); +} + +void PropertyAssignmentList::accept0(Visitor *visitor) +{ + if (visitor->visit(this)) { + for (PropertyAssignmentList *it = this; it; it = it->next) { + accept(it->assignment, visitor); } } diff --git a/src/qml/qml/parser/qqmljsast_p.h b/src/qml/qml/parser/qqmljsast_p.h index 65a598c783..01a872f1e8 100644 --- a/src/qml/qml/parser/qqmljsast_p.h +++ b/src/qml/qml/parser/qqmljsast_p.h @@ -57,7 +57,7 @@ #include "qqmljsglobal_p.h" #include "qqmljsmemorypool_p.h" -#include <QtCore/QString> +#include <QtCore/qstring.h> QT_QML_BEGIN_NAMESPACE @@ -176,8 +176,10 @@ public: Kind_PreDecrementExpression, Kind_PreIncrementExpression, Kind_Program, + Kind_PropertyAssignmentList, + Kind_PropertyGetterSetter, Kind_PropertyName, - Kind_PropertyNameAndValueList, + Kind_PropertyNameAndValue, Kind_RegExpLiteral, Kind_ReturnStatement, Kind_SourceElement, @@ -487,7 +489,7 @@ public: ObjectLiteral(): properties (0) { kind = K; } - ObjectLiteral(PropertyNameAndValueList *plist): + ObjectLiteral(PropertyAssignmentList *plist): properties (plist) { kind = K; } virtual void accept0(Visitor *visitor); @@ -499,7 +501,7 @@ public: { return rbraceToken; } // attributes - PropertyNameAndValueList *properties; + PropertyAssignmentList *properties; SourceLocation lbraceToken; SourceLocation rbraceToken; }; @@ -603,50 +605,113 @@ public: SourceLocation propertyNameToken; }; -class QML_PARSER_EXPORT PropertyNameAndValueList: public Node +class QML_PARSER_EXPORT PropertyAssignment: public Node { public: - QQMLJS_DECLARE_AST_NODE(PropertyNameAndValueList) + PropertyAssignment() {} +}; - PropertyNameAndValueList(PropertyName *n, ExpressionNode *v): - name (n), value (v), next (this) - { kind = K; } +class QML_PARSER_EXPORT PropertyAssignmentList: public Node +{ +public: + QQMLJS_DECLARE_AST_NODE(PropertyAssignmentList) - PropertyNameAndValueList(PropertyNameAndValueList *previous, PropertyName *n, ExpressionNode *v): - name (n), value (v) + PropertyAssignmentList(PropertyAssignment *assignment) + : assignment(assignment) + , next(this) + { kind = K; } + + PropertyAssignmentList(PropertyAssignmentList *previous, PropertyAssignment *assignment) + : assignment(assignment) { kind = K; next = previous->next; previous->next = this; } + inline PropertyAssignmentList *finish () + { + PropertyAssignmentList *front = next; + next = 0; + return front; + } + virtual void accept0(Visitor *visitor); virtual SourceLocation firstSourceLocation() const - { return name->firstSourceLocation(); } + { return assignment->firstSourceLocation(); } virtual SourceLocation lastSourceLocation() const - { - if (next) - return next->lastSourceLocation(); - return value->lastSourceLocation(); - } + { return next ? next->lastSourceLocation() : assignment->lastSourceLocation(); } - inline PropertyNameAndValueList *finish () - { - PropertyNameAndValueList *front = next; - next = 0; - return front; - } +// attributes + PropertyAssignment *assignment; + PropertyAssignmentList *next; + SourceLocation commaToken; +}; + +class QML_PARSER_EXPORT PropertyNameAndValue: public PropertyAssignment +{ +public: + QQMLJS_DECLARE_AST_NODE(PropertyNameAndValue) + + PropertyNameAndValue(PropertyName *n, ExpressionNode *v) + : name(n), value(v) + { kind = K; } + + virtual void accept0(Visitor *visitor); + + virtual SourceLocation firstSourceLocation() const + { return name->firstSourceLocation(); } + + virtual SourceLocation lastSourceLocation() const + { return value->lastSourceLocation(); } // attributes PropertyName *name; - ExpressionNode *value; - PropertyNameAndValueList *next; SourceLocation colonToken; + ExpressionNode *value; SourceLocation commaToken; }; +class QML_PARSER_EXPORT PropertyGetterSetter: public PropertyAssignment +{ +public: + QQMLJS_DECLARE_AST_NODE(PropertyGetterSetter) + + enum Type { + Getter, + Setter + }; + + PropertyGetterSetter(PropertyName *n, FunctionBody *b) + : type(Getter), name(n), formals(0), functionBody (b) + { kind = K; } + + PropertyGetterSetter(PropertyName *n, FormalParameterList *f, FunctionBody *b) + : type(Setter), name(n), formals(f), functionBody (b) + { kind = K; } + + virtual void accept0(Visitor *visitor); + + virtual SourceLocation firstSourceLocation() const + { return getSetToken; } + + virtual SourceLocation lastSourceLocation() const + { return rbraceToken; } + +// attributes + Type type; + SourceLocation getSetToken; + PropertyName *name; + SourceLocation lparenToken; + FormalParameterList *formals; + SourceLocation rparenToken; + SourceLocation lbraceToken; + FunctionBody *functionBody; + SourceLocation rbraceToken; +}; + class QML_PARSER_EXPORT IdentifierPropertyName: public PropertyName { public: diff --git a/src/qml/qml/parser/qqmljsastfwd_p.h b/src/qml/qml/parser/qqmljsastfwd_p.h index 67868234b2..fe5572c4b2 100644 --- a/src/qml/qml/parser/qqmljsastfwd_p.h +++ b/src/qml/qml/parser/qqmljsastfwd_p.h @@ -98,7 +98,9 @@ class ArrayLiteral; class ObjectLiteral; class ElementList; class Elision; -class PropertyNameAndValueList; +class PropertyAssignmentList; +class PropertyGetterSetter; +class PropertyNameAndValue; class PropertyName; class IdentifierPropertyName; class StringLiteralPropertyName; diff --git a/src/qml/qml/parser/qqmljsastvisitor_p.h b/src/qml/qml/parser/qqmljsastvisitor_p.h index 32f94bd436..ef022f617c 100644 --- a/src/qml/qml/parser/qqmljsastvisitor_p.h +++ b/src/qml/qml/parser/qqmljsastvisitor_p.h @@ -137,8 +137,14 @@ public: virtual bool visit(Elision *) { return true; } virtual void endVisit(Elision *) {} - virtual bool visit(PropertyNameAndValueList *) { return true; } - virtual void endVisit(PropertyNameAndValueList *) {} + virtual bool visit(PropertyAssignmentList *) { return true; } + virtual void endVisit(PropertyAssignmentList *) {} + + virtual bool visit(PropertyNameAndValue *) { return true; } + virtual void endVisit(PropertyNameAndValue *) {} + + virtual bool visit(PropertyGetterSetter *) { return true; } + virtual void endVisit(PropertyGetterSetter *) {} virtual bool visit(NestedExpression *) { return true; } virtual void endVisit(NestedExpression *) {} diff --git a/src/qml/qml/parser/qqmljsengine_p.cpp b/src/qml/qml/parser/qqmljsengine_p.cpp index 8e3903d7e0..7dc3b6f6cb 100644 --- a/src/qml/qml/parser/qqmljsengine_p.cpp +++ b/src/qml/qml/parser/qqmljsengine_p.cpp @@ -42,15 +42,15 @@ #include "qqmljsengine_p.h" #include "qqmljsglobal_p.h" -#include <qnumeric.h> -#include <QHash> -#include <QDebug> +#include <QtCore/qnumeric.h> +#include <QtCore/qhash.h> +#include <QtCore/qdebug.h> QT_QML_BEGIN_NAMESPACE namespace QQmlJS { -static int toDigit(char c) +static inline int toDigit(char c) { if ((c >= '0') && (c <= '9')) return c - '0'; diff --git a/src/qml/qml/parser/qqmljsengine_p.h b/src/qml/qml/parser/qqmljsengine_p.h index f1729c0526..4f58e7f8ea 100644 --- a/src/qml/qml/parser/qqmljsengine_p.h +++ b/src/qml/qml/parser/qqmljsengine_p.h @@ -57,8 +57,8 @@ #include "qqmljsastfwd_p.h" #include "qqmljsmemorypool_p.h" -#include <QString> -#include <QSet> +#include <QtCore/qstring.h> +#include <QtCore/qset.h> QT_QML_BEGIN_NAMESPACE diff --git a/src/qml/qml/parser/qqmljsglobal_p.h b/src/qml/qml/parser/qqmljsglobal_p.h index 3aecc863d5..c53e12ea56 100644 --- a/src/qml/qml/parser/qqmljsglobal_p.h +++ b/src/qml/qml/parser/qqmljsglobal_p.h @@ -61,8 +61,10 @@ # if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB) // QmlDevTools is a static library # define QML_PARSER_EXPORT -# else +# elif defined(QT_BUILD_QML_LIB) # define QML_PARSER_EXPORT Q_AUTOTEST_EXPORT +# else +# define QML_PARSER_EXPORT # endif #endif // QT_CREATOR diff --git a/src/qml/qml/parser/qqmljsgrammar.cpp b/src/qml/qml/parser/qqmljsgrammar.cpp index d1b29be70a..4a5672a796 100644 --- a/src/qml/qml/parser/qqmljsgrammar.cpp +++ b/src/qml/qml/parser/qqmljsgrammar.cpp @@ -54,45 +54,46 @@ const char *const QQmlJSGrammar::spell [] = { ")", ";", 0, "*", "*=", "string literal", "property", "signal", "readonly", "switch", "this", "throw", "~", "try", "typeof", "var", "void", "while", "with", "^", "^=", "null", "true", "false", "const", "debugger", "reserved word", "multiline string literal", "comment", 0, - "public", "import", "as", "on", 0, 0, 0, 0, 0, 0, - 0, 0, 0}; + "public", "import", "as", "on", "get", "set", 0, 0, 0, 0, + 0, 0, 0, 0, 0}; const short QQmlJSGrammar::lhs [] = { - 103, 103, 103, 103, 103, 103, 104, 110, 110, 113, - 113, 115, 114, 114, 114, 114, 114, 114, 114, 114, - 117, 112, 111, 120, 120, 121, 121, 122, 122, 119, - 108, 108, 108, 108, 124, 124, 124, 124, 124, 124, - 124, 108, 132, 132, 132, 133, 133, 134, 134, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 118, 118, 118, 118, - 118, 137, 137, 137, 137, 137, 137, 137, 137, 137, - 137, 137, 137, 137, 137, 137, 137, 137, 137, 123, - 139, 139, 139, 139, 138, 138, 141, 141, 143, 143, - 143, 143, 143, 143, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 144, 144, 144, 144, 144, - 144, 144, 144, 144, 144, 145, 145, 116, 116, 116, - 116, 116, 148, 148, 149, 149, 149, 149, 147, 147, - 150, 150, 151, 151, 152, 152, 152, 153, 153, 153, - 153, 153, 153, 153, 153, 153, 153, 154, 154, 154, - 154, 155, 155, 155, 156, 156, 156, 156, 157, 157, - 157, 157, 157, 157, 157, 158, 158, 158, 158, 158, - 158, 159, 159, 159, 159, 159, 160, 160, 160, 160, - 160, 161, 161, 162, 162, 163, 163, 164, 164, 165, - 165, 166, 166, 167, 167, 168, 168, 169, 169, 170, - 170, 171, 171, 172, 172, 142, 142, 173, 173, 174, - 174, 174, 174, 174, 174, 174, 174, 174, 174, 174, - 174, 106, 106, 175, 175, 176, 176, 177, 177, 105, - 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, - 105, 105, 105, 105, 125, 186, 186, 185, 185, 136, - 136, 187, 187, 188, 188, 190, 190, 189, 191, 194, - 192, 192, 195, 193, 193, 126, 127, 127, 128, 128, - 178, 178, 178, 178, 178, 178, 178, 178, 179, 179, - 179, 179, 180, 180, 180, 180, 181, 181, 129, 130, - 196, 196, 199, 199, 197, 197, 200, 198, 182, 182, - 182, 183, 183, 131, 131, 131, 201, 202, 184, 184, - 135, 146, 206, 206, 203, 203, 204, 204, 207, 109, - 109, 208, 208, 107, 107, 205, 205, 140, 140, 209}; + 105, 105, 105, 105, 105, 105, 106, 112, 112, 115, + 115, 117, 116, 116, 116, 116, 116, 116, 116, 116, + 119, 114, 113, 122, 122, 123, 123, 124, 124, 121, + 110, 110, 110, 110, 126, 126, 126, 126, 126, 126, + 126, 110, 134, 134, 134, 135, 135, 136, 136, 110, + 110, 110, 110, 110, 110, 110, 110, 110, 110, 110, + 110, 110, 110, 110, 110, 110, 120, 120, 120, 120, + 120, 120, 120, 139, 139, 139, 139, 139, 139, 139, + 139, 139, 139, 139, 139, 139, 139, 139, 139, 139, + 139, 125, 141, 141, 141, 141, 140, 140, 145, 145, + 145, 143, 143, 146, 146, 146, 146, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 149, 149, + 149, 149, 149, 149, 149, 149, 149, 149, 150, 150, + 118, 118, 118, 118, 118, 153, 153, 154, 154, 154, + 154, 152, 152, 155, 155, 156, 156, 157, 157, 157, + 158, 158, 158, 158, 158, 158, 158, 158, 158, 158, + 159, 159, 159, 159, 160, 160, 160, 161, 161, 161, + 161, 162, 162, 162, 162, 162, 162, 162, 163, 163, + 163, 163, 163, 163, 164, 164, 164, 164, 164, 165, + 165, 165, 165, 165, 166, 166, 167, 167, 168, 168, + 169, 169, 170, 170, 171, 171, 172, 172, 173, 173, + 174, 174, 175, 175, 176, 176, 177, 177, 144, 144, + 178, 178, 179, 179, 179, 179, 179, 179, 179, 179, + 179, 179, 179, 179, 108, 108, 180, 180, 181, 181, + 182, 182, 107, 107, 107, 107, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 107, 127, 191, 191, + 190, 190, 138, 138, 192, 192, 193, 193, 195, 195, + 194, 196, 199, 197, 197, 200, 198, 198, 128, 129, + 129, 130, 130, 183, 183, 183, 183, 183, 183, 183, + 183, 184, 184, 184, 184, 185, 185, 185, 185, 186, + 186, 131, 132, 201, 201, 204, 204, 202, 202, 205, + 203, 187, 188, 188, 133, 133, 133, 206, 207, 189, + 189, 208, 137, 151, 151, 209, 209, 148, 148, 147, + 147, 210, 111, 111, 211, 211, 109, 109, 142, 142, + 212}; const short QQmlJSGrammar::rhs [] = { 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, @@ -103,593 +104,600 @@ const short QQmlJSGrammar::rhs [] = { 6, 3, 3, 7, 7, 4, 4, 5, 5, 5, 6, 6, 10, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 3, 3, 4, 5, 3, 4, 3, 1, - 1, 2, 3, 4, 1, 2, 3, 5, 1, 1, + 1, 1, 1, 2, 3, 3, 4, 5, 3, 4, + 3, 1, 1, 2, 3, 4, 1, 2, 3, 7, + 8, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, - 3, 5, 1, 2, 4, 4, 4, 3, 0, 1, - 1, 3, 1, 1, 1, 2, 2, 1, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 1, 3, 3, - 3, 1, 3, 3, 1, 3, 3, 3, 1, 3, - 3, 3, 3, 3, 3, 1, 3, 3, 3, 3, - 3, 1, 3, 3, 3, 3, 1, 3, 3, 3, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, - 3, 1, 5, 1, 5, 1, 3, 1, 3, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 0, 1, 1, 3, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 2, 0, 1, 3, - 3, 1, 1, 1, 3, 1, 3, 2, 2, 2, - 0, 1, 2, 0, 1, 1, 2, 2, 7, 5, - 7, 7, 7, 5, 9, 10, 7, 8, 2, 2, - 3, 3, 2, 2, 3, 3, 3, 3, 5, 5, - 3, 5, 1, 2, 0, 1, 4, 3, 3, 3, - 3, 3, 3, 3, 3, 4, 5, 2, 2, 2, - 8, 8, 1, 3, 0, 1, 0, 1, 1, 1, - 1, 1, 2, 1, 1, 0, 1, 0, 1, 2}; + 1, 1, 4, 3, 5, 1, 2, 4, 4, 4, + 3, 0, 1, 1, 3, 1, 1, 1, 2, 2, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 3, 3, 3, 1, 3, 3, 1, 3, 3, + 3, 1, 3, 3, 3, 3, 3, 3, 1, 3, + 3, 3, 3, 3, 1, 3, 3, 3, 3, 1, + 3, 3, 3, 3, 1, 3, 1, 3, 1, 3, + 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, + 1, 3, 1, 3, 1, 5, 1, 5, 1, 3, + 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 3, 0, 1, 1, 3, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 1, 2, + 0, 1, 3, 3, 1, 1, 1, 3, 1, 3, + 2, 2, 2, 0, 1, 2, 0, 1, 1, 2, + 2, 7, 5, 7, 7, 7, 5, 9, 10, 7, + 8, 2, 2, 3, 3, 2, 2, 3, 3, 3, + 3, 5, 5, 3, 5, 1, 2, 0, 1, 4, + 3, 3, 3, 3, 3, 3, 4, 5, 2, 2, + 2, 1, 8, 8, 7, 1, 3, 0, 1, 0, + 1, 1, 1, 1, 1, 2, 1, 1, 0, 1, + 2}; const short QQmlJSGrammar::action_default [] = { - 0, 0, 22, 0, 0, 0, 22, 0, 175, 242, - 206, 214, 210, 154, 226, 202, 3, 139, 73, 155, - 218, 222, 143, 172, 153, 158, 138, 192, 179, 0, - 80, 81, 76, 346, 67, 348, 0, 0, 0, 0, - 78, 0, 0, 74, 77, 71, 0, 0, 68, 70, - 69, 79, 72, 0, 75, 0, 0, 168, 0, 0, - 155, 174, 157, 156, 0, 0, 0, 170, 171, 169, - 173, 0, 203, 0, 0, 0, 0, 193, 0, 0, - 0, 0, 0, 0, 183, 0, 0, 0, 177, 178, - 176, 181, 185, 184, 182, 180, 195, 194, 196, 0, - 211, 0, 207, 0, 0, 149, 136, 148, 137, 105, - 106, 107, 132, 108, 133, 109, 110, 111, 112, 113, - 114, 115, 116, 117, 118, 119, 120, 121, 134, 122, - 123, 124, 125, 126, 127, 128, 129, 130, 131, 135, - 0, 0, 147, 243, 150, 0, 151, 0, 152, 146, - 0, 239, 232, 230, 237, 238, 236, 235, 241, 234, - 233, 231, 240, 227, 0, 215, 0, 0, 219, 0, - 0, 223, 0, 0, 149, 141, 0, 140, 0, 145, - 159, 0, 347, 335, 336, 0, 333, 0, 334, 0, - 337, 250, 257, 256, 264, 252, 0, 253, 338, 0, - 345, 254, 255, 260, 258, 342, 339, 344, 261, 0, - 272, 0, 0, 0, 0, 346, 67, 0, 348, 68, - 244, 286, 69, 0, 0, 0, 273, 0, 0, 262, - 263, 0, 251, 259, 287, 288, 332, 343, 0, 303, - 304, 305, 306, 0, 299, 300, 301, 302, 329, 330, - 0, 0, 0, 0, 0, 291, 292, 293, 248, 246, - 208, 216, 212, 228, 204, 249, 0, 155, 220, 224, - 197, 186, 0, 0, 205, 0, 0, 0, 0, 198, - 0, 0, 0, 0, 0, 190, 188, 191, 189, 187, - 200, 199, 201, 0, 213, 0, 209, 0, 247, 155, - 0, 229, 244, 245, 0, 244, 0, 0, 295, 0, - 0, 0, 297, 0, 217, 0, 0, 221, 0, 0, - 225, 284, 0, 276, 285, 279, 0, 283, 0, 244, - 277, 0, 244, 0, 0, 296, 0, 0, 0, 298, - 347, 335, 0, 0, 337, 0, 331, 0, 321, 0, - 0, 0, 290, 0, 289, 0, 349, 0, 104, 266, - 269, 0, 105, 272, 108, 133, 110, 111, 76, 115, - 116, 67, 117, 120, 74, 77, 68, 244, 69, 79, - 123, 72, 125, 75, 127, 128, 273, 130, 131, 135, - 0, 97, 0, 0, 99, 103, 101, 88, 100, 102, - 0, 98, 87, 267, 265, 143, 144, 149, 0, 142, - 0, 320, 0, 307, 308, 0, 319, 0, 0, 0, - 310, 315, 313, 316, 0, 0, 314, 315, 0, 311, - 0, 312, 268, 318, 0, 268, 317, 0, 322, 323, - 0, 268, 324, 325, 0, 0, 326, 0, 0, 0, - 327, 328, 161, 160, 0, 0, 0, 294, 0, 0, - 0, 309, 281, 274, 0, 282, 278, 0, 280, 270, - 0, 271, 275, 91, 0, 0, 95, 82, 0, 84, - 93, 0, 85, 94, 96, 86, 92, 83, 0, 89, - 165, 163, 167, 164, 162, 166, 340, 6, 341, 4, - 2, 65, 90, 0, 0, 68, 70, 69, 31, 5, - 0, 66, 0, 45, 44, 43, 0, 0, 58, 0, - 59, 35, 36, 37, 38, 40, 41, 62, 39, 0, - 45, 0, 0, 0, 0, 0, 54, 0, 55, 0, - 0, 26, 0, 0, 63, 27, 0, 30, 28, 24, - 0, 29, 25, 0, 56, 0, 57, 143, 0, 60, - 64, 0, 0, 0, 0, 61, 0, 52, 46, 53, - 47, 0, 0, 0, 0, 49, 0, 50, 51, 48, - 0, 0, 143, 268, 0, 0, 42, 105, 272, 108, - 133, 110, 111, 76, 115, 116, 67, 117, 120, 74, - 77, 68, 244, 69, 79, 123, 72, 125, 75, 127, - 128, 273, 130, 131, 135, 0, 32, 33, 0, 34, + 0, 0, 22, 0, 0, 0, 22, 0, 178, 245, + 209, 217, 213, 157, 229, 205, 3, 142, 75, 158, + 221, 225, 146, 175, 156, 161, 141, 195, 182, 0, + 82, 83, 78, 0, 72, 67, 349, 0, 0, 0, + 0, 80, 0, 0, 76, 79, 71, 0, 0, 68, + 70, 73, 69, 81, 74, 0, 77, 0, 0, 171, + 0, 0, 158, 177, 160, 159, 0, 0, 0, 173, + 174, 172, 176, 0, 206, 0, 0, 0, 0, 196, + 0, 0, 0, 0, 0, 0, 186, 0, 0, 0, + 180, 181, 179, 184, 188, 187, 185, 183, 198, 197, + 199, 0, 214, 0, 210, 0, 0, 152, 139, 151, + 140, 108, 109, 110, 135, 111, 136, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 137, 125, 126, 127, 128, 129, 130, 131, 132, 133, + 134, 138, 0, 0, 150, 246, 153, 0, 154, 0, + 155, 149, 0, 242, 235, 233, 240, 241, 239, 238, + 244, 237, 236, 234, 243, 230, 0, 218, 0, 0, + 222, 0, 0, 226, 0, 0, 152, 144, 0, 143, + 0, 148, 162, 0, 338, 338, 339, 0, 336, 0, + 337, 0, 340, 253, 260, 259, 267, 255, 0, 256, + 0, 341, 0, 348, 257, 258, 75, 263, 261, 345, + 342, 347, 264, 0, 275, 0, 0, 0, 0, 332, + 0, 349, 247, 289, 0, 0, 0, 276, 0, 0, + 265, 266, 0, 254, 262, 290, 291, 0, 338, 0, + 0, 340, 0, 333, 334, 0, 322, 346, 0, 306, + 307, 308, 309, 0, 302, 303, 304, 305, 330, 331, + 0, 0, 0, 0, 0, 294, 295, 296, 251, 249, + 211, 219, 215, 231, 207, 252, 0, 158, 223, 227, + 200, 189, 0, 0, 208, 0, 0, 0, 0, 201, + 0, 0, 0, 0, 0, 193, 191, 194, 192, 190, + 203, 202, 204, 0, 216, 0, 212, 0, 250, 158, + 0, 232, 247, 248, 0, 247, 0, 0, 298, 0, + 0, 0, 300, 0, 220, 0, 0, 224, 0, 0, + 228, 287, 0, 279, 288, 282, 0, 286, 0, 247, + 280, 0, 247, 0, 0, 299, 0, 0, 0, 301, + 0, 0, 0, 293, 0, 292, 75, 102, 350, 0, + 0, 107, 269, 272, 0, 108, 275, 111, 136, 113, + 114, 78, 118, 119, 72, 120, 123, 76, 79, 247, + 73, 81, 126, 74, 128, 77, 130, 131, 276, 133, + 134, 138, 0, 104, 103, 106, 90, 105, 89, 0, + 99, 270, 268, 0, 0, 0, 340, 0, 100, 146, + 147, 152, 0, 145, 0, 310, 311, 0, 338, 0, + 0, 340, 0, 101, 0, 0, 0, 313, 318, 316, + 319, 0, 0, 317, 318, 0, 314, 0, 315, 271, + 321, 0, 271, 320, 0, 323, 324, 0, 271, 325, + 326, 0, 0, 327, 0, 0, 0, 328, 329, 164, + 163, 0, 0, 0, 297, 0, 0, 0, 312, 284, + 277, 0, 285, 281, 0, 283, 273, 0, 274, 278, + 0, 0, 340, 0, 335, 93, 0, 0, 97, 84, + 0, 86, 95, 0, 87, 96, 98, 88, 94, 85, + 0, 91, 168, 166, 170, 167, 165, 169, 343, 6, + 344, 4, 2, 65, 92, 0, 0, 68, 70, 69, + 31, 5, 0, 66, 0, 45, 44, 43, 0, 0, + 58, 0, 59, 35, 36, 37, 38, 40, 41, 62, + 39, 0, 45, 0, 0, 0, 0, 0, 54, 0, + 55, 0, 0, 26, 0, 0, 63, 27, 0, 30, + 28, 24, 0, 29, 25, 0, 56, 0, 57, 146, + 0, 60, 64, 0, 0, 0, 0, 61, 0, 52, + 46, 53, 47, 0, 0, 0, 0, 49, 0, 50, + 51, 48, 0, 0, 146, 271, 0, 0, 42, 75, + 108, 275, 111, 136, 113, 114, 78, 118, 119, 120, + 123, 76, 79, 247, 81, 126, 74, 128, 77, 130, + 131, 276, 133, 134, 138, 0, 32, 33, 0, 34, 8, 0, 10, 0, 9, 0, 1, 21, 12, 0, 13, 0, 14, 0, 19, 20, 0, 15, 16, 0, - 17, 18, 11, 23, 7, 350}; + 17, 18, 11, 23, 7, 351}; const short QQmlJSGrammar::goto_default [] = { - 7, 626, 207, 196, 205, 509, 497, 625, 644, 496, - 624, 622, 627, 22, 623, 18, 508, 550, 540, 547, - 542, 527, 191, 195, 197, 201, 233, 208, 230, 531, - 571, 570, 200, 232, 26, 475, 474, 357, 356, 9, - 355, 358, 107, 17, 145, 24, 13, 144, 19, 25, - 57, 23, 8, 28, 27, 270, 15, 264, 10, 260, - 12, 262, 11, 261, 20, 268, 21, 269, 14, 263, - 259, 300, 412, 265, 266, 202, 193, 192, 204, 203, - 229, 194, 361, 360, 231, 464, 463, 322, 323, 466, - 325, 465, 324, 420, 424, 427, 423, 422, 442, 443, - 185, 199, 181, 184, 198, 206, 0}; + 7, 636, 211, 198, 209, 521, 509, 635, 654, 508, + 634, 632, 637, 22, 633, 18, 520, 562, 552, 559, + 554, 539, 193, 197, 199, 204, 234, 212, 231, 543, + 583, 582, 203, 233, 26, 487, 486, 359, 358, 9, + 357, 360, 202, 480, 361, 109, 17, 147, 24, 13, + 146, 19, 25, 59, 23, 8, 28, 27, 280, 15, + 274, 10, 270, 12, 272, 11, 271, 20, 278, 21, + 279, 14, 273, 269, 310, 414, 275, 276, 205, 195, + 194, 208, 207, 230, 196, 364, 363, 232, 471, 470, + 332, 333, 473, 335, 472, 334, 427, 431, 434, 430, + 429, 449, 450, 200, 186, 201, 210, 0}; const short QQmlJSGrammar::action_index [] = { - 425, 1471, 2619, 2619, 2718, 1193, 69, 100, 86, -103, - 97, 62, 60, 236, -103, 278, 93, -103, -103, 609, - 83, 117, 266, 184, -103, -103, -103, 514, 179, 1471, - -103, -103, -103, 392, -103, 2421, 1754, 1471, 1471, 1471, - -103, 1001, 1471, -103, -103, -103, 1471, 1471, -103, -103, - -103, -103, -103, 1471, -103, 1471, 1471, -103, 1471, 1471, - 115, 169, -103, -103, 1471, 1471, 1471, -103, -103, -103, - 152, 1471, 286, 1471, 1471, 1471, 1471, 562, 1471, 1471, - 1471, 1471, 1471, 1471, 198, 1471, 1471, 1471, 87, 122, - 138, 212, 197, 183, 227, 265, 562, 504, 472, 1471, - 79, 1471, 102, 2322, 1471, 1471, -103, -103, -103, -103, - -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, - -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, - -103, -103, -103, -103, -103, -103, -103, -103, -103, -103, - 132, 1471, -103, -103, 94, 11, -103, 1471, -103, -103, - 1471, -103, -103, -103, -103, -103, -103, -103, -103, -103, - -103, -103, -103, -103, 1471, 31, 1471, 1471, 67, 68, - 1471, -103, 2322, 1471, 1471, -103, 98, -103, 39, -103, - -103, 61, -103, 296, 66, 30, -103, 376, -103, 35, - 2619, -103, -103, -103, -103, -103, 237, -103, -103, 21, - -103, -103, -103, -103, -103, -103, 2619, -103, -103, 513, - -103, 541, 114, 2718, 36, 422, 59, 42, 2916, 75, - 1471, -103, 77, 53, 1471, 63, -103, 57, 58, -103, - -103, 407, -103, -103, -103, -103, -103, -103, 80, -103, - -103, -103, -103, 82, -103, -103, -103, -103, -103, -103, - 52, 51, 1471, 96, 200, -103, -103, -103, 1659, -103, - 76, 44, 46, -103, 298, 73, 48, 736, 78, 95, - 363, 233, 347, 1471, 303, 1471, 1471, 1471, 1471, 402, - 1471, 1471, 1471, 1471, 1471, 248, 189, 159, 167, 174, - 482, 482, 444, 1471, 7, 1471, 64, 1471, -103, 627, - 1471, -103, 1471, 65, 34, 1471, 54, 2718, -103, 1471, - 140, 2718, -103, 1471, 74, 1471, 1471, 81, 84, 1471, - -103, 71, 116, 33, -103, -103, 1471, -103, 313, 1471, - -103, 70, 1471, 72, 2718, -103, 1471, 234, 2718, -103, - -16, 324, -42, -12, 2619, -39, -103, 2718, -103, 1471, - 151, 2718, 12, 2718, -103, 20, 16, -32, -103, -103, - 2718, -52, 521, -2, 505, 129, 1471, 2718, -5, -35, - 497, 2, -24, 819, 6, 3, -103, 1567, -103, -1, - -36, 26, 1471, 47, 22, 1471, 45, 1471, 17, 15, - 1471, -103, 2520, 49, -103, -103, -103, -103, -103, -103, - 1471, -103, -103, -103, -103, 322, -103, 1471, -25, -103, - 2718, -103, 118, -103, -103, 2718, -103, 1471, 112, 8, - -103, 40, -103, 41, 106, 1471, -103, 38, 32, -103, - -38, -103, 2718, -103, 104, 2718, -103, 247, -103, -103, - 99, 2718, -6, -103, -10, -18, -103, 387, 10, 9, - -103, -103, -103, -103, 1471, 125, 2718, -103, 1471, 127, - 2718, -103, -13, -103, 187, -103, -103, 1471, -103, -103, - 398, -103, -103, -103, 110, 2039, -103, -103, 1849, -103, - -103, 1944, -103, -103, -103, -103, -103, -103, 105, -103, - -103, -103, -103, -103, -103, -103, -103, -103, 2619, -103, - -103, -103, 113, -7, 1009, 145, -8, 19, -103, -103, - 186, -103, 178, -103, -103, -103, 356, 226, -103, 2131, - -103, -103, -103, -103, -103, -103, -103, -103, -103, 322, - -26, 364, 205, 43, 316, 206, -103, -3, -103, 1009, - 107, -103, -11, 827, -103, -103, 1379, -103, -103, -103, - 1286, -103, -103, 195, -103, 2131, -103, 305, -4, -103, - -103, 209, 379, 18, 2131, -103, 182, -103, 199, -103, - 0, -53, 306, 154, 284, -103, 108, -103, -103, -103, - 2223, 918, 300, 2817, 1754, 5, -103, 549, 139, 636, - 114, 1471, 2718, 50, 24, 463, 55, -17, 910, 23, - 56, -103, 1567, -103, 27, 1, 29, 1471, 37, 14, - 1471, 25, 1471, 4, 13, 126, -103, -103, 28, -103, - -103, 1100, -103, 267, -41, 714, -103, -103, 121, 301, - -103, 215, -103, 91, -103, -103, 336, -103, -103, 89, - -103, -103, -103, -103, -103, -103, + 235, 1289, 2663, 2663, 2562, 1005, 64, 90, 103, -105, + 88, 94, 79, 173, -105, 302, 69, -105, -105, 724, + 65, 135, 195, 239, -105, -105, -105, 367, 278, 1289, + -105, -105, -105, 485, -105, -105, 2360, 1772, 1289, 1289, + 1289, -105, 817, 1289, -105, -105, -105, 1289, 1289, -105, + -105, -105, -105, -105, -105, 1289, -105, 1289, 1289, -105, + 1289, 1289, 95, 207, -105, -105, 1289, 1289, 1289, -105, + -105, -105, 202, 1289, 300, 1289, 1289, 1289, 1289, 377, + 1289, 1289, 1289, 1289, 1289, 1289, 253, 1289, 1289, 1289, + 151, 147, 129, 196, 170, 199, 279, 270, 470, 470, + 387, 1289, 53, 1289, 80, 2158, 1289, 1289, -105, -105, + -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, + -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, + -105, -105, -105, -105, -105, -105, -105, -105, -105, -105, + -105, -105, 128, 1289, -105, -105, 74, 52, -105, 1289, + -105, -105, 1289, -105, -105, -105, -105, -105, -105, -105, + -105, -105, -105, -105, -105, -105, 1289, 51, 1289, 1289, + 77, 66, 1289, -105, 2158, 1289, 1289, -105, 125, -105, + 48, -105, -105, 47, 451, 374, 83, 87, -105, 397, + -105, 62, 2663, -105, -105, -105, -105, -105, 205, -105, + 415, -105, 68, -105, -105, -105, 86, -105, -105, -105, + 2663, -105, -105, 622, -105, 576, 102, 2562, 75, 89, + 81, 2865, 1289, -105, 70, 1289, 63, -105, 92, 93, + -105, -105, 546, -105, -105, -105, -105, 91, 546, 40, + 45, 2663, 49, -105, -105, 2562, -105, -105, 106, -105, + -105, -105, -105, 121, -105, -105, -105, -105, -105, -105, + 42, 44, 1289, 114, 222, -105, -105, -105, 1481, -105, + 84, 57, 56, -105, 388, 78, 54, 682, 82, 99, + 357, 247, 546, 1289, 295, 1289, 1289, 1289, 1289, 334, + 1289, 1289, 1289, 1289, 1289, 203, 217, 244, 263, 211, + 341, 319, 351, 1289, 56, 1289, 73, 1289, -105, 724, + 1289, -105, 1289, 67, 46, 1289, 61, 2562, -105, 1289, + 136, 2562, -105, 1289, 76, 1289, 1289, 85, 59, 1289, + -105, 71, 133, 72, -105, -105, 1289, -105, 546, 1289, + -105, -53, 1289, -60, 2562, -105, 1289, 143, 2562, -105, + 1289, 132, 2562, 8, 2562, -105, 7, -105, 12, -37, + 107, -105, -105, 2562, -33, 622, 22, 555, 115, 1289, + 2562, 23, -13, 502, 2259, -10, 817, 18, 6, 1387, + 2259, 0, 9, -6, 1289, -4, -23, 1289, 5, 1289, + -25, -27, 2461, -105, -105, -105, -105, -105, -105, 1289, + -105, -105, -105, -3, -1, 21, 2663, 1, -105, 218, + -105, 1289, 4, -105, 111, -105, -105, 26, 466, 16, + 38, 2663, 39, -105, 1289, 110, 37, -105, 55, -105, + 60, 116, 1289, -105, 58, 43, -105, -15, -105, 2562, + -105, 123, 2562, -105, 154, -105, -105, 96, 2562, 32, + -105, 3, 14, -105, 546, -11, 13, -105, -105, -105, + -105, 1289, 126, 2562, -105, 1289, 130, 2562, -105, 15, + -105, 301, -105, -105, 1289, -105, -105, 546, -105, -105, + -45, -12, 2663, -24, -105, -105, 204, 1578, -105, -105, + 1869, -105, -105, 1675, -105, -105, -105, -105, -105, -105, + 101, -105, -105, -105, -105, -105, -105, -105, -105, -105, + 2663, -105, -105, -105, 105, 2, 910, 206, -47, -2, + -105, -105, 246, -105, 214, -105, -105, -105, 364, 232, + -105, 1963, -105, -105, -105, -105, -105, -105, -105, -105, + -105, 191, 24, 394, 172, -18, 384, 215, -105, -30, + -105, 910, 149, -105, -16, 910, -105, -105, 1100, -105, + -105, -105, 1195, -105, -105, 225, -105, 1963, -105, 316, + -17, -105, -105, 269, 418, -5, 1963, -105, 184, -105, + 175, -105, 20, -9, 546, 182, 469, -105, 104, -105, + -105, -105, 2057, 910, 292, 2764, 1772, 10, -105, 35, + 622, 34, 525, 98, 1289, 2562, 50, 17, 536, 19, + 817, 31, 27, 1387, 28, 9, 29, 1289, 30, 11, + 1289, 41, 1289, 33, 36, 137, -105, -105, 25, -105, + -105, 910, -105, 268, -86, 910, -105, -105, 141, 546, + -105, 156, -105, 117, -105, -105, 546, -105, -105, 138, + -105, -105, -105, -105, -105, -105, - -107, 12, -95, 3, 6, 275, 2, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -37, - -107, -107, -107, -107, -107, -107, -107, -107, -107, 96, - -107, -107, -107, 8, -107, -107, -17, 24, 95, 74, - -107, 85, 175, -107, -107, -107, 172, 168, -107, -107, - -107, -107, -107, 169, -107, 165, 164, -107, 156, 176, - -107, -107, -107, -107, 182, 178, 112, -107, -107, -107, - -107, 121, -107, 144, 118, 116, 117, -107, 108, 133, - 134, 137, 143, 152, -107, 147, 141, 136, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, 107, - -107, 173, -107, 153, 84, 56, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, 36, -107, -107, -107, -107, -107, 30, -107, -107, - 0, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, 79, -107, 99, 44, -107, -107, - 46, -107, 194, 70, 64, -107, -107, -107, -107, -107, - -107, -107, -107, 29, -107, -107, -107, 65, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, 80, -107, -107, 51, - -107, 48, -107, 40, -107, 34, -107, -107, 86, -107, - 88, -107, -107, -107, 78, 60, -107, -107, -107, -107, - -107, -6, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, 21, -107, -107, -107, -107, -107, 104, -107, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, 16, 201, -107, 202, 224, 223, 215, -107, - 67, 73, 75, 59, 106, -107, -107, -107, -107, -107, - -107, -107, -107, 185, -107, 208, -107, 233, -107, -107, - 234, -107, 203, -107, -107, 299, -107, 90, -107, -2, - -107, 11, -107, 181, -107, 200, 192, -107, -107, 189, - -107, -107, -107, -107, -107, -107, 199, -107, 123, 131, - -107, -107, 111, -107, 77, -107, 87, -107, 195, -107, - -107, 110, -107, -107, -50, -107, -107, 39, -107, 42, - -107, 63, -107, 66, -107, -107, -107, -107, -107, -107, - 68, -107, 43, -107, 47, -107, 92, 35, -107, -107, - 31, -107, -107, 105, -107, -107, -107, 94, -107, -107, - -107, -107, 71, -107, 54, 101, -107, 89, -107, -107, - 55, -107, 49, -107, -107, -107, -107, -107, -107, -107, - 38, -107, -107, -107, -107, -107, -107, 114, -107, -107, - 76, -107, -107, -107, -107, 91, -107, 93, -107, -107, - -107, -107, -107, -57, -107, 50, -107, -44, -107, -107, - -107, -107, 98, -107, -107, 97, -107, -107, -107, -107, - -107, 52, -42, -107, -107, 45, -107, 41, -107, 37, - -107, -107, -107, -107, 57, -107, 53, -107, 58, -107, - 62, -107, -107, -107, -107, -107, -107, 9, -107, -107, - 187, -107, -107, -107, -107, 33, -107, -107, 139, -107, - -107, 32, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -107, -107, -107, -107, -107, -107, -107, 82, -107, - -107, -107, -107, -107, -11, -107, -107, -107, -107, -107, - -107, -107, -25, -107, -107, -107, -9, -107, -107, 297, - -107, -107, -107, -107, -107, -107, -107, -107, -107, -107, - -107, -3, -26, -107, -10, -107, -107, -107, -107, 160, - -107, -107, -107, 120, -107, -107, 279, -107, -107, -107, - 285, -107, -107, -107, -107, 329, -107, -107, 17, -107, - -107, -13, 14, -107, 385, -107, -107, -107, 23, -107, - -107, -107, 28, 18, 20, -107, -107, -107, -107, -107, - 313, 188, -107, 26, 267, 7, -107, 5, -107, -1, - -107, 69, 19, -107, -107, 10, -107, -107, 103, -107, - -107, -107, 27, -107, -107, -107, -107, 15, -107, -5, - 61, -107, 81, -107, -107, -107, -107, -107, 13, -107, - -107, 25, -107, -107, 22, 119, -107, -107, -107, 4, - -107, -107, -107, -107, -107, -107, -15, -107, -107, -107, - -107, -107, -107, -107, -107, -107}; + -108, 0, 79, 128, 132, 301, 2, -108, -108, -108, + -108, -108, -108, -108, -108, -108, -108, -108, -108, -47, + -108, -108, -108, -108, -108, -108, -108, -108, -108, 51, + -108, -108, -108, -3, -108, -108, 8, -23, 12, 78, + 106, -108, 69, 74, -108, -108, -108, 195, 204, -108, + -108, -108, -108, -108, -108, 188, -108, 201, 200, -108, + 127, 129, -108, -108, -108, -108, 140, 137, 133, -108, + -108, -108, -108, 146, -108, 177, 168, 170, 167, -108, + 144, 152, 166, 158, 160, 131, -108, 194, 187, 207, + -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, + -108, 88, -108, 112, -108, 121, 90, -38, -108, -108, + -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, + -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, + -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, + -108, -108, -108, 32, -108, -108, -108, -108, -108, 26, + -108, -108, 27, -108, -108, -108, -108, -108, -108, -108, + -108, -108, -108, -108, -108, -108, 102, -108, 103, 41, + -108, -108, 37, -108, 250, 38, 83, -108, -108, -108, + -108, -108, -108, -108, 42, 126, -108, -108, -108, 40, + -108, -108, 43, -108, -108, -108, -108, -108, -108, -108, + 39, -108, -108, -108, -108, -108, -108, -108, -108, -108, + 225, -108, -108, 30, -108, 24, -108, 211, -108, 55, + -108, 77, 60, -108, -108, 66, 34, -108, -108, -108, + -108, -108, -8, -108, -108, -108, -108, -108, 153, -108, + -108, 164, -108, -108, -108, 241, -108, -108, -108, -108, + -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, + -108, -108, 11, -108, -108, -108, -108, -108, 179, -108, + -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, + -108, -108, 19, 259, -108, 255, 228, 240, 246, -108, + 52, 63, 67, 65, 50, -108, -108, -108, -108, -108, + -108, -108, -108, 210, -108, 256, -108, 226, -108, -108, + 252, -108, 161, -108, -108, 268, -108, 197, -108, 5, + -108, 218, -108, 222, -108, 213, 249, -108, -108, 236, + -108, -108, -108, -108, -108, -108, 212, -108, 80, 87, + -108, -108, 86, -108, 98, -108, 61, -108, 245, -108, + 59, -108, 208, -108, 192, -108, -108, -108, -108, -108, + -108, -108, -108, 257, -108, 33, -108, 28, -108, 73, + 71, -108, -108, 36, 57, -108, 62, -108, -108, 46, + 70, -108, -108, -108, 49, -108, 45, 99, -108, 84, + -108, -108, 100, -108, -108, -108, -108, -108, -108, 21, + -108, -108, -108, -108, -108, -108, 118, -108, -108, -108, + -108, 81, -108, -108, -108, -108, -108, -108, 123, -108, + -108, 134, -108, -108, 56, -108, -108, -108, -108, -108, + -58, -108, 47, -108, -57, -108, -108, -108, -108, 265, + -108, -108, 374, -108, -108, -108, -108, -108, 94, -66, + -108, -108, 25, -108, 22, -108, 31, -108, -108, -108, + -108, 58, -108, 229, -108, 35, -108, 235, -108, -108, + -108, -108, -108, -108, 29, -108, -108, 186, -108, -108, + -108, -108, 162, -108, -108, -108, -108, 48, -108, -108, + 163, -108, -108, 44, -108, -108, -108, -108, -108, -108, + -108, -108, -108, -108, -108, -108, -108, -108, -108, -108, + 141, -108, -108, -108, -108, -108, -7, -108, -108, -108, + -108, -108, -108, -108, -19, -108, -108, -108, -6, -108, + -108, 334, -108, -108, -108, -108, -108, -108, -108, -108, + -108, -108, -108, -15, -27, -108, -10, -108, -108, -108, + -108, 159, -108, -108, -108, 176, -108, -108, 319, -108, + -108, -108, 322, -108, -108, -108, -108, 469, -108, -108, + 10, -108, -108, 6, 16, -108, 342, -108, -108, -108, + 17, -108, -108, -108, 15, 3, 9, -108, -108, -108, + -108, -108, 358, 68, -108, 82, 310, 1, -108, -108, + -2, -108, 7, -108, 54, 76, -108, -108, 4, -108, + 64, -108, -108, 23, -108, -108, -108, 18, -108, -5, + 95, -108, 91, -108, -108, -108, -108, -108, -1, -108, + -108, 20, -108, -108, 14, 142, -108, -108, -108, 13, + -108, -108, -108, -108, -108, -108, -11, -108, -108, -108, + -108, -108, -108, -108, -108, -108}; const short QQmlJSGrammar::action_info [] = { - 417, 258, -113, 404, 467, -132, -102, 576, 573, 347, - -103, 532, 349, -121, 445, 441, 346, 431, 343, 349, - 341, 344, 546, 402, 392, 564, 447, 390, 353, 546, - -121, 539, -129, -124, -102, 409, -124, 417, 546, 432, - 454, 421, 441, 425, -126, 425, 425, 441, 566, 458, - 621, 458, -129, 454, -126, 441, 400, -113, 561, 512, - 258, 546, 347, -103, 336, 273, 347, 534, 190, 164, - 449, 149, 258, 141, 187, 170, 236, 273, 349, 99, - 313, 297, 410, 313, 415, 164, 295, 252, 326, 417, - 189, 319, 293, 454, 458, 305, 441, 183, 71, 179, - 645, 141, 147, 71, 141, 444, 141, 0, 0, 302, - 99, 435, 141, 141, 307, 543, 428, 0, 478, 445, - 141, 0, 293, 0, 328, 295, 58, 58, 172, 251, - 0, 332, 334, 141, 543, 141, 172, 59, 59, 101, - 141, 242, 241, 247, 246, 315, -132, 173, 141, 316, - 641, 640, 635, 634, 177, 173, 254, 62, 101, 141, - 621, 429, 58, 544, 64, 489, 479, 166, 63, 578, - 577, 167, 419, 59, 530, 249, 248, 329, 58, 414, - 413, 64, 616, 513, 85, 456, 86, 460, 142, 59, - 249, 248, 85, 580, 86, 470, 64, 87, 0, 85, - 311, 86, 555, 0, 85, 87, 86, 513, 85, 65, - 86, 351, 87, 537, 85, 66, 86, 87, 568, 546, - 515, 87, 85, 85, 86, 86, 65, 87, 513, 515, - 0, 514, 66, 519, 513, 87, 87, 85, 513, 86, - 514, 65, 141, 569, 567, 141, 0, 66, 471, 469, - 87, 103, 85, 515, 86, 141, 556, 554, 85, 0, - 86, 257, 255, 0, 514, 87, 0, 538, 536, 0, - 104, 87, 105, 85, 515, 86, 638, 637, 0, 581, - 515, 172, 0, 0, 515, 514, 87, 520, 518, 256, - 85, 514, 86, 0, 338, 514, 73, 74, 235, 234, - 173, 0, 174, 87, 73, 74, 0, 636, 439, 438, - 0, 0, 0, 34, 631, 172, 275, 276, 0, 0, - 172, 275, 276, 75, 76, 34, 0, 0, 632, 630, - 34, 75, 76, -90, 173, 34, 174, 172, -90, 173, - 0, 174, 34, 277, 278, 34, 0, 0, 277, 278, - 48, 50, 49, 34, 0, 0, 173, 0, 407, 629, - 0, 0, 48, 50, 49, 34, 0, 48, 50, 49, - 0, 0, 48, 50, 49, 0, 34, 45, 0, 48, - 50, 49, 48, 50, 49, 34, 280, 281, 0, 45, - 48, 50, 49, 34, 45, 282, 0, 0, 283, 45, - 284, 0, 48, 50, 49, 34, 45, 0, 34, 45, - 0, 0, 0, 48, 50, 49, 34, 45, 0, 0, - 0, 34, 48, 50, 49, 280, 281, 34, 0, 45, - 48, 50, 49, 0, 282, 0, 34, 283, 0, 284, - 45, 0, 48, 50, 49, 48, 50, 49, 0, 45, - 0, 34, 0, 48, 50, 49, 0, 45, 48, 50, - 49, 0, 0, 0, 48, 50, 49, 280, 281, 45, - 0, 0, 45, 48, 50, 49, 282, 0, 0, 283, - 45, 284, 0, 0, 0, 45, 0, 0, 48, 50, - 49, 45, 34, 0, 0, 78, 79, 0, 0, -346, - 45, 0, 0, 80, 81, 280, 281, 82, 0, 83, - 0, 0, 0, 0, 282, 45, 0, 283, 0, 284, - 6, 5, 4, 1, 3, 2, 34, 78, 79, 48, - 50, 49, 0, -346, 34, 80, 81, 78, 79, 82, - 0, 83, 34, 0, 0, 80, 81, 0, 0, 82, - 34, 83, 0, 0, 0, 0, 45, 0, 0, 0, - 0, 0, 0, 48, 50, 49, 245, 244, 0, 0, - 34, 48, 50, 49, 240, 239, 0, 0, 34, 48, - 50, 49, 240, 239, 0, 78, 79, 48, 50, 49, - 45, 0, 0, 80, 81, 0, 0, 82, 45, 83, - 0, 0, 245, 244, 0, 0, 45, 48, 50, 49, - 240, 239, 151, 0, 45, 48, 50, 49, 0, 0, - 0, 0, 152, 0, 0, 0, 153, 0, 0, 0, - 151, 0, 0, 0, 45, 154, 0, 155, 0, 0, - 152, 0, 45, 0, 153, 0, 0, 0, 156, 0, - 157, 62, 0, 154, 0, 155, 0, 0, 158, 0, - 0, 159, 63, 0, 0, 34, 156, 160, 157, 62, - 0, 0, 0, 161, 0, 0, 158, 0, 0, 159, - 63, 0, 0, 0, 0, 160, 0, 0, 0, 162, - 0, 161, 0, 0, 0, 0, 0, 245, 244, 0, - 0, 0, 48, 50, 49, 0, 0, 162, 0, 0, + 344, -127, 576, -129, 551, 631, 546, -105, 342, 465, + 448, 461, -132, -106, 245, 481, 558, 558, 398, 573, + 392, 482, 402, 268, 354, -124, 350, 578, 585, -135, + -116, 484, 474, 404, -106, -105, -127, -129, -124, 454, + 438, -135, 245, 558, 448, 424, 448, 448, -132, 456, + 439, 588, 452, 268, 406, 350, 408, -116, 558, 405, + 432, 544, 418, 432, 413, 432, 329, 166, 524, 461, + 428, 421, 465, 172, 283, 143, 420, 143, 241, 166, + 262, 73, 149, 185, 323, 283, 307, 323, 336, 73, + 655, 189, 0, 245, 423, 192, 448, 0, 0, 101, + 240, 0, 451, 346, 243, 303, 424, 315, 181, 143, + 0, 268, 151, 0, 399, 312, 452, 350, 143, 261, + 174, 317, 143, 244, 303, 184, 435, 238, 461, 465, + 442, 143, 103, 143, 143, 305, 143, 64, 143, 175, + 143, 338, 101, 60, 143, 555, 0, 191, 65, 325, + 0, 143, 0, 326, 61, 631, 174, 555, 103, 259, + 258, 501, 143, 259, 258, 590, 589, 252, 251, 60, + 426, 436, 416, 415, 264, 175, 259, 258, 645, 644, + 61, 179, 257, 256, 144, 168, 463, 60, 105, 169, + 467, 60, 352, 626, 339, 87, 321, 88, 61, 651, + 650, 525, 61, 348, 525, 556, 174, 106, 89, 107, + 174, 525, 490, 143, 66, 446, 445, 648, 647, 66, + 580, 87, 549, 88, 87, 175, 88, 411, 87, 175, + 88, 176, 567, 174, 89, 542, 87, 89, 88, 531, + 0, 89, 87, 525, 88, 581, 579, 527, 646, 89, + 527, 66, 175, 592, 411, 89, 0, 527, 526, 67, + 491, 526, 0, 0, 67, 68, 236, 235, 526, 87, + 68, 88, 87, 0, 88, 0, 550, 548, 87, 558, + 88, 527, 89, 267, 265, 89, 568, 566, 87, 527, + 88, 89, 526, 532, 530, 87, 67, 88, 525, 0, + 526, 89, 68, 87, 87, 88, 88, 174, 89, 477, + 0, 266, 0, 285, 286, 641, 89, 89, 75, 76, + 75, 76, 0, 0, 0, -92, 175, 0, 176, 642, + 640, 174, 6, 5, 4, 1, 3, 2, 0, 593, + 287, 288, 290, 291, 527, 77, 78, 77, 78, -92, + 175, 292, 176, 0, 293, 526, 294, 290, 291, 0, + 639, 0, 478, 476, 290, 291, 292, 0, 0, 293, + 0, 294, 0, 292, 290, 291, 293, 0, 294, 0, + 290, 291, 0, 292, 0, 0, 293, 0, 294, 292, + 80, 81, 293, 35, 294, 0, 0, 0, 82, 83, + 80, 81, 84, 35, 85, 0, 285, 286, 82, 83, + 80, 81, 84, 35, 85, 0, 0, 0, 82, 83, + 0, 0, 84, 35, 85, 0, 35, 0, 0, 0, + 49, 52, 50, 287, 288, 0, 0, 0, 0, 0, + 49, 52, 50, 0, 35, 0, 0, 35, 0, 0, + 49, 52, 50, 0, 0, 0, 0, 46, 34, 51, + 49, 52, 50, 49, 52, 50, 0, 46, 34, 51, + 0, 0, 0, 0, 0, 0, 0, 46, 34, 51, + 35, 49, 52, 50, 49, 52, 50, 46, 34, 51, + 46, 34, 51, 80, 81, 35, 0, 0, 35, 0, + 0, 82, 83, 0, 0, 84, 0, 85, 46, 34, + 51, 46, 34, 51, 35, 0, 0, 49, 52, 50, + 0, 184, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 35, 49, 52, 50, 49, 52, 50, 184, 0, + 0, 0, 0, 0, 46, 34, 51, 0, 0, 0, + 0, 49, 52, 50, 35, 0, 0, 0, 0, 46, + 34, 51, 46, 34, 51, 35, 0, 0, 49, 52, + 50, 0, 184, 0, 0, 35, 0, 0, 46, 34, + 51, 0, 0, 0, 35, 0, 255, 254, 0, 0, + 0, 49, 52, 50, 0, 46, 34, 51, 0, 0, + 0, 0, 49, 52, 50, 35, 0, 0, 0, 0, + 0, 0, 49, 52, 50, 0, 255, 254, 46, 34, + 51, 49, 52, 50, 0, 0, 0, 0, 0, 46, + 34, 51, 0, 0, 0, 0, 0, 255, 254, 46, + 34, 51, 49, 52, 50, 0, 0, 0, 46, 34, + 51, 35, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 46, + 34, 51, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 250, 249, 153, 0, 0, 49, 52, + 50, 0, 0, 0, 0, 154, 0, 0, 0, 155, + 0, 0, 0, 0, 0, 0, 0, 0, 156, 0, + 157, 0, 0, 319, 0, 46, 34, 51, 0, 0, + 0, 158, 0, 159, 64, 0, 0, 153, 0, 0, + 0, 160, 0, 0, 161, 65, 0, 154, 0, 0, + 162, 155, 0, 0, 0, 0, 163, 0, 0, 0, + 156, 0, 157, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 164, 158, 0, 159, 64, 0, 0, 0, + 0, 0, 0, 160, 0, 0, 161, 65, 0, 0, + 0, 0, 162, 0, 0, 0, 0, 0, 163, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 30, 31, 0, 45, - 0, 0, 0, 0, 0, 0, 33, 0, 0, 151, - 0, 0, 0, 34, 0, 0, 0, 35, 36, 152, - 37, 0, 0, 153, 0, 0, 0, 504, 0, 0, - 0, 44, 154, 0, 155, 0, 0, 309, 0, 0, - 0, 0, 0, 0, 0, 156, 0, 157, 62, 51, - 48, 50, 49, 0, 52, 158, 0, 0, 159, 63, - 0, 0, 0, 0, 160, 43, 54, 32, 0, 0, - 161, 40, 0, 0, 0, 0, 0, 45, 0, 0, - 0, 0, 0, 0, 0, 0, 162, 0, 0, 0, + 0, 0, 0, 0, 164, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 30, 31, 0, 0, 0, 0, 0, 0, 30, - 31, 33, 0, 0, 0, 0, 0, 0, 34, 33, - 0, 0, 35, 36, 0, 37, 34, 0, 0, 0, - 35, 36, 41, 37, 0, 0, 44, 0, 0, 0, - 504, 0, 0, 0, 44, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 51, 48, 50, 49, 0, 52, - 0, 0, 51, 48, 50, 49, 0, 52, 0, 0, - 43, 54, 32, 0, 0, 0, 40, 0, 43, 54, - 32, 0, 45, 0, 40, 0, 0, 0, 0, 0, - 45, 0, 30, 31, 0, 0, 0, 0, 0, 0, - 30, 31, 33, 0, 0, 0, 0, 0, 0, 34, - 33, 0, 0, 35, 36, 0, 37, 34, 0, 0, - 0, 35, 36, 41, 37, 0, 0, 44, 0, 0, - 0, 504, 0, 0, 0, 44, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 51, 48, 50, 49, 0, - 52, 0, 0, 51, 48, 50, 49, 0, 52, 0, - 0, 43, 54, 32, 0, 0, 0, 40, 0, 43, - 54, 32, 0, 45, 0, 40, 0, 0, 0, 0, - 0, 45, 0, 30, 31, 0, 0, 0, 0, 0, - 0, 30, 31, 33, 0, 0, 0, 0, 0, 0, - 34, 33, 0, 0, 35, 36, 0, 37, 34, 0, - 0, 0, 35, 36, 41, 37, 0, 0, 44, 0, - 0, 0, 504, 0, 0, 0, 44, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 51, 48, 50, 49, - 0, 52, 0, 0, 51, 48, 50, 49, 0, 52, - 0, 0, 43, 54, 32, 0, 0, 0, 40, 0, - 43, 54, 32, 0, 45, 0, 40, 0, 0, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, + 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, + 36, 37, 0, 38, 0, 0, 0, 0, 0, 0, + 42, 0, 0, 0, 45, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 53, 49, 52, 50, 0, 54, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 44, 56, + 32, 0, 0, 0, 41, 0, 0, 0, 0, 0, + 46, 34, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30, 31, 0, 0, 0, 0, 0, 0, - 0, 0, 33, 0, 0, 0, 0, 0, 0, 34, - 0, 0, 0, 35, 36, 0, 37, 0, 0, 0, - 0, 0, 0, 504, 0, 0, 0, 44, 0, 0, + 0, 0, 33, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 0, 36, 37, 0, 38, 0, 0, 0, + 0, 0, 0, 516, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 51, 48, 50, 49, 0, - 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 43, 54, 32, 0, 0, 0, 40, 0, 0, - 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 503, 0, 30, 31, 0, 0, 0, - 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, - 0, 0, 34, 0, 0, 0, 35, 36, 0, 37, - 0, 0, 0, 0, 0, 0, 504, 0, 0, 0, - 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 51, 505, - 507, 506, 0, 52, 0, 0, 0, 0, 226, 0, - 0, 0, 0, 0, 43, 54, 32, 210, 0, 0, - 40, 0, 0, 0, 0, 0, 45, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 503, 0, 30, 31, - 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, - 0, 0, 0, 0, 0, 34, 0, 0, 0, 35, - 36, 0, 37, 0, 0, 0, 0, 0, 0, 504, - 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, - 0, 551, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 51, 505, 507, 506, 0, 52, 0, 0, 0, - 0, 226, 0, 0, 0, 0, 0, 43, 54, 32, - 210, 0, 0, 40, 0, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 503, - 0, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 215, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 0, 35, 36, 0, 37, 0, 0, 0, 0, - 0, 0, 504, 0, 0, 0, 44, 0, 0, 0, - 0, 0, 0, 0, 548, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 51, 505, 507, 506, 0, 52, - 0, 0, 0, 0, 226, 0, 0, 0, 0, 0, - 43, 54, 32, 210, 0, 0, 40, 0, 0, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 29, 30, 31, 0, 0, 0, 0, 0, - 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 34, 0, 0, 0, 35, 36, 0, 37, 0, 0, - 0, 38, 0, 39, 41, 42, 0, 0, 44, 0, - 0, 0, 46, 0, 47, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 51, 48, 50, 49, - 0, 52, 0, 53, 0, 55, 0, 56, 0, 0, - 0, 0, 43, 54, 32, 0, 0, 0, 40, 0, - 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, - 0, 0, 0, 0, -122, 0, 0, 0, 29, 30, - 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, - 0, 0, 0, 0, 0, 0, 34, 0, 0, 0, - 35, 36, 0, 37, 0, 0, 0, 38, 0, 39, - 41, 42, 0, 0, 44, 0, 0, 0, 46, 0, - 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 51, 48, 50, 49, 0, 52, 0, 53, - 0, 55, 0, 56, 0, 0, 0, 0, 43, 54, - 32, 0, 0, 0, 40, 0, 0, 0, 0, 0, - 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 0, 35, 36, 0, 37, 0, 0, 0, 38, - 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, - 46, 0, 47, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 51, 48, 50, 49, 0, 52, - 0, 53, 0, 55, 272, 56, 0, 0, 0, 0, - 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, + 0, 0, 0, 0, 0, 53, 49, 52, 50, 0, + 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 44, 56, 32, 0, 0, 0, 41, 0, 0, + 0, 0, 0, 46, 34, 51, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 515, 0, 30, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 219, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 0, 36, 37, + 0, 38, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 476, 0, 0, 29, 30, 31, 0, 0, - 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, - 0, 0, 0, 34, 0, 0, 0, 35, 36, 0, - 37, 0, 0, 0, 38, 0, 39, 41, 42, 0, - 0, 44, 0, 0, 0, 46, 0, 47, 0, 0, - 477, 0, 0, 0, 0, 0, 0, 0, 0, 51, - 48, 50, 49, 0, 52, 0, 53, 0, 55, 0, - 56, 0, 0, 0, 0, 43, 54, 32, 0, 0, - 0, 40, 0, 0, 0, 0, 0, 45, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 476, 0, 0, - 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 0, 35, 36, 0, 37, 0, 0, 0, 38, - 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, - 46, 0, 47, 0, 0, 482, 0, 0, 0, 0, - 0, 0, 0, 0, 51, 48, 50, 49, 0, 52, - 0, 53, 0, 55, 0, 56, 0, 0, 0, 0, - 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 53, 517, 519, 518, 0, 54, 0, 0, 0, 0, + 227, 0, 0, 0, 0, 0, 44, 56, 32, 214, + 0, 0, 41, 0, 0, 0, 0, 0, 46, 34, + 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 515, 0, 30, 31, 0, 0, 0, 0, 0, 0, + 0, 0, 219, 0, 0, 0, 0, 0, 0, 35, + 0, 0, 0, 36, 37, 0, 38, 0, 0, 0, + 0, 0, 0, 516, 0, 0, 0, 45, 0, 0, + 0, 0, 0, 0, 0, 560, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 53, 517, 519, 518, 0, + 54, 0, 0, 0, 0, 227, 0, 0, 0, 0, + 0, 44, 56, 32, 214, 0, 0, 41, 0, 0, + 0, 0, 0, 46, 34, 51, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 515, 0, 30, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 219, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 0, 36, 37, + 0, 38, 0, 0, 0, 0, 0, 0, 516, 0, 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 484, 0, 0, 29, 30, 31, 0, 0, - 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, - 0, 0, 0, 34, 0, 0, 0, 35, 36, 0, - 37, 0, 0, 0, 38, 0, 39, 41, 42, 0, - 0, 44, 0, 0, 0, 46, 0, 47, 0, 0, - 485, 0, 0, 0, 0, 0, 0, 0, 0, 51, - 48, 50, 49, 0, 52, 0, 53, 0, 55, 0, - 56, 0, 0, 0, 0, 43, 54, 32, 0, 0, - 0, 40, 0, 0, 0, 0, 0, 45, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 484, 0, 0, + 563, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 53, 517, 519, 518, 0, 54, 0, 0, 0, 0, + 227, 0, 0, 0, 0, 0, 44, 56, 32, 214, + 0, 0, 41, 0, 0, 0, 0, 0, 46, 34, + 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, - 0, 33, 0, 0, 0, 0, 0, 0, 34, 0, - 0, 0, 35, 36, 0, 37, 0, 0, 0, 38, - 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, - 46, 0, 47, 0, 0, 487, 0, 0, 0, 0, - 0, 0, 0, 0, 51, 48, 50, 49, 0, 52, - 0, 53, 0, 55, 0, 56, 0, 0, 0, 0, - 43, 54, 32, 0, 0, 0, 40, 0, 0, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, + 0, 33, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 0, 36, 37, 0, 38, 0, 0, 0, 39, + 0, 40, 42, 43, 0, 0, 45, 0, 0, 0, + 47, 0, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 53, 49, 52, 50, 0, 54, + 0, 55, 0, 57, 0, 58, 0, 0, 0, 0, + 44, 56, 32, 0, 0, 0, 41, 0, 0, 0, + 0, 0, 46, 34, 51, 0, 0, 0, 0, 0, + 0, 0, 0, 0, -125, 0, 0, 0, 29, 30, + 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, + 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, + 36, 37, 0, 38, 0, 0, 0, 39, 0, 40, + 42, 43, 0, 0, 45, 0, 0, 0, 47, 0, + 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 53, 49, 52, 50, 0, 54, 0, 55, + 0, 57, 0, 58, 0, 0, 0, 0, 44, 56, + 32, 0, 0, 0, 41, 0, 0, 0, 0, 0, + 46, 34, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, - 34, 217, 0, 0, 218, 36, 0, 37, 0, 0, - 0, 38, 0, 39, 41, 42, 0, 0, 44, 0, - 0, 0, 46, 0, 47, 0, 0, 0, 0, 0, - 0, 0, 221, 0, 0, 0, 51, 48, 50, 49, - 223, 52, 0, 53, 225, 55, 0, 56, 0, 228, - 0, 0, 43, 54, 32, 0, 0, 0, 40, 0, - 0, 0, 0, 0, 45, 0, 0, 0, 0, 0, + 35, 0, 0, 0, 36, 37, 0, 38, 0, 0, + 0, 39, 0, 40, 42, 43, 0, 0, 45, 0, + 0, 0, 47, 0, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 53, 49, 52, 50, + 0, 54, 0, 55, 0, 57, 282, 58, 0, 0, + 0, 0, 44, 56, 32, 0, 0, 0, 41, 0, + 0, 0, 0, 0, 46, 34, 51, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 496, 0, 0, 29, + 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, + 33, 0, 0, 0, 0, 0, 0, 35, 0, 0, + 0, 36, 37, 0, 38, 0, 0, 0, 39, 0, + 40, 42, 43, 0, 0, 45, 0, 0, 0, 47, + 0, 48, 0, 0, 499, 0, 0, 0, 0, 0, + 0, 0, 0, 53, 49, 52, 50, 0, 54, 0, + 55, 0, 57, 0, 58, 0, 0, 0, 0, 44, + 56, 32, 0, 0, 0, 41, 0, 0, 0, 0, + 0, 46, 34, 51, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 496, 0, 0, 29, 30, 31, 0, + 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 0, 35, 0, 0, 0, 36, 37, + 0, 38, 0, 0, 0, 39, 0, 40, 42, 43, + 0, 0, 45, 0, 0, 0, 47, 0, 48, 0, + 0, 497, 0, 0, 0, 0, 0, 0, 0, 0, + 53, 49, 52, 50, 0, 54, 0, 55, 0, 57, + 0, 58, 0, 0, 0, 0, 44, 56, 32, 0, + 0, 0, 41, 0, 0, 0, 0, 0, 46, 34, + 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 488, 0, 0, 29, 30, 31, 0, 0, 0, 0, + 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, + 0, 35, 0, 0, 0, 36, 37, 0, 38, 0, + 0, 0, 39, 0, 40, 42, 43, 0, 0, 45, + 0, 0, 0, 47, 0, 48, 0, 0, 489, 0, + 0, 0, 0, 0, 0, 0, 0, 53, 49, 52, + 50, 0, 54, 0, 55, 0, 57, 0, 58, 0, + 0, 0, 0, 44, 56, 32, 0, 0, 0, 41, + 0, 0, 0, 0, 0, 46, 34, 51, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 488, 0, 0, + 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, + 0, 33, 0, 0, 0, 0, 0, 0, 35, 0, + 0, 0, 36, 37, 0, 38, 0, 0, 0, 39, + 0, 40, 42, 43, 0, 0, 45, 0, 0, 0, + 47, 0, 48, 0, 0, 494, 0, 0, 0, 0, + 0, 0, 0, 0, 53, 49, 52, 50, 0, 54, + 0, 55, 0, 57, 0, 58, 0, 0, 0, 0, + 44, 56, 32, 0, 0, 0, 41, 0, 0, 0, + 0, 0, 46, 34, 51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, - 0, 0, 34, 217, 0, 0, 583, 584, 0, 37, - 0, 0, 0, 38, 0, 39, 41, 42, 0, 0, - 44, 0, 0, 0, 46, 0, 47, 0, 0, 0, - 0, 0, 0, 0, 221, 0, 0, 0, 51, 48, - 50, 49, 223, 52, 0, 53, 225, 55, 0, 56, - 0, 228, 0, 0, 43, 54, 32, 0, 0, 0, - 40, 0, 0, 0, 0, 0, 45, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 109, 110, 111, 0, - 0, 113, 115, 116, 0, 0, 117, 0, 118, 0, - 0, 0, 120, 121, 122, 0, 0, 0, 0, 0, - 0, 34, 123, 124, 125, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 126, 0, 0, 0, 0, + 0, 0, 35, 220, 0, 0, 221, 37, 0, 38, + 0, 0, 0, 39, 0, 40, 42, 43, 0, 0, + 45, 0, 0, 0, 47, 0, 48, 0, 0, 0, + 0, 0, 0, 0, 223, 0, 0, 0, 53, 49, + 52, 50, 224, 54, 0, 55, 226, 57, 0, 58, + 0, 229, 0, 0, 44, 56, 32, 0, 0, 0, + 41, 0, 0, 0, 0, 0, 46, 34, 51, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 29, 30, + 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, + 0, 0, 0, 0, 0, 0, 35, 220, 0, 0, + 595, 596, 0, 38, 0, 0, 0, 39, 0, 40, + 42, 43, 0, 0, 45, 0, 0, 0, 47, 0, + 48, 0, 0, 0, 0, 0, 0, 0, 223, 0, + 0, 0, 53, 49, 52, 50, 224, 54, 0, 55, + 226, 57, 0, 58, 0, 229, 0, 0, 44, 56, + 32, 0, 0, 0, 41, 0, 0, 0, 0, 0, + 46, 34, 51, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 111, 112, 113, 0, 0, 115, 117, 118, + 0, 0, 119, 0, 120, 0, 0, 0, 122, 123, + 124, 0, 0, 0, 0, 0, 0, 35, 125, 126, + 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 131, 0, 0, + 0, 0, 0, 0, 49, 52, 50, 132, 133, 134, + 0, 136, 137, 138, 139, 140, 141, 0, 0, 129, + 135, 121, 114, 116, 130, 0, 0, 0, 0, 0, + 0, 46, 34, 51, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 111, 112, 113, 0, 0, 115, 117, + 118, 0, 0, 119, 0, 120, 0, 0, 0, 122, + 123, 124, 0, 0, 0, 0, 0, 0, 35, 125, + 126, 127, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 128, 0, 0, 0, 395, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 131, 0, + 0, 0, 0, 0, 397, 49, 52, 50, 132, 133, + 134, 0, 136, 137, 138, 139, 140, 141, 0, 0, + 129, 135, 121, 114, 116, 130, 0, 0, 0, 0, + 0, 0, 46, 34, 51, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 111, 112, 113, 0, 0, 115, + 117, 118, 0, 0, 119, 0, 120, 0, 0, 0, + 122, 123, 124, 0, 0, 0, 0, 0, 0, 35, + 125, 126, 127, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 128, 0, 0, 0, 395, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 131, + 0, 0, 0, 0, 0, 397, 49, 52, 50, 132, + 133, 134, 0, 136, 137, 138, 139, 140, 141, 0, + 0, 129, 135, 121, 114, 116, 130, 0, 0, 0, + 0, 0, 0, 46, 374, 380, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 111, 112, 113, 0, 0, + 115, 117, 118, 0, 0, 119, 0, 120, 0, 0, + 0, 122, 123, 124, 0, 0, 0, 0, 0, 0, + 35, 125, 126, 127, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 0, 0, 0, 395, 0, + 0, 0, 0, 0, 0, 0, 396, 0, 0, 0, + 131, 0, 0, 0, 0, 0, 397, 49, 52, 50, + 132, 133, 134, 0, 136, 137, 138, 139, 140, 141, + 0, 0, 129, 135, 121, 114, 116, 130, 0, 0, + 0, 0, 0, 0, 46, 374, 380, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, + 0, 215, 0, 29, 30, 31, 217, 0, 0, 0, + 0, 0, 0, 218, 33, 0, 0, 0, 0, 0, + 0, 35, 220, 0, 0, 221, 37, 0, 38, 0, + 0, 0, 39, 0, 40, 42, 43, 0, 0, 45, + 0, 0, 0, 47, 0, 48, 0, 0, 0, 0, + 0, 222, 0, 223, 0, 0, 0, 53, 49, 52, + 50, 224, 54, 225, 55, 226, 57, 227, 58, 228, + 229, 0, 0, 44, 56, 32, 214, 216, 0, 41, + 0, 0, 0, 0, 0, 46, 34, 51, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 213, 0, 0, + 0, 0, 215, 0, 29, 30, 31, 217, 0, 0, + 0, 0, 0, 0, 218, 219, 0, 0, 0, 0, + 0, 0, 35, 220, 0, 0, 221, 37, 0, 38, + 0, 0, 0, 39, 0, 40, 42, 43, 0, 0, + 45, 0, 0, 0, 47, 0, 48, 0, 0, 0, + 0, 0, 222, 0, 223, 0, 0, 0, 53, 49, + 52, 50, 224, 54, 225, 55, 226, 57, 227, 58, + 228, 229, 0, 0, 44, 56, 32, 214, 216, 0, + 41, 0, 0, 0, 0, 0, 46, 34, 51, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 600, 112, + 113, 0, 0, 602, 117, 604, 30, 31, 605, 0, + 120, 0, 0, 0, 122, 607, 608, 0, 0, 0, + 0, 0, 0, 35, 609, 126, 127, 221, 37, 0, + 38, 0, 0, 0, 39, 0, 40, 610, 43, 0, + 0, 612, 0, 0, 0, 47, 0, 48, 0, 0, + 0, 0, 0, 613, 0, 223, 0, 0, 0, 614, + 49, 52, 50, 615, 616, 617, 55, 619, 620, 621, + 622, 623, 624, 0, 0, 611, 618, 606, 601, 603, + 130, 41, 0, 0, 0, 0, 0, 46, 374, 380, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 365, + 112, 113, 0, 0, 367, 117, 369, 30, 31, 370, + 0, 120, 0, 0, 0, 122, 372, 373, 0, 0, + 0, 0, 0, 0, 35, 375, 126, 127, 221, 37, + 0, 38, 0, 0, 0, 39, 0, 40, 376, 43, + 0, 0, 378, 0, 0, 0, 47, 0, 48, 0, + -271, 0, 0, 0, 379, 0, 223, 0, 0, 0, + 381, 49, 52, 50, 382, 383, 384, 55, 386, 387, + 388, 389, 390, 391, 0, 0, 377, 385, 371, 366, + 368, 130, 41, 0, 0, 0, 0, 0, 46, 374, + 380, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 565, 148, 545, 16, 649, 547, 541, 469, 320, 529, + 528, 630, 183, 248, 263, 500, 485, 447, 629, 183, + 627, 444, 253, 393, 587, 652, 313, 152, 643, 572, + 591, 575, 586, 638, 331, 574, 453, 455, 466, 253, + 437, 178, 433, 253, 0, 248, 584, 458, 248, 313, + 441, 183, 444, 457, 237, 190, 447, 188, 206, 425, + 400, 462, 351, 313, 347, 150, 165, 447, 475, 444, + 183, 145, 393, 260, 0, 409, 173, 409, 260, 362, + 171, 514, 409, 495, 362, 393, 206, 498, 628, 313, + 313, 206, 356, 142, 206, 331, 362, 599, 403, 0, + 345, 62, 62, 62, 182, 62, 299, 182, 295, 206, + 410, 417, 410, 206, 62, 393, 62, 410, 62, 296, + 148, 298, 148, 297, 62, 62, 182, 504, 412, 62, + 180, 502, 511, 206, 512, 62, 108, 460, 188, 62, + 394, 188, 62, 206, 460, 247, 62, 206, 459, 206, + 62, 102, 459, 62, 62, 514, 206, 62, 653, 503, + 407, 343, 341, 62, 313, 110, 419, 167, 188, 187, + 170, 340, 514, 104, 0, 553, 422, 206, 62, 206, + 62, 63, 62, 72, 62, 510, 71, 97, 62, 514, + 70, 62, 557, 69, 355, 62, 239, 62, 493, 318, + 86, 469, 492, 62, 483, 74, 242, 206, 93, 62, + 353, 62, 206, 260, 95, 0, 96, 62, 62, 62, + 322, 62, 94, 206, 100, 98, 206, 99, 62, 247, + 277, 464, 0, 206, 79, 281, 314, 468, 62, 62, + 206, 507, 91, 246, 206, 62, 62, 349, 505, 90, + 206, 62, 62, 460, 459, 62, 206, 506, 62, 401, + 206, 62, 92, 309, 62, 108, 281, 362, 281, 281, + 0, 313, 206, 62, 304, 479, 0, 309, 281, 62, + 206, 327, 281, 0, 281, 337, 300, 309, 324, 0, + 0, 62, 281, 0, 110, 177, 281, 62, 301, 308, + 309, 0, 281, 309, 302, 281, 62, 62, 281, 330, + 62, 281, 281, 289, 514, 281, 0, 0, 306, 284, + 0, 522, 328, 569, 561, 311, 553, 564, 625, 0, + 0, 0, 514, 513, 523, 514, 0, 0, 0, 522, + 0, 0, 522, 316, 0, 0, 0, 0, 0, 485, + 440, 513, 523, 0, 513, 523, 533, 534, 535, 536, + 540, 537, 538, 577, 533, 534, 535, 536, 540, 537, + 538, 594, 0, 0, 0, 0, 362, 0, 597, 598, + 533, 534, 535, 536, 540, 537, 538, 0, 0, 206, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 129, 0, 0, 0, 0, 0, 0, 48, 50, - 49, 130, 131, 132, 0, 134, 135, 136, 137, 138, - 139, 0, 0, 127, 133, 119, 112, 114, 128, 0, - 0, 0, 0, 0, 0, 45, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 109, 110, 111, 0, 0, - 113, 115, 116, 0, 0, 117, 0, 118, 0, 0, - 0, 120, 121, 122, 0, 0, 0, 0, 0, 0, - 394, 123, 124, 125, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 126, 0, 0, 0, 395, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 129, 0, 0, 0, 0, 0, 399, 396, 398, 0, - 130, 131, 132, 0, 134, 135, 136, 137, 138, 139, - 0, 0, 127, 133, 119, 112, 114, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 109, 110, 111, 0, 0, 113, - 115, 116, 0, 0, 117, 0, 118, 0, 0, 0, - 120, 121, 122, 0, 0, 0, 0, 0, 0, 394, - 123, 124, 125, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 126, 0, 0, 0, 395, 0, 0, - 0, 0, 0, 0, 0, 397, 0, 0, 0, 129, - 0, 0, 0, 0, 0, 399, 396, 398, 0, 130, - 131, 132, 0, 134, 135, 136, 137, 138, 139, 0, - 0, 127, 133, 119, 112, 114, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 209, 0, 0, 0, 0, 211, 0, - 29, 30, 31, 213, 0, 0, 0, 0, 0, 0, - 214, 215, 0, 0, 0, 0, 0, 0, 216, 217, - 0, 0, 218, 36, 0, 37, 0, 0, 0, 38, - 0, 39, 41, 42, 0, 0, 44, 0, 0, 0, - 46, 0, 47, 0, 0, 0, 0, 0, 220, 0, - 221, 0, 0, 0, 51, 219, 222, 49, 223, 52, - 224, 53, 225, 55, 226, 56, 227, 228, 0, 0, - 43, 54, 32, 210, 212, 0, 40, 0, 0, 0, - 0, 0, 45, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 209, 0, 0, 0, 0, 211, 0, 29, - 30, 31, 213, 0, 0, 0, 0, 0, 0, 214, - 33, 0, 0, 0, 0, 0, 0, 216, 217, 0, - 0, 218, 36, 0, 37, 0, 0, 0, 38, 0, - 39, 41, 42, 0, 0, 44, 0, 0, 0, 46, - 0, 47, 0, 0, 0, 0, 0, 220, 0, 221, - 0, 0, 0, 51, 219, 222, 49, 223, 52, 224, - 53, 225, 55, 226, 56, 227, 228, 0, 0, 43, - 54, 32, 210, 212, 0, 40, 0, 0, 0, 0, - 0, 45, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 587, 110, 111, 0, 0, 589, 115, 591, 30, - 31, 592, 0, 118, 0, 0, 0, 120, 594, 595, - 0, 0, 0, 0, 0, 0, 596, 597, 124, 125, - 218, 36, 0, 37, 0, 0, 0, 38, 0, 39, - 598, 42, 0, 0, 600, 0, 0, 0, 46, 0, - 47, 0, 0, 0, 0, 0, 602, 0, 221, 0, - 0, 0, 604, 601, 603, 49, 605, 606, 607, 53, - 609, 610, 611, 612, 613, 614, 0, 0, 599, 608, - 593, 588, 590, 128, 40, 0, 0, 0, 0, 0, - 45, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 362, 110, 111, 0, 0, 364, 115, 366, 30, 31, - 367, 0, 118, 0, 0, 0, 120, 369, 370, 0, - 0, 0, 0, 0, 0, 371, 372, 124, 125, 218, - 36, 0, 37, 0, 0, 0, 38, 0, 39, 373, - 42, 0, 0, 375, 0, 0, 0, 46, 0, 47, - 0, -268, 0, 0, 0, 377, 0, 221, 0, 0, - 0, 379, 376, 378, 49, 380, 381, 382, 53, 384, - 385, 386, 387, 388, 389, 0, 0, 374, 383, 368, - 363, 365, 128, 40, 0, 0, 0, 0, 0, 45, - 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 639, 310, 529, 533, 516, 535, 517, 499, 500, 462, - 498, 620, 553, 312, 243, 16, 562, 440, 437, 633, - 238, 250, 473, 182, 253, 182, 617, 488, 359, 563, - 303, 321, 619, 642, 150, 575, 560, 250, 628, 163, - 426, 348, 250, 579, 186, 350, 182, 574, 468, 340, - 430, 345, 572, 434, 359, 457, 448, 446, 238, 450, - 455, 459, 243, 243, 461, 352, 238, 451, 354, 148, - 403, 483, 486, 176, 437, 143, 440, 401, 411, 335, - 188, 437, 440, 169, 237, 171, 237, 140, 359, 393, - 337, 303, 308, 416, 391, 146, 418, 303, 405, 359, - 359, 0, 0, 146, 0, 0, 0, 60, 178, 60, - 0, 452, 288, 0, 303, 60, 405, 60, 405, 180, - 285, 60, 60, 60, 491, 186, 286, 60, 287, 60, - 406, 453, 502, 502, 303, 643, 545, 60, 321, 453, - 60, 165, 180, 60, 60, 490, 180, 60, 406, 60, - 406, 452, 267, 146, 60, 60, 60, 271, 408, 289, - 60, 84, 69, 168, 60, 60, 60, 100, 106, 60, - 97, 98, 96, 502, 481, 0, 541, 72, 480, 436, - 433, 60, 60, 333, 60, 60, 91, 92, 90, 60, - 93, 60, 60, 89, 108, 60, 94, 339, 77, 88, - 60, 502, 462, 331, 60, 95, 303, 61, 618, 106, - 342, 330, 60, 60, 453, 452, 60, 60, 494, 495, - 60, 60, 493, 60, 60, 492, 60, 70, 68, 60, - 60, 102, 67, 60, 271, 108, 175, 299, 271, 0, - 299, 0, 271, 0, 314, 271, 294, 299, 60, 60, - 60, 0, 271, 271, 271, 271, 60, 279, 274, 320, - 0, 271, 318, 60, 0, 317, 0, 296, 271, 327, - 292, 60, 60, 472, 0, 304, 271, 271, 291, 290, - 557, 299, 299, 541, 549, 615, 271, 271, 502, 0, - 552, 0, 502, 0, 0, 510, 0, 0, 502, 510, - 0, 0, 303, 298, 301, 510, 473, 501, 511, 0, - 0, 501, 511, 0, 0, 0, 0, 501, 511, 521, - 522, 523, 524, 528, 525, 526, 582, 0, 0, 0, - 0, 0, 0, 585, 586, 521, 522, 523, 524, 528, - 525, 526, 557, 0, 0, 0, 0, 0, 0, 558, - 559, 521, 522, 523, 524, 528, 525, 526, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 306, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 443, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 565, 521, 522, 523, - 524, 528, 525, 526, 0, 0, 0, 0, 0, 0, + 0, 0, 569, 0, 0, 0, 0, 0, 0, 570, + 571, 533, 534, 535, 536, 540, 537, 538, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -697,120 +705,101 @@ const short QQmlJSGrammar::action_info [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0}; + 0, 0, 0, 0, 0, 0, 0}; const short QQmlJSGrammar::action_check [] = { - 36, 36, 7, 55, 17, 7, 7, 60, 8, 7, - 7, 37, 36, 7, 20, 33, 55, 55, 60, 36, - 36, 33, 33, 55, 8, 7, 36, 7, 16, 33, - 7, 34, 7, 7, 7, 60, 7, 36, 33, 7, - 36, 33, 33, 5, 7, 5, 5, 33, 29, 36, - 91, 36, 7, 36, 7, 33, 7, 7, 66, 66, - 36, 33, 7, 7, 31, 1, 7, 24, 33, 2, - 60, 60, 36, 8, 8, 7, 55, 1, 36, 48, - 2, 8, 7, 2, 7, 2, 79, 36, 17, 36, - 60, 7, 48, 36, 36, 61, 33, 36, 1, 60, - 0, 8, 8, 1, 8, 6, 8, -1, -1, 61, - 48, 7, 8, 8, 60, 8, 10, -1, 8, 20, - 8, -1, 48, -1, 8, 79, 40, 40, 15, 77, - -1, 61, 60, 8, 8, 8, 15, 51, 51, 79, - 8, 61, 62, 61, 62, 50, 7, 34, 8, 54, - 61, 62, 61, 62, 56, 34, 60, 42, 79, 8, - 91, 55, 40, 56, 12, 60, 56, 50, 53, 61, - 62, 54, 60, 51, 29, 61, 62, 61, 40, 61, - 62, 12, 56, 29, 25, 60, 27, 60, 56, 51, - 61, 62, 25, 7, 27, 8, 12, 38, -1, 25, - 60, 27, 7, -1, 25, 38, 27, 29, 25, 57, - 27, 60, 38, 7, 25, 63, 27, 38, 36, 33, - 75, 38, 25, 25, 27, 27, 57, 38, 29, 75, - -1, 86, 63, 7, 29, 38, 38, 25, 29, 27, - 86, 57, 8, 61, 62, 8, -1, 63, 61, 62, - 38, 15, 25, 75, 27, 8, 61, 62, 25, -1, - 27, 61, 62, -1, 86, 38, -1, 61, 62, -1, - 34, 38, 36, 25, 75, 27, 61, 62, -1, 93, - 75, 15, -1, -1, 75, 86, 38, 61, 62, 89, - 25, 86, 27, -1, 60, 86, 18, 19, 61, 62, - 34, -1, 36, 38, 18, 19, -1, 92, 61, 62, - -1, -1, -1, 29, 47, 15, 18, 19, -1, -1, - 15, 18, 19, 45, 46, 29, -1, -1, 61, 62, - 29, 45, 46, 33, 34, 29, 36, 15, 33, 34, - -1, 36, 29, 45, 46, 29, -1, -1, 45, 46, - 66, 67, 68, 29, -1, -1, 34, -1, 36, 92, - -1, -1, 66, 67, 68, 29, -1, 66, 67, 68, - -1, -1, 66, 67, 68, -1, 29, 93, -1, 66, - 67, 68, 66, 67, 68, 29, 23, 24, -1, 93, - 66, 67, 68, 29, 93, 32, -1, -1, 35, 93, - 37, -1, 66, 67, 68, 29, 93, -1, 29, 93, - -1, -1, -1, 66, 67, 68, 29, 93, -1, -1, - -1, 29, 66, 67, 68, 23, 24, 29, -1, 93, - 66, 67, 68, -1, 32, -1, 29, 35, -1, 37, - 93, -1, 66, 67, 68, 66, 67, 68, -1, 93, - -1, 29, -1, 66, 67, 68, -1, 93, 66, 67, - 68, -1, -1, -1, 66, 67, 68, 23, 24, 93, - -1, -1, 93, 66, 67, 68, 32, -1, -1, 35, - 93, 37, -1, -1, -1, 93, -1, -1, 66, 67, - 68, 93, 29, -1, -1, 23, 24, -1, -1, 36, - 93, -1, -1, 31, 32, 23, 24, 35, -1, 37, - -1, -1, -1, -1, 32, 93, -1, 35, -1, 37, - 95, 96, 97, 98, 99, 100, 29, 23, 24, 66, - 67, 68, -1, 36, 29, 31, 32, 23, 24, 35, - -1, 37, 29, -1, -1, 31, 32, -1, -1, 35, - 29, 37, -1, -1, -1, -1, 93, -1, -1, -1, - -1, -1, -1, 66, 67, 68, 61, 62, -1, -1, - 29, 66, 67, 68, 61, 62, -1, -1, 29, 66, - 67, 68, 61, 62, -1, 23, 24, 66, 67, 68, - 93, -1, -1, 31, 32, -1, -1, 35, 93, 37, - -1, -1, 61, 62, -1, -1, 93, 66, 67, 68, - 61, 62, 3, -1, 93, 66, 67, 68, -1, -1, - -1, -1, 13, -1, -1, -1, 17, -1, -1, -1, - 3, -1, -1, -1, 93, 26, -1, 28, -1, -1, - 13, -1, 93, -1, 17, -1, -1, -1, 39, -1, - 41, 42, -1, 26, -1, 28, -1, -1, 49, -1, - -1, 52, 53, -1, -1, 29, 39, 58, 41, 42, - -1, -1, -1, 64, -1, -1, 49, -1, -1, 52, - 53, -1, -1, -1, -1, 58, -1, -1, -1, 80, - -1, 64, -1, -1, -1, -1, -1, 61, 62, -1, - -1, -1, 66, 67, 68, -1, -1, 80, -1, -1, + 60, 7, 7, 7, 34, 91, 24, 7, 61, 36, + 33, 36, 7, 7, 7, 60, 33, 33, 55, 66, + 8, 33, 55, 36, 16, 7, 36, 29, 8, 7, + 7, 55, 17, 36, 7, 7, 7, 7, 7, 36, + 55, 7, 7, 33, 33, 36, 33, 33, 7, 60, + 7, 60, 20, 36, 33, 36, 55, 7, 33, 60, + 5, 37, 36, 5, 60, 5, 7, 2, 66, 36, + 33, 33, 36, 7, 1, 8, 60, 8, 33, 2, + 36, 1, 8, 36, 2, 1, 8, 2, 17, 1, + 0, 8, -1, 7, 55, 33, 33, -1, -1, 48, + 60, -1, 6, 31, 55, 48, 36, 61, 60, 8, + -1, 36, 60, -1, 7, 61, 20, 36, 8, 77, + 15, 60, 8, 55, 48, 36, 10, 36, 36, 36, + 7, 8, 79, 8, 8, 79, 8, 42, 8, 34, + 8, 8, 48, 40, 8, 8, -1, 60, 53, 50, + -1, 8, -1, 54, 51, 91, 15, 8, 79, 61, + 62, 60, 8, 61, 62, 61, 62, 61, 62, 40, + 60, 55, 61, 62, 60, 34, 61, 62, 61, 62, + 51, 56, 61, 62, 56, 50, 60, 40, 15, 54, + 60, 40, 60, 56, 61, 25, 60, 27, 51, 61, + 62, 29, 51, 60, 29, 56, 15, 34, 38, 36, + 15, 29, 8, 8, 12, 61, 62, 61, 62, 12, + 36, 25, 7, 27, 25, 34, 27, 36, 25, 34, + 27, 36, 7, 15, 38, 29, 25, 38, 27, 7, + -1, 38, 25, 29, 27, 61, 62, 75, 92, 38, + 75, 12, 34, 7, 36, 38, -1, 75, 86, 57, + 56, 86, -1, -1, 57, 63, 61, 62, 86, 25, + 63, 27, 25, -1, 27, -1, 61, 62, 25, 33, + 27, 75, 38, 61, 62, 38, 61, 62, 25, 75, + 27, 38, 86, 61, 62, 25, 57, 27, 29, -1, + 86, 38, 63, 25, 25, 27, 27, 15, 38, 8, + -1, 89, -1, 18, 19, 47, 38, 38, 18, 19, + 18, 19, -1, -1, -1, 33, 34, -1, 36, 61, + 62, 15, 97, 98, 99, 100, 101, 102, -1, 93, + 45, 46, 23, 24, 75, 45, 46, 45, 46, 33, + 34, 32, 36, -1, 35, 86, 37, 23, 24, -1, + 92, -1, 61, 62, 23, 24, 32, -1, -1, 35, + -1, 37, -1, 32, 23, 24, 35, -1, 37, -1, + 23, 24, -1, 32, -1, -1, 35, -1, 37, 32, + 23, 24, 35, 29, 37, -1, -1, -1, 31, 32, + 23, 24, 35, 29, 37, -1, 18, 19, 31, 32, + 23, 24, 35, 29, 37, -1, -1, -1, 31, 32, + -1, -1, 35, 29, 37, -1, 29, -1, -1, -1, + 66, 67, 68, 45, 46, -1, -1, -1, -1, -1, + 66, 67, 68, -1, 29, -1, -1, 29, -1, -1, + 66, 67, 68, -1, -1, -1, -1, 93, 94, 95, + 66, 67, 68, 66, 67, 68, -1, 93, 94, 95, + -1, -1, -1, -1, -1, -1, -1, 93, 94, 95, + 29, 66, 67, 68, 66, 67, 68, 93, 94, 95, + 93, 94, 95, 23, 24, 29, -1, -1, 29, -1, + -1, 31, 32, -1, -1, 35, -1, 37, 93, 94, + 95, 93, 94, 95, 29, -1, -1, 66, 67, 68, + -1, 36, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 29, 66, 67, 68, 66, 67, 68, 36, -1, + -1, -1, -1, -1, 93, 94, 95, -1, -1, -1, + -1, 66, 67, 68, 29, -1, -1, -1, -1, 93, + 94, 95, 93, 94, 95, 29, -1, -1, 66, 67, + 68, -1, 36, -1, -1, 29, -1, -1, 93, 94, + 95, -1, -1, -1, 29, -1, 61, 62, -1, -1, + -1, 66, 67, 68, -1, 93, 94, 95, -1, -1, + -1, -1, 66, 67, 68, 29, -1, -1, -1, -1, + -1, -1, 66, 67, 68, -1, 61, 62, 93, 94, + 95, 66, 67, 68, -1, -1, -1, -1, -1, 93, + 94, 95, -1, -1, -1, -1, -1, 61, 62, 93, + 94, 95, 66, 67, 68, -1, -1, -1, 93, 94, + 95, 29, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 93, + 94, 95, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 61, 62, 3, -1, -1, 66, 67, + 68, -1, -1, -1, -1, 13, -1, -1, -1, 17, + -1, -1, -1, -1, -1, -1, -1, -1, 26, -1, + 28, -1, -1, 31, -1, 93, 94, 95, -1, -1, + -1, 39, -1, 41, 42, -1, -1, 3, -1, -1, + -1, 49, -1, -1, 52, 53, -1, 13, -1, -1, + 58, 17, -1, -1, -1, -1, 64, -1, -1, -1, + 26, -1, 28, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 80, 39, -1, 41, 42, -1, -1, -1, + -1, -1, -1, 49, -1, -1, 52, 53, -1, -1, + -1, -1, 58, -1, -1, -1, -1, -1, 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 12, 13, -1, 93, - -1, -1, -1, -1, -1, -1, 22, -1, -1, 3, - -1, -1, -1, 29, -1, -1, -1, 33, 34, 13, - 36, -1, -1, 17, -1, -1, -1, 43, -1, -1, - -1, 47, 26, -1, 28, -1, -1, 31, -1, -1, - -1, -1, -1, -1, -1, 39, -1, 41, 42, 65, - 66, 67, 68, -1, 70, 49, -1, -1, 52, 53, - -1, -1, -1, -1, 58, 81, 82, 83, -1, -1, - 64, 87, -1, -1, -1, -1, -1, 93, -1, -1, - -1, -1, -1, -1, -1, -1, 80, -1, -1, -1, + -1, -1, -1, -1, 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 12, 13, -1, -1, -1, -1, -1, -1, 12, - 13, 22, -1, -1, -1, -1, -1, -1, 29, 22, - -1, -1, 33, 34, -1, 36, 29, -1, -1, -1, - 33, 34, 43, 36, -1, -1, 47, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, + 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, + -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, + 33, 34, -1, 36, -1, -1, -1, -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, -1, - 81, 82, 83, -1, -1, -1, 87, -1, 81, 82, - 83, -1, 93, -1, 87, -1, -1, -1, -1, -1, - 93, -1, 12, 13, -1, -1, -1, -1, -1, -1, - 12, 13, 22, -1, -1, -1, -1, -1, -1, 29, - 22, -1, -1, 33, 34, -1, 36, 29, -1, -1, - -1, 33, 34, 43, 36, -1, -1, 47, -1, -1, - -1, 43, -1, -1, -1, 47, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, - 70, -1, -1, 65, 66, 67, 68, -1, 70, -1, - -1, 81, 82, 83, -1, -1, -1, 87, -1, 81, - 82, 83, -1, 93, -1, 87, -1, -1, -1, -1, - -1, 93, -1, 12, 13, -1, -1, -1, -1, -1, - -1, 12, 13, 22, -1, -1, -1, -1, -1, -1, - 29, 22, -1, -1, 33, 34, -1, 36, 29, -1, - -1, -1, 33, 34, 43, 36, -1, -1, 47, -1, - -1, -1, 43, -1, -1, -1, 47, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, - -1, 70, -1, -1, 65, 66, 67, 68, -1, 70, - -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, - 81, 82, 83, -1, 93, -1, 87, -1, -1, -1, - -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 81, 82, + 83, -1, -1, -1, 87, -1, -1, -1, -1, -1, + 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, @@ -819,44 +808,45 @@ const short QQmlJSGrammar::action_check [] = { -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, - -1, -1, -1, 93, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 10, -1, 12, 13, -1, -1, -1, - -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, - -1, -1, 29, -1, -1, -1, 33, 34, -1, 36, - -1, -1, -1, -1, -1, -1, 43, -1, -1, -1, - 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, - 67, 68, -1, 70, -1, -1, -1, -1, 75, -1, - -1, -1, -1, -1, 81, 82, 83, 84, -1, -1, - 87, -1, -1, -1, -1, -1, 93, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 10, -1, 12, 13, - -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, - -1, -1, -1, -1, -1, 29, -1, -1, -1, 33, - 34, -1, 36, -1, -1, -1, -1, -1, -1, 43, - -1, -1, -1, 47, -1, -1, -1, -1, -1, -1, - -1, 55, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 65, 66, 67, 68, -1, 70, -1, -1, -1, - -1, 75, -1, -1, -1, -1, -1, 81, 82, 83, - 84, -1, -1, 87, -1, -1, -1, -1, -1, 93, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, - -1, 12, 13, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 93, 94, 95, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 10, -1, 12, 13, -1, + -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, + -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, + -1, 36, -1, -1, -1, -1, -1, -1, 43, -1, + -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 65, 66, 67, 68, -1, 70, -1, -1, -1, -1, + 75, -1, -1, -1, -1, -1, 81, 82, 83, 84, + -1, -1, 87, -1, -1, -1, -1, -1, 93, 94, + 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 10, -1, 12, 13, -1, -1, -1, -1, -1, -1, + -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, + -1, -1, -1, 33, 34, -1, 36, -1, -1, -1, + -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, + -1, -1, -1, -1, -1, 55, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, + 70, -1, -1, -1, -1, 75, -1, -1, -1, -1, + -1, 81, 82, 83, 84, -1, -1, 87, -1, -1, + -1, -1, -1, 93, 94, 95, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 10, -1, 12, 13, -1, + -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, + -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, + -1, 36, -1, -1, -1, -1, -1, -1, 43, -1, + -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, + 55, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 65, 66, 67, 68, -1, 70, -1, -1, -1, -1, + 75, -1, -1, -1, -1, -1, 81, 82, 83, 84, + -1, -1, 87, -1, -1, -1, -1, -1, 93, 94, + 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, - -1, -1, 33, 34, -1, 36, -1, -1, -1, -1, - -1, -1, 43, -1, -1, -1, 47, -1, -1, -1, - -1, -1, -1, -1, 55, -1, -1, -1, -1, -1, + -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, + -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, + 51, -1, 53, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, - -1, -1, -1, -1, 75, -1, -1, -1, -1, -1, - 81, 82, 83, 84, -1, -1, 87, -1, -1, -1, - -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, - -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, - 29, -1, -1, -1, 33, 34, -1, 36, -1, -1, - -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, - -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, - -1, 70, -1, 72, -1, 74, -1, 76, -1, -1, - -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, - -1, -1, -1, -1, 93, -1, -1, -1, -1, -1, + -1, 72, -1, 74, -1, 76, -1, -1, -1, -1, + 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, + -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, 7, -1, -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, -1, @@ -866,44 +856,45 @@ const short QQmlJSGrammar::action_check [] = { -1, -1, 65, 66, 67, 68, -1, 70, -1, 72, -1, 74, -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, -1, -1, - 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, - -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, - -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, - -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, - 51, -1, 53, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, - -1, 72, -1, 74, 75, 76, -1, -1, -1, -1, - 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, - -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 8, -1, -1, 11, 12, 13, -1, -1, - -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, - -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, - 36, -1, -1, -1, 40, -1, 42, 43, 44, -1, - -1, 47, -1, -1, -1, 51, -1, 53, -1, -1, - 56, -1, -1, -1, -1, -1, -1, -1, -1, 65, - 66, 67, 68, -1, 70, -1, 72, -1, 74, -1, - 76, -1, -1, -1, -1, 81, 82, 83, -1, -1, - -1, 87, -1, -1, -1, -1, -1, 93, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, - 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, - -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, - -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, - -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, - 51, -1, 53, -1, -1, 56, -1, -1, -1, -1, - -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, - -1, 72, -1, 74, -1, 76, -1, -1, -1, -1, - 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, - -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 8, -1, -1, 11, 12, 13, -1, -1, - -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, - -1, -1, -1, 29, -1, -1, -1, 33, 34, -1, - 36, -1, -1, -1, 40, -1, 42, 43, 44, -1, - -1, 47, -1, -1, -1, 51, -1, 53, -1, -1, - 56, -1, -1, -1, -1, -1, -1, -1, -1, 65, - 66, 67, 68, -1, 70, -1, 72, -1, 74, -1, - 76, -1, -1, -1, -1, 81, 82, 83, -1, -1, - -1, 87, -1, -1, -1, -1, -1, 93, -1, -1, + 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, + -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, + 29, -1, -1, -1, 33, 34, -1, 36, -1, -1, + -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, + -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 65, 66, 67, 68, + -1, 70, -1, 72, -1, 74, 75, 76, -1, -1, + -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, + -1, -1, -1, -1, 93, 94, 95, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8, -1, -1, 11, + 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, + 22, -1, -1, -1, -1, -1, -1, 29, -1, -1, + -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, + 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, + -1, 53, -1, -1, 56, -1, -1, -1, -1, -1, + -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, + 72, -1, 74, -1, 76, -1, -1, -1, -1, 81, + 82, 83, -1, -1, -1, 87, -1, -1, -1, -1, + -1, 93, 94, 95, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 8, -1, -1, 11, 12, 13, -1, + -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, + -1, -1, -1, -1, 29, -1, -1, -1, 33, 34, + -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, + -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, + -1, 56, -1, -1, -1, -1, -1, -1, -1, -1, + 65, 66, 67, 68, -1, 70, -1, 72, -1, 74, + -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, + -1, -1, 87, -1, -1, -1, -1, -1, 93, 94, + 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 8, -1, -1, 11, 12, 13, -1, -1, -1, -1, + -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, + -1, 29, -1, -1, -1, 33, 34, -1, 36, -1, + -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, + -1, -1, -1, 51, -1, 53, -1, -1, 56, -1, + -1, -1, -1, -1, -1, -1, -1, 65, 66, 67, + 68, -1, 70, -1, 72, -1, 74, -1, 76, -1, + -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, + -1, -1, -1, -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, 8, -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, -1, @@ -913,16 +904,7 @@ const short QQmlJSGrammar::action_check [] = { -1, -1, -1, -1, 65, 66, 67, 68, -1, 70, -1, 72, -1, 74, -1, 76, -1, -1, -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, -1, -1, - -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, - -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, - 29, 30, -1, -1, 33, 34, -1, 36, -1, -1, - -1, 40, -1, 42, 43, 44, -1, -1, 47, -1, - -1, -1, 51, -1, 53, -1, -1, -1, -1, -1, - -1, -1, 61, -1, -1, -1, 65, 66, 67, 68, - 69, 70, -1, 72, 73, 74, -1, 76, -1, 78, - -1, -1, 81, 82, 83, -1, -1, -1, 87, -1, - -1, -1, -1, -1, 93, -1, -1, -1, -1, -1, + -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, 11, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, -1, -1, -1, -1, -1, -1, 29, 30, -1, -1, 33, 34, -1, 36, @@ -931,120 +913,149 @@ const short QQmlJSGrammar::action_check [] = { -1, -1, -1, -1, 61, -1, -1, -1, 65, 66, 67, 68, 69, 70, -1, 72, 73, 74, -1, 76, -1, 78, -1, -1, 81, 82, 83, -1, -1, -1, - 87, -1, -1, -1, -1, -1, 93, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 4, 5, 6, -1, - -1, 9, 10, 11, -1, -1, 14, -1, 16, -1, - -1, -1, 20, 21, 22, -1, -1, -1, -1, -1, - -1, 29, 30, 31, 32, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 43, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 59, -1, -1, -1, -1, -1, -1, 66, 67, - 68, 69, 70, 71, -1, 73, 74, 75, 76, 77, - 78, -1, -1, 81, 82, 83, 84, 85, 86, -1, - -1, -1, -1, -1, -1, 93, -1, -1, -1, -1, + 87, -1, -1, -1, -1, -1, 93, 94, 95, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 11, 12, + 13, -1, -1, -1, -1, -1, -1, -1, -1, 22, + -1, -1, -1, -1, -1, -1, 29, 30, -1, -1, + 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, + 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, + 53, -1, -1, -1, -1, -1, -1, -1, 61, -1, + -1, -1, 65, 66, 67, 68, 69, 70, -1, 72, + 73, 74, -1, 76, -1, 78, -1, -1, 81, 82, + 83, -1, -1, -1, 87, -1, -1, -1, -1, -1, + 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 4, 5, 6, -1, -1, 9, 10, 11, + -1, -1, 14, -1, 16, -1, -1, -1, 20, 21, + 22, -1, -1, -1, -1, -1, -1, 29, 30, 31, + 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 43, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 59, -1, -1, + -1, -1, -1, -1, 66, 67, 68, 69, 70, 71, + -1, 73, 74, 75, 76, 77, 78, -1, -1, 81, + 82, 83, 84, 85, 86, -1, -1, -1, -1, -1, + -1, 93, 94, 95, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 4, 5, 6, -1, -1, 9, 10, + 11, -1, -1, 14, -1, 16, -1, -1, -1, 20, + 21, 22, -1, -1, -1, -1, -1, -1, 29, 30, + 31, 32, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 43, -1, -1, -1, 47, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 59, -1, + -1, -1, -1, -1, 65, 66, 67, 68, 69, 70, + 71, -1, 73, 74, 75, 76, 77, 78, -1, -1, + 81, 82, 83, 84, 85, 86, -1, -1, -1, -1, + -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4, 5, 6, -1, -1, 9, + 10, 11, -1, -1, 14, -1, 16, -1, -1, -1, + 20, 21, 22, -1, -1, -1, -1, -1, -1, 29, + 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 59, + -1, -1, -1, -1, -1, 65, 66, 67, 68, 69, + 70, 71, -1, 73, 74, 75, 76, 77, 78, -1, + -1, 81, 82, 83, 84, 85, 86, -1, -1, -1, + -1, -1, -1, 93, 94, 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, 6, -1, -1, 9, 10, 11, -1, -1, 14, -1, 16, -1, -1, -1, 20, 21, 22, -1, -1, -1, -1, -1, -1, 29, 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 43, -1, -1, -1, 47, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 59, -1, -1, -1, -1, -1, 65, 66, 67, -1, + -1, -1, -1, -1, -1, -1, 55, -1, -1, -1, + 59, -1, -1, -1, -1, -1, 65, 66, 67, 68, 69, 70, 71, -1, 73, 74, 75, 76, 77, 78, -1, -1, 81, 82, 83, 84, 85, 86, -1, -1, + -1, -1, -1, -1, 93, 94, 95, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 4, -1, -1, -1, + -1, 9, -1, 11, 12, 13, 14, -1, -1, -1, + -1, -1, -1, 21, 22, -1, -1, -1, -1, -1, + -1, 29, 30, -1, -1, 33, 34, -1, 36, -1, + -1, -1, 40, -1, 42, 43, 44, -1, -1, 47, + -1, -1, -1, 51, -1, 53, -1, -1, -1, -1, + -1, 59, -1, 61, -1, -1, -1, 65, 66, 67, + 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, + 78, -1, -1, 81, 82, 83, 84, 85, -1, 87, + -1, -1, -1, -1, -1, 93, 94, 95, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 4, -1, -1, + -1, -1, 9, -1, 11, 12, 13, 14, -1, -1, + -1, -1, -1, -1, 21, 22, -1, -1, -1, -1, + -1, -1, 29, 30, -1, -1, 33, 34, -1, 36, + -1, -1, -1, 40, -1, 42, 43, 44, -1, -1, + 47, -1, -1, -1, 51, -1, 53, -1, -1, -1, + -1, -1, 59, -1, 61, -1, -1, -1, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + 77, 78, -1, -1, 81, 82, 83, 84, 85, -1, + 87, -1, -1, -1, -1, -1, 93, 94, 95, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 4, 5, + 6, -1, -1, 9, 10, 11, 12, 13, 14, -1, + 16, -1, -1, -1, 20, 21, 22, -1, -1, -1, + -1, -1, -1, 29, 30, 31, 32, 33, 34, -1, + 36, -1, -1, -1, 40, -1, 42, 43, 44, -1, + -1, 47, -1, -1, -1, 51, -1, 53, -1, -1, + -1, -1, -1, 59, -1, 61, -1, -1, -1, 65, + 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, + 76, 77, 78, -1, -1, 81, 82, 83, 84, 85, + 86, 87, -1, -1, -1, -1, -1, 93, 94, 95, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 4, + 5, 6, -1, -1, 9, 10, 11, 12, 13, 14, + -1, 16, -1, -1, -1, 20, 21, 22, -1, -1, + -1, -1, -1, -1, 29, 30, 31, 32, 33, 34, + -1, 36, -1, -1, -1, 40, -1, 42, 43, 44, + -1, -1, 47, -1, -1, -1, 51, -1, 53, -1, + 55, -1, -1, -1, 59, -1, 61, -1, -1, -1, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, -1, -1, 81, 82, 83, 84, + 85, 86, 87, -1, -1, -1, -1, -1, 93, 94, + 95, -1, -1, -1, -1, -1, -1, -1, -1, -1, + + 15, 39, 29, 3, 15, 15, 13, 15, 3, 15, + 29, 9, 15, 15, 3, 3, 39, 22, 19, 15, + 19, 3, 15, 15, 15, 11, 3, 74, 15, 19, + 15, 15, 29, 13, 15, 29, 102, 15, 3, 15, + 97, 3, 100, 15, -1, 15, 29, 22, 15, 3, + 3, 15, 3, 22, 15, 15, 22, 15, 15, 3, + 39, 3, 3, 3, 3, 39, 39, 22, 39, 3, + 15, 39, 15, 2, -1, 13, 39, 13, 2, 2, + 39, 13, 13, 39, 2, 15, 15, 39, 20, 3, + 3, 15, 15, 3, 15, 15, 2, 15, 41, -1, + 2, 51, 51, 51, 53, 51, 56, 53, 56, 15, + 48, 41, 48, 15, 51, 15, 51, 48, 51, 56, + 39, 56, 39, 56, 51, 51, 53, 53, 47, 51, + 47, 53, 4, 15, 2, 51, 15, 53, 15, 51, + 40, 15, 51, 15, 53, 4, 51, 15, 53, 15, + 51, 63, 53, 51, 51, 13, 15, 51, 16, 53, + 42, 75, 75, 51, 3, 44, 43, 65, 15, 43, + 67, 91, 13, 61, -1, 16, 42, 15, 51, 15, + 51, 54, 51, 54, 51, 106, 53, 56, 51, 13, + 53, 51, 16, 53, 2, 51, 43, 51, 35, 2, + 56, 15, 39, 51, 42, 59, 42, 15, 56, 51, + 2, 51, 15, 2, 56, -1, 56, 51, 51, 51, + 2, 51, 56, 15, 57, 57, 15, 57, 51, 4, + 51, 2, -1, 15, 57, 56, 75, 2, 51, 51, + 15, 53, 55, 2, 15, 51, 51, 2, 53, 55, + 15, 51, 51, 53, 53, 51, 15, 53, 51, 2, + 15, 51, 55, 51, 51, 15, 56, 2, 56, 56, + -1, 3, 15, 51, 64, 89, -1, 51, 56, 51, + 15, 68, 56, -1, 56, 73, 58, 51, 66, -1, + -1, 51, 56, -1, 44, 45, 56, 51, 58, 73, + 51, -1, 56, 51, 58, 56, 51, 51, 56, 73, + 51, 56, 56, 58, 13, 56, -1, -1, 62, 60, + -1, 20, 73, 13, 5, 73, 16, 5, 18, -1, + -1, -1, 13, 32, 33, 13, -1, -1, -1, 20, + -1, -1, 20, 75, -1, -1, -1, -1, -1, 39, + 85, 32, 33, -1, 32, 33, 22, 23, 24, 25, + 26, 27, 28, 21, 22, 23, 24, 25, 26, 27, + 28, 13, -1, -1, -1, -1, 2, -1, 20, 21, + 22, 23, 24, 25, 26, 27, 28, -1, -1, 15, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 4, 5, 6, -1, -1, 9, - 10, 11, -1, -1, 14, -1, 16, -1, -1, -1, - 20, 21, 22, -1, -1, -1, -1, -1, -1, 29, - 30, 31, 32, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 43, -1, -1, -1, 47, -1, -1, - -1, -1, -1, -1, -1, 55, -1, -1, -1, 59, - -1, -1, -1, -1, -1, 65, 66, 67, -1, 69, - 70, 71, -1, 73, 74, 75, 76, 77, 78, -1, - -1, 81, 82, 83, 84, 85, 86, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 4, -1, -1, -1, -1, 9, -1, - 11, 12, 13, 14, -1, -1, -1, -1, -1, -1, - 21, 22, -1, -1, -1, -1, -1, -1, 29, 30, - -1, -1, 33, 34, -1, 36, -1, -1, -1, 40, - -1, 42, 43, 44, -1, -1, 47, -1, -1, -1, - 51, -1, 53, -1, -1, -1, -1, -1, 59, -1, - 61, -1, -1, -1, 65, 66, 67, 68, 69, 70, - 71, 72, 73, 74, 75, 76, 77, 78, -1, -1, - 81, 82, 83, 84, 85, -1, 87, -1, -1, -1, - -1, -1, 93, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 4, -1, -1, -1, -1, 9, -1, 11, - 12, 13, 14, -1, -1, -1, -1, -1, -1, 21, - 22, -1, -1, -1, -1, -1, -1, 29, 30, -1, - -1, 33, 34, -1, 36, -1, -1, -1, 40, -1, - 42, 43, 44, -1, -1, 47, -1, -1, -1, 51, - -1, 53, -1, -1, -1, -1, -1, 59, -1, 61, - -1, -1, -1, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, 77, 78, -1, -1, 81, - 82, 83, 84, 85, -1, 87, -1, -1, -1, -1, - -1, 93, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 4, 5, 6, -1, -1, 9, 10, 11, 12, - 13, 14, -1, 16, -1, -1, -1, 20, 21, 22, - -1, -1, -1, -1, -1, -1, 29, 30, 31, 32, - 33, 34, -1, 36, -1, -1, -1, 40, -1, 42, - 43, 44, -1, -1, 47, -1, -1, -1, 51, -1, - 53, -1, -1, -1, -1, -1, 59, -1, 61, -1, - -1, -1, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, -1, -1, 81, 82, - 83, 84, 85, 86, 87, -1, -1, -1, -1, -1, - 93, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 4, 5, 6, -1, -1, 9, 10, 11, 12, 13, - 14, -1, 16, -1, -1, -1, 20, 21, 22, -1, - -1, -1, -1, -1, -1, 29, 30, 31, 32, 33, - 34, -1, 36, -1, -1, -1, 40, -1, 42, 43, - 44, -1, -1, 47, -1, -1, -1, 51, -1, 53, - -1, 55, -1, -1, -1, 59, -1, 61, -1, -1, - -1, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, -1, -1, 81, 82, 83, - 84, 85, 86, 87, -1, -1, -1, -1, -1, 93, - -1, -1, -1, -1, -1, -1, -1, -1, -1, - - 15, 3, 13, 29, 29, 15, 15, 4, 2, 15, - 105, 9, 15, 2, 15, 3, 29, 22, 3, 15, - 15, 2, 39, 15, 3, 15, 19, 3, 2, 15, - 3, 15, 19, 11, 71, 15, 19, 2, 13, 39, - 97, 2, 2, 15, 15, 3, 15, 29, 39, 15, - 94, 101, 29, 3, 2, 2, 15, 99, 15, 22, - 3, 3, 15, 15, 2, 2, 15, 22, 2, 39, - 2, 39, 39, 3, 3, 39, 22, 39, 2, 2, - 15, 3, 22, 39, 4, 39, 4, 3, 2, 40, - 3, 3, 2, 2, 39, 39, 3, 3, 13, 2, - 2, -1, -1, 39, -1, -1, -1, 48, 44, 48, - -1, 50, 53, -1, 3, 48, 13, 48, 13, 50, - 53, 48, 48, 48, 50, 15, 53, 48, 53, 48, - 45, 50, 13, 13, 3, 16, 16, 48, 15, 50, - 48, 62, 50, 48, 48, 50, 50, 48, 45, 48, - 45, 50, 48, 39, 48, 48, 48, 53, 44, 53, - 48, 53, 50, 64, 48, 48, 48, 60, 15, 48, - 54, 54, 54, 13, 35, -1, 16, 56, 39, 82, - 82, 48, 48, 72, 48, 48, 53, 53, 52, 48, - 53, 48, 48, 52, 41, 48, 53, 2, 54, 52, - 48, 13, 15, 72, 48, 53, 3, 51, 20, 15, - 100, 88, 48, 48, 50, 50, 48, 48, 50, 50, - 48, 48, 50, 48, 48, 50, 48, 51, 50, 48, - 48, 58, 50, 48, 53, 41, 42, 48, 53, -1, - 48, -1, 53, -1, 63, 53, 61, 48, 48, 48, - 48, -1, 53, 53, 53, 53, 48, 55, 57, 70, - -1, 53, 70, 48, -1, 65, -1, 59, 53, 70, - 55, 48, 48, 86, -1, 72, 53, 53, 55, 55, - 13, 48, 48, 16, 5, 18, 53, 53, 13, -1, - 5, -1, 13, -1, -1, 20, -1, -1, 13, 20, - -1, -1, 3, 70, 70, 20, 39, 32, 33, -1, - -1, 32, 33, -1, -1, -1, -1, 32, 33, 22, - 23, 24, 25, 26, 27, 28, 13, -1, -1, -1, - -1, -1, -1, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 13, -1, -1, -1, -1, -1, -1, 20, - 21, 22, 23, 24, 25, 26, 27, 28, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 72, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 21, 22, 23, 24, - 25, 26, 27, 28, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 85, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 13, -1, -1, -1, -1, -1, -1, 20, + 21, 22, 23, 24, 25, 26, 27, 28, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -1052,6 +1063,6 @@ const short QQmlJSGrammar::action_check [] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1}; + -1, -1, -1, -1, -1, -1, -1}; QT_END_NAMESPACE diff --git a/src/qml/qml/parser/qqmljsgrammar_p.h b/src/qml/qml/parser/qqmljsgrammar_p.h index 651c6e391f..9ef4695d69 100644 --- a/src/qml/qml/parser/qqmljsgrammar_p.h +++ b/src/qml/qml/parser/qqmljsgrammar_p.h @@ -63,8 +63,8 @@ class QQmlJSGrammar public: enum VariousConstants { EOF_SYMBOL = 0, - REDUCE_HERE = 102, - SHIFT_THERE = 101, + REDUCE_HERE = 104, + SHIFT_THERE = 103, T_AND = 1, T_AND_AND = 2, T_AND_EQ = 3, @@ -90,18 +90,19 @@ public: T_EQ = 17, T_EQ_EQ = 18, T_EQ_EQ_EQ = 19, - T_ERROR = 94, + T_ERROR = 96, T_FALSE = 83, - T_FEED_JS_EXPRESSION = 98, - T_FEED_JS_PROGRAM = 100, - T_FEED_JS_SOURCE_ELEMENT = 99, - T_FEED_JS_STATEMENT = 97, - T_FEED_UI_OBJECT_MEMBER = 96, - T_FEED_UI_PROGRAM = 95, + T_FEED_JS_EXPRESSION = 100, + T_FEED_JS_PROGRAM = 102, + T_FEED_JS_SOURCE_ELEMENT = 101, + T_FEED_JS_STATEMENT = 99, + T_FEED_UI_OBJECT_MEMBER = 98, + T_FEED_UI_PROGRAM = 97, T_FINALLY = 20, T_FOR = 21, T_FUNCTION = 22, T_GE = 23, + T_GET = 94, T_GT = 24, T_GT_GT = 25, T_GT_GT_EQ = 26, @@ -148,6 +149,7 @@ public: T_RETURN = 59, T_RPAREN = 60, T_SEMICOLON = 61, + T_SET = 95, T_SIGNAL = 67, T_STAR = 63, T_STAR_EQ = 64, @@ -166,15 +168,15 @@ public: T_XOR = 79, T_XOR_EQ = 80, - ACCEPT_STATE = 645, - RULE_COUNT = 350, - STATE_COUNT = 646, - TERMINAL_COUNT = 103, - NON_TERMINAL_COUNT = 107, + ACCEPT_STATE = 655, + RULE_COUNT = 351, + STATE_COUNT = 656, + TERMINAL_COUNT = 105, + NON_TERMINAL_COUNT = 108, - GOTO_INDEX_OFFSET = 646, - GOTO_INFO_OFFSET = 3019, - GOTO_CHECK_OFFSET = 3019 + GOTO_INDEX_OFFSET = 656, + GOTO_INFO_OFFSET = 2970, + GOTO_CHECK_OFFSET = 2970 }; static const char *const spell []; diff --git a/src/qml/qml/parser/qqmljskeywords_p.h b/src/qml/qml/parser/qqmljskeywords_p.h index 8bbbe2355b..7fcf001303 100644 --- a/src/qml/qml/parser/qqmljskeywords_p.h +++ b/src/qml/qml/parser/qqmljskeywords_p.h @@ -53,6 +53,12 @@ // We mean it. // +#include "qqmljslexer_p.h" + +QT_QML_BEGIN_NAMESPACE + +namespace QQmlJS { + static inline int classify2(const QChar *s, bool qmlMode) { if (s[0].unicode() == 'a') { if (s[1].unicode() == 's') { @@ -88,6 +94,13 @@ static inline int classify3(const QChar *s, bool qmlMode) { } } } + else if (s[0].unicode() == 'g') { + if (s[1].unicode() == 'e') { + if (s[2].unicode() == 't') { + return Lexer::T_GET; + } + } + } else if (s[0].unicode() == 'i') { if (s[1].unicode() == 'n') { if (s[2].unicode() == 't') { @@ -102,6 +115,13 @@ static inline int classify3(const QChar *s, bool qmlMode) { } } } + else if (s[0].unicode() == 's') { + if (s[1].unicode() == 'e') { + if (s[2].unicode() == 't') { + return Lexer::T_SET; + } + } + } else if (s[0].unicode() == 't') { if (s[1].unicode() == 'r') { if (s[2].unicode() == 'y') { @@ -309,7 +329,7 @@ static inline int classify5(const QChar *s, bool qmlMode) { if (s[2].unicode() == 'p') { if (s[3].unicode() == 'e') { if (s[4].unicode() == 'r') { - return qmlMode ? int(Lexer::T_SUPER) : int(Lexer::T_IDENTIFIER); + return qmlMode ? int(Lexer::T_SUPER) : int(Lexer::T_RESERVED_WORD); } } } @@ -857,4 +877,8 @@ int Lexer::classify(const QChar *s, int n, bool qmlMode) { } // switch } +} // namespace QQmlJS + +QT_QML_END_NAMESPACE + #endif // QQMLJSKEYWORDS_P_H diff --git a/src/qml/qml/parser/qqmljslexer.cpp b/src/qml/qml/parser/qqmljslexer.cpp index ec9b718917..cb78238f99 100644 --- a/src/qml/qml/parser/qqmljslexer.cpp +++ b/src/qml/qml/parser/qqmljslexer.cpp @@ -42,10 +42,11 @@ #include "qqmljslexer_p.h" #include "qqmljsengine_p.h" #include "qqmljsmemorypool_p.h" +#include "qqmljskeywords_p.h" -#include <QtCore/QCoreApplication> -#include <QtCore/QVarLengthArray> -#include <QtCore/QDebug> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qvarlengtharray.h> +#include <QtCore/qdebug.h> QT_BEGIN_NAMESPACE Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); @@ -53,7 +54,7 @@ QT_END_NAMESPACE using namespace QQmlJS; -static int regExpFlagFromChar(const QChar &ch) +static inline int regExpFlagFromChar(const QChar &ch) { switch (ch.unicode()) { case 'g': return Lexer::RegExp_Global; @@ -63,7 +64,7 @@ static int regExpFlagFromChar(const QChar &ch) return 0; } -static unsigned char convertHex(ushort c) +static inline unsigned char convertHex(ushort c) { if (c >= '0' && c <= '9') return (c - '0'); @@ -73,12 +74,12 @@ static unsigned char convertHex(ushort c) return (c - 'A' + 10); } -static QChar convertHex(QChar c1, QChar c2) +static inline QChar convertHex(QChar c1, QChar c2) { return QChar((convertHex(c1.unicode()) << 4) + convertHex(c2.unicode())); } -static QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4) +static inline QChar convertUnicode(QChar c1, QChar c2, QChar c3, QChar c4) { return QChar((convertHex(c3.unicode()) << 4) + convertHex(c4.unicode()), (convertHex(c1.unicode()) << 4) + convertHex(c2.unicode())); @@ -136,6 +137,7 @@ void Lexer::setCode(const QString &code, int lineno, bool qmlMode) _tokenSpell = QStringRef(); _codePtr = code.unicode(); + _endPtr = _codePtr + code.length(); _lastLinePtr = _codePtr; _tokenLinePtr = _codePtr; _tokenStartPtr = _codePtr; @@ -177,6 +179,52 @@ void Lexer::scanChar() } } +namespace { +inline bool isBinop(int tok) +{ + switch (tok) { + case Lexer::T_AND: + case Lexer::T_AND_AND: + case Lexer::T_AND_EQ: + case Lexer::T_DIVIDE_: + case Lexer::T_DIVIDE_EQ: + case Lexer::T_EQ: + case Lexer::T_EQ_EQ: + case Lexer::T_EQ_EQ_EQ: + case Lexer::T_GE: + case Lexer::T_GT: + case Lexer::T_GT_GT: + case Lexer::T_GT_GT_EQ: + case Lexer::T_GT_GT_GT: + case Lexer::T_GT_GT_GT_EQ: + case Lexer::T_LE: + case Lexer::T_LT: + case Lexer::T_LT_LT: + case Lexer::T_LT_LT_EQ: + case Lexer::T_MINUS: + case Lexer::T_MINUS_EQ: + case Lexer::T_NOT_EQ: + case Lexer::T_NOT_EQ_EQ: + case Lexer::T_OR: + case Lexer::T_OR_EQ: + case Lexer::T_OR_OR: + case Lexer::T_PLUS: + case Lexer::T_PLUS_EQ: + case Lexer::T_REMAINDER: + case Lexer::T_REMAINDER_EQ: + case Lexer::T_RETURN: + case Lexer::T_STAR: + case Lexer::T_STAR_EQ: + case Lexer::T_XOR: + case Lexer::T_XOR_EQ: + return true; + + default: + return false; + } +} +} // anonymous namespace + int Lexer::lex() { const int previousTokenKind = _tokenKind; @@ -193,9 +241,15 @@ int Lexer::lex() switch (_tokenKind) { case T_LBRACE: case T_SEMICOLON: + case T_QUESTION: case T_COLON: + case T_TILDE: _delimited = true; break; + default: + if (isBinop(_tokenKind)) + _delimited = true; + break; case T_IF: case T_FOR: @@ -275,6 +329,80 @@ QChar Lexer::decodeUnicodeEscapeCharacter(bool *ok) return QChar(); } +QChar Lexer::decodeHexEscapeCharacter(bool *ok) +{ + if (isHexDigit(_codePtr[0]) && isHexDigit(_codePtr[1])) { + scanChar(); + + const QChar c1 = _char; + scanChar(); + + const QChar c2 = _char; + scanChar(); + + if (ok) + *ok = true; + + return convertHex(c1, c2); + } + + *ok = false; + return QChar(); +} + +static inline bool isIdentifierStart(QChar ch) +{ + // fast path for ascii + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || + (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || + ch == '$' || ch == '_') + return true; + + switch (ch.category()) { + case QChar::Number_Letter: + case QChar::Letter_Uppercase: + case QChar::Letter_Lowercase: + case QChar::Letter_Titlecase: + case QChar::Letter_Modifier: + case QChar::Letter_Other: + return true; + default: + break; + } + return false; +} + +static bool isIdentifierPart(QChar ch) +{ + // fast path for ascii + if ((ch.unicode() >= 'a' && ch.unicode() <= 'z') || + (ch.unicode() >= 'A' && ch.unicode() <= 'Z') || + (ch.unicode() >= '0' && ch.unicode() <= '9') || + ch == '$' || ch == '_' || + ch.unicode() == 0x200c /* ZWNJ */ || ch.unicode() == 0x200d /* ZWJ */) + return true; + + switch (ch.category()) { + case QChar::Mark_NonSpacing: + case QChar::Mark_SpacingCombining: + + case QChar::Number_DecimalDigit: + case QChar::Number_Letter: + + case QChar::Letter_Uppercase: + case QChar::Letter_Lowercase: + case QChar::Letter_Titlecase: + case QChar::Letter_Modifier: + case QChar::Letter_Other: + + case QChar::Punctuation_Connector: + return true; + default: + break; + } + return false; +} + int Lexer::scanToken() { if (_stackToken != -1) { @@ -310,7 +438,7 @@ again: _tokenStartPtr = _codePtr - 1; _tokenLine = _currentLineNumber; - if (_char.isNull()) + if (_codePtr > _endPtr) return EOF_SYMBOL; const QChar ch = _char; @@ -395,7 +523,7 @@ again: case '/': if (_char == QLatin1Char('*')) { scanChar(); - while (!_char.isNull()) { + while (_codePtr <= _endPtr) { if (_char == QLatin1Char('*')) { scanChar(); if (_char == QLatin1Char('/')) { @@ -413,7 +541,7 @@ again: } } } else if (_char == QLatin1Char('/')) { - while (!_char.isNull() && !isLineTerminator()) { + while (_codePtr <= _endPtr && !isLineTerminator()) { scanChar(); } if (_engine) { @@ -555,8 +683,14 @@ again: const QChar *startCode = _codePtr; if (_engine) { - while (!_char.isNull()) { - if (isLineTerminator() || _char == QLatin1Char('\\')) { + while (_codePtr <= _endPtr) { + if (isLineTerminator()) { + if (qmlMode()) + break; + _errorCode = IllegalCharacter; + _errorMessage = QCoreApplication::translate("QQmlParser", "Stray newline in string literal"); + return T_ERROR; + } else if (_char == QLatin1Char('\\')) { break; } else if (_char == quote) { _tokenSpell = _engine->midRef(startCode - _code.unicode() - 1, _codePtr - startCode); @@ -574,7 +708,7 @@ again: while (startCode != _codePtr - 1) _tokenText += *startCode++; - while (! _char.isNull()) { + while (_codePtr <= _endPtr) { if (unsigned sequenceLength = isLineTerminatorSequence()) { multilineStringLiteral = true; _tokenText += _char; @@ -592,32 +726,29 @@ again: scanChar(); QChar u; - bool ok = false; switch (_char.unicode()) { // unicode escape sequence - case 'u': + case 'u': { + bool ok = false; u = decodeUnicodeEscapeCharacter(&ok); - if (! ok) - u = _char; - break; + if (! ok) { + _errorCode = IllegalUnicodeEscapeSequence; + _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence"); + return T_ERROR; + } + } break; // hex escape sequence - case 'x': - if (isHexDigit(_codePtr[0]) && isHexDigit(_codePtr[1])) { - scanChar(); - - const QChar c1 = _char; - scanChar(); - - const QChar c2 = _char; - scanChar(); - - u = convertHex(c1, c2); - } else { - u = _char; + case 'x': { + bool ok = false; + u = decodeHexEscapeCharacter(&ok); + if (!ok) { + _errorCode = IllegalHexadecimalEscapeSequence; + _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal hexadecimal escape sequence"); + return T_ERROR; } - break; + } break; // single character escape sequence case '\\': u = QLatin1Char('\\'); scanChar(); break; @@ -631,32 +762,31 @@ again: case 'v': u = QLatin1Char('\v'); scanChar(); break; case '0': - if (! _codePtr[1].isDigit()) { + if (! _codePtr->isDigit()) { scanChar(); u = QLatin1Char('\0'); - } else { - // ### parse deprecated octal escape sequence ? - u = _char; + break; } - break; + // fall through + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + _errorCode = IllegalEscapeSequence; + _errorMessage = QCoreApplication::translate("QQmlParser", "Octal escape sequences are not allowed"); + return T_ERROR; case '\r': - if (isLineTerminatorSequence() == 2) { - _tokenText += QLatin1Char('\r'); - u = QLatin1Char('\n'); - } else { - u = QLatin1Char('\r'); - } - scanChar(); - break; - case '\n': case 0x2028u: case 0x2029u: - u = _char; scanChar(); - break; - + continue; default: // non escape character @@ -687,28 +817,28 @@ again: case '9': return scanNumber(ch); - default: - if (ch.isLetter() || ch == QLatin1Char('$') || ch == QLatin1Char('_') || (ch == QLatin1Char('\\') && _char == QLatin1Char('u'))) { - bool identifierWithEscapeChars = false; - if (ch == QLatin1Char('\\')) { - identifierWithEscapeChars = true; + default: { + QChar c = ch; + bool identifierWithEscapeChars = false; + if (c == QLatin1Char('\\') && _char == QLatin1Char('u')) { + identifierWithEscapeChars = true; + bool ok = false; + c = decodeUnicodeEscapeCharacter(&ok); + if (! ok) { + _errorCode = IllegalUnicodeEscapeSequence; + _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence"); + return T_ERROR; + } + } + if (isIdentifierStart(c)) { + if (identifierWithEscapeChars) { _tokenText.resize(0); - bool ok = false; - _tokenText += decodeUnicodeEscapeCharacter(&ok); + _tokenText += c; _validTokenText = true; - if (! ok) { - _errorCode = IllegalUnicodeEscapeSequence; - _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence"); - return T_ERROR; - } } while (true) { - if (_char.isLetterOrNumber() || _char == QLatin1Char('$') || _char == QLatin1Char('_')) { - if (identifierWithEscapeChars) - _tokenText += _char; - - scanChar(); - } else if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) { + c = _char; + if (_char == QLatin1Char('\\') && _codePtr[0] == QLatin1Char('u')) { if (! identifierWithEscapeChars) { identifierWithEscapeChars = true; _tokenText.resize(0); @@ -718,31 +848,41 @@ again: scanChar(); // skip '\\' bool ok = false; - _tokenText += decodeUnicodeEscapeCharacter(&ok); + c = decodeUnicodeEscapeCharacter(&ok); if (! ok) { _errorCode = IllegalUnicodeEscapeSequence; _errorMessage = QCoreApplication::translate("QQmlParser", "Illegal unicode escape sequence"); return T_ERROR; } - } else { - _tokenLength = _codePtr - _tokenStartPtr - 1; + if (isIdentifierPart(c)) + _tokenText += c; + continue; + } else if (isIdentifierPart(c)) { + if (identifierWithEscapeChars) + _tokenText += c; - int kind = T_IDENTIFIER; + scanChar(); + continue; + } - if (! identifierWithEscapeChars) - kind = classify(_tokenStartPtr, _tokenLength, _qmlMode); + _tokenLength = _codePtr - _tokenStartPtr - 1; - if (_engine) { - if (kind == T_IDENTIFIER && identifierWithEscapeChars) - _tokenSpell = _engine->newStringRef(_tokenText); - else - _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength); - } + int kind = T_IDENTIFIER; + + if (! identifierWithEscapeChars) + kind = classify(_tokenStartPtr, _tokenLength, _qmlMode); - return kind; + if (_engine) { + if (kind == T_IDENTIFIER && identifierWithEscapeChars) + _tokenSpell = _engine->newStringRef(_tokenText); + else + _tokenSpell = _engine->midRef(_tokenStartPtr - _code.unicode(), _tokenLength); } + + return kind; } } + } break; } @@ -753,12 +893,14 @@ again: int Lexer::scanNumber(QChar ch) { if (ch != QLatin1Char('0')) { - double integer = ch.unicode() - '0'; + QByteArray buf; + buf.reserve(64); + buf += ch.toLatin1(); QChar n = _char; const QChar *code = _codePtr; while (n.isDigit()) { - integer = integer * 10 + (n.unicode() - '0'); + buf += n.toLatin1(); n = *code++; } @@ -767,17 +909,23 @@ int Lexer::scanNumber(QChar ch) _codePtr = code - 1; scanChar(); } - _tokenValue = integer; + buf.append('\0'); + _tokenValue = strtod(buf.constData(), 0); return T_NUMERIC_LITERAL; } + } else if (_char.isDigit() && !qmlMode()) { + _errorCode = IllegalCharacter; + _errorMessage = QCoreApplication::translate("QQmlParser", "Decimal numbers can't start with '0'"); + return T_ERROR; } QVarLengthArray<char,32> chars; chars.append(ch.unicode()); if (ch == QLatin1Char('0') && (_char == QLatin1Char('x') || _char == QLatin1Char('X'))) { - // parse hex integer literal + ch = _char; // remember the x or X to use it in the error message below. + // parse hex integer literal chars.append(_char.unicode()); scanChar(); // consume `x' @@ -786,6 +934,12 @@ int Lexer::scanNumber(QChar ch) scanChar(); } + if (chars.size() < 3) { + _errorCode = IllegalHexNumber; + _errorMessage = QCoreApplication::translate("QQmlParser", "At least one hexadecimal digit is required after '0%1'").arg(ch); + return T_ERROR; + } + _tokenValue = integerFromString(chars.constData(), chars.size(), 16); return T_NUMERIC_LITERAL; } @@ -900,7 +1054,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix) _tokenText += _char; scanChar(); - if (_char.isNull() || isLineTerminator()) { + if (_codePtr > _endPtr || isLineTerminator()) { _errorMessage = QCoreApplication::translate("QQmlParser", "Unterminated regular expression backslash sequence"); return false; } @@ -914,7 +1068,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix) _tokenText += _char; scanChar(); - while (! _char.isNull() && ! isLineTerminator()) { + while (_codePtr <= _endPtr && ! isLineTerminator()) { if (_char == QLatin1Char(']')) break; else if (_char == QLatin1Char('\\')) { @@ -922,7 +1076,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix) _tokenText += _char; scanChar(); - if (_char.isNull() || isLineTerminator()) { + if (_codePtr > _endPtr || isLineTerminator()) { _errorMessage = QCoreApplication::translate("QQmlParser", "Unterminated regular expression backslash sequence"); return false; } @@ -945,7 +1099,7 @@ bool Lexer::scanRegExp(RegExpBodyPrefix prefix) break; default: - if (_char.isNull() || isLineTerminator()) { + if (_codePtr > _endPtr || isLineTerminator()) { _errorMessage = QCoreApplication::translate("QQmlParser", "Unterminated regular expression literal"); return false; } else { @@ -1172,5 +1326,3 @@ bool Lexer::scanDirectives(Directives *directives) return true; } - -#include "qqmljskeywords_p.h" diff --git a/src/qml/qml/parser/qqmljslexer_p.h b/src/qml/qml/parser/qqmljslexer_p.h index c6ae0931c1..23af61d650 100644 --- a/src/qml/qml/parser/qqmljslexer_p.h +++ b/src/qml/qml/parser/qqmljslexer_p.h @@ -55,7 +55,8 @@ #include "qqmljsglobal_p.h" #include "qqmljsgrammar_p.h" -#include <QtCore/QString> + +#include <QtCore/qstring.h> QT_QML_BEGIN_NAMESPACE @@ -121,12 +122,14 @@ public: enum Error { NoError, IllegalCharacter, + IllegalHexNumber, UnclosedStringLiteral, IllegalEscapeSequence, IllegalUnicodeEscapeSequence, UnclosedComment, IllegalExponentIndicator, - IllegalIdentifier + IllegalIdentifier, + IllegalHexadecimalEscapeSequence }; enum RegExpBodyPrefix { @@ -201,6 +204,7 @@ private: void syncProhibitAutomaticSemicolon(); QChar decodeUnicodeEscapeCharacter(bool *ok); + QChar decodeHexEscapeCharacter(bool *ok); private: Engine *_engine; @@ -211,6 +215,7 @@ private: QStringRef _tokenSpell; const QChar *_codePtr; + const QChar *_endPtr; const QChar *_lastLinePtr; const QChar *_tokenLinePtr; const QChar *_tokenStartPtr; diff --git a/src/qml/qml/parser/qqmljsparser.cpp b/src/qml/qml/parser/qqmljsparser.cpp index 1ef760b80a..a0fa7a4711 100644 --- a/src/qml/qml/parser/qqmljsparser.cpp +++ b/src/qml/qml/parser/qqmljsparser.cpp @@ -39,20 +39,20 @@ ** ****************************************************************************/ -#include <QtCore/QtDebug> -#include <QtCore/QCoreApplication> - -#include <string.h> - #include "qqmljsengine_p.h" #include "qqmljslexer_p.h" #include "qqmljsast_p.h" #include "qqmljsmemorypool_p.h" +#include <QtCore/qdebug.h> +#include <QtCore/qcoreapplication.h> + +#include <string.h> #include "qqmljsparser_p.h" -#include <QVarLengthArray> + +#include <QtCore/qvarlengtharray.h> // // W A R N I N G @@ -537,49 +537,49 @@ case 65: { sym(1).Node = new (pool) AST::UiSourceElement(sym(1).Node); } break; -case 71: { +case 73: { AST::ThisExpression *node = new (pool) AST::ThisExpression(); node->thisToken = loc(1); sym(1).Node = node; } break; -case 72: { +case 74: { AST::IdentifierExpression *node = new (pool) AST::IdentifierExpression(stringRef(1)); node->identifierToken = loc(1); sym(1).Node = node; } break; -case 73: { +case 75: { AST::NullExpression *node = new (pool) AST::NullExpression(); node->nullToken = loc(1); sym(1).Node = node; } break; -case 74: { +case 76: { AST::TrueLiteral *node = new (pool) AST::TrueLiteral(); node->trueToken = loc(1); sym(1).Node = node; } break; -case 75: { +case 77: { AST::FalseLiteral *node = new (pool) AST::FalseLiteral(); node->falseToken = loc(1); sym(1).Node = node; } break; -case 76: { +case 78: { AST::NumericLiteral *node = new (pool) AST::NumericLiteral(sym(1).dval); node->literalToken = loc(1); sym(1).Node = node; } break; -case 77: -case 78: { +case 79: +case 80: { AST::StringLiteral *node = new (pool) AST::StringLiteral(stringRef(1)); node->literalToken = loc(1); sym(1).Node = node; } break; -case 79: { +case 81: { bool rx = lexer->scanRegExp(Lexer::NoPrefix); if (!rx) { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); @@ -595,7 +595,7 @@ case 79: { sym(1).Node = node; } break; -case 80: { +case 82: { bool rx = lexer->scanRegExp(Lexer::EqualPrefix); if (!rx) { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Error, location(lexer), lexer->errorMessage())); @@ -611,28 +611,28 @@ case 80: { sym(1).Node = node; } break; -case 81: { +case 83: { AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral((AST::Elision *) 0); node->lbracketToken = loc(1); node->rbracketToken = loc(2); sym(1).Node = node; } break; -case 82: { +case 84: { AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).Elision->finish()); node->lbracketToken = loc(1); node->rbracketToken = loc(3); sym(1).Node = node; } break; -case 83: { +case 85: { AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish ()); node->lbracketToken = loc(1); node->rbracketToken = loc(3); sym(1).Node = node; } break; -case 84: { +case 86: { AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (), (AST::Elision *) 0); node->lbracketToken = loc(1); @@ -641,7 +641,7 @@ case 84: { sym(1).Node = node; } break; -case 85: { +case 87: { AST::ArrayLiteral *node = new (pool) AST::ArrayLiteral(sym(2).ElementList->finish (), sym(4).Elision->finish()); node->lbracketToken = loc(1); @@ -650,11 +650,11 @@ case 85: { sym(1).Node = node; } break; -case 86: { +case 88: { AST::ObjectLiteral *node = 0; if (sym(2).Node) node = new (pool) AST::ObjectLiteral( - sym(2).PropertyNameAndValueList->finish ()); + sym(2).PropertyAssignmentList->finish ()); else node = new (pool) AST::ObjectLiteral(); node->lbraceToken = loc(1); @@ -662,22 +662,22 @@ case 86: { sym(1).Node = node; } break; -case 87: { +case 89: { AST::ObjectLiteral *node = new (pool) AST::ObjectLiteral( - sym(2).PropertyNameAndValueList->finish ()); + sym(2).PropertyAssignmentList->finish ()); node->lbraceToken = loc(1); node->rbraceToken = loc(4); sym(1).Node = node; } break; -case 88: { +case 90: { AST::NestedExpression *node = new (pool) AST::NestedExpression(sym(2).Expression); node->lparenToken = loc(1); node->rparenToken = loc(3); sym(1).Node = node; } break; -case 89: { +case 91: { if (AST::ArrayMemberExpression *mem = AST::cast<AST::ArrayMemberExpression *>(sym(1).Expression)) { diagnostic_messages.append(DiagnosticMessage(DiagnosticMessage::Warning, mem->lbracketToken, QLatin1String("Ignored annotation"))); @@ -697,100 +697,119 @@ case 89: { } } break; -case 90: { +case 92: { sym(1).Node = new (pool) AST::ElementList((AST::Elision *) 0, sym(1).Expression); } break; -case 91: { +case 93: { sym(1).Node = new (pool) AST::ElementList(sym(1).Elision->finish(), sym(2).Expression); } break; -case 92: { +case 94: { AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, (AST::Elision *) 0, sym(3).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 93: { +case 95: { AST::ElementList *node = new (pool) AST::ElementList(sym(1).ElementList, sym(3).Elision->finish(), sym(4).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 94: { +case 96: { AST::Elision *node = new (pool) AST::Elision(); node->commaToken = loc(1); sym(1).Node = node; } break; -case 95: { +case 97: { AST::Elision *node = new (pool) AST::Elision(sym(1).Elision); node->commaToken = loc(2); sym(1).Node = node; } break; -case 96: { - AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList( +case 98: { + AST::PropertyNameAndValue *node = new (pool) AST::PropertyNameAndValue( sym(1).PropertyName, sym(3).Expression); node->colonToken = loc(2); sym(1).Node = node; } break; -case 97: { - AST::PropertyNameAndValueList *node = new (pool) AST::PropertyNameAndValueList( - sym(1).PropertyNameAndValueList, sym(3).PropertyName, sym(5).Expression); - node->commaToken = loc(2); - node->colonToken = loc(4); +case 99: { + AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( + sym(2).PropertyName, sym(6).FunctionBody); + node->getSetToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(4); + node->lbraceToken = loc(5); + node->rbraceToken = loc(7); sym(1).Node = node; } break; -case 98: { - AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); - node->propertyNameToken = loc(1); +case 100: { + AST::PropertyGetterSetter *node = new (pool) AST::PropertyGetterSetter( + sym(2).PropertyName, sym(4).FormalParameterList, sym(7).FunctionBody); + node->getSetToken = loc(1); + node->lparenToken = loc(3); + node->rparenToken = loc(5); + node->lbraceToken = loc(6); + node->rbraceToken = loc(8); sym(1).Node = node; } break; -case 99: -case 100: { + +case 101: { + sym(1).Node = new (pool) AST::PropertyAssignmentList(sym(1).PropertyAssignment); +} break; + +case 102: { + AST::PropertyAssignmentList *node = new (pool) AST::PropertyAssignmentList( + sym(1).PropertyAssignmentList, sym(3).PropertyAssignment); + node->commaToken = loc(2); + sym(1).Node = node; +} break; + +case 103: { AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); node->propertyNameToken = loc(1); sym(1).Node = node; } break; -case 101: { +case 104: { AST::StringLiteralPropertyName *node = new (pool) AST::StringLiteralPropertyName(stringRef(1)); node->propertyNameToken = loc(1); sym(1).Node = node; } break; -case 102: { +case 105: { AST::NumericLiteralPropertyName *node = new (pool) AST::NumericLiteralPropertyName(sym(1).dval); node->propertyNameToken = loc(1); sym(1).Node = node; } break; -case 103: { +case 106: { AST::IdentifierPropertyName *node = new (pool) AST::IdentifierPropertyName(stringRef(1)); node->propertyNameToken = loc(1); sym(1).Node = node; } break; -case 139: { +case 142: { AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression); node->lbracketToken = loc(2); node->rbracketToken = loc(4); sym(1).Node = node; } break; -case 140: { +case 143: { AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); node->dotToken = loc(2); node->identifierToken = loc(3); sym(1).Node = node; } break; -case 141: { +case 144: { AST::NewMemberExpression *node = new (pool) AST::NewMemberExpression(sym(2).Expression, sym(4).ArgumentList); node->newToken = loc(1); node->lparenToken = loc(3); @@ -798,384 +817,384 @@ case 141: { sym(1).Node = node; } break; -case 143: { +case 146: { AST::NewExpression *node = new (pool) AST::NewExpression(sym(2).Expression); node->newToken = loc(1); sym(1).Node = node; } break; -case 144: { +case 147: { AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList); node->lparenToken = loc(2); node->rparenToken = loc(4); sym(1).Node = node; } break; -case 145: { +case 148: { AST::CallExpression *node = new (pool) AST::CallExpression(sym(1).Expression, sym(3).ArgumentList); node->lparenToken = loc(2); node->rparenToken = loc(4); sym(1).Node = node; } break; -case 146: { +case 149: { AST::ArrayMemberExpression *node = new (pool) AST::ArrayMemberExpression(sym(1).Expression, sym(3).Expression); node->lbracketToken = loc(2); node->rbracketToken = loc(4); sym(1).Node = node; } break; -case 147: { +case 150: { AST::FieldMemberExpression *node = new (pool) AST::FieldMemberExpression(sym(1).Expression, stringRef(3)); node->dotToken = loc(2); node->identifierToken = loc(3); sym(1).Node = node; } break; -case 148: { +case 151: { sym(1).Node = 0; } break; -case 149: { +case 152: { sym(1).Node = sym(1).ArgumentList->finish(); } break; -case 150: { +case 153: { sym(1).Node = new (pool) AST::ArgumentList(sym(1).Expression); } break; -case 151: { +case 154: { AST::ArgumentList *node = new (pool) AST::ArgumentList(sym(1).ArgumentList, sym(3).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 155: { +case 158: { AST::PostIncrementExpression *node = new (pool) AST::PostIncrementExpression(sym(1).Expression); node->incrementToken = loc(2); sym(1).Node = node; } break; -case 156: { +case 159: { AST::PostDecrementExpression *node = new (pool) AST::PostDecrementExpression(sym(1).Expression); node->decrementToken = loc(2); sym(1).Node = node; } break; -case 158: { +case 161: { AST::DeleteExpression *node = new (pool) AST::DeleteExpression(sym(2).Expression); node->deleteToken = loc(1); sym(1).Node = node; } break; -case 159: { +case 162: { AST::VoidExpression *node = new (pool) AST::VoidExpression(sym(2).Expression); node->voidToken = loc(1); sym(1).Node = node; } break; -case 160: { +case 163: { AST::TypeOfExpression *node = new (pool) AST::TypeOfExpression(sym(2).Expression); node->typeofToken = loc(1); sym(1).Node = node; } break; -case 161: { +case 164: { AST::PreIncrementExpression *node = new (pool) AST::PreIncrementExpression(sym(2).Expression); node->incrementToken = loc(1); sym(1).Node = node; } break; -case 162: { +case 165: { AST::PreDecrementExpression *node = new (pool) AST::PreDecrementExpression(sym(2).Expression); node->decrementToken = loc(1); sym(1).Node = node; } break; -case 163: { +case 166: { AST::UnaryPlusExpression *node = new (pool) AST::UnaryPlusExpression(sym(2).Expression); node->plusToken = loc(1); sym(1).Node = node; } break; -case 164: { +case 167: { AST::UnaryMinusExpression *node = new (pool) AST::UnaryMinusExpression(sym(2).Expression); node->minusToken = loc(1); sym(1).Node = node; } break; -case 165: { +case 168: { AST::TildeExpression *node = new (pool) AST::TildeExpression(sym(2).Expression); node->tildeToken = loc(1); sym(1).Node = node; } break; -case 166: { +case 169: { AST::NotExpression *node = new (pool) AST::NotExpression(sym(2).Expression); node->notToken = loc(1); sym(1).Node = node; } break; -case 168: { +case 171: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Mul, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 169: { +case 172: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Div, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 170: { +case 173: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Mod, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 172: { +case 175: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Add, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 173: { +case 176: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Sub, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 175: { +case 178: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::LShift, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 176: { +case 179: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::RShift, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 177: { +case 180: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::URShift, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 179: { +case 182: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Lt, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 180: { +case 183: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Gt, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 181: { +case 184: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Le, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 182: { +case 185: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Ge, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 183: { +case 186: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 184: { +case 187: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::In, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 186: { +case 189: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Lt, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 187: { +case 190: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Gt, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 188: { +case 191: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Le, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 189: { +case 192: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Ge, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 190: { +case 193: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::InstanceOf, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 192: { +case 195: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Equal, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 193: { +case 196: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::NotEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 194: { +case 197: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 195: { +case 198: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::StrictNotEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 197: { +case 200: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Equal, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 198: { +case 201: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::NotEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 199: { +case 202: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::StrictEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 200: { +case 203: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::StrictNotEqual, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 202: { +case 205: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitAnd, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 204: { +case 207: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitAnd, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 206: { +case 209: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitXor, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 208: { +case 211: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitXor, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 210: { +case 213: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitOr, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 212: { +case 215: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::BitOr, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 214: { +case 217: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::And, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 216: { +case 219: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::And, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 218: { +case 221: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Or, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 220: { +case 223: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, QSOperator::Or, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 222: { +case 225: { AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, sym(3).Expression, sym(5).Expression); node->questionToken = loc(2); @@ -1183,7 +1202,7 @@ case 222: { sym(1).Node = node; } break; -case 224: { +case 227: { AST::ConditionalExpression *node = new (pool) AST::ConditionalExpression(sym(1).Expression, sym(3).Expression, sym(5).Expression); node->questionToken = loc(2); @@ -1191,112 +1210,112 @@ case 224: { sym(1).Node = node; } break; -case 226: { +case 229: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 228: { +case 231: { AST::BinaryExpression *node = new (pool) AST::BinaryExpression(sym(1).Expression, sym(2).ival, sym(3).Expression); node->operatorToken = loc(2); sym(1).Node = node; } break; -case 229: { +case 232: { sym(1).ival = QSOperator::Assign; } break; -case 230: { +case 233: { sym(1).ival = QSOperator::InplaceMul; } break; -case 231: { +case 234: { sym(1).ival = QSOperator::InplaceDiv; } break; -case 232: { +case 235: { sym(1).ival = QSOperator::InplaceMod; } break; -case 233: { +case 236: { sym(1).ival = QSOperator::InplaceAdd; } break; -case 234: { +case 237: { sym(1).ival = QSOperator::InplaceSub; } break; -case 235: { +case 238: { sym(1).ival = QSOperator::InplaceLeftShift; } break; -case 236: { +case 239: { sym(1).ival = QSOperator::InplaceRightShift; } break; -case 237: { +case 240: { sym(1).ival = QSOperator::InplaceURightShift; } break; -case 238: { +case 241: { sym(1).ival = QSOperator::InplaceAnd; } break; -case 239: { +case 242: { sym(1).ival = QSOperator::InplaceXor; } break; -case 240: { +case 243: { sym(1).ival = QSOperator::InplaceOr; } break; -case 242: { +case 245: { AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 243: { +case 246: { sym(1).Node = 0; } break; -case 246: { +case 249: { AST::Expression *node = new (pool) AST::Expression(sym(1).Expression, sym(3).Expression); node->commaToken = loc(2); sym(1).Node = node; } break; -case 247: { +case 250: { sym(1).Node = 0; } break; -case 264: { +case 267: { AST::Block *node = new (pool) AST::Block(sym(2).StatementList); node->lbraceToken = loc(1); node->rbraceToken = loc(3); sym(1).Node = node; } break; -case 265: { +case 268: { sym(1).Node = new (pool) AST::StatementList(sym(1).Statement); } break; -case 266: { +case 269: { sym(1).Node = new (pool) AST::StatementList(sym(1).StatementList, sym(2).Statement); } break; -case 267: { +case 270: { sym(1).Node = 0; } break; -case 268: { +case 271: { sym(1).Node = sym(1).StatementList->finish (); } break; -case 270: { +case 273: { AST::VariableStatement *node = new (pool) AST::VariableStatement( sym(2).VariableDeclarationList->finish (/*readOnly=*/sym(1).ival == T_CONST)); node->declarationKindToken = loc(1); @@ -1304,76 +1323,76 @@ case 270: { sym(1).Node = node; } break; -case 271: { +case 274: { sym(1).ival = T_CONST; } break; -case 272: { +case 275: { sym(1).ival = T_VAR; } break; -case 273: { +case 276: { sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration); } break; -case 274: { +case 277: { AST::VariableDeclarationList *node = new (pool) AST::VariableDeclarationList( sym(1).VariableDeclarationList, sym(3).VariableDeclaration); node->commaToken = loc(2); sym(1).Node = node; } break; -case 275: { +case 278: { sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclaration); } break; -case 276: { +case 279: { sym(1).Node = new (pool) AST::VariableDeclarationList(sym(1).VariableDeclarationList, sym(3).VariableDeclaration); } break; -case 277: { +case 280: { AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression); node->identifierToken = loc(1); sym(1).Node = node; } break; -case 278: { +case 281: { AST::VariableDeclaration *node = new (pool) AST::VariableDeclaration(stringRef(1), sym(2).Expression); node->identifierToken = loc(1); sym(1).Node = node; } break; -case 279: { +case 282: { // ### TODO: AST for initializer sym(1) = sym(2); } break; -case 280: { +case 283: { sym(1).Node = 0; } break; -case 282: { +case 285: { // ### TODO: AST for initializer sym(1) = sym(2); } break; -case 283: { +case 286: { sym(1).Node = 0; } break; -case 285: { +case 288: { AST::EmptyStatement *node = new (pool) AST::EmptyStatement(); node->semicolonToken = loc(1); sym(1).Node = node; } break; -case 287: { +case 290: { AST::ExpressionStatement *node = new (pool) AST::ExpressionStatement(sym(1).Expression); node->semicolonToken = loc(2); sym(1).Node = node; } break; -case 288: { +case 291: { AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement, sym(7).Statement); node->ifToken = loc(1); node->lparenToken = loc(2); @@ -1382,7 +1401,7 @@ case 288: { sym(1).Node = node; } break; -case 289: { +case 292: { AST::IfStatement *node = new (pool) AST::IfStatement(sym(3).Expression, sym(5).Statement); node->ifToken = loc(1); node->lparenToken = loc(2); @@ -1390,7 +1409,7 @@ case 289: { sym(1).Node = node; } break; -case 292: { +case 295: { AST::DoWhileStatement *node = new (pool) AST::DoWhileStatement(sym(2).Statement, sym(5).Expression); node->doToken = loc(1); node->whileToken = loc(3); @@ -1400,7 +1419,7 @@ case 292: { sym(1).Node = node; } break; -case 293: { +case 296: { AST::WhileStatement *node = new (pool) AST::WhileStatement(sym(3).Expression, sym(5).Statement); node->whileToken = loc(1); node->lparenToken = loc(2); @@ -1408,7 +1427,7 @@ case 293: { sym(1).Node = node; } break; -case 294: { +case 297: { AST::ForStatement *node = new (pool) AST::ForStatement(sym(3).Expression, sym(5).Expression, sym(7).Expression, sym(9).Statement); node->forToken = loc(1); @@ -1419,7 +1438,7 @@ case 294: { sym(1).Node = node; } break; -case 295: { +case 298: { AST::LocalForStatement *node = new (pool) AST::LocalForStatement( sym(4).VariableDeclarationList->finish (/*readOnly=*/false), sym(6).Expression, sym(8).Expression, sym(10).Statement); @@ -1432,7 +1451,7 @@ case 295: { sym(1).Node = node; } break; -case 296: { +case 299: { AST:: ForEachStatement *node = new (pool) AST::ForEachStatement(sym(3).Expression, sym(5).Expression, sym(7).Statement); node->forToken = loc(1); @@ -1442,7 +1461,7 @@ case 296: { sym(1).Node = node; } break; -case 297: { +case 300: { AST::LocalForEachStatement *node = new (pool) AST::LocalForEachStatement( sym(4).VariableDeclaration, sym(6).Expression, sym(8).Statement); node->forToken = loc(1); @@ -1453,14 +1472,14 @@ case 297: { sym(1).Node = node; } break; -case 299: { +case 302: { AST::ContinueStatement *node = new (pool) AST::ContinueStatement(); node->continueToken = loc(1); node->semicolonToken = loc(2); sym(1).Node = node; } break; -case 301: { +case 304: { AST::ContinueStatement *node = new (pool) AST::ContinueStatement(stringRef(2)); node->continueToken = loc(1); node->identifierToken = loc(2); @@ -1468,14 +1487,14 @@ case 301: { sym(1).Node = node; } break; -case 303: { +case 306: { AST::BreakStatement *node = new (pool) AST::BreakStatement(QStringRef()); node->breakToken = loc(1); node->semicolonToken = loc(2); sym(1).Node = node; } break; -case 305: { +case 308: { AST::BreakStatement *node = new (pool) AST::BreakStatement(stringRef(2)); node->breakToken = loc(1); node->identifierToken = loc(2); @@ -1483,14 +1502,14 @@ case 305: { sym(1).Node = node; } break; -case 307: { +case 310: { AST::ReturnStatement *node = new (pool) AST::ReturnStatement(sym(2).Expression); node->returnToken = loc(1); node->semicolonToken = loc(3); sym(1).Node = node; } break; -case 308: { +case 311: { AST::WithStatement *node = new (pool) AST::WithStatement(sym(3).Expression, sym(5).Statement); node->withToken = loc(1); node->lparenToken = loc(2); @@ -1498,7 +1517,7 @@ case 308: { sym(1).Node = node; } break; -case 309: { +case 312: { AST::SwitchStatement *node = new (pool) AST::SwitchStatement(sym(3).Expression, sym(5).CaseBlock); node->switchToken = loc(1); node->lparenToken = loc(2); @@ -1506,90 +1525,83 @@ case 309: { sym(1).Node = node; } break; -case 310: { +case 313: { AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses); node->lbraceToken = loc(1); node->rbraceToken = loc(3); sym(1).Node = node; } break; -case 311: { +case 314: { AST::CaseBlock *node = new (pool) AST::CaseBlock(sym(2).CaseClauses, sym(3).DefaultClause, sym(4).CaseClauses); node->lbraceToken = loc(1); node->rbraceToken = loc(5); sym(1).Node = node; } break; -case 312: { +case 315: { sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClause); } break; -case 313: { +case 316: { sym(1).Node = new (pool) AST::CaseClauses(sym(1).CaseClauses, sym(2).CaseClause); } break; -case 314: { +case 317: { sym(1).Node = 0; } break; -case 315: { +case 318: { sym(1).Node = sym(1).CaseClauses->finish (); } break; -case 316: { +case 319: { AST::CaseClause *node = new (pool) AST::CaseClause(sym(2).Expression, sym(4).StatementList); node->caseToken = loc(1); node->colonToken = loc(3); sym(1).Node = node; } break; -case 317: { +case 320: { AST::DefaultClause *node = new (pool) AST::DefaultClause(sym(3).StatementList); node->defaultToken = loc(1); node->colonToken = loc(2); sym(1).Node = node; } break; -case 318: -case 319: { - AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement); - node->identifierToken = loc(1); - node->colonToken = loc(2); - sym(1).Node = node; -} break; -case 320: { +case 321: { AST::LabelledStatement *node = new (pool) AST::LabelledStatement(stringRef(1), sym(3).Statement); node->identifierToken = loc(1); node->colonToken = loc(2); sym(1).Node = node; } break; -case 322: { +case 323: { AST::ThrowStatement *node = new (pool) AST::ThrowStatement(sym(2).Expression); node->throwToken = loc(1); node->semicolonToken = loc(3); sym(1).Node = node; } break; -case 323: { +case 324: { AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch); node->tryToken = loc(1); sym(1).Node = node; } break; -case 324: { +case 325: { AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Finally); node->tryToken = loc(1); sym(1).Node = node; } break; -case 325: { +case 326: { AST::TryStatement *node = new (pool) AST::TryStatement(sym(2).Statement, sym(3).Catch, sym(4).Finally); node->tryToken = loc(1); sym(1).Node = node; } break; -case 326: { +case 327: { AST::Catch *node = new (pool) AST::Catch(stringRef(3), sym(5).Block); node->catchToken = loc(1); node->lparenToken = loc(2); @@ -1598,20 +1610,20 @@ case 326: { sym(1).Node = node; } break; -case 327: { +case 328: { AST::Finally *node = new (pool) AST::Finally(sym(2).Block); node->finallyToken = loc(1); sym(1).Node = node; } break; -case 329: { +case 330: { AST::DebuggerStatement *node = new (pool) AST::DebuggerStatement(); node->debuggerToken = loc(1); node->semicolonToken = loc(2); sym(1).Node = node; } break; -case 330: { +case 332: { AST::FunctionDeclaration *node = new (pool) AST::FunctionDeclaration(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody); node->functionToken = loc(1); node->identifierToken = loc(2); @@ -1622,7 +1634,7 @@ case 330: { sym(1).Node = node; } break; -case 331: { +case 333: { AST::FunctionExpression *node = new (pool) AST::FunctionExpression(stringRef(2), sym(4).FormalParameterList, sym(7).FunctionBody); node->functionToken = loc(1); if (! stringRef(2).isNull()) @@ -1634,60 +1646,66 @@ case 331: { sym(1).Node = node; } break; -case 332: { +case 334: { + AST::FunctionExpression *node = new (pool) AST::FunctionExpression(QStringRef(), sym(3).FormalParameterList, sym(6).FunctionBody); + node->functionToken = loc(1); + node->lparenToken = loc(2); + node->rparenToken = loc(4); + node->lbraceToken = loc(5); + node->rbraceToken = loc(7); + sym(1).Node = node; +} break; + +case 335: { AST::FormalParameterList *node = new (pool) AST::FormalParameterList(stringRef(1)); node->identifierToken = loc(1); sym(1).Node = node; } break; -case 333: { +case 336: { AST::FormalParameterList *node = new (pool) AST::FormalParameterList(sym(1).FormalParameterList, stringRef(3)); node->commaToken = loc(2); node->identifierToken = loc(3); sym(1).Node = node; } break; -case 334: { +case 337: { sym(1).Node = 0; } break; -case 335: { +case 338: { sym(1).Node = sym(1).FormalParameterList->finish (); } break; -case 336: { +case 339: { sym(1).Node = 0; } break; -case 338: { +case 341: { sym(1).Node = new (pool) AST::FunctionBody(sym(1).SourceElements->finish ()); } break; -case 340: { +case 343: { sym(1).Node = new (pool) AST::Program(sym(1).SourceElements->finish ()); } break; -case 341: { +case 344: { sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElement); } break; -case 342: { +case 345: { sym(1).Node = new (pool) AST::SourceElements(sym(1).SourceElements, sym(2).SourceElement); } break; -case 343: { +case 346: { sym(1).Node = new (pool) AST::StatementSourceElement(sym(1).Statement); } break; -case 344: { +case 347: { sym(1).Node = new (pool) AST::FunctionSourceElement(sym(1).FunctionDeclaration); } break; -case 345: { - stringRef(1) = QStringRef(); -} break; - -case 347: { +case 348: { sym(1).Node = 0; } break; diff --git a/src/qml/qml/parser/qqmljsparser_p.h b/src/qml/qml/parser/qqmljsparser_p.h index 3da1b9a6a4..1b13690547 100644 --- a/src/qml/qml/parser/qqmljsparser_p.h +++ b/src/qml/qml/parser/qqmljsparser_p.h @@ -71,8 +71,8 @@ #include "qqmljsast_p.h" #include "qqmljsengine_p.h" -#include <QtCore/QList> -#include <QtCore/QString> +#include <QtCore/qlist.h> +#include <QtCore/qstring.h> QT_QML_BEGIN_NAMESPACE @@ -101,7 +101,8 @@ public: AST::FunctionDeclaration *FunctionDeclaration; AST::Node *Node; AST::PropertyName *PropertyName; - AST::PropertyNameAndValueList *PropertyNameAndValueList; + AST::PropertyAssignment *PropertyAssignment; + AST::PropertyAssignmentList *PropertyAssignmentList; AST::SourceElement *SourceElement; AST::SourceElements *SourceElements; AST::Statement *Statement; @@ -244,9 +245,9 @@ protected: -#define J_SCRIPT_REGEXPLITERAL_RULE1 79 +#define J_SCRIPT_REGEXPLITERAL_RULE1 81 -#define J_SCRIPT_REGEXPLITERAL_RULE2 80 +#define J_SCRIPT_REGEXPLITERAL_RULE2 82 QT_QML_END_NAMESPACE diff --git a/src/qml/qml/qml.pri b/src/qml/qml/qml.pri index 20b46f0939..aafc50db9b 100644 --- a/src/qml/qml/qml.pri +++ b/src/qml/qml/qml.pri @@ -1,12 +1,9 @@ SOURCES += \ $$PWD/qqmlinstruction.cpp \ - $$PWD/qquicklistmodel.cpp \ - $$PWD/qquicklistmodelworkeragent.cpp \ $$PWD/qqmlopenmetaobject.cpp \ $$PWD/qqmlvmemetaobject.cpp \ $$PWD/qqmlengine.cpp \ $$PWD/qqmlexpression.cpp \ - $$PWD/qqmlbinding.cpp \ $$PWD/qqmlproperty.cpp \ $$PWD/qqmlcomponent.cpp \ $$PWD/qqmlincubator.cpp \ @@ -38,7 +35,6 @@ SOURCES += \ $$PWD/qqmltypenotavailable.cpp \ $$PWD/qqmltypenamecache.cpp \ $$PWD/qqmlscriptstring.cpp \ - $$PWD/qquickworkerscript.cpp \ $$PWD/qqmlnetworkaccessmanagerfactory.cpp \ $$PWD/qqmldirparser.cpp \ $$PWD/qqmlextensionplugin.cpp \ @@ -53,20 +49,16 @@ SOURCES += \ $$PWD/qqmlfile.cpp \ $$PWD/qqmlbundle.cpp \ $$PWD/qqmlmemoryprofiler.cpp \ - $$PWD/qqmlconnections.cpp \ - $$PWD/qqmltimer.cpp \ - $$PWD/qqmlbind.cpp + $$PWD/qqmlplatform.cpp \ + $$PWD/qqmlbinding.cpp \ + $$PWD/qqmlapplicationengine.cpp HEADERS += \ $$PWD/qqmlglobal_p.h \ $$PWD/qqmlinstruction_p.h \ - $$PWD/qquicklistmodel_p.h\ - $$PWD/qquicklistmodel_p_p.h\ - $$PWD/qquicklistmodelworkeragent_p.h \ $$PWD/qqmlopenmetaobject_p.h \ $$PWD/qqmlvmemetaobject_p.h \ $$PWD/qqml.h \ - $$PWD/qqmlbinding_p.h \ $$PWD/qqmlproperty.h \ $$PWD/qqmlcomponent.h \ $$PWD/qqmlcomponent_p.h \ @@ -111,7 +103,6 @@ HEADERS += \ $$PWD/qqmltypenotavailable_p.h \ $$PWD/qqmltypenamecache_p.h \ $$PWD/qqmlscriptstring.h \ - $$PWD/qquickworkerscript_p.h \ $$PWD/qqmlguard_p.h \ $$PWD/qqmlnetworkaccessmanagerfactory.h \ $$PWD/qqmldirparser_p.h \ @@ -129,9 +120,11 @@ HEADERS += \ $$PWD/qqmlfile.h \ $$PWD/qqmlbundle_p.h \ $$PWD/qqmlmemoryprofiler_p.h \ - $$PWD/qqmlconnections_p.h \ - $$PWD/qqmltimer_p.h \ - $$PWD/qqmlbind_p.h + $$PWD/qqmlplatform_p.h \ + $$PWD/qqmlbinding_p.h \ + $$PWD/qqmlextensionplugin_p.h \ + $$PWD/qqmlapplicationengine_p.h \ + $$PWD/qqmlapplicationengine.h include(parser/parser.pri) diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 597c59eeff..7e6e0d1d36 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -49,8 +49,7 @@ #include <QtCore/qbytearray.h> #include <QtCore/qmetaobject.h> - -QT_BEGIN_HEADER +#include <QtCore/qdebug.h> #define QML_VERSION 0x020000 #define QML_VERSION_STR "2.0" @@ -465,11 +464,29 @@ inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versi return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api); } + +inline int qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName) +{ + if (url.isRelative()) { + // User input check must go here, because QQmlPrivate::qmlregister is also used internally for composite types + qWarning() << "qmlRegisterType requires absolute URLs."; + return 0; + } + + QQmlPrivate::RegisterCompositeType type = { + url, + uri, + versionMajor, + versionMinor, + qmlName + }; + + return QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, &type); +} + QT_END_NAMESPACE QML_DECLARE_TYPE(QObject) Q_DECLARE_METATYPE(QVariant) -QT_END_HEADER - #endif // QQML_H diff --git a/src/qml/qml/qqmlaccessors_p.h b/src/qml/qml/qqmlaccessors_p.h index 24b548c58c..6df624eaf1 100644 --- a/src/qml/qml/qqmlaccessors_p.h +++ b/src/qml/qml/qqmlaccessors_p.h @@ -52,8 +52,6 @@ #include <stdint.h> #endif -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QObject; @@ -167,6 +165,4 @@ QQmlAccessorProperties::Properties::Properties() QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLACCESSORS_P_H diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp new file mode 100644 index 0000000000..7dc2c77922 --- /dev/null +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -0,0 +1,285 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Research In Motion. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtCore/QCoreApplication> +#include <QtCore/QTranslator> +#include <QQmlComponent> +#include "qqmlapplicationengine.h" +#include "qqmlapplicationengine_p.h" + +QT_BEGIN_NAMESPACE + +QQmlApplicationEnginePrivate::QQmlApplicationEnginePrivate(QQmlEngine *e) + : QQmlEnginePrivate(e) +{ +} + +QQmlApplicationEnginePrivate::~QQmlApplicationEnginePrivate() +{ + qDeleteAll(objects); +#ifndef QT_NO_TRANSLATIONS + qDeleteAll(translators); +#endif +} + +void QQmlApplicationEnginePrivate::init() +{ + Q_Q(QQmlApplicationEngine); + q->connect(&statusMapper, SIGNAL(mapped(QObject*)), + q, SLOT(_q_finishLoad(QObject*))); + q->connect(q, SIGNAL(quit()), QCoreApplication::instance(), SLOT(quit())); +#ifndef QT_NO_TRANSLATIONS + QTranslator* qtTranslator = new QTranslator; + if (qtTranslator->load(QLatin1String("qt_") + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) + QCoreApplication::installTranslator(qtTranslator); + translators << qtTranslator; +#endif +} + +void QQmlApplicationEnginePrivate::loadTranslations(const QUrl &rootFile) +{ +#ifndef QT_NO_TRANSLATIONS + if (rootFile.scheme() != QLatin1String("file") && rootFile.scheme() != QLatin1String("qrc")) + return; + + QFileInfo fi(rootFile.toLocalFile()); + + QTranslator *translator = new QTranslator; + if (translator->load(QLatin1String("qml_") + QLocale::system().name(), fi.path() + QLatin1String("/i18n"))) { + QCoreApplication::installTranslator(translator); + translators << translator; + } else { + delete translator; + } +#endif +} + +void QQmlApplicationEnginePrivate::startLoad(const QUrl &url, const QByteArray &data, bool dataFlag) +{ + Q_Q(QQmlApplicationEngine); + + loadTranslations(url); //Translations must be loaded before the QML file is + QQmlComponent *c = new QQmlComponent(q, q); + + if (dataFlag) + c->setData(data,url); + else + c->loadUrl(url); + + if (!c->isLoading()) { + _q_finishLoad(c); + return; + } + statusMapper.setMapping(c, c); + q->connect(c, SIGNAL(statusChanged(QQmlComponent::Status)), + &statusMapper, SLOT(map())); +} + +void QQmlApplicationEnginePrivate::_q_finishLoad(QObject *o) +{ + Q_Q(QQmlApplicationEngine); + QQmlComponent *c = qobject_cast<QQmlComponent *>(o); + if (!c) + return; + switch (c->status()) { + case QQmlComponent::Error: + qWarning() << "QQmlApplicationEngine failed to load component"; + qWarning() << qPrintable(c->errorString()); + q->objectCreated(0, c->url()); + break; + case QQmlComponent::Ready: + objects << c->create(); + q->objectCreated(objects.last(), c->url()); + break; + case QQmlComponent::Loading: + case QQmlComponent::Null: + return; //These cases just wait for the next status update + } + delete c; +} + +/*! + \class QQmlApplicationEngine + \since 5.1 + \inmodule QtQml + \brief QQmlApplicationEngine provides a convenient way to load an application from a single QML file. + + This class combines a QQmlEngine and QQmlComponent to provide a convenient way to load a single QML file. It also exposes some central application functionality to QML, which a C++/QML hybrid application would normally control from C++. + + It can be used like so: + + \code + #include <QGuiApplication> + #include <QQmlApplicationEngine> + + int main(int argc, char *argv[]) + { + QGuiApplication app(argc, argv); + QQmlApplicationEngine engine("main.qml"); + return app.exec(); + } + \endcode + + You can also use QCoreApplication with QQmlApplicationEngine, if you are not using any QML modules which require a QGuiApplication (such as QtQuick). + + List of configuration changes from a default QQmlEngine: + + \list + \li Connecting Qt.quit() to QCoreApplication::quit() + \li Automatically loads translation files from an i18n directory adjacent to the main QML file. + \endlist + + The engine behavior can be further tweaked by using the inherited methods from QQmlEngine. +*/ + +/*! + \fn QQmlApplicationEngine::objectCreated(QObject *object, const QUrl &url) + + This signal is emitted when an object finishes loading. If loading was successful, \a object contains a pointer to the loaded object. + Otherwise the pointer is NULL. The \a url loaded is also provided, note that if a QString file path was initially passed to the + QQmlApplicationEngine, this url will be the equivalent of QUrl::fromLocalFile(filePath). +*/ + +/*! + Create a new QQmlApplicationEngine with the given \a parent. You will have to call load() later in + order to load a QML file. +*/ +QQmlApplicationEngine::QQmlApplicationEngine(QObject *parent) +: QQmlEngine(*(new QQmlApplicationEnginePrivate(this)), parent) +{ + Q_D(QQmlApplicationEngine); + d->init(); +} + +/*! + Create a new QQmlApplicationEngine and loads the QML file at the given \a url. + This is provided as a convenience, and is the same as using the empty constructor and calling load afterwards. +*/ +QQmlApplicationEngine::QQmlApplicationEngine(const QUrl &url, QObject *parent) + : QQmlEngine(*(new QQmlApplicationEnginePrivate(this)), parent) +{ + Q_D(QQmlApplicationEngine); + d->init(); + load(url); +} + +/*! + Create a new QQmlApplicationEngine and loads the QML file at the given + \a filePath, which must be a local file path. If a relative path is + given then it will be interpreted as relative to the working directory of the + application. + + This is provided as a convenience, and is the same as using the empty constructor and calling load afterwards. +*/ +QQmlApplicationEngine::QQmlApplicationEngine(const QString &filePath, QObject *parent) + : QQmlEngine(*(new QQmlApplicationEnginePrivate(this)), parent) +{ + Q_D(QQmlApplicationEngine); + d->init(); + load(QUrl::fromLocalFile(filePath)); +} + +/*! + Destroys the QQmlApplicationEngine and all QML objects it loaded. +*/ +QQmlApplicationEngine::~QQmlApplicationEngine() +{ + //Instantiated root objects cleaned up in private class +} + +/*! + Loads the root QML file located at \a url. The object tree defined by the file + is created immediately for local file urls. Remote urls are loaded asynchronously, + listen to the objectCreated signal to determine when the object + tree is ready. + + If an error occurs, error messages are printed with qWarning. +*/ +void QQmlApplicationEngine::load(const QUrl &url) +{ + Q_D(QQmlApplicationEngine); + d->startLoad(url); +} + +/*! + Loads the root QML file located at \a filePath. \a filePath must be a path to + a local file. If \a filePath is a relative path, it is taken as relative to + the application's working directory. The object tree defined by the file is + instantiated immediately. + + If an error occurs, error messages are printed with qWarning. +*/ +void QQmlApplicationEngine::load(const QString &filePath) +{ + Q_D(QQmlApplicationEngine); + d->startLoad(QUrl::fromLocalFile(filePath)); +} + +/*! + Loads the QML given in \a data. The object tree defined by \a data is + instantiated immediately. + + If a \a url is specified it is used as the base url of the component. This affects + relative paths within the data and error messages. + + If an error occurs, error messages are printed with qWarning. +*/ +void QQmlApplicationEngine::loadData(const QByteArray &data, const QUrl &url) +{ + Q_D(QQmlApplicationEngine); + d->startLoad(url, data, true); +} + +/*! + Returns a list of all the root objects instantiated by the + QQmlApplicationEngine. This will only contain objects loaded via load() or a + convenience constructor. +*/ + +QList<QObject *> QQmlApplicationEngine::rootObjects() +{ + Q_D(QQmlApplicationEngine); + return d->objects; +} + +QT_END_NAMESPACE + +#include "moc_qqmlapplicationengine.cpp" diff --git a/src/qml/qml/qqmlconnections_p.h b/src/qml/qml/qqmlapplicationengine.h index 15fba24df8..b5de998100 100644 --- a/src/qml/qml/qqmlconnections_p.h +++ b/src/qml/qml/qqmlapplicationengine.h @@ -1,6 +1,6 @@ /**************************************************************************** ** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Research In Motion. ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtQml module of the Qt Toolkit. @@ -39,62 +39,42 @@ ** ****************************************************************************/ -#ifndef QQMLCONNECTIONS_H -#define QQMLCONNECTIONS_H +#ifndef QQMLAPPLICATIONENGINE_H +#define QQMLAPPLICATIONENGINE_H -#include <qqml.h> -#include <private/qqmlcustomparser_p.h> +#include <QtQml/qqmlengine.h> +#include <QtCore/qurl.h> #include <QtCore/qobject.h> -#include <QtCore/qstring.h> - -QT_BEGIN_HEADER +#include <QtCore/qlist.h> QT_BEGIN_NAMESPACE -class QQmlBoundSignal; -class QQmlContext; -class QQmlConnectionsPrivate; -class Q_AUTOTEST_EXPORT QQmlConnections : public QObject, public QQmlParserStatus +class QQmlApplicationEnginePrivate; +class Q_QML_EXPORT QQmlApplicationEngine : public QQmlEngine { Q_OBJECT - Q_DECLARE_PRIVATE(QQmlConnections) - - Q_INTERFACES(QQmlParserStatus) - Q_PROPERTY(QObject *target READ target WRITE setTarget NOTIFY targetChanged) - Q_PROPERTY(bool ignoreUnknownSignals READ ignoreUnknownSignals WRITE setIgnoreUnknownSignals) - public: - QQmlConnections(QObject *parent=0); - ~QQmlConnections(); + QQmlApplicationEngine(QObject *parent=0); + QQmlApplicationEngine(const QUrl &url, QObject *parent=0); + QQmlApplicationEngine(const QString &filePath, QObject *parent=0); + ~QQmlApplicationEngine(); - QObject *target() const; - void setTarget(QObject *); - - bool ignoreUnknownSignals() const; - void setIgnoreUnknownSignals(bool ignore); + QList<QObject*> rootObjects(); +public Q_SLOTS: + void load(const QUrl &url); + void load(const QString &filePath); + void loadData(const QByteArray &data, const QUrl &url = QUrl()); Q_SIGNALS: - void targetChanged(); + void objectCreated(QObject *object, const QUrl &url); private: - void connectSignals(); - void classBegin(); - void componentComplete(); + Q_DISABLE_COPY(QQmlApplicationEngine) + Q_DECLARE_PRIVATE(QQmlApplicationEngine) + Q_PRIVATE_SLOT(d_func(), void _q_finishLoad(QObject*)) }; -class QQmlConnectionsParser : public QQmlCustomParser -{ -public: - virtual QByteArray compile(const QList<QQmlCustomParserProperty> &); - virtual void setCustomData(QObject *, const QByteArray &); -}; - - QT_END_NAMESPACE -QML_DECLARE_TYPE(QQmlConnections) - -QT_END_HEADER - #endif diff --git a/src/qml/qml/qqmlapplicationengine_p.h b/src/qml/qml/qqmlapplicationengine_p.h new file mode 100644 index 0000000000..db144af504 --- /dev/null +++ b/src/qml/qml/qqmlapplicationengine_p.h @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Research In Motion. +** Contact: http://www.qt-project.org/legal +** +** This file is part of the QtQml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQMLAPPLICATIONENGINE_P_H +#define QQMLAPPLICATIONENGINE_P_H + +#include "qqmlapplicationengine.h" +#include "qqmlengine_p.h" +#include <QSignalMapper> +#include <QCoreApplication> +#include <QFileInfo> +#include <QLibraryInfo> + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_NAMESPACE + +class QTranslator; +class Q_QML_PRIVATE_EXPORT QQmlApplicationEnginePrivate : public QQmlEnginePrivate +{ + Q_DECLARE_PUBLIC(QQmlApplicationEngine) +public: + QQmlApplicationEnginePrivate(QQmlEngine *e); + ~QQmlApplicationEnginePrivate(); + void init(); + + void startLoad(const QUrl &url, const QByteArray &data = QByteArray(), bool dataFlag = false); + void loadTranslations(const QUrl &rootFile); + void _q_finishLoad(QObject *component); + QList<QObject *> objects; + QSignalMapper statusMapper; + QObject *appObj; + +#ifndef QT_NO_TRANSLATIONS + QList<QTranslator *> translators; +#endif +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/qml/qml/qqmlbind.cpp b/src/qml/qml/qqmlbind.cpp deleted file mode 100644 index 7eb182b034..0000000000 --- a/src/qml/qml/qqmlbind.cpp +++ /dev/null @@ -1,310 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmlbind_p.h" - -#include <private/qqmlnullablevalue_p_p.h> -#include <private/qqmlproperty_p.h> -#include <private/qqmlbinding_p.h> -#include <private/qqmlguard_p.h> - -#include <qqmlengine.h> -#include <qqmlcontext.h> -#include <qqmlproperty.h> -#include <qqmlinfo.h> - -#include <QtCore/qfile.h> -#include <QtCore/qdebug.h> - -#include <private/qobject_p.h> - -QT_BEGIN_NAMESPACE - -class QQmlBindPrivate : public QObjectPrivate -{ -public: - QQmlBindPrivate() : componentComplete(true), obj(0), prevBind(0) {} - ~QQmlBindPrivate() { if (prevBind) prevBind->destroy(); } - - QQmlNullableValue<bool> when; - bool componentComplete; - QQmlGuard<QObject> obj; - QString propName; - QQmlNullableValue<QVariant> value; - QQmlProperty prop; - QQmlAbstractBinding *prevBind; -}; - - -/*! - \qmltype Binding - \instantiates QQmlBind - \inqmlmodule QtQuick 2 - \ingroup qtquick-interceptors - \brief Enables the arbitrary creation of property bindings - - \section1 Binding to an inaccessible property - - Sometimes it is necessary to bind to a property of an object that wasn't - directly instantiated by QML - generally a property of a class exported - to QML by C++. In these cases, regular property binding doesn't work. Binding - allows you to bind any value to any property. - - For example, imagine a C++ application that maps an "app.enteredText" - property into QML. You could use Binding to update the enteredText property - like this. - \code - TextEdit { id: myTextField; text: "Please type here..." } - Binding { target: app; property: "enteredText"; value: myTextField.text } - \endcode - Whenever the text in the TextEdit is updated, the C++ property will be - updated also. - - \section1 "Single-branch" conditional binding - - In some circumstances you may want to control the value of a property - only when a certain condition is true (and relinquish control in all - other circumstances). This often isn't possible to accomplish with a direct - binding, as you need to supply values for all possible branches. - - \code - // produces warning: "Unable to assign [undefined] to double value" - value: if (mouse.pressed) mouse.mouseX - \endcode - - The above example will produce a warning whenever we release the mouse, as the value - of the binding is undefined when the mouse isn't pressed. We can use the Binding - type to rewrite the above code and avoid the warning. - - \qml - Binding on value { - when: mouse.pressed - value: mouse.mouseX - } - \endqml - - The Binding type will also restore any previously set direct bindings on - the property. In that sense, it functions much like a simplified State. - - \qml - // this is equivalent to the above Binding - State { - name: "pressed" - when: mouse.pressed - PropertyChanges { - target: obj - value: mouse.mouseX - } - } - \endqml - - If the binding target or binding property is changed, the bound value is - immediately pushed onto the new target. - - \sa QtQml -*/ -QQmlBind::QQmlBind(QObject *parent) - : QObject(*(new QQmlBindPrivate), parent) -{ -} - -QQmlBind::~QQmlBind() -{ -} - -/*! - \qmlproperty bool QtQuick2::Binding::when - - This property holds when the binding is active. - This should be set to an expression that evaluates to true when you want the binding to be active. - - \code - Binding { - target: contactName; property: 'text' - value: name; when: list.ListView.isCurrentItem - } - \endcode - - When the binding becomes inactive again, any direct bindings that were previously - set on the property will be restored. -*/ -bool QQmlBind::when() const -{ - Q_D(const QQmlBind); - return d->when; -} - -void QQmlBind::setWhen(bool v) -{ - Q_D(QQmlBind); - if (!d->when.isNull && d->when == v) - return; - - d->when = v; - eval(); -} - -/*! - \qmlproperty Object QtQuick2::Binding::target - - The object to be updated. -*/ -QObject *QQmlBind::object() -{ - Q_D(const QQmlBind); - return d->obj; -} - -void QQmlBind::setObject(QObject *obj) -{ - Q_D(QQmlBind); - if (d->obj && d->when.isValid() && d->when) { - /* if we switch the object at runtime, we need to restore the - previous binding on the old object before continuing */ - d->when = false; - eval(); - d->when = true; - } - d->obj = obj; - if (d->componentComplete) - d->prop = QQmlProperty(d->obj, d->propName); - eval(); -} - -/*! - \qmlproperty string QtQuick2::Binding::property - - The property to be updated. -*/ -QString QQmlBind::property() const -{ - Q_D(const QQmlBind); - return d->propName; -} - -void QQmlBind::setProperty(const QString &p) -{ - Q_D(QQmlBind); - if (!d->propName.isEmpty() && d->when.isValid() && d->when) { - /* if we switch the property name at runtime, we need to restore the - previous binding on the old object before continuing */ - d->when = false; - eval(); - d->when = true; - } - d->propName = p; - if (d->componentComplete) - d->prop = QQmlProperty(d->obj, d->propName); - eval(); -} - -/*! - \qmlproperty any QtQuick2::Binding::value - - The value to be set on the target object and property. This can be a - constant (which isn't very useful), or a bound expression. -*/ -QVariant QQmlBind::value() const -{ - Q_D(const QQmlBind); - return d->value.value; -} - -void QQmlBind::setValue(const QVariant &v) -{ - Q_D(QQmlBind); - d->value = v; - eval(); -} - -void QQmlBind::setTarget(const QQmlProperty &p) -{ - Q_D(QQmlBind); - d->prop = p; -} - -void QQmlBind::classBegin() -{ - Q_D(QQmlBind); - d->componentComplete = false; -} - -void QQmlBind::componentComplete() -{ - Q_D(QQmlBind); - d->componentComplete = true; - if (!d->prop.isValid()) - d->prop = QQmlProperty(d->obj, d->propName); - eval(); -} - -void QQmlBind::eval() -{ - Q_D(QQmlBind); - if (!d->prop.isValid() || d->value.isNull || !d->componentComplete) - return; - - if (d->when.isValid()) { - if (!d->when) { - //restore any previous binding - if (d->prevBind) { - QQmlAbstractBinding *tmp = d->prevBind; - d->prevBind = 0; - tmp = QQmlPropertyPrivate::setBinding(d->prop, tmp); - if (tmp) //should this ever be true? - tmp->destroy(); - } - return; - } - - //save any set binding for restoration - QQmlAbstractBinding *tmp; - tmp = QQmlPropertyPrivate::setBinding(d->prop, 0); - if (tmp && d->prevBind) - tmp->destroy(); - else if (!d->prevBind) - d->prevBind = tmp; - } - - d->prop.write(d->value.value); -} - -QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlbundle.cpp b/src/qml/qml/qqmlbundle.cpp index 62925ced1e..273462aa25 100644 --- a/src/qml/qml/qqmlbundle.cpp +++ b/src/qml/qml/qqmlbundle.cpp @@ -40,7 +40,6 @@ ****************************************************************************/ #include "qqmlbundle_p.h" -#include <QtCore/QtCore> #include <iostream> #include <cstdlib> diff --git a/src/qml/qml/qqmlcompileddata.cpp b/src/qml/qml/qqmlcompileddata.cpp index 62150b1af1..7279762565 100644 --- a/src/qml/qml/qqmlcompileddata.cpp +++ b/src/qml/qml/qqmlcompileddata.cpp @@ -105,7 +105,7 @@ void QQmlCompiledData::destroy() QQmlCompiledData::~QQmlCompiledData() { if (isRegisteredWithEngine) - QQmlEnginePrivate::get(engine)->unregisterCompositeType(this); + QQmlEnginePrivate::get(engine)->unregisterInternalCompositeType(this); clear(); diff --git a/src/qml/qml/qqmlcompiler.cpp b/src/qml/qml/qqmlcompiler.cpp index 7a65515634..6951c8c387 100644 --- a/src/qml/qml/qqmlcompiler.cpp +++ b/src/qml/qml/qqmlcompiler.cpp @@ -815,7 +815,10 @@ bool QQmlCompiler::compile(QQmlEngine *engine, const QQmlTypeData::TypeReference &tref = resolvedTypes.at(ii); QQmlScript::TypeReference *parserRef = referencedTypes.at(ii); - if (tref.type) { + if (tref.typeData) { //QML-based type + ref.component = tref.typeData->compiledData(); + ref.component->addref(); + } else if (tref.type) {//C++-based type ref.type = tref.type; if (!ref.type->isCreatable()) { QString err = ref.type->noCreationReason(); @@ -823,21 +826,18 @@ bool QQmlCompiler::compile(QQmlEngine *engine, err = tr( "Element is not creatable."); COMPILE_EXCEPTION(parserRef->firstUse, err); } - + if (ref.type->containsRevisionedAttributes()) { QQmlError cacheError; ref.typePropertyCache = enginePrivate->cache(ref.type, resolvedTypes.at(ii).minorVersion, cacheError); - if (!ref.typePropertyCache) + if (!ref.typePropertyCache) COMPILE_EXCEPTION(parserRef->firstUse, cacheError.description()); ref.typePropertyCache->addref(); } - - } else if (tref.typeData) { - ref.component = tref.typeData->compiledData(); - ref.component->addref(); } + out->types << ref; } @@ -944,7 +944,7 @@ void QQmlCompiler::compileTree(QQmlScript::Object *tree) Q_ASSERT(tree->metatype); if (!tree->synthdata.isEmpty()) { - enginePrivate->registerCompositeType(output); + enginePrivate->registerInternalCompositeType(output); } else if (output->types.at(tree->type).component) { output->metaTypeId = output->types.at(tree->type).component->metaTypeId; output->listMetaTypeId = output->types.at(tree->type).component->listMetaTypeId; @@ -954,7 +954,7 @@ void QQmlCompiler::compileTree(QQmlScript::Object *tree) output->listMetaTypeId = output->types.at(tree->type).type->qListTypeId(); } if (!tree->synthdata.isEmpty()) - enginePrivate->registerCompositeType(output); + enginePrivate->registerInternalCompositeType(output); } static bool QStringList_contains(const QStringList &list, const QHashedStringRef &string) @@ -1752,7 +1752,7 @@ bool QQmlCompiler::buildProperty(QQmlScript::Property *prop, QQmlType *type = 0; QQmlImportNamespace *typeNamespace = 0; - unit->imports().resolveType(prop->name(), &type, 0, 0, 0, &typeNamespace); + unit->imports().resolveType(prop->name(), &type, 0, 0, &typeNamespace); if (typeNamespace) { COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj, @@ -1874,7 +1874,7 @@ bool QQmlCompiler::buildPropertyInNamespace(QQmlImportNamespace *ns, // Setup attached property data QQmlType *type = 0; - unit->imports().resolveType(ns, prop->name(), &type, 0, 0, 0); + unit->imports().resolveType(ns, prop->name(), &type, 0, 0); if (!type || !type->attachedPropertiesType()) COMPILE_EXCEPTION(prop, tr("Non-existent attached object")); @@ -2527,7 +2527,7 @@ bool QQmlCompiler::buildPropertyLiteralAssignment(QQmlScript::Property *prop, struct StaticQtMetaObject : public QObject { static const QMetaObject *get() - { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; } + { return &staticQtMetaObject; } }; bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop, @@ -2572,10 +2572,12 @@ bool QQmlCompiler::testQualifiedEnumAssignment(QQmlScript::Property *prop, } QQmlType *type = 0; - unit->imports().resolveType(typeName, &type, 0, 0, 0, 0); + unit->imports().resolveType(typeName, &type, 0, 0, 0); if (!type && typeName != QLatin1String("Qt")) return true; + if (type && type->isComposite()) //No enums on composite types + return true; int value = 0; bool ok = false; @@ -2619,7 +2621,7 @@ int QQmlCompiler::evaluateEnum(const QHashedStringRef &scope, const QByteArray& if (scope != QLatin1String("Qt")) { QQmlType *type = 0; - unit->imports().resolveType(scope, &type, 0, 0, 0, 0); + unit->imports().resolveType(scope, &type, 0, 0, 0); return type ? type->enumValue(QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1; } @@ -2636,7 +2638,7 @@ int QQmlCompiler::evaluateEnum(const QHashedStringRef &scope, const QByteArray& const QMetaObject *QQmlCompiler::resolveType(const QString& name) const { QQmlType *qmltype = 0; - if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0, 0)) + if (!unit->imports().resolveType(name, &qmltype, 0, 0, 0)) return 0; if (!qmltype) return 0; @@ -3024,12 +3026,11 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod // lazily resolved type Q_ASSERT(s->parameterTypes.at(i) == Object::DynamicProperty::Custom); QQmlType *qmltype = 0; - QString url; - if (!unit->imports().resolveType(s->parameterTypeNames.at(i).toString(), &qmltype, &url, 0, 0, 0)) + if (!unit->imports().resolveType(s->parameterTypeNames.at(i).toString(), &qmltype, 0, 0, 0)) COMPILE_EXCEPTION(s, tr("Invalid signal parameter type: %1").arg(s->parameterTypeNames.at(i).toString())); - if (!qmltype) { - QQmlTypeData *tdata = enginePrivate->typeLoader.getType(QUrl(url)); + if (qmltype->isComposite()) { + QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl()); Q_ASSERT(tdata); Q_ASSERT(tdata->isComplete()); @@ -3121,12 +3122,12 @@ bool QQmlCompiler::buildDynamicMeta(QQmlScript::Object *obj, DynamicMetaMode mod p->type == Object::DynamicProperty::Custom); QQmlType *qmltype = 0; - QString url; - if (!unit->imports().resolveType(p->customType.toString(), &qmltype, &url, 0, 0, 0)) + if (!unit->imports().resolveType(p->customType.toString(), &qmltype, 0, 0, 0)) COMPILE_EXCEPTION(p, tr("Invalid property type")); - if (!qmltype) { - QQmlTypeData *tdata = enginePrivate->typeLoader.getType(QUrl(url)); + Q_ASSERT(qmltype); + if (qmltype->isComposite()) { + QQmlTypeData *tdata = enginePrivate->typeLoader.getType(qmltype->sourceUrl()); Q_ASSERT(tdata); Q_ASSERT(tdata->isComplete()); @@ -3885,7 +3886,7 @@ QQmlType *QQmlCompiler::toQmlType(QQmlScript::Object *from) type = QQmlMetaType::qmlType(mo); mo = mo->superClass(); } - return type; + return type; } QStringList QQmlCompiler::deferredProperties(QQmlScript::Object *obj) diff --git a/src/qml/qml/qqmlcomponent.h b/src/qml/qml/qqmlcomponent.h index e2d49b32db..aefad475b4 100644 --- a/src/qml/qml/qqmlcomponent.h +++ b/src/qml/qml/qqmlcomponent.h @@ -49,8 +49,6 @@ #include <QtCore/qstring.h> #include <QtQml/qjsvalue.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -139,6 +137,4 @@ Q_DECLARE_METATYPE(QQmlComponent::Status) QML_DECLARE_TYPE(QQmlComponent) QML_DECLARE_TYPEINFO(QQmlComponent, QML_HAS_ATTACHED_PROPERTIES) -QT_END_HEADER - #endif // QQMLCOMPONENT_H diff --git a/src/qml/qml/qqmlcomponentattached_p.h b/src/qml/qml/qqmlcomponentattached_p.h index 9901821b94..3c27e795c6 100644 --- a/src/qml/qml/qqmlcomponentattached_p.h +++ b/src/qml/qml/qqmlcomponentattached_p.h @@ -45,8 +45,6 @@ #include <QtQml/qqml.h> #include <QtCore/QObject> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -80,6 +78,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLCOMPONENTATTACHED_P_H diff --git a/src/qml/qml/qqmlconnections.cpp b/src/qml/qml/qqmlconnections.cpp deleted file mode 100644 index f2d29bf393..0000000000 --- a/src/qml/qml/qqmlconnections.cpp +++ /dev/null @@ -1,321 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmlconnections_p.h" - -#include <private/qqmlexpression_p.h> -#include <private/qqmlproperty_p.h> -#include <private/qqmlboundsignal_p.h> -#include <qqmlcontext.h> -#include <private/qqmlcontext_p.h> -#include <qqmlinfo.h> - -#include <QtCore/qdebug.h> -#include <QtCore/qstringlist.h> - -#include <private/qobject_p.h> - -QT_BEGIN_NAMESPACE - -class QQmlConnectionsPrivate : public QObjectPrivate -{ -public: - QQmlConnectionsPrivate() : target(0), targetSet(false), ignoreUnknownSignals(false), componentcomplete(true) {} - - QList<QQmlBoundSignal*> boundsignals; - QObject *target; - - bool targetSet; - bool ignoreUnknownSignals; - bool componentcomplete; - - QByteArray data; -}; - -/*! - \qmltype Connections - \instantiates QQmlConnections - \inqmlmodule QtQuick 2 - \ingroup qtquick-interceptors - \brief Describes generalized connections to signals - - A Connections object creates a connection to a QML signal. - - When connecting to signals in QML, the usual way is to create an - "on<Signal>" handler that reacts when a signal is received, like this: - - \qml - MouseArea { - onClicked: { foo(parameters) } - } - \endqml - - However, it is not possible to connect to a signal in this way in some - cases, such as when: - - \list - \li Multiple connections to the same signal are required - \li Creating connections outside the scope of the signal sender - \li Connecting to targets not defined in QML - \endlist - - When any of these are needed, the Connections type can be used instead. - - For example, the above code can be changed to use a Connections object, - like this: - - \qml - MouseArea { - Connections { - onClicked: foo(parameters) - } - } - \endqml - - More generally, the Connections object can be a child of some object other than - the sender of the signal: - - \qml - MouseArea { - id: area - } - // ... - \endqml - \qml - Connections { - target: area - onClicked: foo(parameters) - } - \endqml - - \sa QtQml -*/ -QQmlConnections::QQmlConnections(QObject *parent) : - QObject(*(new QQmlConnectionsPrivate), parent) -{ -} - -QQmlConnections::~QQmlConnections() -{ -} - -/*! - \qmlproperty Object QtQuick2::Connections::target - This property holds the object that sends the signal. - - If this property is not set, the \c target defaults to the parent of the Connection. - - If set to null, no connection is made and any signal handlers are ignored - until the target is not null. -*/ -QObject *QQmlConnections::target() const -{ - Q_D(const QQmlConnections); - return d->targetSet ? d->target : parent(); -} - -class QQmlBoundSignalDeleter : public QObject -{ -public: - QQmlBoundSignalDeleter(QQmlBoundSignal *signal) : m_signal(signal) { m_signal->removeFromObject(); } - ~QQmlBoundSignalDeleter() { delete m_signal; } - -private: - QQmlBoundSignal *m_signal; -}; - -void QQmlConnections::setTarget(QObject *obj) -{ - Q_D(QQmlConnections); - d->targetSet = true; // even if setting to 0, it is *set* - if (d->target == obj) - return; - foreach (QQmlBoundSignal *s, d->boundsignals) { - // It is possible that target is being changed due to one of our signal - // handlers -> use deleteLater(). - if (s->isEvaluating()) - (new QQmlBoundSignalDeleter(s))->deleteLater(); - else - delete s; - } - d->boundsignals.clear(); - d->target = obj; - connectSignals(); - emit targetChanged(); -} - -/*! - \qmlproperty bool QtQuick2::Connections::ignoreUnknownSignals - - Normally, a connection to a non-existent signal produces runtime errors. - - If this property is set to \c true, such errors are ignored. - This is useful if you intend to connect to different types of objects, handling - a different set of signals for each object. -*/ -bool QQmlConnections::ignoreUnknownSignals() const -{ - Q_D(const QQmlConnections); - return d->ignoreUnknownSignals; -} - -void QQmlConnections::setIgnoreUnknownSignals(bool ignore) -{ - Q_D(QQmlConnections); - d->ignoreUnknownSignals = ignore; -} - - - -QByteArray -QQmlConnectionsParser::compile(const QList<QQmlCustomParserProperty> &props) -{ - QByteArray rv; - QDataStream ds(&rv, QIODevice::WriteOnly); - - for(int ii = 0; ii < props.count(); ++ii) - { - QString propName = props.at(ii).name(); - int propLine = props.at(ii).location().line; - int propColumn = props.at(ii).location().column; - - if (!propName.startsWith(QLatin1String("on")) || !propName.at(2).isUpper()) { - error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName)); - return QByteArray(); - } - - QList<QVariant> values = props.at(ii).assignedValues(); - - for (int i = 0; i < values.count(); ++i) { - const QVariant &value = values.at(i); - - if (value.userType() == qMetaTypeId<QQmlCustomParserNode>()) { - error(props.at(ii), QQmlConnections::tr("Connections: nested objects not allowed")); - return QByteArray(); - } else if (value.userType() == qMetaTypeId<QQmlCustomParserProperty>()) { - error(props.at(ii), QQmlConnections::tr("Connections: syntax error")); - return QByteArray(); - } else { - QQmlScript::Variant v = qvariant_cast<QQmlScript::Variant>(value); - if (v.isScript()) { - ds << propName; - ds << rewriteSignalHandler(v, propName).toUtf8(); - ds << propLine; - ds << propColumn; - } else { - error(props.at(ii), QQmlConnections::tr("Connections: script expected")); - return QByteArray(); - } - } - } - } - - return rv; -} - -void QQmlConnectionsParser::setCustomData(QObject *object, - const QByteArray &data) -{ - QQmlConnectionsPrivate *p = - static_cast<QQmlConnectionsPrivate *>(QObjectPrivate::get(object)); - p->data = data; -} - - -void QQmlConnections::connectSignals() -{ - Q_D(QQmlConnections); - if (!d->componentcomplete || (d->targetSet && !target())) - return; - - QDataStream ds(d->data); - while (!ds.atEnd()) { - QString propName; - ds >> propName; - QByteArray script; - ds >> script; - int line; - ds >> line; - int column; - ds >> column; - - QQmlProperty prop(target(), propName); - if (prop.isValid() && (prop.type() & QQmlProperty::SignalProperty)) { - int signalIndex = QQmlPropertyPrivate::get(prop)->signalIndex(); - QQmlBoundSignal *signal = - new QQmlBoundSignal(target(), signalIndex, this, qmlEngine(this)); - - QString location; - QQmlContextData *ctxtdata = 0; - QQmlData *ddata = QQmlData::get(this); - if (ddata) { - ctxtdata = ddata->outerContext; - if (ctxtdata && !ctxtdata->url.isEmpty()) - location = ddata->outerContext->urlString; - } - - QQmlBoundSignalExpression *expression = ctxtdata ? - new QQmlBoundSignalExpression(target(), signalIndex, - ctxtdata, this, script, - true, location, line, column) : 0; - signal->takeExpression(expression); - d->boundsignals += signal; - } else { - if (!d->ignoreUnknownSignals) - qmlInfo(this) << tr("Cannot assign to non-existent property \"%1\"").arg(propName); - } - } -} - -void QQmlConnections::classBegin() -{ - Q_D(QQmlConnections); - d->componentcomplete=false; -} - -void QQmlConnections::componentComplete() -{ - Q_D(QQmlConnections); - d->componentcomplete=true; - connectSignals(); -} - -QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlcontext.h b/src/qml/qml/qqmlcontext.h index 5477b46e92..e191807cf4 100644 --- a/src/qml/qml/qqmlcontext.h +++ b/src/qml/qml/qqmlcontext.h @@ -48,8 +48,6 @@ #include <QtCore/qmetatype.h> #include <QtCore/qvariant.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -107,6 +105,4 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QList<QObject*>) -QT_END_HEADER - #endif // QQMLCONTEXT_H diff --git a/src/qml/qml/qqmlcustomparser_p.h b/src/qml/qml/qqmlcustomparser_p.h index 3114c52870..7a3fd47b46 100644 --- a/src/qml/qml/qqmlcustomparser_p.h +++ b/src/qml/qml/qqmlcustomparser_p.h @@ -61,8 +61,6 @@ #include <QtCore/qbytearray.h> #include <QtCore/qxmlstream.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -163,6 +161,4 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QQmlCustomParserProperty) Q_DECLARE_METATYPE(QQmlCustomParserNode) -QT_END_HEADER - #endif diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 145818aadf..25ef080cb5 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -55,8 +55,6 @@ #include "qqmlxmlhttprequest_p.h" #include "qqmlscriptstring.h" #include "qqmlglobal_p.h" -#include "qquicklistmodel_p.h" -#include "qquickworkerscript_p.h" #include "qqmlcomponent_p.h" #include "qqmlnetworkaccessmanagerfactory.h" #include "qqmldirparser_p.h" @@ -89,9 +87,16 @@ #include <private/qqmllocale_p.h> -#include "qqmlbind_p.h" -#include "qqmlconnections_p.h" -#include "qqmltimer_p.h" +#include <private/qqmlbind_p.h> +#include <private/qqmlconnections_p.h> +#include <private/qqmltimer_p.h> +#include <private/qqmllistmodel_p.h> +#include <private/qqmlplatform_p.h> +#include <private/qquickpackage_p.h> +#include <private/qqmldelegatemodel_p.h> +#include <private/qqmlobjectmodel_p.h> +#include <private/qquickworkerscript_p.h> +#include <private/qqmlinstantiator_p.h> #ifdef Q_OS_WIN // for %APPDATA% #include <qt_windows.h> @@ -179,16 +184,22 @@ void QQmlEnginePrivate::registerBaseTypes(const char *uri, int versionMajor, int qmlRegisterType<QQmlBind>(uri, versionMajor, versionMinor,"Binding"); qmlRegisterType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections"); qmlRegisterType<QQmlTimer>(uri, versionMajor, versionMinor,"Timer"); + qmlRegisterType<QQmlInstantiator>(uri, versionMajor, (versionMinor < 1 ? 1 : versionMinor), "Instantiator"); //Only available in >=2.1 qmlRegisterCustomType<QQmlConnections>(uri, versionMajor, versionMinor,"Connections", new QQmlConnectionsParser); + qmlRegisterType<QQmlInstanceModel>(); } // These QtQuick types' implementation resides in the QtQml module void QQmlEnginePrivate::registerQtQuick2Types(const char *uri, int versionMajor, int versionMinor) { - qmlRegisterType<QQuickListElement>(uri, versionMajor, versionMinor, "ListElement"); - qmlRegisterCustomType<QQuickListModel>(uri, versionMajor, versionMinor, "ListModel", new QQuickListModelParser); + qmlRegisterType<QQmlListElement>(uri, versionMajor, versionMinor, "ListElement"); // Now in QtQml.Models, here for compatibility + qmlRegisterCustomType<QQmlListModel>(uri, versionMajor, versionMinor, "ListModel", new QQmlListModelParser); // Now in QtQml.Models, here for compatibility qmlRegisterType<QQuickWorkerScript>(uri, versionMajor, versionMinor, "WorkerScript"); + qmlRegisterType<QQuickPackage>(uri, versionMajor, versionMinor, "Package"); + qmlRegisterType<QQmlDelegateModel>(uri, versionMajor, versionMinor, "VisualDataModel"); + qmlRegisterType<QQmlDelegateModelGroup>(uri, versionMajor, versionMinor, "VisualDataGroup"); + qmlRegisterType<QQmlObjectModel>(uri, versionMajor, versionMinor, "VisualItemModel"); } void QQmlEnginePrivate::defineQtQuick2Module() @@ -359,6 +370,36 @@ The following functions are also on the Qt object. */ /*! + \qmlproperty object Qt::platform + \since QtQml 2.1 + + The \c platform object provides info about the underlying platform. + + Its properties are: + + \table + \row + \li \c platform.os + \li + + This read-only property contains the name of the operating system. + + Possible values are: + + \list + \li \c "android" - Android + \li \c "blackberry" - BlackBerry OS + \li \c "ios" - Apple iOS + \li \c "linux" - Linux + \li \c "mac" - Mac OS X + \li \c "unix" - Other Unix-based OS + \li \c "windows" - Windows + \li \c "wince" - Windows CE + \endlist + \endtable +*/ + +/*! \qmlproperty object Qt::application \since QtQuick 1.1 @@ -398,13 +439,31 @@ The following functions are also on the Qt object. \li Qt.RightToLeft - Text and graphics elements should be positioned from right to left. \endlist - + \row + \li \c application.arguments + \li This is a string list of the arguments the executable was invoked with. + \row + \li \c application.name + \li This is the application name set on the QCoreApplication instance. This property can be written + to in order to set the application name. + \row + \li \c application.version + \li This is the application version set on the QCoreApplication instance. This property can be written + to in order to set the application name. \endtable + The object also has one signal, aboutToQuit(), which is the same as \l QCoreApplication::aboutToQuit(). + The following example uses the \c application object to indicate whether the application is currently active: \snippet qml/application.qml document + + Note that when using QML without a QGuiApplication, the following properties will be undefined: + \list + \li application.active + \li application.layoutDirection + \endlist */ /*! @@ -757,6 +816,16 @@ QQmlEngine::QQmlEngine(QObject *parent) } /*! +* \internal +*/ +QQmlEngine::QQmlEngine(QQmlEnginePrivate &dd, QObject *parent) +: QJSEngine(dd, parent) +{ + Q_D(QQmlEngine); + d->init(); +} + +/*! Destroys the QQmlEngine. Any QQmlContext's created on this engine will be @@ -2023,7 +2092,7 @@ QQmlPropertyCache *QQmlEnginePrivate::rawPropertyCacheForType(int t) } } -void QQmlEnginePrivate::registerCompositeType(QQmlCompiledData *data) +void QQmlEnginePrivate::registerInternalCompositeType(QQmlCompiledData *data) { QByteArray name = data->rootPropertyCache->className(); @@ -2058,7 +2127,7 @@ void QQmlEnginePrivate::registerCompositeType(QQmlCompiledData *data) m_compositeTypes.insert(ptr_type, data); } -void QQmlEnginePrivate::unregisterCompositeType(QQmlCompiledData *data) +void QQmlEnginePrivate::unregisterInternalCompositeType(QQmlCompiledData *data) { int ptr_type = data->metaTypeId; int lst_type = data->listMetaTypeId; diff --git a/src/qml/qml/qqmlengine.h b/src/qml/qml/qqmlengine.h index 76e6ce1d75..45826a4a67 100644 --- a/src/qml/qml/qqmlengine.h +++ b/src/qml/qml/qqmlengine.h @@ -49,8 +49,6 @@ #include <QtQml/qqmlerror.h> #include <QtQml/qqmldebug.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -144,6 +142,7 @@ public: static void setObjectOwnership(QObject *, ObjectOwnership); static ObjectOwnership objectOwnership(QObject *); protected: + QQmlEngine(QQmlEnginePrivate &dd, QObject *p); virtual bool event(QEvent *); Q_SIGNALS: @@ -157,6 +156,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLENGINE_H diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index 43bcc0390f..b5af0bb7cd 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -235,8 +235,8 @@ public: QQmlMetaObject metaObjectForType(int) const; QQmlPropertyCache *propertyCacheForType(int); QQmlPropertyCache *rawPropertyCacheForType(int); - void registerCompositeType(QQmlCompiledData *); - void unregisterCompositeType(QQmlCompiledData *); + void registerInternalCompositeType(QQmlCompiledData *); + void unregisterInternalCompositeType(QQmlCompiledData *); bool isTypeLoaded(const QUrl &url) const; bool isScriptLoaded(const QUrl &url) const; diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h index c95e0c50b9..cea9ee4cc0 100644 --- a/src/qml/qml/qqmlerror.h +++ b/src/qml/qml/qqmlerror.h @@ -47,8 +47,6 @@ #include <QtCore/qurl.h> #include <QtCore/qstring.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -84,6 +82,4 @@ Q_DECLARE_TYPEINFO(QQmlError, Q_MOVABLE_TYPE); QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLERROR_H diff --git a/src/qml/qml/qqmlexpression.h b/src/qml/qml/qqmlexpression.h index 8c3bf38581..b04abc1b98 100644 --- a/src/qml/qml/qqmlexpression.h +++ b/src/qml/qml/qqmlexpression.h @@ -48,8 +48,6 @@ #include <QtCore/qobject.h> #include <QtCore/qvariant.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -113,7 +111,5 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLEXPRESSION_H diff --git a/src/qml/qml/qqmlextensioninterface.h b/src/qml/qml/qqmlextensioninterface.h index 35facb0333..be2939d366 100644 --- a/src/qml/qml/qqmlextensioninterface.h +++ b/src/qml/qml/qqmlextensioninterface.h @@ -45,8 +45,6 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qobject.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -76,6 +74,4 @@ Q_DECLARE_INTERFACE(QQmlExtensionInterface, QQmlExtensionInterface_iid) QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLEXTENSIONINTERFACE_H diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp index bbc0fed768..edef5a91cd 100644 --- a/src/qml/qml/qqmlextensionplugin.cpp +++ b/src/qml/qml/qqmlextensionplugin.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qqmlextensionplugin.h" +#include "qqmlextensionplugin_p.h" QT_BEGIN_NAMESPACE @@ -144,7 +145,7 @@ QT_BEGIN_NAMESPACE explicitly. */ QQmlExtensionPlugin::QQmlExtensionPlugin(QObject *parent) - : QObject(parent) + : QObject(*(new QQmlExtensionPluginPrivate), parent) { } @@ -155,6 +156,12 @@ QQmlExtensionPlugin::~QQmlExtensionPlugin() { } +QUrl QQmlExtensionPlugin::baseUrl() const +{ + Q_D(const QQmlExtensionPlugin); + return d->baseUrl; +} + /*! \fn void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri) diff --git a/src/qml/qml/qqmlextensionplugin.h b/src/qml/qml/qqmlextensionplugin.h index a7f5da137a..170c7915a5 100644 --- a/src/qml/qml/qqmlextensionplugin.h +++ b/src/qml/qml/qqmlextensionplugin.h @@ -43,35 +43,34 @@ #define QQMLEXTENSIONPLUGIN_H #include <QtCore/qplugin.h> - +#include <QtCore/QUrl> #include <QtQml/qqmlextensioninterface.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE - class QQmlEngine; +class QQmlExtensionPluginPrivate; -class Q_QML_EXPORT QQmlExtensionPlugin : public QObject, - public QQmlExtensionInterface +class Q_QML_EXPORT QQmlExtensionPlugin + : public QObject + , public QQmlExtensionInterface { Q_OBJECT + Q_DECLARE_PRIVATE(QQmlExtensionPlugin) Q_INTERFACES(QQmlExtensionInterface) Q_INTERFACES(QQmlTypesExtensionInterface) public: explicit QQmlExtensionPlugin(QObject *parent = 0); ~QQmlExtensionPlugin(); + QUrl baseUrl() const; + virtual void registerTypes(const char *uri) = 0; virtual void initializeEngine(QQmlEngine *engine, const char *uri); -private: Q_DISABLE_COPY(QQmlExtensionPlugin) }; QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLEXTENSIONPLUGIN_H diff --git a/src/qml/qml/qquickworkerscript_p.h b/src/qml/qml/qqmlextensionplugin_p.h index e643751953..747bc78efb 100644 --- a/src/qml/qml/qquickworkerscript_p.h +++ b/src/qml/qml/qqmlextensionplugin_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QQUICKWORKERSCRIPT_P_H -#define QQUICKWORKERSCRIPT_P_H +#ifndef QQMLEXTENSIONPLUGIN_P_H +#define QQMLEXTENSIONPLUGIN_P_H // // W A R N I N G @@ -53,78 +53,22 @@ // We mean it. // -#include "qqml.h" -#include "qqmlparserstatus.h" - -#include <QtCore/qthread.h> -#include <QtQml/qjsvalue.h> -#include <QtCore/qurl.h> - -QT_BEGIN_HEADER +#include <QtCore/private/qobject_p.h> +#include "qqmlextensionplugin.h" QT_BEGIN_NAMESPACE - -class QQuickWorkerScript; -class QQuickWorkerScriptEnginePrivate; -class QQuickWorkerScriptEngine : public QThread +class QQmlExtensionPluginPrivate : public QObjectPrivate { -Q_OBJECT -public: - QQuickWorkerScriptEngine(QQmlEngine *parent = 0); - virtual ~QQuickWorkerScriptEngine(); - - int registerWorkerScript(QQuickWorkerScript *); - void removeWorkerScript(int); - void executeUrl(int, const QUrl &); - void sendMessage(int, const QByteArray &); - -protected: - virtual void run(); - -private: - QQuickWorkerScriptEnginePrivate *d; -}; + Q_DECLARE_PUBLIC(QQmlExtensionPlugin) -class QQmlV8Function; -class QQmlV8Handle; -class Q_AUTOTEST_EXPORT QQuickWorkerScript : public QObject, public QQmlParserStatus -{ - Q_OBJECT - Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) - - Q_INTERFACES(QQmlParserStatus) public: - QQuickWorkerScript(QObject *parent = 0); - virtual ~QQuickWorkerScript(); - - QUrl source() const; - void setSource(const QUrl &); - -public slots: - void sendMessage(QQmlV8Function*); + static QQmlExtensionPluginPrivate* get(QQmlExtensionPlugin *e) { return e->d_func(); } -signals: - void sourceChanged(); - void message(const QQmlV8Handle &messageObject); + QUrl baseUrl; -protected: - virtual void classBegin(); - virtual void componentComplete(); - virtual bool event(QEvent *); - -private: - QQuickWorkerScriptEngine *engine(); - QQuickWorkerScriptEngine *m_engine; - int m_scriptId; - QUrl m_source; - bool m_componentComplete; }; QT_END_NAMESPACE -QML_DECLARE_TYPE(QQuickWorkerScript) - -QT_END_HEADER - -#endif // QQUICKWORKERSCRIPT_P_H +#endif // QQMLEXTENSIONPLUGIN_P_H diff --git a/src/qml/qml/qqmlfile.h b/src/qml/qml/qqmlfile.h index 777bc0db7b..5e7a42d6bd 100644 --- a/src/qml/qml/qqmlfile.h +++ b/src/qml/qml/qqmlfile.h @@ -44,8 +44,6 @@ #include <QtQml/qtqmlglobal.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QUrl; @@ -119,6 +117,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLFILE_H diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp index 5d4b2a567b..607ee4d0ac 100644 --- a/src/qml/qml/qqmlglobal.cpp +++ b/src/qml/qml/qqmlglobal.cpp @@ -44,6 +44,7 @@ #include <QtCore/qvariant.h> #include <QtCore/qstringlist.h> #include <QtCore/qdebug.h> +#include <QtCore/QCoreApplication> QT_BEGIN_NAMESPACE @@ -54,6 +55,7 @@ QQmlValueTypeProvider::QQmlValueTypeProvider() QQmlValueTypeProvider::~QQmlValueTypeProvider() { + QQml_removeValueTypeProvider(this); } QQmlValueType *QQmlValueTypeProvider::createValueType(int type) @@ -266,13 +268,13 @@ bool QQmlValueTypeProvider::store(int, const void *, void *, size_t) { return fa bool QQmlValueTypeProvider::read(int, const void *, size_t, int, void *) { return false; } bool QQmlValueTypeProvider::write(int, const void *, void *, size_t) { return false; } +Q_GLOBAL_STATIC(QQmlValueTypeProvider, nullValueTypeProvider) static QQmlValueTypeProvider *valueTypeProvider = 0; static QQmlValueTypeProvider **getValueTypeProvider(void) { if (valueTypeProvider == 0) { - static QQmlValueTypeProvider nullValueTypeProvider; - valueTypeProvider = &nullValueTypeProvider; + valueTypeProvider = nullValueTypeProvider; } return &valueTypeProvider; @@ -285,6 +287,34 @@ Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *newPr *providerPtr = newProvider; } +Q_QML_PRIVATE_EXPORT void QQml_removeValueTypeProvider(QQmlValueTypeProvider *oldProvider) +{ + if (oldProvider == nullValueTypeProvider) { + // don't remove the null provider + // we get here when the QtQml library is being unloaded + return; + } + + // the only entry with next = 0 is the null provider + Q_ASSERT(oldProvider->next); + + QQmlValueTypeProvider *prev = valueTypeProvider; + if (prev == oldProvider) { + valueTypeProvider = oldProvider->next; + return; + } + + // singly-linked list removal + for ( ; prev; prev = prev->next) { + if (prev->next != oldProvider) + continue; // this is not the provider you're looking for + prev->next = oldProvider->next; + return; + } + + qWarning("QQml_removeValueTypeProvider: was asked to remove provider %p but it was not found", oldProvider); +} + Q_AUTOTEST_EXPORT QQmlValueTypeProvider *QQml_valueTypeProvider(void) { static QQmlValueTypeProvider **providerPtr = getValueTypeProvider(); @@ -328,7 +358,7 @@ Q_AUTOTEST_EXPORT QQmlColorProvider *QQml_colorProvider(void) QQmlGuiProvider::~QQmlGuiProvider() {} -QObject *QQmlGuiProvider::application(QObject *) { return 0; } +QObject *QQmlGuiProvider::application(QObject *) { return new QQmlApplication(); } QStringList QQmlGuiProvider::fontFamilies() { return QStringList(); } bool QQmlGuiProvider::openUrlExternally(QUrl &) { return false; } @@ -354,8 +384,7 @@ Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *newPr static QQmlGuiProvider **getGuiProvider(void) { if (guiProvider == 0) { - qWarning() << "Warning: QQml_guiProvider: no GUI provider has been set!"; - static QQmlGuiProvider nullGuiProvider; + static QQmlGuiProvider nullGuiProvider; //Still provides an application with no GUI support guiProvider = &nullGuiProvider; } @@ -368,4 +397,51 @@ Q_AUTOTEST_EXPORT QQmlGuiProvider *QQml_guiProvider(void) return *providerPtr; } +//Docs in qqmlengine.cpp +QQmlApplication::QQmlApplication(QObject *parent) + : QObject(*(new QQmlApplicationPrivate),parent) +{ + connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), + this, SIGNAL(aboutToQuit())); +} + +QQmlApplication::QQmlApplication(QQmlApplicationPrivate &dd, QObject *parent) + : QObject(dd, parent) +{ + connect(QCoreApplication::instance(), SIGNAL(aboutToQuit()), + this, SIGNAL(aboutToQuit())); +} + +QStringList QQmlApplication::args() +{ + Q_D(QQmlApplication); + if (!d->argsInit) { + d->argsInit = true; + d->args = QCoreApplication::arguments(); + } + return d->args; +} + +QString QQmlApplication::name() const +{ + return QCoreApplication::instance()->applicationName(); +} + +QString QQmlApplication::version() const +{ + return QCoreApplication::instance()->applicationVersion(); +} + +void QQmlApplication::setName(const QString &arg) +{ + QCoreApplication::instance()->setApplicationName(arg); + emit nameChanged(); //Note that we don't get notified if it's changed from C++ +} + +void QQmlApplication::setVersion(const QString &arg) +{ + QCoreApplication::instance()->setApplicationVersion(arg); + emit versionChanged(); //Note that we don't get notified if it's changed from C++ +} + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlglobal_p.h b/src/qml/qml/qqmlglobal_p.h index 2631fc459f..6ca54f65cd 100644 --- a/src/qml/qml/qqmlglobal_p.h +++ b/src/qml/qml/qqmlglobal_p.h @@ -48,8 +48,6 @@ #include <private/qmetaobject_p.h> #include <private/qv8engine_p.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -273,6 +271,7 @@ private: virtual bool write(int, const void *, void *, size_t); friend Q_QML_PRIVATE_EXPORT void QQml_addValueTypeProvider(QQmlValueTypeProvider *); + friend Q_QML_PRIVATE_EXPORT void QQml_removeValueTypeProvider(QQmlValueTypeProvider *); QQmlValueTypeProvider *next; }; @@ -314,8 +313,53 @@ public: Q_QML_PRIVATE_EXPORT QQmlGuiProvider *QQml_setGuiProvider(QQmlGuiProvider *); Q_AUTOTEST_EXPORT QQmlGuiProvider *QQml_guiProvider(); -QT_END_NAMESPACE +class QQmlApplicationPrivate; + +class Q_QML_PRIVATE_EXPORT QQmlApplication : public QObject +{ + //Application level logic, subclassed by QtQuick if available via QQmlGuiProvider + Q_OBJECT + Q_PROPERTY(QStringList arguments READ args CONSTANT) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY versionChanged) +public: + QQmlApplication(QObject* parent=0); + + QStringList args(); + + QString name() const; + QString version() const; + +public Q_SLOTS: + void setName(const QString &arg); + void setVersion(const QString &arg); + +Q_SIGNALS: + void aboutToQuit(); + + void nameChanged(); + void versionChanged(); + +protected: + QQmlApplication(QQmlApplicationPrivate &dd, QObject* parent=0); -QT_END_HEADER +private: + Q_DISABLE_COPY(QQmlApplication); + Q_DECLARE_PRIVATE(QQmlApplication); +}; + +class QQmlApplicationPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQmlApplication) +public: + QQmlApplicationPrivate() { + argsInit = false; + } + + bool argsInit; + QStringList args; +}; + +QT_END_NAMESPACE #endif // QQMLGLOBAL_H diff --git a/src/qml/qml/qqmlguard_p.h b/src/qml/qml/qqmlguard_p.h index cef4c8fb8d..455f5c93a8 100644 --- a/src/qml/qml/qqmlguard_p.h +++ b/src/qml/qml/qqmlguard_p.h @@ -201,7 +201,7 @@ template<class T> T *QQmlGuard<T>::object() const { return static_cast<T *>(o); -}; +} template<class T> void QQmlGuard<T>::setObject(T *g) diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index 52d07b23ec..f793ca9604 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -49,6 +49,8 @@ #include <QtCore/qlibraryinfo.h> #include <QtCore/qreadwritelock.h> #include <QtQml/qqmlextensioninterface.h> +#include <QtQml/qqmlextensionplugin.h> +#include <private/qqmlextensionplugin_p.h> #include <private/qqmlglobal_p.h> #include <private/qqmltypenamecache_p.h> #include <private/qqmlengine_p.h> @@ -124,6 +126,39 @@ bool isPathAbsolute(const QString &path) #endif } +// If the type does not already exist as a file import, add the type and return the new type +QQmlType *getTypeForUrl(const QString &urlString, const QHashedStringRef& typeName, QList<QQmlError> *errors) +{ + QUrl url(urlString); + QQmlType *ret = QQmlMetaType::qmlType(url); + if (!ret) { //QQmlType not yet existing for composite type + int dot = typeName.indexOf(QLatin1Char('.')); + QHashedStringRef unqualifiedtype = dot < 0 ? typeName : QHashedStringRef(typeName.constData() + dot + 1, typeName.length() - dot - 1); + + //XXX: The constData of the string ref is pointing somewhere unsafe in qmlregister, so we need to create a temporary copy + QByteArray buf(unqualifiedtype.toUtf8().constData()); + + QQmlPrivate::RegisterCompositeType reg = { + url, + "", //Empty URI indicates loaded via file imports + -1, + -1, + buf.constData() + }; + ret = QQmlMetaType::qmlTypeFromIndex(QQmlPrivate::qmlregister(QQmlPrivate::CompositeRegistration, ®)); + } + if (!ret) {//Usually when a type name is "found" but invalid + //qDebug() << ret << urlString << QQmlMetaType::qmlType(url); + if (!errors) // Cannot list errors properly, just quit + qFatal("%s", QQmlMetaType::typeRegistrationFailures().join('\n').toLatin1().constData()); + QQmlError error; + error.setDescription(QQmlMetaType::typeRegistrationFailures().join('\n')); + errors->prepend(error); + } + return ret; + +} + } typedef QMap<QString, QString> StringStringMap; @@ -150,8 +185,7 @@ public: static QQmlDirScripts getVersionedScripts(const QQmlDirScripts &qmldirscripts, int vmaj, int vmin); bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, - int *vmajor, int *vminor, - QQmlType** type_return, QString* url_return, + int *vmajor, int *vminor, QQmlType** type_return, QString *base = 0, bool *typeRecursionDetected = 0) const; }; QList<Import *> imports; @@ -159,8 +193,7 @@ public: Import *findImport(const QString &uri); bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type, - int *vmajor, int *vminor, - QQmlType** type_return, QString* url_return, + int *vmajor, int *vminor, QQmlType** type_return, QString *base = 0, QList<QQmlError> *errors = 0); // Prefix when used as a qualified import. Otherwise empty. @@ -194,8 +227,7 @@ public: QList<QQmlError> *errors); bool resolveType(const QHashedStringRef &type, int *vmajor, int *vminor, - QQmlType** type_return, QString* url_return, - QList<QQmlError> *errors); + QQmlType** type_return, QList<QQmlError> *errors); QUrl baseUrl; QString base; @@ -228,7 +260,7 @@ public: QQmlImportNamespace::Import *addImportToNamespace(QQmlImportNamespace *nameSpace, const QString &uri, const QString &url, int vmaj, int vmin, QQmlScript::Import::Type type, - QList<QQmlError> *errors); + QList<QQmlError> *errors, bool lowPrecedence = false); }; /*! @@ -379,9 +411,8 @@ QString QQmlImports::completeQmldirPath(const QString &uri, const QString &base, The given (namespace qualified) \a type is resolved to either \list - \li a QQmlImportNamespace stored at \a ns_return, - \li a QQmlType stored at \a type_return, or - \li a component located at \a url_return. + \li a QQmlImportNamespace stored at \a ns_return, or + \li a QQmlType stored at \a type_return, \endlist If any return pointer is 0, the corresponding search is not done. @@ -389,7 +420,7 @@ QString QQmlImports::completeQmldirPath(const QString &uri, const QString &base, \sa addFileImport(), addLibraryImport */ bool QQmlImports::resolveType(const QHashedStringRef &type, - QQmlType** type_return, QString* url_return, int *vmaj, int *vmin, + QQmlType** type_return, int *vmaj, int *vmin, QQmlImportNamespace** ns_return, QList<QQmlError> *errors) const { QQmlImportNamespace* ns = d->findQualifiedNamespace(type); @@ -398,19 +429,16 @@ bool QQmlImports::resolveType(const QHashedStringRef &type, *ns_return = ns; return true; } - if (type_return || url_return) { - if (d->resolveType(type,vmaj,vmin,type_return,url_return, errors)) { + if (type_return) { + if (d->resolveType(type,vmaj,vmin,type_return, errors)) { if (qmlImportTrace()) { #define RESOLVE_TYPE_DEBUG qDebug().nospace() << "QQmlImports(" << qPrintable(baseUrl().toString()) \ << ')' << "::resolveType: " << type.toString() << " => " - if (type_return && *type_return && url_return && !url_return->isEmpty()) - RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << ' ' << *url_return << " TYPE/URL"; - if (type_return && *type_return) + if (type_return && *type_return && (*type_return)->isComposite()) + RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << ' ' << (*type_return)->sourceUrl() << " TYPE/URL"; + else if (type_return && *type_return) RESOLVE_TYPE_DEBUG << (*type_return)->typeName() << " TYPE"; - if (url_return && !url_return->isEmpty()) - RESOLVE_TYPE_DEBUG << *url_return << " URL"; - #undef RESOLVE_TYPE_DEBUG } return true; @@ -469,23 +497,21 @@ QQmlDirScripts QQmlImportNamespace::Import::getVersionedScripts(const QQmlDirScr \internal Searching \e only in the namespace \a ns (previously returned in a call to - resolveType(), \a type is found and returned to either - a QQmlType stored at \a type_return, or - a component located at \a url_return. + resolveType(), \a type is found and returned to + a QQmlType stored at \a type_return. If the type is from a QML file, the returned + type will be a CompositeType. - If either return pointer is 0, the corresponding search is not done. + If the return pointer is 0, the corresponding search is not done. */ bool QQmlImports::resolveType(QQmlImportNamespace* ns, const QHashedStringRef &type, - QQmlType** type_return, QString* url_return, - int *vmaj, int *vmin) const + QQmlType** type_return, int *vmaj, int *vmin) const { - return ns->resolveType(d->typeLoader,type,vmaj,vmin,type_return,url_return); + return ns->resolveType(d->typeLoader,type,vmaj,vmin,type_return); } bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef& type, int *vmajor, int *vminor, - QQmlType** type_return, QString* url_return, - QString *base, bool *typeRecursionDetected) const + QQmlType** type_return, QString *base, bool *typeRecursionDetected) const { if (majversion >= 0 && minversion >= 0) { QQmlType *t = QQmlMetaType::qmlType(type, uri, majversion, minversion); @@ -530,9 +556,9 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader, } if (candidate != end) { - if (url_return) - *url_return = componentUrl; - return true; + if (type_return) + *type_return = getTypeForUrl(componentUrl, type, 0); + return (*type_return != 0); } } else if (!isLibrary) { QString qmlUrl = url + QString::fromRawData(type.constData(), type.length()) + dotqml_string; @@ -550,9 +576,9 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader, if (typeRecursionDetected) *typeRecursionDetected = true; } else { - if (url_return) - *url_return = qmlUrl; - return true; + if (type_return) + *type_return = getTypeForUrl(qmlUrl, type, 0); + return (*type_return) != 0; } } } @@ -561,8 +587,7 @@ bool QQmlImportNamespace::Import::resolveType(QQmlTypeLoader *typeLoader, } bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, int *vminor, - QQmlType** type_return, QString* url_return, - QList<QQmlError> *errors) + QQmlType** type_return, QList<QQmlError> *errors) { QQmlImportNamespace *s = 0; int dot = type.indexOf(Dot); @@ -591,12 +616,12 @@ bool QQmlImportsPrivate::resolveType(const QHashedStringRef& type, int *vmajor, } QHashedStringRef unqualifiedtype = dot < 0 ? type : QHashedStringRef(type.constData()+dot+1, type.length()-dot-1); if (s) { - if (s->resolveType(typeLoader,unqualifiedtype,vmajor,vminor,type_return,url_return, &base, errors)) + if (s->resolveType(typeLoader,unqualifiedtype,vmajor,vminor,type_return, &base, errors)) return true; - if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && url_return && s != &unqualifiedset) { + if (s->imports.count() == 1 && !s->imports.at(0)->isLibrary && type_return && s != &unqualifiedset) { // qualified, and only 1 url - *url_return = resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")); - return true; + *type_return = getTypeForUrl(resolveLocalUrl(s->imports.at(0)->url, unqualifiedtype.toString() + QLatin1String(".qml")), type, errors); + return (*type_return != 0); } } @@ -615,18 +640,18 @@ QQmlImportNamespace::Import *QQmlImportNamespace::findImport(const QString &uri) bool QQmlImportNamespace::resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, int *vmajor, int *vminor, QQmlType** type_return, - QString* url_return, QString *base, QList<QQmlError> *errors) + QString *base, QList<QQmlError> *errors) { bool typeRecursionDetected = false; for (int i=0; i<imports.count(); ++i) { const Import *import = imports.at(i); - if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, url_return, + if (import->resolveType(typeLoader, type, vmajor, vminor, type_return, base, &typeRecursionDetected)) { if (qmlCheckTypes()) { // check for type clashes for (int j = i+1; j<imports.count(); ++j) { const Import *import2 = imports.at(j); - if (import2->resolveType(typeLoader, type, vmajor, vminor, 0, 0, base)) { + if (import2->resolveType(typeLoader, type, vmajor, vminor, 0, base)) { if (errors) { QString u1 = import->url; QString u2 = import2->url; @@ -978,7 +1003,7 @@ QQmlImportNamespace *QQmlImportsPrivate::importNamespace(const QString &prefix) QQmlImportNamespace::Import *QQmlImportsPrivate::addImportToNamespace(QQmlImportNamespace *nameSpace, const QString &uri, const QString &url, int vmaj, int vmin, QQmlScript::Import::Type type, - QList<QQmlError> *errors) + QList<QQmlError> *errors, bool lowPrecedence) { Q_ASSERT(nameSpace); Q_ASSERT(errors); @@ -992,7 +1017,11 @@ QQmlImportNamespace::Import *QQmlImportsPrivate::addImportToNamespace(QQmlImport import->minversion = vmin; import->isLibrary = (type == QQmlScript::Import::Library); - nameSpace->imports.prepend(import); + if (lowPrecedence) + nameSpace->imports.append(import); + else + nameSpace->imports.prepend(import); + return import; } @@ -1137,7 +1166,7 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix if (!url.endsWith(Slash) && !url.endsWith(Backslash)) url += Slash; - QQmlImportNamespace::Import *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QQmlScript::Import::File, errors); + QQmlImportNamespace::Import *inserted = addImportToNamespace(nameSpace, importUri, url, vmaj, vmin, QQmlScript::Import::File, errors, isImplicitImport); Q_ASSERT(inserted); if (!incomplete && !qmldirIdentifier.isEmpty()) { @@ -1213,6 +1242,8 @@ bool QQmlImportsPrivate::updateQmldirContent(const QString &uri, const QString & Adds an implicit "." file import. This is equivalent to calling addFileImport(), but error messages related to the path or qmldir file not existing are suppressed. + + Additionally, this will add the import with lowest instead of highest precedence. */ bool QQmlImports::addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlError> *errors) { @@ -1660,6 +1691,10 @@ bool QQmlImportDatabase::importPlugin(const QString &filePath, const QString &ur QQmlMetaType::setTypeRegistrationNamespace(typeNamespace); + if (QQmlExtensionPlugin *plugin = qobject_cast<QQmlExtensionPlugin *>(instance)) { + // Set the directory, not the library file itself + QQmlExtensionPluginPrivate::get(plugin)->baseUrl = QUrl::fromLocalFile(fileInfo.absolutePath()); + } iface->registerTypes(moduleId); registrationFailures = QQmlMetaType::typeRegistrationFailures(); diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h index ad4b3dfee9..140ca6695e 100644 --- a/src/qml/qml/qqmlimport_p.h +++ b/src/qml/qml/qqmlimport_p.h @@ -85,14 +85,13 @@ public: QUrl baseUrl() const; bool resolveType(const QHashedStringRef &type, - QQmlType** type_return, QString* url_return, + QQmlType** type_return, int *version_major, int *version_minor, QQmlImportNamespace** ns_return, QList<QQmlError> *errors = 0) const; bool resolveType(QQmlImportNamespace*, const QHashedStringRef& type, - QQmlType** type_return, QString* url_return, - int *version_major, int *version_minor) const; + QQmlType** type_return, int *version_major, int *version_minor) const; bool addImplicitImport(QQmlImportDatabase *importDb, QList<QQmlError> *errors); diff --git a/src/qml/qml/qqmlincubator.h b/src/qml/qml/qqmlincubator.h index bbb232bfa2..4d3287a394 100644 --- a/src/qml/qml/qqmlincubator.h +++ b/src/qml/qml/qqmlincubator.h @@ -45,8 +45,6 @@ #include <QtQml/qtqmlglobal.h> #include <QtQml/qqmlerror.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -125,6 +123,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLINCUBATOR_H diff --git a/src/qml/qml/qqmlinfo.h b/src/qml/qml/qqmlinfo.h index c2b2cb353e..16fca9428e 100644 --- a/src/qml/qml/qqmlinfo.h +++ b/src/qml/qml/qqmlinfo.h @@ -46,8 +46,6 @@ #include <QtCore/qurl.h> #include <QtQml/qqmlerror.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -98,6 +96,4 @@ Q_QML_EXPORT QQmlInfo qmlInfo(const QObject *me, const QList<QQmlError> &errors) QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLINFO_H diff --git a/src/qml/qml/qqmllist.h b/src/qml/qml/qqmllist.h index d2425bc6bf..a27a2da9ae 100644 --- a/src/qml/qml/qqmllist.h +++ b/src/qml/qml/qqmllist.h @@ -46,8 +46,6 @@ #include <QtCore/qlist.h> #include <QtCore/qvariant.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -150,6 +148,4 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QQmlListReference) -QT_END_HEADER - #endif // QQMLLIST_H diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index e1ac75f5f0..c9ce4773c3 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -464,8 +464,11 @@ v8::Handle<v8::Value> QQmlNumberExtension::toLocaleString(const v8::Arguments& a if (!args[1]->IsString()) V8THROW_ERROR("Locale: Number.toLocaleString(): Invalid arguments"); v8::Local<v8::String> fs = args[1]->ToString(); - if (!fs.IsEmpty() && fs->Length()) - format = fs->GetCharacter(0); + if (!fs.IsEmpty() && fs->Length()) { + v8::String::Value value(fs); + Q_ASSERT(*value != NULL); + format = **value; + } } int prec = 2; if (args.Length() > 2) { diff --git a/src/qml/qml/qqmllocale_p.h b/src/qml/qml/qqmllocale_p.h index 8015ca2bbe..25f98d9168 100644 --- a/src/qml/qml/qqmllocale_p.h +++ b/src/qml/qml/qqmllocale_p.h @@ -49,8 +49,6 @@ #include <private/qv8engine_p.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -133,6 +131,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif diff --git a/src/qml/qml/qqmlmemoryprofiler_p.h b/src/qml/qml/qqmlmemoryprofiler_p.h index d0d96f20f9..dfc26aa8fb 100644 --- a/src/qml/qml/qqmlmemoryprofiler_p.h +++ b/src/qml/qml/qqmlmemoryprofiler_p.h @@ -44,7 +44,6 @@ #include <private/qtqmlglobal_p.h> -QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QUrl; @@ -76,6 +75,4 @@ public: #define QML_MEMORY_SCOPE_STRING(s) QQmlMemoryScope _qml_memory_scope(s) QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLMEMORYPROFILER_H diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 2389c45574..372475d85c 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -75,6 +75,8 @@ struct QQmlMetaTypeData Ids idToType; typedef QHash<QHashedStringRef,QQmlType *> Names; Names nameToType; + typedef QHash<QUrl, QQmlType *> Files; //For file imported composite types only + Files urlToType; typedef QHash<const QMetaObject *, QQmlType *> MetaObjects; MetaObjects metaObjectToType; typedef QHash<int, QQmlMetaType::StringConverter> StringConverters; @@ -148,48 +150,68 @@ QQmlMetaTypeData::~QQmlMetaTypeData() class QQmlTypePrivate { public: - QQmlTypePrivate(); + QQmlTypePrivate(QQmlType::RegistrationType type); ~QQmlTypePrivate(); void init() const; void initEnums() const; void insertEnums(const QMetaObject *metaObject) const; - bool m_isInterface : 1; - const char *m_iid; - QHashedString m_module; - QString m_name; - QString m_elementName; - int m_version_maj; - int m_version_min; - int m_typeId; int m_listId; - int m_revision; - mutable bool m_containsRevisionedAttributes; - mutable QQmlType *m_superType; - - int m_allocationSize; - void (*m_newFunc)(void *); - QString m_noCreationReason; - - const QMetaObject *m_baseMetaObject; - QQmlAttachedPropertiesFunc m_attachedPropertiesFunc; - const QMetaObject *m_attachedPropertiesType; - int m_attachedPropertiesId; - int m_parserStatusCast; - int m_propertyValueSourceCast; - int m_propertyValueInterceptorCast; - QObject *(*m_extFunc)(QObject *); - const QMetaObject *m_extMetaObject; - int m_index; - QQmlCustomParser *m_customParser; - mutable volatile bool m_isSetup:1; - mutable volatile bool m_isEnumSetup:1; - mutable bool m_haveSuperType:1; - mutable QList<QQmlProxyMetaObject::ProxyData> m_metaObjects; - mutable QStringHash<int> m_enums; - QQmlType::SingletonInstanceInfo *m_singletonInstanceInfo; - - static QHash<const QMetaObject *, int> m_attachedPropertyIds; + QQmlType::RegistrationType regType; + + struct QQmlCppTypeData + { + int allocationSize; + void (*newFunc)(void *); + QString noCreationReason; + int parserStatusCast; + QObject *(*extFunc)(QObject *); + const QMetaObject *extMetaObject; + QQmlCustomParser *customParser; + QQmlAttachedPropertiesFunc attachedPropertiesFunc; + const QMetaObject *attachedPropertiesType; + int attachedPropertiesId; + int propertyValueSourceCast; + int propertyValueInterceptorCast; + }; + + struct QQmlSingletonTypeData + { + QQmlType::SingletonInstanceInfo *singletonInstanceInfo; + }; + + struct QQmlCompositeTypeData + { + QUrl url; + }; + + union extraData { + QQmlCppTypeData* cd; + QQmlSingletonTypeData* sd; + QQmlCompositeTypeData* fd; + } extraData; + + const char *iid; + QHashedString module; + QString name; + QString elementName; + int version_maj; + int version_min; + int typeId; + int listId; + int revision; + mutable bool containsRevisionedAttributes; + mutable QQmlType *superType; + const QMetaObject *baseMetaObject; + + int index; + mutable volatile bool isSetup:1; + mutable volatile bool isEnumSetup:1; + mutable bool haveSuperType:1; + mutable QList<QQmlProxyMetaObject::ProxyData> metaObjects; + mutable QStringHash<int> enums; + + static QHash<const QMetaObject *, int> attachedPropertyIds; }; // Avoid multiple fromUtf8(), copies and hashing of the module name. @@ -250,147 +272,195 @@ QJSValue QQmlType::SingletonInstanceInfo::scriptApi(QQmlEngine *e) const return scriptApis.value(e); } -QHash<const QMetaObject *, int> QQmlTypePrivate::m_attachedPropertyIds; - -QQmlTypePrivate::QQmlTypePrivate() -: m_isInterface(false), m_iid(0), m_typeId(0), m_listId(0), m_revision(0), m_containsRevisionedAttributes(false), - m_superType(0), m_allocationSize(0), m_newFunc(0), m_baseMetaObject(0), m_attachedPropertiesFunc(0), - m_attachedPropertiesType(0), m_parserStatusCast(-1), m_propertyValueSourceCast(-1), - m_propertyValueInterceptorCast(-1), m_extFunc(0), m_extMetaObject(0), m_index(-1), m_customParser(0), - m_isSetup(false), m_isEnumSetup(false), m_haveSuperType(false), m_singletonInstanceInfo(0) -{ +QHash<const QMetaObject *, int> QQmlTypePrivate::attachedPropertyIds; + +QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type) +: regType(type), iid(0), typeId(0), listId(0), revision(0), + containsRevisionedAttributes(false), superType(0), baseMetaObject(0), + index(-1), isSetup(false), isEnumSetup(false), haveSuperType(false) +{ + switch (type) { + case QQmlType::CppType: + extraData.cd = new QQmlCppTypeData; + extraData.cd->allocationSize = 0; + extraData.cd->newFunc = 0; + extraData.cd->parserStatusCast = -1; + extraData.cd->extFunc = 0; + extraData.cd->extMetaObject = 0; + extraData.cd->customParser = 0; + extraData.cd->attachedPropertiesFunc = 0; + extraData.cd->attachedPropertiesType = 0; + extraData.cd->propertyValueSourceCast = -1; + extraData.cd->propertyValueInterceptorCast = -1; + break; + case QQmlType::SingletonType: + extraData.sd = new QQmlSingletonTypeData; + extraData.sd->singletonInstanceInfo = 0; + break; + case QQmlType::InterfaceType: + extraData.cd = 0; + break; + case QQmlType::CompositeType: + extraData.fd = new QQmlCompositeTypeData; + break; + default: qFatal("QQmlTypePrivate Internal Error."); + } } QQmlTypePrivate::~QQmlTypePrivate() { - delete m_singletonInstanceInfo; + switch (regType) { + case QQmlType::CppType: + delete extraData.cd->customParser; + delete extraData.cd; + break; + case QQmlType::SingletonType: + delete extraData.sd->singletonInstanceInfo; + delete extraData.sd; + break; + case QQmlType::CompositeType: + delete extraData.fd; + break; + default: //Also InterfaceType, because it has no extra data + break; + } } QQmlType::QQmlType(int index, const QQmlPrivate::RegisterInterface &interface) -: d(new QQmlTypePrivate) +: d(new QQmlTypePrivate(InterfaceType)) { - d->m_isInterface = true; - d->m_iid = interface.iid; - d->m_typeId = interface.typeId; - d->m_listId = interface.listId; - d->m_newFunc = 0; - d->m_index = index; - d->m_isSetup = true; - d->m_version_maj = 0; - d->m_version_min = 0; + d->iid = interface.iid; + d->typeId = interface.typeId; + d->listId = interface.listId; + d->index = index; + d->isSetup = true; + d->version_maj = 0; + d->version_min = 0; } QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterSingletonType &type) -: d(new QQmlTypePrivate) +: d(new QQmlTypePrivate(SingletonType)) { - d->m_elementName = elementName; - d->m_module = moduleFromUtf8(type.uri); + d->elementName = elementName; + d->module = moduleFromUtf8(type.uri); - d->m_version_maj = type.versionMajor; - d->m_version_min = type.versionMinor; + d->version_maj = type.versionMajor; + d->version_min = type.versionMinor; if (type.qobjectApi) { if (type.version >= 1) // static metaobject added in version 1 - d->m_baseMetaObject = type.instanceMetaObject; + d->baseMetaObject = type.instanceMetaObject; if (type.version >= 2) // typeId added in version 2 - d->m_typeId = type.typeId; + d->typeId = type.typeId; if (type.version >= 2) // revisions added in version 2 - d->m_revision = type.revision; + d->revision = type.revision; } - d->m_newFunc = 0; - d->m_index = index; + d->index = index; - d->m_singletonInstanceInfo = new SingletonInstanceInfo; - d->m_singletonInstanceInfo->scriptCallback = type.scriptApi; - d->m_singletonInstanceInfo->qobjectCallback = type.qobjectApi; - d->m_singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName); - d->m_singletonInstanceInfo->instanceMetaObject = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : 0; + d->extraData.sd->singletonInstanceInfo = new SingletonInstanceInfo; + d->extraData.sd->singletonInstanceInfo->scriptCallback = type.scriptApi; + d->extraData.sd->singletonInstanceInfo->qobjectCallback = type.qobjectApi; + d->extraData.sd->singletonInstanceInfo->typeName = QString::fromUtf8(type.typeName); + d->extraData.sd->singletonInstanceInfo->instanceMetaObject + = (type.qobjectApi && type.version >= 1) ? type.instanceMetaObject : 0; } QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterType &type) -: d(new QQmlTypePrivate) +: d(new QQmlTypePrivate(CppType)) { - d->m_elementName = elementName; - d->m_module = moduleFromUtf8(type.uri); + d->elementName = elementName; + d->module = moduleFromUtf8(type.uri); - d->m_version_maj = type.versionMajor; - d->m_version_min = type.versionMinor; + d->version_maj = type.versionMajor; + d->version_min = type.versionMinor; if (type.version >= 1) // revisions added in version 1 - d->m_revision = type.revision; - d->m_typeId = type.typeId; - d->m_listId = type.listId; - d->m_allocationSize = type.objectSize; - d->m_newFunc = type.create; - d->m_noCreationReason = type.noCreationReason; - d->m_baseMetaObject = type.metaObject; - d->m_attachedPropertiesFunc = type.attachedPropertiesFunction; - d->m_attachedPropertiesType = type.attachedPropertiesMetaObject; - if (d->m_attachedPropertiesType) { - QHash<const QMetaObject *, int>::Iterator iter = d->m_attachedPropertyIds.find(d->m_baseMetaObject); - if (iter == d->m_attachedPropertyIds.end()) - iter = d->m_attachedPropertyIds.insert(d->m_baseMetaObject, index); - d->m_attachedPropertiesId = *iter; + d->revision = type.revision; + d->typeId = type.typeId; + d->listId = type.listId; + d->extraData.cd->allocationSize = type.objectSize; + d->extraData.cd->newFunc = type.create; + d->extraData.cd->noCreationReason = type.noCreationReason; + d->baseMetaObject = type.metaObject; + d->extraData.cd->attachedPropertiesFunc = type.attachedPropertiesFunction; + d->extraData.cd->attachedPropertiesType = type.attachedPropertiesMetaObject; + if (d->extraData.cd->attachedPropertiesType) { + QHash<const QMetaObject *, int>::Iterator iter = d->attachedPropertyIds.find(d->baseMetaObject); + if (iter == d->attachedPropertyIds.end()) + iter = d->attachedPropertyIds.insert(d->baseMetaObject, index); + d->extraData.cd->attachedPropertiesId = *iter; } else { - d->m_attachedPropertiesId = -1; + d->extraData.cd->attachedPropertiesId = -1; } - d->m_parserStatusCast = type.parserStatusCast; - d->m_propertyValueSourceCast = type.valueSourceCast; - d->m_propertyValueInterceptorCast = type.valueInterceptorCast; - d->m_extFunc = type.extensionObjectCreate; - d->m_index = index; - d->m_customParser = type.customParser; + d->extraData.cd->parserStatusCast = type.parserStatusCast; + d->extraData.cd->propertyValueSourceCast = type.valueSourceCast; + d->extraData.cd->propertyValueInterceptorCast = type.valueInterceptorCast; + d->extraData.cd->extFunc = type.extensionObjectCreate; + d->extraData.cd->customParser = type.customParser; + d->index = index; if (type.extensionMetaObject) - d->m_extMetaObject = type.extensionMetaObject; + d->extraData.cd->extMetaObject = type.extensionMetaObject; +} + +QQmlType::QQmlType(int index, const QString &elementName, const QQmlPrivate::RegisterCompositeType &type) +: d(new QQmlTypePrivate(CompositeType)) +{ + d->index = index; + d->elementName = elementName; + + d->module = moduleFromUtf8(type.uri); + d->version_maj = type.versionMajor; + d->version_min = type.versionMinor; + + d->extraData.fd->url = type.url; } QQmlType::~QQmlType() { - delete d->m_customParser; delete d; } const QHashedString &QQmlType::module() const { - return d->m_module; + return d->module; } int QQmlType::majorVersion() const { - return d->m_version_maj; + return d->version_maj; } int QQmlType::minorVersion() const { - return d->m_version_min; + return d->version_min; } bool QQmlType::availableInVersion(int vmajor, int vminor) const { Q_ASSERT(vmajor >= 0 && vminor >= 0); - return vmajor == d->m_version_maj && vminor >= d->m_version_min; + return vmajor == d->version_maj && vminor >= d->version_min; } bool QQmlType::availableInVersion(const QHashedStringRef &module, int vmajor, int vminor) const { Q_ASSERT(vmajor >= 0 && vminor >= 0); - return module == d->m_module && vmajor == d->m_version_maj && vminor >= d->m_version_min; + return module == d->module && vmajor == d->version_maj && vminor >= d->version_min; } // returns the nearest _registered_ super class QQmlType *QQmlType::superType() const { - if (!d->m_haveSuperType && d->m_baseMetaObject) { - const QMetaObject *mo = d->m_baseMetaObject->superClass(); - while (mo && !d->m_superType) { - d->m_superType = QQmlMetaType::qmlType(mo, d->m_module, d->m_version_maj, d->m_version_min); + if (!d->haveSuperType && d->baseMetaObject) { + const QMetaObject *mo = d->baseMetaObject->superClass(); + while (mo && !d->superType) { + d->superType = QQmlMetaType::qmlType(mo, d->module, d->version_maj, d->version_min); mo = mo->superClass(); } - d->m_haveSuperType = true; + d->haveSuperType = true; } - return d->m_superType; + return d->superType; } static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, @@ -481,92 +551,95 @@ static bool isPropertyRevisioned(const QMetaObject *mo, int index) void QQmlTypePrivate::init() const { - if (m_isSetup) return; + if (isSetup) + return; QWriteLocker lock(metaTypeDataLock()); - if (m_isSetup) + if (isSetup) return; - const QMetaObject *mo = m_baseMetaObject; + const QMetaObject *mo = baseMetaObject; if (!mo) { - // singleton type without metaobject information + // version 0 singleton type without metaobject information return; } - // Setup extended meta object - // XXX - very inefficient - if (m_extFunc) { - QMetaObjectBuilder builder; - clone(builder, m_extMetaObject, m_extMetaObject, m_extMetaObject); - builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); - QMetaObject *mmo = builder.toMetaObject(); - mmo->d.superdata = mo; - QQmlProxyMetaObject::ProxyData data = { mmo, m_extFunc, 0, 0 }; - m_metaObjects << data; + if (regType == QQmlType::CppType) { + // Setup extended meta object + // XXX - very inefficient + if (extraData.cd->extFunc) { + QMetaObjectBuilder builder; + clone(builder, extraData.cd->extMetaObject, extraData.cd->extMetaObject, extraData.cd->extMetaObject); + builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); + QMetaObject *mmo = builder.toMetaObject(); + mmo->d.superdata = mo; + QQmlProxyMetaObject::ProxyData data = { mmo, extraData.cd->extFunc, 0, 0 }; + metaObjects << data; + } } mo = mo->d.superdata; while(mo) { QQmlType *t = metaTypeData()->metaObjectToType.value(mo); if (t) { - if (t->d->m_extFunc) { + if (t->d->extraData.cd->extFunc) { QMetaObjectBuilder builder; - clone(builder, t->d->m_extMetaObject, t->d->m_baseMetaObject, m_baseMetaObject); + clone(builder, t->d->extraData.cd->extMetaObject, t->d->baseMetaObject, baseMetaObject); builder.setFlags(QMetaObjectBuilder::DynamicMetaObject); QMetaObject *mmo = builder.toMetaObject(); - mmo->d.superdata = m_baseMetaObject; - if (!m_metaObjects.isEmpty()) - m_metaObjects.last().metaObject->d.superdata = mmo; - QQmlProxyMetaObject::ProxyData data = { mmo, t->d->m_extFunc, 0, 0 }; - m_metaObjects << data; + mmo->d.superdata = baseMetaObject; + if (!metaObjects.isEmpty()) + metaObjects.last().metaObject->d.superdata = mmo; + QQmlProxyMetaObject::ProxyData data = { mmo, t->d->extraData.cd->extFunc, 0, 0 }; + metaObjects << data; } } mo = mo->d.superdata; } - for (int ii = 0; ii < m_metaObjects.count(); ++ii) { - m_metaObjects[ii].propertyOffset = - m_metaObjects.at(ii).metaObject->propertyOffset(); - m_metaObjects[ii].methodOffset = - m_metaObjects.at(ii).metaObject->methodOffset(); + for (int ii = 0; ii < metaObjects.count(); ++ii) { + metaObjects[ii].propertyOffset = + metaObjects.at(ii).metaObject->propertyOffset(); + metaObjects[ii].methodOffset = + metaObjects.at(ii).metaObject->methodOffset(); } - + // Check for revisioned details { const QMetaObject *mo = 0; - if (m_metaObjects.isEmpty()) - mo = m_baseMetaObject; + if (metaObjects.isEmpty()) + mo = baseMetaObject; else - mo = m_metaObjects.first().metaObject; + mo = metaObjects.first().metaObject; - for (int ii = 0; !m_containsRevisionedAttributes && ii < mo->propertyCount(); ++ii) { + for (int ii = 0; !containsRevisionedAttributes && ii < mo->propertyCount(); ++ii) { if (isPropertyRevisioned(mo, ii)) - m_containsRevisionedAttributes = true; + containsRevisionedAttributes = true; } - for (int ii = 0; !m_containsRevisionedAttributes && ii < mo->methodCount(); ++ii) { + for (int ii = 0; !containsRevisionedAttributes && ii < mo->methodCount(); ++ii) { if (mo->method(ii).revision() != 0) - m_containsRevisionedAttributes = true; + containsRevisionedAttributes = true; } } - m_isSetup = true; + isSetup = true; lock.unlock(); } void QQmlTypePrivate::initEnums() const { - if (m_isEnumSetup) return; + if (isEnumSetup) return; init(); QWriteLocker lock(metaTypeDataLock()); - if (m_isEnumSetup) return; + if (isEnumSetup) return; - if (m_baseMetaObject) // could be singleton type without metaobject - insertEnums(m_baseMetaObject); + if (baseMetaObject) // could be singleton type without metaobject + insertEnums(baseMetaObject); - m_isEnumSetup = true; + isEnumSetup = true; } void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const @@ -584,157 +657,182 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) { QMetaEnum e = metaObject->enumerator(ii); for (int jj = 0; jj < e.keyCount(); ++jj) - m_enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj)); + enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj)); } } QByteArray QQmlType::typeName() const { - if (d->m_singletonInstanceInfo) - return d->m_singletonInstanceInfo->typeName.toUtf8(); - if (d->m_baseMetaObject) - return d->m_baseMetaObject->className(); + if (d->regType == SingletonType) + return d->extraData.sd->singletonInstanceInfo->typeName.toUtf8(); + else if (d->baseMetaObject) + return d->baseMetaObject->className(); else return QByteArray(); } const QString &QQmlType::elementName() const { - return d->m_elementName; + return d->elementName; } const QString &QQmlType::qmlTypeName() const { - if (d->m_name.isEmpty()) { - if (!d->m_module.isEmpty()) - d->m_name = static_cast<QString>(d->m_module) + QLatin1Char('/') + d->m_elementName; + if (d->name.isEmpty()) { + if (!d->module.isEmpty()) + d->name = static_cast<QString>(d->module) + QLatin1Char('/') + d->elementName; else - d->m_name = d->m_elementName; + d->name = d->elementName; } - return d->m_name; + return d->name; } QObject *QQmlType::create() const { + if (!isCreatable()) + return 0; + d->init(); - QObject *rv = (QObject *)operator new(d->m_allocationSize); - d->m_newFunc(rv); + QObject *rv = (QObject *)operator new(d->extraData.cd->allocationSize); + d->extraData.cd->newFunc(rv); - if (rv && !d->m_metaObjects.isEmpty()) - (void)new QQmlProxyMetaObject(rv, &d->m_metaObjects); + if (rv && !d->metaObjects.isEmpty()) + (void)new QQmlProxyMetaObject(rv, &d->metaObjects); return rv; } void QQmlType::create(QObject **out, void **memory, size_t additionalMemory) const { + if (!isCreatable()) + return; + d->init(); - QObject *rv = (QObject *)operator new(d->m_allocationSize + additionalMemory); - d->m_newFunc(rv); + QObject *rv = (QObject *)operator new(d->extraData.cd->allocationSize + additionalMemory); + d->extraData.cd->newFunc(rv); - if (rv && !d->m_metaObjects.isEmpty()) - (void)new QQmlProxyMetaObject(rv, &d->m_metaObjects); + if (rv && !d->metaObjects.isEmpty()) + (void)new QQmlProxyMetaObject(rv, &d->metaObjects); *out = rv; - *memory = ((char *)rv) + d->m_allocationSize; + *memory = ((char *)rv) + d->extraData.cd->allocationSize; } QQmlType::SingletonInstanceInfo *QQmlType::singletonInstanceInfo() const { - return d->m_singletonInstanceInfo; + if (d->regType != SingletonType) + return 0; + return d->extraData.sd->singletonInstanceInfo; } QQmlCustomParser *QQmlType::customParser() const { - return d->m_customParser; + if (d->regType != CppType) + return 0; + return d->extraData.cd->customParser; } QQmlType::CreateFunc QQmlType::createFunction() const { - return d->m_newFunc; + if (d->regType != CppType) + return 0; + return d->extraData.cd->newFunc; } QString QQmlType::noCreationReason() const { - return d->m_noCreationReason; + if (d->regType != CppType) + return QString(); + return d->extraData.cd->noCreationReason; } int QQmlType::createSize() const { - return d->m_allocationSize; + if (d->regType != CppType) + return 0; + return d->extraData.cd->allocationSize; } bool QQmlType::isCreatable() const { - return d->m_newFunc != 0; + return d->regType == CppType && d->extraData.cd->newFunc; } bool QQmlType::isExtendedType() const { d->init(); - return !d->m_metaObjects.isEmpty(); + return !d->metaObjects.isEmpty(); } bool QQmlType::isSingleton() const { - return d->m_singletonInstanceInfo != 0; + return d->regType == SingletonType; } bool QQmlType::isInterface() const { - return d->m_isInterface; + return d->regType == InterfaceType; +} + +bool QQmlType::isComposite() const +{ + return d->regType == CompositeType; } int QQmlType::typeId() const { - return d->m_typeId; + return d->typeId; } int QQmlType::qListTypeId() const { - return d->m_listId; + return d->listId; } const QMetaObject *QQmlType::metaObject() const { d->init(); - if (d->m_metaObjects.isEmpty()) - return d->m_baseMetaObject; + if (d->metaObjects.isEmpty()) + return d->baseMetaObject; else - return d->m_metaObjects.first().metaObject; + return d->metaObjects.first().metaObject; } const QMetaObject *QQmlType::baseMetaObject() const { - return d->m_baseMetaObject; + return d->baseMetaObject; } bool QQmlType::containsRevisionedAttributes() const { d->init(); - return d->m_containsRevisionedAttributes; + return d->containsRevisionedAttributes; } int QQmlType::metaObjectRevision() const { - return d->m_revision; + return d->revision; } QQmlAttachedPropertiesFunc QQmlType::attachedPropertiesFunction() const { - return d->m_attachedPropertiesFunc; + if (d->regType != CppType) + return 0; + return d->extraData.cd->attachedPropertiesFunc; } const QMetaObject *QQmlType::attachedPropertiesType() const { - return d->m_attachedPropertiesType; + if (d->regType != CppType) + return 0; + return d->extraData.cd->attachedPropertiesType; } /* @@ -744,32 +842,49 @@ Qt 4.7 and QtQuick 1.0). */ int QQmlType::attachedPropertiesId() const { - return d->m_attachedPropertiesId; + if (d->regType != CppType) + return 0; + return d->extraData.cd->attachedPropertiesId; } int QQmlType::parserStatusCast() const { - return d->m_parserStatusCast; + if (d->regType != CppType) + return -1; + return d->extraData.cd->parserStatusCast; } int QQmlType::propertyValueSourceCast() const { - return d->m_propertyValueSourceCast; + if (d->regType != CppType) + return -1; + return d->extraData.cd->propertyValueSourceCast; } int QQmlType::propertyValueInterceptorCast() const { - return d->m_propertyValueInterceptorCast; + if (d->regType != CppType) + return -1; + return d->extraData.cd->propertyValueInterceptorCast; } const char *QQmlType::interfaceIId() const { - return d->m_iid; + if (d->regType != InterfaceType) + return 0; + return d->iid; } int QQmlType::index() const { - return d->m_index; + return d->index; +} + +QUrl QQmlType::sourceUrl() const +{ + if (d->regType != CompositeType) + return QUrl(); + return d->extraData.fd->url; } int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const @@ -779,7 +894,7 @@ int QQmlType::enumValue(const QHashedStringRef &name, bool *ok) const d->initEnums(); - int *rv = d->m_enums.value(name); + int *rv = d->enums.value(name); if (rv) return *rv; @@ -794,7 +909,7 @@ int QQmlType::enumValue(const QHashedCStringRef &name, bool *ok) const d->initEnums(); - int *rv = d->m_enums.value(name); + int *rv = d->enums.value(name); if (rv) return *rv; @@ -809,7 +924,7 @@ int QQmlType::enumValue(const QHashedV8String &name, bool *ok) const d->initEnums(); - int *rv = d->m_enums.value(name); + int *rv = d->enums.value(name); if (rv) return *rv; @@ -998,6 +1113,8 @@ QString registrationTypeString(QQmlType::RegistrationType typeType) typeStr = QStringLiteral("element"); else if (typeType == QQmlType::SingletonType) typeStr = QStringLiteral("singleton type"); + else + typeStr = QStringLiteral("type"); return typeStr; } @@ -1007,7 +1124,7 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da if (!typeName.isEmpty()) { int typeNameLen = typeName.length(); for (int ii = 0; ii < typeNameLen; ++ii) { - if (!typeName.at(ii).isLetterOrNumber()) { + if (!(typeName.at(ii).isLetterOrNumber() || typeName.at(ii) == '_')) { QString failure(QCoreApplication::translate("qmlRegisterType", "Invalid QML %1 name \"%2\"")); data->typeRegistrationFailures.append(failure.arg(registrationTypeString(typeType)).arg(typeName)); return false; @@ -1040,46 +1157,59 @@ bool checkRegistration(QQmlType::RegistrationType typeType, QQmlMetaTypeData *da return true; } -int registerType(const QQmlPrivate::RegisterType &type) +// NOTE: caller must hold a QWriteLocker on "data" +void addTypeToData(QQmlType* type, QQmlMetaTypeData *data) { - QWriteLocker lock(metaTypeDataLock()); - QQmlMetaTypeData *data = metaTypeData(); - QString elementName = QString::fromUtf8(type.elementName); - if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName)) - return -1; - - int index = data->types.count(); - - QQmlType *dtype = new QQmlType(index, elementName, type); - - data->types.append(dtype); - data->idToType.insert(dtype->typeId(), dtype); - if (dtype->qListTypeId()) data->idToType.insert(dtype->qListTypeId(), dtype); + if (!type->elementName().isEmpty()) + data->nameToType.insertMulti(type->elementName(), type); - if (!dtype->elementName().isEmpty()) - data->nameToType.insertMulti(dtype->elementName(), dtype); + if (type->baseMetaObject()) + data->metaObjectToType.insertMulti(type->baseMetaObject(), type); - data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype); + if (type->typeId()) { + data->idToType.insert(type->typeId(), type); + if (data->objects.size() <= type->typeId()) + data->objects.resize(type->typeId() + 16); + data->objects.setBit(type->typeId(), true); + } - if (data->objects.size() <= type.typeId) - data->objects.resize(type.typeId + 16); - if (data->lists.size() <= type.listId) - data->lists.resize(type.listId + 16); - data->objects.setBit(type.typeId, true); - if (type.listId) data->lists.setBit(type.listId, true); + if (type->qListTypeId()) { + if (data->lists.size() <= type->qListTypeId()) + data->lists.resize(type->qListTypeId() + 16); + data->lists.setBit(type->qListTypeId(), true); + data->idToType.insert(type->qListTypeId(), type); + } - if (!dtype->module().isEmpty()) { - const QHashedString &mod = dtype->module(); + if (!type->module().isEmpty()) { + const QHashedString &mod = type->module(); - QQmlMetaTypeData::VersionedUri versionedUri(mod, type.versionMajor); + QQmlMetaTypeData::VersionedUri versionedUri(mod, type->majorVersion()); QQmlTypeModule *module = data->uriToModule.value(versionedUri); if (!module) { module = new QQmlTypeModule; module->d->uri = versionedUri; data->uriToModule.insert(versionedUri, module); } - module->d->add(dtype); + module->d->add(type); } +} + +int registerType(const QQmlPrivate::RegisterType &type) +{ + QWriteLocker lock(metaTypeDataLock()); + QQmlMetaTypeData *data = metaTypeData(); + QString elementName = QString::fromUtf8(type.elementName); + if (!checkRegistration(QQmlType::CppType, data, type.uri, elementName)) + return -1; + + int index = data->types.count(); + + QQmlType *dtype = new QQmlType(index, elementName, type); + + data->types.append(dtype); + addTypeToData(dtype, data); + if (!type.typeId) + data->idToType.insert(dtype->typeId(), dtype); return index; } @@ -1097,32 +1227,31 @@ int registerSingletonType(const QQmlPrivate::RegisterSingletonType &type) QQmlType *dtype = new QQmlType(index, typeName, type); data->types.append(dtype); - data->idToType.insert(dtype->typeId(), dtype); + addTypeToData(dtype, data); - if (!dtype->elementName().isEmpty()) - data->nameToType.insertMulti(dtype->elementName(), dtype); + return index; +} - if (dtype->baseMetaObject()) - data->metaObjectToType.insertMulti(dtype->baseMetaObject(), dtype); +int registerCompositeType(const QQmlPrivate::RegisterCompositeType &type) +{ + // Assumes URL is absolute and valid. Checking of user input should happen before the URL enters type. + QWriteLocker lock(metaTypeDataLock()); + QQmlMetaTypeData *data = metaTypeData(); + QString typeName = QString::fromUtf8(type.typeName); + bool fileImport = false; + if (*(type.uri) == '\0') + fileImport = true; + if (!checkRegistration(QQmlType::CompositeType, data, fileImport?0:type.uri, typeName)) + return -1; - if (type.typeId) { - if (data->objects.size() <= type.typeId) - data->objects.resize(type.typeId + 16); - data->objects.setBit(type.typeId, true); - } + int index = data->types.count(); - if (!dtype->module().isEmpty()) { - const QHashedString &mod = dtype->module(); + QQmlType *dtype = new QQmlType(index, typeName, type); + data->types.append(dtype); + addTypeToData(dtype, data); - QQmlMetaTypeData::VersionedUri versionedUri(mod, type.versionMajor); - QQmlTypeModule *module = data->uriToModule.value(versionedUri); - if (!module) { - module = new QQmlTypeModule; - module->d->uri = versionedUri; - data->uriToModule.insert(versionedUri, module); - } - module->d->add(dtype); - } + if (fileImport) + data->urlToType.insertMulti(type.url, dtype); return index; } @@ -1142,6 +1271,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data) return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data)); } else if (type == SingletonRegistration) { return registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data)); + } else if (type == CompositeRegistration) { + return registerCompositeType(*reinterpret_cast<RegisterCompositeType *>(data)); } return -1; } @@ -1455,10 +1586,10 @@ QQmlType *QQmlMetaType::qmlType(const QHashedStringRef &name, const QHashedStrin QReadLocker lock(metaTypeDataLock()); QQmlMetaTypeData *data = metaTypeData(); - QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.find(name); + QQmlMetaTypeData::Names::ConstIterator it = data->nameToType.constFind(name); while (it != data->nameToType.end() && it.key() == name) { // XXX version_major<0 just a kludge for QQmlPropertyPrivate::initProperty - if (version_major < 0 || (*it)->availableInVersion(module, version_major,version_minor)) + if (version_major < 0 || module.isEmpty() || (*it)->availableInVersion(module, version_major,version_minor)) return (*it); ++it; } @@ -1489,10 +1620,10 @@ QQmlType *QQmlMetaType::qmlType(const QMetaObject *metaObject, const QHashedStri QReadLocker lock(metaTypeDataLock()); QQmlMetaTypeData *data = metaTypeData(); - QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.find(metaObject); + QQmlMetaTypeData::MetaObjects::const_iterator it = data->metaObjectToType.constFind(metaObject); while (it != data->metaObjectToType.end() && it.key() == metaObject) { QQmlType *t = *it; - if (version_major < 0 || t->availableInVersion(module, version_major,version_minor)) + if (version_major < 0 || module.isEmpty() || t->availableInVersion(module, version_major,version_minor)) return t; ++it; } @@ -1517,6 +1648,39 @@ QQmlType *QQmlMetaType::qmlType(int userType) } /*! + Returns the type (if any) that corresponds to the given \a url in the set of + composite types added through file imports. + + Returns null if no such type is registered. +*/ +QQmlType *QQmlMetaType::qmlType(const QUrl &url) +{ + QReadLocker lock(metaTypeDataLock()); + QQmlMetaTypeData *data = metaTypeData(); + + QQmlType *type = data->urlToType.value(url); + if (type && type->sourceUrl() == url) + return type; + else + return 0; +} + +/*! + Returns the type (if any) with the given \a index in the global type store. + This is for use when you just got the index back from a qmlRegister function. + Returns null if the index is out of bounds. +*/ +QQmlType *QQmlMetaType::qmlTypeFromIndex(int idx) +{ + QReadLocker lock(metaTypeDataLock()); + QQmlMetaTypeData *data = metaTypeData(); + + if (idx < 0 || idx >= data->types.count()) + return 0; + return data->types[idx]; +} + +/*! Returns the list of registered QML type names. */ QList<QString> QQmlMetaType::qmlTypeNames() diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 474eac184c..497afffb5d 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -84,6 +84,8 @@ public: static QQmlType *qmlType(const QMetaObject *); static QQmlType *qmlType(const QMetaObject *metaObject, const QHashedStringRef &module, int version_major, int version_minor); static QQmlType *qmlType(int); + static QQmlType *qmlType(const QUrl &url); + static QQmlType *qmlTypeFromIndex(int); static QMetaProperty defaultProperty(const QMetaObject *); static QMetaProperty defaultProperty(QObject *); @@ -164,6 +166,7 @@ public: bool isSingleton() const; bool isInterface() const; + bool isComposite() const; int typeId() const; int qListTypeId() const; @@ -206,6 +209,7 @@ public: QHash<QQmlEngine *, QObject *> qobjectApis; }; SingletonInstanceInfo *singletonInstanceInfo() const; + QUrl sourceUrl() const; int enumValue(const QHashedStringRef &, bool *ok) const; int enumValue(const QHashedCStringRef &, bool *ok) const; @@ -217,17 +221,20 @@ private: enum RegistrationType { CppType = 0, - SingletonType = 1 - // In the future, we should register all types via QQmlType, including Composite types. + SingletonType = 1, + InterfaceType = 2, + CompositeType = 3 }; friend QString registrationTypeString(RegistrationType); friend bool checkRegistration(RegistrationType, QQmlMetaTypeData *, const char *, const QString &); friend int registerType(const QQmlPrivate::RegisterType &); friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &); friend int registerInterface(const QQmlPrivate::RegisterInterface &); + friend int registerCompositeType(const QQmlPrivate::RegisterCompositeType &); QQmlType(int, const QQmlPrivate::RegisterInterface &); QQmlType(int, const QString &, const QQmlPrivate::RegisterSingletonType &); QQmlType(int, const QString &, const QQmlPrivate::RegisterType &); + QQmlType(int, const QString &, const QQmlPrivate::RegisterCompositeType &); ~QQmlType(); QQmlTypePrivate *d; @@ -249,8 +256,8 @@ public: QList<QQmlType*> singletonTypes(int) const; private: - friend int registerType(const QQmlPrivate::RegisterType &); - friend int registerSingletonType(const QQmlPrivate::RegisterSingletonType &); + //Used by register functions and creates the QQmlTypeModule for them + friend void addTypeToData(QQmlType* type, QQmlMetaTypeData *data); friend struct QQmlMetaTypeData; QQmlTypeModule(); diff --git a/src/qml/qml/qqmlnetworkaccessmanagerfactory.h b/src/qml/qml/qqmlnetworkaccessmanagerfactory.h index 6a79118c50..4c12e00c09 100644 --- a/src/qml/qml/qqmlnetworkaccessmanagerfactory.h +++ b/src/qml/qml/qqmlnetworkaccessmanagerfactory.h @@ -45,8 +45,6 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qobject.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -61,6 +59,4 @@ public: QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLNETWORKACCESSMANAGERFACTORY_H diff --git a/src/qml/qml/qqmlopenmetaobject_p.h b/src/qml/qml/qqmlopenmetaobject_p.h index fd442e4ad9..a8c5744078 100644 --- a/src/qml/qml/qqmlopenmetaobject_p.h +++ b/src/qml/qml/qqmlopenmetaobject_p.h @@ -50,8 +50,6 @@ #include <private/qtqmlglobal_p.h> #include <private/qobject_p.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -130,6 +128,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLOPENMETAOBJECT_H diff --git a/src/qml/qml/qqmlparserstatus.h b/src/qml/qml/qqmlparserstatus.h index 253fe64022..d3447e7752 100644 --- a/src/qml/qml/qqmlparserstatus.h +++ b/src/qml/qml/qqmlparserstatus.h @@ -45,8 +45,6 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qobject.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -72,6 +70,4 @@ Q_DECLARE_INTERFACE(QQmlParserStatus, QQmlParserStatus_iid) QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLPARSERSTATUS_H diff --git a/src/qml/qml/qqmltimer_p.h b/src/qml/qml/qqmlplatform.cpp index ff6d6207ff..de48f60f56 100644 --- a/src/qml/qml/qqmltimer_p.h +++ b/src/qml/qml/qqmlplatform.cpp @@ -39,73 +39,45 @@ ** ****************************************************************************/ -#ifndef QQMLTIMER_H -#define QQMLTIMER_H - -#include <qqml.h> - -#include <QtCore/qobject.h> - -#include <private/qtqmlglobal_p.h> - -QT_BEGIN_HEADER +#include "qqmlplatform_p.h" QT_BEGIN_NAMESPACE -class QQmlTimerPrivate; -class Q_QML_PRIVATE_EXPORT QQmlTimer : public QObject, public QQmlParserStatus -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QQmlTimer) - Q_INTERFACES(QQmlParserStatus) - Q_PROPERTY(int interval READ interval WRITE setInterval NOTIFY intervalChanged) - Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) - Q_PROPERTY(bool repeat READ isRepeating WRITE setRepeating NOTIFY repeatChanged) - Q_PROPERTY(bool triggeredOnStart READ triggeredOnStart WRITE setTriggeredOnStart NOTIFY triggeredOnStartChanged) - Q_PROPERTY(QObject *parent READ parent CONSTANT) - -public: - QQmlTimer(QObject *parent=0); - - void setInterval(int interval); - int interval() const; - - bool isRunning() const; - void setRunning(bool running); - - bool isRepeating() const; - void setRepeating(bool repeating); - - bool triggeredOnStart() const; - void setTriggeredOnStart(bool triggeredOnStart); +/* + This object and its properties are documented as part of the Qt object, + in qqmlengine.cpp +*/ -protected: - void classBegin(); - void componentComplete(); - -public Q_SLOTS: - void start(); - void stop(); - void restart(); - -Q_SIGNALS: - void triggered(); - void runningChanged(); - void intervalChanged(); - void repeatChanged(); - void triggeredOnStartChanged(); +QQmlPlatform::QQmlPlatform(QObject *parent) + : QObject(parent) +{ +} -private: - void update(); +QQmlPlatform::~QQmlPlatform() +{ +} -private Q_SLOTS: - void ticked(); -}; +QString QQmlPlatform::os() +{ +#if defined(Q_OS_ANDROID) + return QLatin1String("android"); +#elif defined(Q_OS_BLACKBERRY) + return QLatin1String("blackberry"); +#elif defined(Q_OS_IOS) + return QLatin1String("ios"); +#elif defined(Q_OS_MAC) + return QLatin1String("mac"); +#elif defined(Q_OS_WINCE) + return QLatin1String("wince"); +#elif defined(Q_OS_WIN) + return QLatin1String("windows"); +#elif defined(Q_OS_LINUX) + return QLatin1String("linux"); +#elif defined(Q_OS_UNIX) + return QLatin1String("unix"); +#else + return QLatin1String("unknown"); +#endif +} QT_END_NAMESPACE - -QML_DECLARE_TYPE(QQmlTimer) - -QT_END_HEADER - -#endif diff --git a/src/qml/qml/qqmlbind_p.h b/src/qml/qml/qqmlplatform_p.h index 04dc72a4c0..7a212d5bdf 100644 --- a/src/qml/qml/qqmlbind_p.h +++ b/src/qml/qml/qqmlplatform_p.h @@ -39,58 +39,32 @@ ** ****************************************************************************/ -#ifndef QQMLBIND_H -#define QQMLBIND_H +#ifndef QQMLPLATFORM_P_H +#define QQMLPLATFORM_P_H +#include <QtCore/QObject> #include <qqml.h> - -#include <QtCore/qobject.h> - -QT_BEGIN_HEADER +#include <private/qtqmlglobal_p.h> QT_BEGIN_NAMESPACE -class QQmlBindPrivate; -class Q_AUTOTEST_EXPORT QQmlBind : public QObject, public QQmlPropertyValueSource, public QQmlParserStatus +class Q_QML_PRIVATE_EXPORT QQmlPlatform : public QObject { Q_OBJECT - Q_DECLARE_PRIVATE(QQmlBind) - Q_INTERFACES(QQmlParserStatus) - Q_INTERFACES(QQmlPropertyValueSource) - Q_PROPERTY(QObject *target READ object WRITE setObject) - Q_PROPERTY(QString property READ property WRITE setProperty) - Q_PROPERTY(QVariant value READ value WRITE setValue) - Q_PROPERTY(bool when READ when WRITE setWhen) + Q_PROPERTY(QString os READ os CONSTANT) public: - QQmlBind(QObject *parent=0); - ~QQmlBind(); - - bool when() const; - void setWhen(bool); - - QObject *object(); - void setObject(QObject *); + explicit QQmlPlatform(QObject *parent = 0); + virtual ~QQmlPlatform(); - QString property() const; - void setProperty(const QString &); - - QVariant value() const; - void setValue(const QVariant &); - -protected: - virtual void setTarget(const QQmlProperty &); - virtual void classBegin(); - virtual void componentComplete(); + static QString os(); private: - void eval(); + Q_DISABLE_COPY(QQmlPlatform) }; QT_END_NAMESPACE -QML_DECLARE_TYPE(QQmlBind) - -QT_END_HEADER +QML_DECLARE_TYPE(QQmlPlatform) -#endif +#endif // QQMLPLATFORM_P_H diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index e548f860be..570435ae81 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -57,8 +57,7 @@ #include <QtCore/qglobal.h> #include <QtCore/qvariant.h> - -QT_BEGIN_HEADER +#include <QtCore/qurl.h> QT_BEGIN_NAMESPACE @@ -253,11 +252,20 @@ namespace QQmlPrivate // If this is extended ensure "version" is bumped!!! }; + struct RegisterCompositeType { + const QUrl &url; + const char *uri; + int versionMajor; + int versionMinor; + const char *typeName; + }; + enum RegistrationType { - TypeRegistration = 0, + TypeRegistration = 0, InterfaceRegistration = 1, AutoParentRegistration = 2, - SingletonRegistration = 3 + SingletonRegistration = 3, + CompositeRegistration = 4 }; int Q_QML_EXPORT qmlregister(RegistrationType, void *); @@ -265,6 +273,4 @@ namespace QQmlPrivate QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLPRIVATE_H diff --git a/src/qml/qml/qqmlproperty.h b/src/qml/qml/qqmlproperty.h index 0079fed09a..c3322c0048 100644 --- a/src/qml/qml/qqmlproperty.h +++ b/src/qml/qml/qqmlproperty.h @@ -45,8 +45,6 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qmetaobject.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -140,6 +138,4 @@ Q_DECLARE_TYPEINFO(QQmlProperty, Q_MOVABLE_TYPE); QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLPROPERTY_H diff --git a/src/qml/qml/qqmlpropertycache.cpp b/src/qml/qml/qqmlpropertycache.cpp index e1aa310e3e..b1ffc9a2d5 100644 --- a/src/qml/qml/qqmlpropertycache.cpp +++ b/src/qml/qml/qqmlpropertycache.cpp @@ -1055,7 +1055,7 @@ QStringList QQmlPropertyCache::propertyNames() const struct StaticQtMetaObject : public QObject { static const QMetaObject *get() - { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; } + { return &staticQtMetaObject; } }; static int EnumType(const QMetaObject *metaobj, const QByteArray &str, int type) diff --git a/src/qml/qml/qqmlpropertyvaluesource.h b/src/qml/qml/qqmlpropertyvaluesource.h index 38f06d0b02..ccf40eb6f8 100644 --- a/src/qml/qml/qqmlpropertyvaluesource.h +++ b/src/qml/qml/qqmlpropertyvaluesource.h @@ -45,8 +45,6 @@ #include <QtQml/qtqmlglobal.h> #include <QtCore/qobject.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -65,6 +63,4 @@ Q_DECLARE_INTERFACE(QQmlPropertyValueSource, QQmlPropertyValueSource_iid) QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLPROPERTYVALUESOURCE_H diff --git a/src/qml/qml/qqmlproxymetaobject_p.h b/src/qml/qml/qqmlproxymetaobject_p.h index 9f9c346d9f..c7b266835d 100644 --- a/src/qml/qml/qqmlproxymetaobject_p.h +++ b/src/qml/qml/qqmlproxymetaobject_p.h @@ -61,8 +61,6 @@ #include <private/qobject_p.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -93,7 +91,5 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QQMLPROXYMETAOBJECT_P_H diff --git a/src/qml/qml/qqmlscript.cpp b/src/qml/qml/qqmlscript.cpp index 2f8750ee0f..613ff24f20 100644 --- a/src/qml/qml/qqmlscript.cpp +++ b/src/qml/qml/qqmlscript.cpp @@ -651,7 +651,7 @@ QString ProcessAST::asString(AST::UiQualifiedId *node) const QString s; for (AST::UiQualifiedId *it = node; it; it = it->next) { - s.append(it->name.toString()); + s.append(it->name); if (it->next) s.append(QLatin1Char('.')); diff --git a/src/qml/qml/qqmlscript_p.h b/src/qml/qml/qqmlscript_p.h index 20cec3703d..54e7a67b65 100644 --- a/src/qml/qml/qqmlscript_p.h +++ b/src/qml/qml/qqmlscript_p.h @@ -62,8 +62,6 @@ #include <QtCore/QList> #include <QtCore/QUrl> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -520,6 +518,4 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QQmlScript::Variant) -QT_END_HEADER - #endif // QQMLSCRIPT_P_H diff --git a/src/qml/qml/qqmlscriptstring.h b/src/qml/qml/qqmlscriptstring.h index fc732877ab..5421ef95fc 100644 --- a/src/qml/qml/qqmlscriptstring.h +++ b/src/qml/qml/qqmlscriptstring.h @@ -47,8 +47,6 @@ #include <QtCore/qshareddata.h> #include <QtCore/qmetatype.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -86,7 +84,5 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QQmlScriptString) -QT_END_HEADER - #endif // QQMLSCRIPTSTRING_H diff --git a/src/qml/qml/qqmltimer.cpp b/src/qml/qml/qqmltimer.cpp deleted file mode 100644 index c9f6bc7982..0000000000 --- a/src/qml/qml/qqmltimer.cpp +++ /dev/null @@ -1,328 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qqmltimer_p.h" - -#include <QtCore/qcoreapplication.h> -#include "private/qpauseanimationjob_p.h" -#include <qdebug.h> - -#include <private/qobject_p.h> - -QT_BEGIN_NAMESPACE - - - -class QQmlTimerPrivate : public QObjectPrivate, public QAnimationJobChangeListener -{ - Q_DECLARE_PUBLIC(QQmlTimer) -public: - QQmlTimerPrivate() - : interval(1000), running(false), repeating(false), triggeredOnStart(false) - , classBegun(false), componentComplete(false), firstTick(true) {} - - virtual void animationFinished(QAbstractAnimationJob *); - virtual void animationCurrentLoopChanged(QAbstractAnimationJob *) { Q_Q(QQmlTimer); q->ticked(); } - - int interval; - QPauseAnimationJob pause; - bool running : 1; - bool repeating : 1; - bool triggeredOnStart : 1; - bool classBegun : 1; - bool componentComplete : 1; - bool firstTick : 1; -}; - -/*! - \qmltype Timer - \instantiates QQmlTimer - \inqmlmodule QtQuick 2 - \ingroup qtquick-interceptors - \brief Triggers a handler at a specified interval - - A Timer can be used to trigger an action either once, or repeatedly - at a given interval. - - Here is a Timer that shows the current date and time, and updates - the text every 500 milliseconds. It uses the JavaScript \c Date - object to access the current time. - - \qml - import QtQuick 2.0 - - Item { - Timer { - interval: 500; running: true; repeat: true - onTriggered: time.text = Date().toString() - } - - Text { id: time } - } - \endqml - - The Timer type is synchronized with the animation timer. Since the animation - timer is usually set to 60fps, the resolution of Timer will be - at best 16ms. - - If the Timer is running and one of its properties is changed, the - elapsed time will be reset. For example, if a Timer with interval of - 1000ms has its \e repeat property changed 500ms after starting, the - elapsed time will be reset to 0, and the Timer will be triggered - 1000ms later. - - \sa {declarative/toys/clocks}{Clocks example} -*/ - -QQmlTimer::QQmlTimer(QObject *parent) - : QObject(*(new QQmlTimerPrivate), parent) -{ - Q_D(QQmlTimer); - d->pause.addAnimationChangeListener(d, QAbstractAnimationJob::Completion | QAbstractAnimationJob::CurrentLoop); - d->pause.setLoopCount(1); - d->pause.setDuration(d->interval); -} - -/*! - \qmlproperty int QtQuick2::Timer::interval - - Sets the \a interval between triggers, in milliseconds. - - The default interval is 1000 milliseconds. -*/ -void QQmlTimer::setInterval(int interval) -{ - Q_D(QQmlTimer); - if (interval != d->interval) { - d->interval = interval; - update(); - emit intervalChanged(); - } -} - -int QQmlTimer::interval() const -{ - Q_D(const QQmlTimer); - return d->interval; -} - -/*! - \qmlproperty bool QtQuick2::Timer::running - - If set to true, starts the timer; otherwise stops the timer. - For a non-repeating timer, \a running is set to false after the - timer has been triggered. - - \a running defaults to false. - - \sa repeat -*/ -bool QQmlTimer::isRunning() const -{ - Q_D(const QQmlTimer); - return d->running; -} - -void QQmlTimer::setRunning(bool running) -{ - Q_D(QQmlTimer); - if (d->running != running) { - d->running = running; - d->firstTick = true; - emit runningChanged(); - update(); - } -} - -/*! - \qmlproperty bool QtQuick2::Timer::repeat - - If \a repeat is true the timer is triggered repeatedly at the - specified interval; otherwise, the timer will trigger once at the - specified interval and then stop (i.e. running will be set to false). - - \a repeat defaults to false. - - \sa running -*/ -bool QQmlTimer::isRepeating() const -{ - Q_D(const QQmlTimer); - return d->repeating; -} - -void QQmlTimer::setRepeating(bool repeating) -{ - Q_D(QQmlTimer); - if (repeating != d->repeating) { - d->repeating = repeating; - update(); - emit repeatChanged(); - } -} - -/*! - \qmlproperty bool QtQuick2::Timer::triggeredOnStart - - When a timer is started, the first trigger is usually after the specified - interval has elapsed. It is sometimes desirable to trigger immediately - when the timer is started; for example, to establish an initial - state. - - If \a triggeredOnStart is true, the timer is triggered immediately - when started, and subsequently at the specified interval. Note that if - \e repeat is set to false, the timer is triggered twice; once on start, - and again at the interval. - - \a triggeredOnStart defaults to false. - - \sa running -*/ -bool QQmlTimer::triggeredOnStart() const -{ - Q_D(const QQmlTimer); - return d->triggeredOnStart; -} - -void QQmlTimer::setTriggeredOnStart(bool triggeredOnStart) -{ - Q_D(QQmlTimer); - if (d->triggeredOnStart != triggeredOnStart) { - d->triggeredOnStart = triggeredOnStart; - update(); - emit triggeredOnStartChanged(); - } -} - -/*! - \qmlmethod QtQuick2::Timer::start() - \brief Starts the timer - - If the timer is already running, calling this method has no effect. The - \c running property will be true following a call to \c start(). -*/ -void QQmlTimer::start() -{ - setRunning(true); -} - -/*! - \qmlmethod QtQuick2::Timer::stop() - \brief Stops the timer - - If the timer is not running, calling this method has no effect. The - \c running property will be false following a call to \c stop(). -*/ -void QQmlTimer::stop() -{ - setRunning(false); -} - -/*! - \qmlmethod QtQuick2::Timer::restart() - \brief Restarts the timer - - If the Timer is not running it will be started, otherwise it will be - stopped, reset to initial state and started. The \c running property - will be true following a call to \c restart(). -*/ -void QQmlTimer::restart() -{ - setRunning(false); - setRunning(true); -} - -void QQmlTimer::update() -{ - Q_D(QQmlTimer); - if (d->classBegun && !d->componentComplete) - return; - d->pause.stop(); - if (d->running) { - d->pause.setCurrentTime(0); - d->pause.setLoopCount(d->repeating ? -1 : 1); - d->pause.setDuration(d->interval); - d->pause.start(); - if (d->triggeredOnStart && d->firstTick) { - QCoreApplication::removePostedEvents(this, QEvent::MetaCall); - QMetaObject::invokeMethod(this, "ticked", Qt::QueuedConnection); - } - } -} - -void QQmlTimer::classBegin() -{ - Q_D(QQmlTimer); - d->classBegun = true; -} - -void QQmlTimer::componentComplete() -{ - Q_D(QQmlTimer); - d->componentComplete = true; - update(); -} - -/*! - \qmlsignal QtQuick2::Timer::onTriggered() - - This handler is called when the Timer is triggered. -*/ -void QQmlTimer::ticked() -{ - Q_D(QQmlTimer); - if (d->running && (d->pause.currentTime() > 0 || (d->triggeredOnStart && d->firstTick))) - emit triggered(); - d->firstTick = false; -} - -void QQmlTimerPrivate::animationFinished(QAbstractAnimationJob *) -{ - Q_Q(QQmlTimer); - if (repeating || !running) - return; - running = false; - firstTick = false; - emit q->triggered(); - emit q->runningChanged(); -} - -QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index aa7a2d95c7..e800eb815d 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -124,6 +124,7 @@ public: public slots: void finished(); void downloadProgress(qint64, qint64); + void manualFinished(QNetworkReply*); private: QQmlDataLoader *l; @@ -183,6 +184,14 @@ void QQmlDataLoaderNetworkReplyProxy::downloadProgress(qint64 bytesReceived, qin l->networkReplyProgress(reply, bytesReceived, bytesTotal); } +// This function is for when you want to shortcut the signals and call directly +void QQmlDataLoaderNetworkReplyProxy::manualFinished(QNetworkReply *reply) +{ + qint64 replySize = reply->size(); + l->networkReplyProgress(reply, replySize, replySize); + l->networkReplyFinished(reply); +} + /*! \class QQmlDataBlob @@ -1008,17 +1017,23 @@ void QQmlDataLoader::loadThread(QQmlDataBlob *blob) } else { QNetworkReply *reply = m_thread->networkAccessManager()->get(QNetworkRequest(blob->m_url)); - QObject *nrp = m_thread->networkReplyProxy(); - QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), - nrp, SLOT(downloadProgress(qint64,qint64))); - QObject::connect(reply, SIGNAL(finished()), - nrp, SLOT(finished())); + QQmlDataLoaderNetworkReplyProxy *nrp = m_thread->networkReplyProxy(); + blob->addref(); m_networkReplies.insert(reply, blob); + + if (reply->isFinished()) { + nrp->manualFinished(reply); + } else { + QObject::connect(reply, SIGNAL(downloadProgress(qint64,qint64)), + nrp, SLOT(downloadProgress(qint64,qint64))); + QObject::connect(reply, SIGNAL(finished()), + nrp, SLOT(finished())); + } + #ifdef DATABLOB_DEBUG qWarning("QQmlDataBlob: requested %s", qPrintable(blob->url().toString())); #endif - blob->addref(); } } @@ -1887,7 +1902,7 @@ QQmlTypeData::TypeDataCallback::~TypeDataCallback() QQmlTypeData::QQmlTypeData(const QUrl &url, QQmlTypeLoader::Options options, QQmlTypeLoader *manager) : QQmlTypeLoader::Blob(url, QmlFile, manager), m_options(options), - m_typesResolved(false), m_compiledData(0), m_implicitImport(0) + m_typesResolved(false), m_compiledData(0), m_implicitImport(0), m_implicitImportLoaded(false) { } @@ -1993,23 +2008,14 @@ void QQmlTypeData::completed() } } -void QQmlTypeData::dataReceived(const Data &data) +bool QQmlTypeData::loadImplicitImport() { - QString code = QString::fromUtf8(data.data(), data.size()); - QByteArray preparseData; - - if (data.isFile()) preparseData = data.asFile()->metaData(QLatin1String("qml:preparse")); - - if (!scriptParser.parse(code, preparseData, finalUrl(), finalUrlString())) { - setError(scriptParser.errors()); - return; - } + m_implicitImportLoaded = true; // Even if we hit an error, count as loaded (we'd just keep hitting the error) m_imports.setBaseUrl(finalUrl(), finalUrlString()); QQmlImportDatabase *importDatabase = typeLoader()->importDatabase(); - - // For local urls, add an implicit import "." as first (most overridden) lookup. + // For local urls, add an implicit import "." as most overridden lookup. // This will also trigger the loading of the qmldir and the import of any native // types from available plugins. QList<QQmlError> implicitImportErrors; @@ -2017,20 +2023,41 @@ void QQmlTypeData::dataReceived(const Data &data) if (!implicitImportErrors.isEmpty()) { setError(implicitImportErrors); + return false; + } + + return true; +} + +void QQmlTypeData::dataReceived(const Data &data) +{ + QString code = QString::fromUtf8(data.data(), data.size()); + QByteArray preparseData; + + if (data.isFile()) preparseData = data.asFile()->metaData(QLatin1String("qml:preparse")); + + if (!scriptParser.parse(code, preparseData, finalUrl(), finalUrlString())) { + setError(scriptParser.errors()); return; } - QList<QQmlError> errors; + m_imports.setBaseUrl(finalUrl(), finalUrlString()); + // For remote URLs, we don't delay the loading of the implicit import + // because the loading probably requires an asynchronous fetch of the + // qmldir (so we can't load it just in time). if (!finalUrl().scheme().isEmpty()) { QUrl qmldirUrl = finalUrl().resolved(QUrl(QLatin1String("qmldir"))); if (!QQmlImports::isLocal(qmldirUrl)) { + if (!loadImplicitImport()) + return; // This qmldir is for the implicit import m_implicitImport = new QQmlScript::Import; m_implicitImport->uri = QLatin1String("."); m_implicitImport->qualifier = QString(); m_implicitImport->majorVersion = -1; m_implicitImport->minorVersion = -1; + QList<QQmlError> errors; if (!fetchQmldir(qmldirUrl, m_implicitImport, 1, &errors)) { setError(errors); @@ -2039,6 +2066,8 @@ void QQmlTypeData::dataReceived(const Data &data) } } + QList<QQmlError> errors; + foreach (const QQmlScript::Import &import, scriptParser.imports()) { if (!addImport(import, &errors)) { Q_ASSERT(errors.size()); @@ -2135,13 +2164,26 @@ void QQmlTypeData::resolveTypes() TypeReference ref; QString url; - int majorVersion; - int minorVersion; + int majorVersion = -1; + int minorVersion = -1; QQmlImportNamespace *typeNamespace = 0; QList<QQmlError> errors; - if (!m_imports.resolveType(parserRef->name, &ref.type, &url, &majorVersion, &minorVersion, - &typeNamespace, &errors) || typeNamespace) { + bool typeFound = m_imports.resolveType(parserRef->name, &ref.type, + &majorVersion, &minorVersion, &typeNamespace, &errors); + if (!typeNamespace && !typeFound && !m_implicitImportLoaded) { + // Lazy loading of implicit import + if (loadImplicitImport()) { + // Try again to find the type + errors.clear(); + typeFound = m_imports.resolveType(parserRef->name, &ref.type, + &majorVersion, &minorVersion, &typeNamespace, &errors); + } else { + return; //loadImplicitImport() hit an error, and called setError already + } + } + + if (!typeFound || typeNamespace) { // Known to not be a type: // - known to be a namespace (Namespace {}) // - type with unknown namespace (UnknownNamespace.SomeType {}) @@ -2169,13 +2211,12 @@ void QQmlTypeData::resolveTypes() return; } - if (ref.type) { - ref.majorVersion = majorVersion; - ref.minorVersion = minorVersion; - } else { - ref.typeData = typeLoader()->getType(QUrl(url)); + if (ref.type->isComposite()) { + ref.typeData = typeLoader()->getType(ref.type->sourceUrl()); addDependency(ref.typeData); } + ref.majorVersion = majorVersion; + ref.minorVersion = minorVersion; Q_ASSERT(parserRef->firstUse); ref.location = parserRef->firstUse->location.start; diff --git a/src/qml/qml/qqmltypeloader_p.h b/src/qml/qml/qqmltypeloader_p.h index b4ecfb77d1..68b8f33f88 100644 --- a/src/qml/qml/qqmltypeloader_p.h +++ b/src/qml/qml/qqmltypeloader_p.h @@ -465,6 +465,8 @@ private: QList<TypeDataCallback *> m_callbacks; QQmlScript::Import *m_implicitImport; + bool m_implicitImportLoaded; + bool loadImplicitImport(); }; // QQmlScriptData instances are created, uninitialized, by the loader in the diff --git a/src/qml/qml/qqmltypenotavailable_p.h b/src/qml/qml/qqmltypenotavailable_p.h index f2e829e2ac..2529db3e5f 100644 --- a/src/qml/qml/qqmltypenotavailable_p.h +++ b/src/qml/qml/qqmltypenotavailable_p.h @@ -44,8 +44,6 @@ #include <qqml.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -59,6 +57,4 @@ QT_END_NAMESPACE QML_DECLARE_TYPE(QQmlTypeNotAvailable) -QT_END_HEADER - #endif // QQMLTYPENOTAVAILABLE_H diff --git a/src/qml/qml/qqmlvme.cpp b/src/qml/qml/qqmlvme.cpp index 4abc6f46fa..8198eeca66 100644 --- a/src/qml/qml/qqmlvme.cpp +++ b/src/qml/qml/qqmlvme.cpp @@ -558,6 +558,11 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, QObject *o = 0; void *memory = 0; type.type->create(&o, &memory, sizeof(QQmlData)); + + if (!o) + VME_EXCEPTION(tr("Unable to create object of type %1").arg(type.type->elementName()), + instr.line); + QQmlData *ddata = new (memory) QQmlData; ddata->ownMemory = false; QObjectPrivate::get(o)->declarativeData = ddata; @@ -572,10 +577,6 @@ QObject *QQmlVME::run(QList<QQmlError> *errors, ddata->propertyCache->addref(); } - if (!o) - VME_EXCEPTION(tr("Unable to create object of type %1").arg(type.type->elementName()), - instr.line); - if (states.count() == 1) { // Keep a reference to the compiled data we rely on ddata->compiledData = states[0].compiledData; diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp index 9bd769f157..80f5deccdb 100644 --- a/src/qml/qml/qqmlxmlhttprequest.cpp +++ b/src/qml/qml/qqmlxmlhttprequest.cpp @@ -496,25 +496,25 @@ v8::Handle<v8::Object> Node::prototype(QV8Engine *engine) if (d->nodePrototype.IsEmpty()) { d->nodePrototype = qPersistentNew<v8::Object>(v8::Object::New()); d->nodePrototype->SetAccessor(v8::String::New("nodeName"), nodeName, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->nodePrototype->SetAccessor(v8::String::New("nodeValue"), nodeValue, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->nodePrototype->SetAccessor(v8::String::New("nodeType"), nodeType, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->nodePrototype->SetAccessor(v8::String::New("parentNode"), parentNode, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->nodePrototype->SetAccessor(v8::String::New("childNodes"), childNodes, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->nodePrototype->SetAccessor(v8::String::New("firstChild"), firstChild, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->nodePrototype->SetAccessor(v8::String::New("lastChild"), lastChild, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->nodePrototype->SetAccessor(v8::String::New("previousSibling"), previousSibling, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->nodePrototype->SetAccessor(v8::String::New("nextSibling"), nextSibling, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->nodePrototype->SetAccessor(v8::String::New("attributes"), attributes, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); engine->freezeObject(d->nodePrototype); } return d->nodePrototype; @@ -564,7 +564,7 @@ v8::Handle<v8::Object> Element::prototype(QV8Engine *engine) d->elementPrototype = qPersistentNew<v8::Object>(v8::Object::New()); d->elementPrototype->SetPrototype(Node::prototype(engine)); d->elementPrototype->SetAccessor(v8::String::New("tagName"), nodeName, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); engine->freezeObject(d->elementPrototype); } return d->elementPrototype; @@ -577,11 +577,11 @@ v8::Handle<v8::Object> Attr::prototype(QV8Engine *engine) d->attrPrototype = qPersistentNew<v8::Object>(v8::Object::New()); d->attrPrototype->SetPrototype(Node::prototype(engine)); d->attrPrototype->SetAccessor(v8::String::New("name"), name, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->attrPrototype->SetAccessor(v8::String::New("value"), value, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->attrPrototype->SetAccessor(v8::String::New("ownerElement"), ownerElement, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); engine->freezeObject(d->attrPrototype); } return d->attrPrototype; @@ -630,9 +630,9 @@ v8::Handle<v8::Object> CharacterData::prototype(QV8Engine *engine) d->characterDataPrototype = qPersistentNew<v8::Object>(v8::Object::New()); d->characterDataPrototype->SetPrototype(Node::prototype(engine)); d->characterDataPrototype->SetAccessor(v8::String::New("data"), nodeValue, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->characterDataPrototype->SetAccessor(v8::String::New("length"), length, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); engine->freezeObject(d->characterDataPrototype); } return d->characterDataPrototype; @@ -663,9 +663,9 @@ v8::Handle<v8::Object> Text::prototype(QV8Engine *engine) d->textPrototype = qPersistentNew<v8::Object>(v8::Object::New()); d->textPrototype->SetPrototype(CharacterData::prototype(engine)); d->textPrototype->SetAccessor(v8::String::New("isElementContentWhitespace"), isElementContentWhitespace, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->textPrototype->SetAccessor(v8::String::New("wholeText"), wholeText, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); engine->freezeObject(d->textPrototype); } return d->textPrototype; @@ -689,13 +689,13 @@ v8::Handle<v8::Object> Document::prototype(QV8Engine *engine) d->documentPrototype = qPersistentNew<v8::Object>(v8::Object::New()); d->documentPrototype->SetPrototype(Node::prototype(engine)); d->documentPrototype->SetAccessor(v8::String::New("xmlVersion"), xmlVersion, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->documentPrototype->SetAccessor(v8::String::New("xmlEncoding"), xmlEncoding, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->documentPrototype->SetAccessor(v8::String::New("xmlStandalone"), xmlStandalone, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); d->documentPrototype->SetAccessor(v8::String::New("documentElement"), documentElement, - 0, v8::External::Wrap(engine)); + 0, v8::External::New(engine)); engine->freezeObject(d->documentPrototype); } return d->documentPrototype; @@ -854,9 +854,9 @@ v8::Handle<v8::Object> NamedNodeMap::prototype(QV8Engine *engine) QQmlXMLHttpRequestData *d = xhrdata(engine); if (d->namedNodeMapPrototype.IsEmpty()) { v8::Local<v8::ObjectTemplate> ot = v8::ObjectTemplate::New(); - ot->SetAccessor(v8::String::New("length"), length, 0, v8::External::Wrap(engine)); - ot->SetIndexedPropertyHandler(indexed, 0, 0, 0, 0, v8::External::Wrap(engine)); - ot->SetFallbackPropertyHandler(named, 0, 0, 0, 0, v8::External::Wrap(engine)); + ot->SetAccessor(v8::String::New("length"), length, 0, v8::External::New(engine)); + ot->SetIndexedPropertyHandler(indexed, 0, 0, 0, 0, v8::External::New(engine)); + ot->SetFallbackPropertyHandler(named, 0, 0, 0, 0, v8::External::New(engine)); d->namedNodeMapPrototype = qPersistentNew<v8::Object>(ot->NewInstance()); engine->freezeObject(d->namedNodeMapPrototype); } @@ -903,8 +903,8 @@ v8::Handle<v8::Object> NodeList::prototype(QV8Engine *engine) QQmlXMLHttpRequestData *d = xhrdata(engine); if (d->nodeListPrototype.IsEmpty()) { v8::Local<v8::ObjectTemplate> ot = v8::ObjectTemplate::New(); - ot->SetAccessor(v8::String::New("length"), length, 0, v8::External::Wrap(engine)); - ot->SetIndexedPropertyHandler(indexed, 0, 0, 0, 0, v8::External::Wrap(engine)); + ot->SetAccessor(v8::String::New("length"), length, 0, v8::External::New(engine)); + ot->SetIndexedPropertyHandler(indexed, 0, 0, 0, 0, v8::External::New(engine)); d->nodeListPrototype = qPersistentNew<v8::Object>(ot->NewInstance()); engine->freezeObject(d->nodeListPrototype); } @@ -1790,7 +1790,7 @@ void *qt_add_qmlxmlhttprequest(QV8Engine *engine) // XMLHttpRequest v8::Local<v8::FunctionTemplate> xmlhttprequest = v8::FunctionTemplate::New(qmlxmlhttprequest_new, - v8::External::Wrap(engine)); + v8::External::New(engine)); xmlhttprequest->InstanceTemplate()->SetHasExternalResource(true); // Methods diff --git a/src/qml/qml/qquicklistmodel.cpp b/src/qml/qml/qquicklistmodel.cpp deleted file mode 100644 index 91c1a9c476..0000000000 --- a/src/qml/qml/qquicklistmodel.cpp +++ /dev/null @@ -1,2567 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquicklistmodel_p_p.h" -#include "qquicklistmodelworkeragent_p.h" -#include "qqmlopenmetaobject_p.h" -#include <private/qqmljsast_p.h> -#include <private/qqmljsengine_p.h> - - -#include <private/qqmlcustomparser_p.h> -#include <private/qqmlscript_p.h> -#include <private/qqmlengine_p.h> -#include <qqmlcontext.h> -#include <qqmlinfo.h> - -#include <QtCore/qdebug.h> -#include <QtCore/qstack.h> -#include <QXmlStreamReader> - -QT_BEGIN_NAMESPACE - -// Set to 1024 as a debugging aid - easier to distinguish uids from indices of elements/models. -enum { MIN_LISTMODEL_UID = 1024 }; - -static QAtomicInt uidCounter(MIN_LISTMODEL_UID); - -template <typename T> -static bool isMemoryUsed(const char *mem) -{ - for (size_t i=0 ; i < sizeof(T) ; ++i) { - if (mem[i] != 0) - return true; - } - - return false; -} - -static QString roleTypeName(ListLayout::Role::DataType t) -{ - QString result; - const char *roleTypeNames[] = { "String", "Number", "Bool", "List", "QObject", "VariantMap", "DateTime" }; - - if (t > ListLayout::Role::Invalid && t < ListLayout::Role::MaxDataType) - result = QString::fromLatin1(roleTypeNames[t]); - - return result; -} - -const ListLayout::Role &ListLayout::getRoleOrCreate(const QString &key, Role::DataType type) -{ - QStringHash<Role *>::Node *node = roleHash.findNode(key); - if (node) { - const Role &r = *node->value; - if (type != r.type) - qmlInfo(0) << QString::fromLatin1("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type)); - return r; - } - - return createRole(key, type); -} - -const ListLayout::Role &ListLayout::getRoleOrCreate(v8::Handle<v8::String> key, Role::DataType type) -{ - QHashedV8String hashedKey(key); - QStringHash<Role *>::Node *node = roleHash.findNode(hashedKey); - if (node) { - const Role &r = *node->value; - if (type != r.type) - qmlInfo(0) << QString::fromLatin1("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(r.name).arg(roleTypeName(type)).arg(roleTypeName(r.type)); - return r; - } - - QString qkey; - qkey.resize(key->Length()); - key->Write(reinterpret_cast<uint16_t*>(qkey.data())); - - return createRole(qkey, type); -} - -const ListLayout::Role &ListLayout::createRole(const QString &key, ListLayout::Role::DataType type) -{ - const int dataSizes[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QQmlGuard<QObject>), sizeof(QVariantMap), sizeof(QDateTime) }; - const int dataAlignments[] = { sizeof(QString), sizeof(double), sizeof(bool), sizeof(ListModel *), sizeof(QObject *), sizeof(QVariantMap), sizeof(QDateTime) }; - - Role *r = new Role; - r->name = key; - r->type = type; - - if (type == Role::List) { - r->subLayout = new ListLayout; - } else { - r->subLayout = 0; - } - - int dataSize = dataSizes[type]; - int dataAlignment = dataAlignments[type]; - - int dataOffset = (currentBlockOffset + dataAlignment-1) & ~(dataAlignment-1); - if (dataOffset + dataSize > ListElement::BLOCK_SIZE) { - r->blockIndex = ++currentBlock; - r->blockOffset = 0; - currentBlockOffset = dataSize; - } else { - r->blockIndex = currentBlock; - r->blockOffset = dataOffset; - currentBlockOffset = dataOffset + dataSize; - } - - int roleIndex = roles.count(); - r->index = roleIndex; - - roles.append(r); - roleHash.insert(key, r); - - return *r; -} - -ListLayout::ListLayout(const ListLayout *other) : currentBlock(0), currentBlockOffset(0) -{ - for (int i=0 ; i < other->roles.count() ; ++i) { - Role *role = new Role(other->roles[i]); - roles.append(role); - roleHash.insert(role->name, role); - } - currentBlockOffset = other->currentBlockOffset; - currentBlock = other->currentBlock; -} - -ListLayout::~ListLayout() -{ - for (int i=0 ; i < roles.count() ; ++i) { - delete roles[i]; - } -} - -void ListLayout::sync(ListLayout *src, ListLayout *target) -{ - int roleOffset = target->roles.count(); - int newRoleCount = src->roles.count() - roleOffset; - - for (int i=0 ; i < newRoleCount ; ++i) { - Role *role = new Role(src->roles[roleOffset + i]); - target->roles.append(role); - target->roleHash.insert(role->name, role); - } - - target->currentBlockOffset = src->currentBlockOffset; - target->currentBlock = src->currentBlock; -} - -ListLayout::Role::Role(const Role *other) -{ - name = other->name; - type = other->type; - blockIndex = other->blockIndex; - blockOffset = other->blockOffset; - index = other->index; - if (other->subLayout) - subLayout = new ListLayout(other->subLayout); - else - subLayout = 0; -} - -ListLayout::Role::~Role() -{ - delete subLayout; -} - -const ListLayout::Role *ListLayout::getRoleOrCreate(const QString &key, const QVariant &data) -{ - Role::DataType type; - - switch (data.type()) { - case QVariant::Double: type = Role::Number; break; - case QVariant::Int: type = Role::Number; break; - case QVariant::UserType: type = Role::List; break; - case QVariant::Bool: type = Role::Bool; break; - case QVariant::String: type = Role::String; break; - case QVariant::Map: type = Role::VariantMap; break; - default: type = Role::Invalid; break; - } - - if (type == Role::Invalid) { - qmlInfo(0) << "Can't create role for unsupported data type"; - return 0; - } - - return &getRoleOrCreate(key, type); -} - -const ListLayout::Role *ListLayout::getExistingRole(const QString &key) -{ - Role *r = 0; - QStringHash<Role *>::Node *node = roleHash.findNode(key); - if (node) - r = node->value; - return r; -} - -const ListLayout::Role *ListLayout::getExistingRole(v8::Handle<v8::String> key) -{ - Role *r = 0; - QHashedV8String hashedKey(key); - QStringHash<Role *>::Node *node = roleHash.findNode(hashedKey); - if (node) - r = node->value; - return r; -} - -ModelObject *ListModel::getOrCreateModelObject(QQuickListModel *model, int elementIndex) -{ - ListElement *e = elements[elementIndex]; - if (e->m_objectCache == 0) { - e->m_objectCache = new ModelObject(model, elementIndex); - } - return e->m_objectCache; -} - -void ListModel::sync(ListModel *src, ListModel *target, QHash<int, ListModel *> *targetModelHash) -{ - // Sanity check - target->m_uid = src->m_uid; - if (targetModelHash) - targetModelHash->insert(target->m_uid, target); - - // Build hash of elements <-> uid for each of the lists - QHash<int, ElementSync> elementHash; - for (int i=0 ; i < target->elements.count() ; ++i) { - ListElement *e = target->elements.at(i); - int uid = e->getUid(); - ElementSync sync; - sync.target = e; - elementHash.insert(uid, sync); - } - for (int i=0 ; i < src->elements.count() ; ++i) { - ListElement *e = src->elements.at(i); - int uid = e->getUid(); - - QHash<int, ElementSync>::iterator it = elementHash.find(uid); - if (it == elementHash.end()) { - ElementSync sync; - sync.src = e; - elementHash.insert(uid, sync); - } else { - ElementSync &sync = it.value(); - sync.src = e; - } - } - - // Get list of elements that are in the target but no longer in the source. These get deleted first. - QHash<int, ElementSync>::iterator it = elementHash.begin(); - QHash<int, ElementSync>::iterator end = elementHash.end(); - while (it != end) { - const ElementSync &s = it.value(); - if (s.src == 0) { - s.target->destroy(target->m_layout); - target->elements.removeOne(s.target); - delete s.target; - } - ++it; - } - - // Sync the layouts - ListLayout::sync(src->m_layout, target->m_layout); - - // Clear the target list, and append in correct order from the source - target->elements.clear(); - for (int i=0 ; i < src->elements.count() ; ++i) { - ListElement *srcElement = src->elements.at(i); - it = elementHash.find(srcElement->getUid()); - const ElementSync &s = it.value(); - ListElement *targetElement = s.target; - if (targetElement == 0) { - targetElement = new ListElement(srcElement->getUid()); - } - ListElement::sync(srcElement, src->m_layout, targetElement, target->m_layout, targetModelHash); - target->elements.append(targetElement); - } - - target->updateCacheIndices(); - - // Update values stored in target meta objects - for (int i=0 ; i < target->elements.count() ; ++i) { - ListElement *e = target->elements[i]; - if (e->m_objectCache) - e->m_objectCache->updateValues(); - } -} - -ListModel::ListModel(ListLayout *layout, QQuickListModel *modelCache, int uid) : m_layout(layout), m_modelCache(modelCache) -{ - if (uid == -1) - uid = uidCounter.fetchAndAddOrdered(1); - m_uid = uid; -} - -void ListModel::destroy() -{ - clear(); - m_uid = -1; - m_layout = 0; - if (m_modelCache && m_modelCache->m_primary == false) - delete m_modelCache; - m_modelCache = 0; -} - -int ListModel::appendElement() -{ - int elementIndex = elements.count(); - newElement(elementIndex); - return elementIndex; -} - -void ListModel::insertElement(int index) -{ - newElement(index); - updateCacheIndices(); -} - -void ListModel::move(int from, int to, int n) -{ - if (from > to) { - // Only move forwards - flip if backwards moving - int tfrom = from; - int tto = to; - from = tto; - to = tto+n; - n = tfrom-tto; - } - - QPODVector<ListElement *, 4> store; - for (int i=0 ; i < (to-from) ; ++i) - store.append(elements[from+n+i]); - for (int i=0 ; i < n ; ++i) - store.append(elements[from+i]); - for (int i=0 ; i < store.count() ; ++i) - elements[from+i] = store[i]; - - updateCacheIndices(); -} - -void ListModel::newElement(int index) -{ - ListElement *e = new ListElement; - elements.insert(index, e); -} - -void ListModel::updateCacheIndices() -{ - for (int i=0 ; i < elements.count() ; ++i) { - ListElement *e = elements.at(i); - if (e->m_objectCache) { - e->m_objectCache->m_elementIndex = i; - } - } -} - -QVariant ListModel::getProperty(int elementIndex, int roleIndex, const QQuickListModel *owner, QV8Engine *eng) -{ - ListElement *e = elements[elementIndex]; - const ListLayout::Role &r = m_layout->getExistingRole(roleIndex); - return e->getProperty(r, owner, eng); -} - -ListModel *ListModel::getListProperty(int elementIndex, const ListLayout::Role &role) -{ - ListElement *e = elements[elementIndex]; - return e->getListProperty(role); -} - -void ListModel::set(int elementIndex, v8::Handle<v8::Object> object, QVector<int> *roles, QV8Engine *eng) -{ - ListElement *e = elements[elementIndex]; - - v8::Local<v8::Array> propertyNames = object->GetPropertyNames(); - int propertyCount = propertyNames->Length(); - - for (int i=0 ; i < propertyCount ; ++i) { - v8::Local<v8::String> propertyName = propertyNames->Get(i)->ToString(); - v8::Local<v8::Value> propertyValue = object->Get(propertyName); - - // Check if this key exists yet - int roleIndex = -1; - - // Add the value now - if (propertyValue->IsString()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String); - v8::Handle<v8::String> jsString = propertyValue->ToString(); - QString qstr; - qstr.resize(jsString->Length()); - jsString->Write(reinterpret_cast<uint16_t*>(qstr.data())); - roleIndex = e->setStringProperty(r, qstr); - } else if (propertyValue->IsNumber()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number); - roleIndex = e->setDoubleProperty(r, propertyValue->NumberValue()); - } else if (propertyValue->IsArray()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List); - ListModel *subModel = new ListModel(r.subLayout, 0, -1); - - v8::Handle<v8::Array> subArray = v8::Handle<v8::Array>::Cast(propertyValue); - int arrayLength = subArray->Length(); - for (int j=0 ; j < arrayLength ; ++j) { - v8::Handle<v8::Object> subObject = subArray->Get(j)->ToObject(); - subModel->append(subObject, eng); - } - - roleIndex = e->setListProperty(r, subModel); - } else if (propertyValue->IsBoolean()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool); - roleIndex = e->setBoolProperty(r, propertyValue->BooleanValue()); - } else if (propertyValue->IsDate()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime); - QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(propertyValue)->NumberValue()); - roleIndex = e->setDateTimeProperty(r, dt); - } else if (propertyValue->IsObject()) { - QV8ObjectResource *r = (QV8ObjectResource *) propertyValue->ToObject()->GetExternalResource(); - if (r && r->resourceType() == QV8ObjectResource::QObjectType) { - QObject *o = QV8QObjectWrapper::toQObject(r); - const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); - if (role.type == ListLayout::Role::QObject) - roleIndex = e->setQObjectProperty(role, o); - } else { - const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap); - if (role.type == ListLayout::Role::VariantMap) - roleIndex = e->setVariantMapProperty(role, propertyValue->ToObject(), eng); - } - } else if (propertyValue.IsEmpty() || propertyValue->IsUndefined() || propertyValue->IsNull()) { - const ListLayout::Role *r = m_layout->getExistingRole(propertyName); - if (r) - e->clearProperty(*r); - } - - if (roleIndex != -1) - roles->append(roleIndex); - } - - if (e->m_objectCache) { - e->m_objectCache->updateValues(*roles); - } -} - -void ListModel::set(int elementIndex, v8::Handle<v8::Object> object, QV8Engine *eng) -{ - ListElement *e = elements[elementIndex]; - - v8::Local<v8::Array> propertyNames = object->GetPropertyNames(); - int propertyCount = propertyNames->Length(); - - for (int i=0 ; i < propertyCount ; ++i) { - v8::Local<v8::String> propertyName = propertyNames->Get(i)->ToString(); - v8::Local<v8::Value> propertyValue = object->Get(propertyName); - - // Add the value now - if (propertyValue->IsString()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::String); - if (r.type == ListLayout::Role::String) { - v8::Handle<v8::String> jsString = propertyValue->ToString(); - QString qstr; - qstr.resize(jsString->Length()); - jsString->Write(reinterpret_cast<uint16_t*>(qstr.data())); - e->setStringPropertyFast(r, qstr); - } - } else if (propertyValue->IsNumber()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Number); - if (r.type == ListLayout::Role::Number) { - e->setDoublePropertyFast(r, propertyValue->NumberValue()); - } - } else if (propertyValue->IsArray()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::List); - if (r.type == ListLayout::Role::List) { - ListModel *subModel = new ListModel(r.subLayout, 0, -1); - - v8::Handle<v8::Array> subArray = v8::Handle<v8::Array>::Cast(propertyValue); - int arrayLength = subArray->Length(); - for (int j=0 ; j < arrayLength ; ++j) { - v8::Handle<v8::Object> subObject = subArray->Get(j)->ToObject(); - subModel->append(subObject, eng); - } - - e->setListPropertyFast(r, subModel); - } - } else if (propertyValue->IsBoolean()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::Bool); - if (r.type == ListLayout::Role::Bool) { - e->setBoolPropertyFast(r, propertyValue->BooleanValue()); - } - } else if (propertyValue->IsDate()) { - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime); - if (r.type == ListLayout::Role::DateTime) { - QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(propertyValue)->NumberValue()); - e->setDateTimePropertyFast(r, dt); - } - } else if (propertyValue->IsObject()) { - QV8ObjectResource *r = (QV8ObjectResource *) propertyValue->ToObject()->GetExternalResource(); - if (r && r->resourceType() == QV8ObjectResource::QObjectType) { - QObject *o = QV8QObjectWrapper::toQObject(r); - const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::QObject); - if (r.type == ListLayout::Role::QObject) - e->setQObjectPropertyFast(r, o); - } else { - const ListLayout::Role &role = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::VariantMap); - if (role.type == ListLayout::Role::VariantMap) - e->setVariantMapFast(role, propertyValue->ToObject(), eng); - } - } else if (propertyValue.IsEmpty() || propertyValue->IsUndefined() || propertyValue->IsNull()) { - const ListLayout::Role *r = m_layout->getExistingRole(propertyName); - if (r) - e->clearProperty(*r); - } - } -} - -void ListModel::clear() -{ - int elementCount = elements.count(); - for (int i=0 ; i < elementCount ; ++i) { - elements[i]->destroy(m_layout); - delete elements[i]; - } - elements.clear(); -} - -void ListModel::remove(int index, int count) -{ - for (int i=0 ; i < count ; ++i) { - elements[index+i]->destroy(m_layout); - delete elements[index+i]; - } - elements.remove(index, count); - updateCacheIndices(); -} - -void ListModel::insert(int elementIndex, v8::Handle<v8::Object> object, QV8Engine *eng) -{ - insertElement(elementIndex); - set(elementIndex, object, eng); -} - -int ListModel::append(v8::Handle<v8::Object> object, QV8Engine *eng) -{ - int elementIndex = appendElement(); - set(elementIndex, object, eng); - return elementIndex; -} - -int ListModel::setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data) -{ - int roleIndex = -1; - - if (elementIndex >= 0 && elementIndex < elements.count()) { - ListElement *e = elements[elementIndex]; - - const ListLayout::Role *r = m_layout->getRoleOrCreate(key, data); - if (r) { - roleIndex = e->setVariantProperty(*r, data); - - if (roleIndex != -1 && e->m_objectCache) { - QVector<int> roles; - roles << roleIndex; - e->m_objectCache->updateValues(roles); - } - } - } - - return roleIndex; -} - -int ListModel::setExistingProperty(int elementIndex, const QString &key, v8::Handle<v8::Value> data, QV8Engine *eng) -{ - int roleIndex = -1; - - if (elementIndex >= 0 && elementIndex < elements.count()) { - ListElement *e = elements[elementIndex]; - const ListLayout::Role *r = m_layout->getExistingRole(key); - if (r) - roleIndex = e->setJsProperty(*r, data, eng); - } - - return roleIndex; -} - -inline char *ListElement::getPropertyMemory(const ListLayout::Role &role) -{ - ListElement *e = this; - int blockIndex = 0; - while (blockIndex < role.blockIndex) { - if (e->next == 0) { - e->next = new ListElement; - e->next->uid = uid; - } - e = e->next; - ++blockIndex; - } - - char *mem = &e->data[role.blockOffset]; - return mem; -} - -QString *ListElement::getStringProperty(const ListLayout::Role &role) -{ - char *mem = getPropertyMemory(role); - QString *s = reinterpret_cast<QString *>(mem); - return s->data_ptr() ? s : 0; -} - -QObject *ListElement::getQObjectProperty(const ListLayout::Role &role) -{ - char *mem = getPropertyMemory(role); - QQmlGuard<QObject> *o = reinterpret_cast<QQmlGuard<QObject> *>(mem); - return o->data(); -} - -QVariantMap *ListElement::getVariantMapProperty(const ListLayout::Role &role) -{ - QVariantMap *map = 0; - - char *mem = getPropertyMemory(role); - if (isMemoryUsed<QVariantMap>(mem)) - map = reinterpret_cast<QVariantMap *>(mem); - - return map; -} - -QDateTime *ListElement::getDateTimeProperty(const ListLayout::Role &role) -{ - QDateTime *dt = 0; - - char *mem = getPropertyMemory(role); - if (isMemoryUsed<QDateTime>(mem)) - dt = reinterpret_cast<QDateTime *>(mem); - - return dt; -} - -QQmlGuard<QObject> *ListElement::getGuardProperty(const ListLayout::Role &role) -{ - char *mem = getPropertyMemory(role); - - bool existingGuard = false; - for (size_t i=0 ; i < sizeof(QQmlGuard<QObject>) ; ++i) { - if (mem[i] != 0) { - existingGuard = true; - break; - } - } - - QQmlGuard<QObject> *o = 0; - - if (existingGuard) - o = reinterpret_cast<QQmlGuard<QObject> *>(mem); - - return o; -} - -ListModel *ListElement::getListProperty(const ListLayout::Role &role) -{ - char *mem = getPropertyMemory(role); - ListModel **value = reinterpret_cast<ListModel **>(mem); - return *value; -} - -QVariant ListElement::getProperty(const ListLayout::Role &role, const QQuickListModel *owner, QV8Engine *eng) -{ - char *mem = getPropertyMemory(role); - - QVariant data; - - switch (role.type) { - case ListLayout::Role::Number: - { - double *value = reinterpret_cast<double *>(mem); - data = *value; - } - break; - case ListLayout::Role::String: - { - QString *value = reinterpret_cast<QString *>(mem); - if (value->data_ptr() != 0) - data = *value; - } - break; - case ListLayout::Role::Bool: - { - bool *value = reinterpret_cast<bool *>(mem); - data = *value; - } - break; - case ListLayout::Role::List: - { - ListModel **value = reinterpret_cast<ListModel **>(mem); - ListModel *model = *value; - - if (model) { - if (model->m_modelCache == 0) { - model->m_modelCache = new QQuickListModel(owner, model, eng); - QQmlEngine::setContextForObject(model->m_modelCache, QQmlEngine::contextForObject(owner)); - } - - QObject *object = model->m_modelCache; - data = QVariant::fromValue(object); - } - } - break; - case ListLayout::Role::QObject: - { - QQmlGuard<QObject> *guard = reinterpret_cast<QQmlGuard<QObject> *>(mem); - QObject *object = guard->data(); - if (object) - data = QVariant::fromValue(object); - } - break; - case ListLayout::Role::VariantMap: - { - if (isMemoryUsed<QVariantMap>(mem)) { - QVariantMap *map = reinterpret_cast<QVariantMap *>(mem); - data = *map; - } - } - break; - case ListLayout::Role::DateTime: - { - if (isMemoryUsed<QDateTime>(mem)) { - QDateTime *dt = reinterpret_cast<QDateTime *>(mem); - data = *dt; - } - } - break; - default: - break; - } - - return data; -} - -int ListElement::setStringProperty(const ListLayout::Role &role, const QString &s) -{ - int roleIndex = -1; - - if (role.type == ListLayout::Role::String) { - char *mem = getPropertyMemory(role); - QString *c = reinterpret_cast<QString *>(mem); - bool changed; - if (c->data_ptr() == 0) { - new (mem) QString(s); - changed = true; - } else { - changed = c->compare(s) != 0; - *c = s; - } - if (changed) - roleIndex = role.index; - } - - return roleIndex; -} - -int ListElement::setDoubleProperty(const ListLayout::Role &role, double d) -{ - int roleIndex = -1; - - if (role.type == ListLayout::Role::Number) { - char *mem = getPropertyMemory(role); - double *value = new (mem) double; - bool changed = *value != d; - *value = d; - if (changed) - roleIndex = role.index; - } - - return roleIndex; -} - -int ListElement::setBoolProperty(const ListLayout::Role &role, bool b) -{ - int roleIndex = -1; - - if (role.type == ListLayout::Role::Bool) { - char *mem = getPropertyMemory(role); - bool *value = new (mem) bool; - bool changed = *value != b; - *value = b; - if (changed) - roleIndex = role.index; - } - - return roleIndex; -} - -int ListElement::setListProperty(const ListLayout::Role &role, ListModel *m) -{ - int roleIndex = -1; - - if (role.type == ListLayout::Role::List) { - char *mem = getPropertyMemory(role); - ListModel **value = new (mem) ListModel *; - if (*value) { - (*value)->destroy(); - delete *value; - } - *value = m; - roleIndex = role.index; - } - - return roleIndex; -} - -int ListElement::setQObjectProperty(const ListLayout::Role &role, QObject *o) -{ - int roleIndex = -1; - - if (role.type == ListLayout::Role::QObject) { - char *mem = getPropertyMemory(role); - QQmlGuard<QObject> *g = reinterpret_cast<QQmlGuard<QObject> *>(mem); - bool existingGuard = false; - for (size_t i=0 ; i < sizeof(QQmlGuard<QObject>) ; ++i) { - if (mem[i] != 0) { - existingGuard = true; - break; - } - } - bool changed; - if (existingGuard) { - changed = g->data() != o; - g->~QQmlGuard(); - } else { - changed = true; - } - new (mem) QQmlGuard<QObject>(o); - if (changed) - roleIndex = role.index; - } - - return roleIndex; -} - -int ListElement::setVariantMapProperty(const ListLayout::Role &role, v8::Handle<v8::Object> o, QV8Engine *eng) -{ - int roleIndex = -1; - - if (role.type == ListLayout::Role::VariantMap) { - char *mem = getPropertyMemory(role); - if (isMemoryUsed<QVariantMap>(mem)) { - QVariantMap *map = reinterpret_cast<QVariantMap *>(mem); - map->~QMap(); - } - new (mem) QVariantMap(eng->variantMapFromJS(o)); - roleIndex = role.index; - } - - return roleIndex; -} - -int ListElement::setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m) -{ - int roleIndex = -1; - - if (role.type == ListLayout::Role::VariantMap) { - char *mem = getPropertyMemory(role); - if (isMemoryUsed<QVariantMap>(mem)) { - QVariantMap *map = reinterpret_cast<QVariantMap *>(mem); - map->~QMap(); - } - if (m) - new (mem) QVariantMap(*m); - else - new (mem) QVariantMap; - roleIndex = role.index; - } - - return roleIndex; -} - -int ListElement::setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt) -{ - int roleIndex = -1; - - if (role.type == ListLayout::Role::DateTime) { - char *mem = getPropertyMemory(role); - if (isMemoryUsed<QDateTime>(mem)) { - QDateTime *dt = reinterpret_cast<QDateTime *>(mem); - dt->~QDateTime(); - } - new (mem) QDateTime(dt); - roleIndex = role.index; - } - - return roleIndex; -} - -void ListElement::setStringPropertyFast(const ListLayout::Role &role, const QString &s) -{ - char *mem = getPropertyMemory(role); - new (mem) QString(s); -} - -void ListElement::setDoublePropertyFast(const ListLayout::Role &role, double d) -{ - char *mem = getPropertyMemory(role); - double *value = new (mem) double; - *value = d; -} - -void ListElement::setBoolPropertyFast(const ListLayout::Role &role, bool b) -{ - char *mem = getPropertyMemory(role); - bool *value = new (mem) bool; - *value = b; -} - -void ListElement::setQObjectPropertyFast(const ListLayout::Role &role, QObject *o) -{ - char *mem = getPropertyMemory(role); - new (mem) QQmlGuard<QObject>(o); -} - -void ListElement::setListPropertyFast(const ListLayout::Role &role, ListModel *m) -{ - char *mem = getPropertyMemory(role); - ListModel **value = new (mem) ListModel *; - *value = m; -} - -void ListElement::setVariantMapFast(const ListLayout::Role &role, v8::Handle<v8::Object> o, QV8Engine *eng) -{ - char *mem = getPropertyMemory(role); - QVariantMap *map = new (mem) QVariantMap; - *map = eng->variantMapFromJS(o); -} - -void ListElement::setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt) -{ - char *mem = getPropertyMemory(role); - new (mem) QDateTime(dt); -} - -void ListElement::clearProperty(const ListLayout::Role &role) -{ - switch (role.type) { - case ListLayout::Role::String: - setStringProperty(role, QString()); - break; - case ListLayout::Role::Number: - setDoubleProperty(role, 0.0); - break; - case ListLayout::Role::Bool: - setBoolProperty(role, false); - break; - case ListLayout::Role::List: - setListProperty(role, 0); - break; - case ListLayout::Role::QObject: - setQObjectProperty(role, 0); - break; - case ListLayout::Role::DateTime: - setDateTimeProperty(role, QDateTime()); - break; - case ListLayout::Role::VariantMap: - setVariantMapProperty(role, 0); - break; - default: - break; - } -} - -ListElement::ListElement() -{ - m_objectCache = 0; - uid = uidCounter.fetchAndAddOrdered(1); - next = 0; - memset(data, 0, sizeof(data)); -} - -ListElement::ListElement(int existingUid) -{ - m_objectCache = 0; - uid = existingUid; - next = 0; - memset(data, 0, sizeof(data)); -} - -ListElement::~ListElement() -{ - delete next; -} - -void ListElement::sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout, QHash<int, ListModel *> *targetModelHash) -{ - for (int i=0 ; i < srcLayout->roleCount() ; ++i) { - const ListLayout::Role &srcRole = srcLayout->getExistingRole(i); - const ListLayout::Role &targetRole = targetLayout->getExistingRole(i); - - switch (srcRole.type) { - case ListLayout::Role::List: - { - ListModel *srcSubModel = src->getListProperty(srcRole); - ListModel *targetSubModel = target->getListProperty(targetRole); - - if (srcSubModel) { - if (targetSubModel == 0) { - targetSubModel = new ListModel(targetRole.subLayout, 0, srcSubModel->getUid()); - target->setListPropertyFast(targetRole, targetSubModel); - } - ListModel::sync(srcSubModel, targetSubModel, targetModelHash); - } - } - break; - case ListLayout::Role::QObject: - { - QObject *object = src->getQObjectProperty(srcRole); - target->setQObjectProperty(targetRole, object); - } - break; - case ListLayout::Role::String: - case ListLayout::Role::Number: - case ListLayout::Role::Bool: - case ListLayout::Role::DateTime: - { - QVariant v = src->getProperty(srcRole, 0, 0); - target->setVariantProperty(targetRole, v); - } - case ListLayout::Role::VariantMap: - { - QVariantMap *map = src->getVariantMapProperty(srcRole); - target->setVariantMapProperty(targetRole, map); - } - break; - default: - break; - } - } - -} - -void ListElement::destroy(ListLayout *layout) -{ - if (layout) { - for (int i=0 ; i < layout->roleCount() ; ++i) { - const ListLayout::Role &r = layout->getExistingRole(i); - - switch (r.type) { - case ListLayout::Role::String: - { - QString *string = getStringProperty(r); - if (string) - string->~QString(); - } - break; - case ListLayout::Role::List: - { - ListModel *model = getListProperty(r); - if (model) { - model->destroy(); - delete model; - } - } - break; - case ListLayout::Role::QObject: - { - QQmlGuard<QObject> *guard = getGuardProperty(r); - if (guard) - guard->~QQmlGuard(); - } - break; - case ListLayout::Role::VariantMap: - { - QVariantMap *map = getVariantMapProperty(r); - if (map) - map->~QMap(); - } - break; - case ListLayout::Role::DateTime: - { - QDateTime *dt = getDateTimeProperty(r); - if (dt) - dt->~QDateTime(); - } - break; - default: - // other types don't need explicit cleanup. - break; - } - } - - delete m_objectCache; - } - - if (next) - next->destroy(0); - uid = -1; -} - -int ListElement::setVariantProperty(const ListLayout::Role &role, const QVariant &d) -{ - int roleIndex = -1; - - switch (role.type) { - case ListLayout::Role::Number: - roleIndex = setDoubleProperty(role, d.toDouble()); - break; - case ListLayout::Role::String: - roleIndex = setStringProperty(role, d.toString()); - break; - case ListLayout::Role::Bool: - roleIndex = setBoolProperty(role, d.toBool()); - break; - case ListLayout::Role::List: - roleIndex = setListProperty(role, d.value<ListModel *>()); - break; - case ListLayout::Role::VariantMap: { - QVariantMap map = d.toMap(); - roleIndex = setVariantMapProperty(role, &map); - } - break; - case ListLayout::Role::DateTime: - roleIndex = setDateTimeProperty(role, d.toDateTime()); - break; - default: - break; - } - - return roleIndex; -} - -int ListElement::setJsProperty(const ListLayout::Role &role, v8::Handle<v8::Value> d, QV8Engine *eng) -{ - // Check if this key exists yet - int roleIndex = -1; - - // Add the value now - if (d->IsString()) { - v8::Handle<v8::String> jsString = d->ToString(); - QString qstr; - qstr.resize(jsString->Length()); - jsString->Write(reinterpret_cast<uint16_t*>(qstr.data())); - roleIndex = setStringProperty(role, qstr); - } else if (d->IsNumber()) { - roleIndex = setDoubleProperty(role, d->NumberValue()); - } else if (d->IsArray()) { - if (role.type == ListLayout::Role::List) { - ListModel *subModel = new ListModel(role.subLayout, 0, -1); - v8::Handle<v8::Array> subArray = v8::Handle<v8::Array>::Cast(d); - int arrayLength = subArray->Length(); - for (int j=0 ; j < arrayLength ; ++j) { - v8::Handle<v8::Object> subObject = subArray->Get(j)->ToObject(); - subModel->append(subObject, eng); - } - roleIndex = setListProperty(role, subModel); - } else { - qmlInfo(0) << QString::fromLatin1("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List)); - } - } else if (d->IsBoolean()) { - roleIndex = setBoolProperty(role, d->BooleanValue()); - } else if (d->IsDate()) { - QDateTime dt = QV8Engine::qtDateTimeFromJsDate(v8::Handle<v8::Date>::Cast(d)->NumberValue()); - roleIndex = setDateTimeProperty(role, dt); - } else if (d->IsObject()) { - QV8ObjectResource *r = (QV8ObjectResource *) d->ToObject()->GetExternalResource(); - if (role.type == ListLayout::Role::QObject && r && r->resourceType() == QV8ObjectResource::QObjectType) { - QObject *o = QV8QObjectWrapper::toQObject(r); - roleIndex = setQObjectProperty(role, o); - } else if (role.type == ListLayout::Role::VariantMap) { - roleIndex = setVariantMapProperty(role, d->ToObject(), eng); - } - } else if (d.IsEmpty() || d->IsUndefined() || d->IsNull()) { - clearProperty(role); - } - - return roleIndex; -} - -ModelObject::ModelObject(QQuickListModel *model, int elementIndex) -: m_model(model), m_elementIndex(elementIndex), m_meta(new ModelNodeMetaObject(this)) -{ - updateValues(); - setNodeUpdatesEnabled(true); -} - -void ModelObject::updateValues() -{ - int roleCount = m_model->m_listModel->roleCount(); - for (int i=0 ; i < roleCount ; ++i) { - const ListLayout::Role &role = m_model->m_listModel->getExistingRole(i); - QByteArray name = role.name.toUtf8(); - const QVariant &data = m_model->data(m_elementIndex, i); - setValue(name, data, role.type == ListLayout::Role::List); - } -} - -void ModelObject::updateValues(const QVector<int> &roles) -{ - int roleCount = roles.count(); - for (int i=0 ; i < roleCount ; ++i) { - int roleIndex = roles.at(i); - const ListLayout::Role &role = m_model->m_listModel->getExistingRole(roleIndex); - QByteArray name = role.name.toUtf8(); - const QVariant &data = m_model->data(m_elementIndex, roleIndex); - setValue(name, data, role.type == ListLayout::Role::List); - } -} - -ModelNodeMetaObject::ModelNodeMetaObject(ModelObject *object) -: QQmlOpenMetaObject(object), m_enabled(false), m_obj(object) -{ -} - -ModelNodeMetaObject::~ModelNodeMetaObject() -{ -} - -void ModelNodeMetaObject::propertyWritten(int index) -{ - if (!m_enabled) - return; - - QV8Engine *eng = m_obj->m_model->engine(); - - QString propName = QString::fromUtf8(name(index)); - QVariant value = operator[](index); - - v8::HandleScope handle_scope; - v8::Context::Scope scope(eng->context()); - - v8::Handle<v8::Value> v = eng->fromVariant(value); - - int roleIndex = m_obj->m_model->m_listModel->setExistingProperty(m_obj->m_elementIndex, propName, v, eng); - if (roleIndex != -1) { - QVector<int> roles; - roles << roleIndex; - m_obj->m_model->emitItemsChanged(m_obj->m_elementIndex, 1, roles); - } -} - -DynamicRoleModelNode::DynamicRoleModelNode(QQuickListModel *owner, int uid) : m_owner(owner), m_uid(uid), m_meta(new DynamicRoleModelNodeMetaObject(this)) -{ - setNodeUpdatesEnabled(true); -} - -DynamicRoleModelNode *DynamicRoleModelNode::create(const QVariantMap &obj, QQuickListModel *owner) -{ - DynamicRoleModelNode *object = new DynamicRoleModelNode(owner, uidCounter.fetchAndAddOrdered(1)); - QVector<int> roles; - object->updateValues(obj, roles); - return object; -} - -void DynamicRoleModelNode::sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQuickListModel *> *targetModelHash) -{ - for (int i=0 ; i < src->m_meta->count() ; ++i) { - const QByteArray &name = src->m_meta->name(i); - QVariant value = src->m_meta->value(i); - - QQuickListModel *srcModel = qobject_cast<QQuickListModel *>(value.value<QObject *>()); - QQuickListModel *targetModel = qobject_cast<QQuickListModel *>(target->m_meta->value(i).value<QObject *>()); - - if (srcModel) { - if (targetModel == 0) - targetModel = QQuickListModel::createWithOwner(target->m_owner); - - QQuickListModel::sync(srcModel, targetModel, targetModelHash); - - QObject *targetModelObject = targetModel; - value = QVariant::fromValue(targetModelObject); - } else if (targetModel) { - delete targetModel; - } - - target->setValue(name, value); - } -} - -void DynamicRoleModelNode::updateValues(const QVariantMap &object, QVector<int> &roles) -{ - const QList<QString> &keys = object.keys(); - - QList<QString>::const_iterator it = keys.begin(); - QList<QString>::const_iterator end = keys.end(); - - while (it != end) { - const QString &key = *it; - - int roleIndex = m_owner->m_roles.indexOf(key); - if (roleIndex == -1) { - roleIndex = m_owner->m_roles.count(); - m_owner->m_roles.append(key); - } - - QVariant value = object[key]; - - if (value.type() == QVariant::List) { - QQuickListModel *subModel = QQuickListModel::createWithOwner(m_owner); - - QVariantList subArray = value.toList(); - QVariantList::const_iterator subIt = subArray.begin(); - QVariantList::const_iterator subEnd = subArray.end(); - while (subIt != subEnd) { - const QVariantMap &subObject = subIt->toMap(); - subModel->m_modelObjects.append(DynamicRoleModelNode::create(subObject, subModel)); - ++subIt; - } - - QObject *subModelObject = subModel; - value = QVariant::fromValue(subModelObject); - } - - const QByteArray &keyUtf8 = key.toUtf8(); - - QQuickListModel *existingModel = qobject_cast<QQuickListModel *>(m_meta->value(keyUtf8).value<QObject *>()); - if (existingModel) - delete existingModel; - - if (m_meta->setValue(keyUtf8, value)) - roles << roleIndex; - - ++it; - } -} - -DynamicRoleModelNodeMetaObject::DynamicRoleModelNodeMetaObject(DynamicRoleModelNode *object) - : QQmlOpenMetaObject(object), m_enabled(false), m_owner(object) -{ -} - -DynamicRoleModelNodeMetaObject::~DynamicRoleModelNodeMetaObject() -{ - for (int i=0 ; i < count() ; ++i) { - QQuickListModel *subModel = qobject_cast<QQuickListModel *>(value(i).value<QObject *>()); - if (subModel) - delete subModel; - } -} - -void DynamicRoleModelNodeMetaObject::propertyWrite(int index) -{ - if (!m_enabled) - return; - - QVariant v = value(index); - QQuickListModel *model = qobject_cast<QQuickListModel *>(v.value<QObject *>()); - if (model) - delete model; -} - -void DynamicRoleModelNodeMetaObject::propertyWritten(int index) -{ - if (!m_enabled) - return; - - QQuickListModel *parentModel = m_owner->m_owner; - - QVariant v = value(index); - if (v.type() == QVariant::List) { - QQuickListModel *subModel = QQuickListModel::createWithOwner(parentModel); - - QVariantList subArray = v.toList(); - QVariantList::const_iterator subIt = subArray.begin(); - QVariantList::const_iterator subEnd = subArray.end(); - while (subIt != subEnd) { - const QVariantMap &subObject = subIt->toMap(); - subModel->m_modelObjects.append(DynamicRoleModelNode::create(subObject, subModel)); - ++subIt; - } - - QObject *subModelObject = subModel; - v = QVariant::fromValue(subModelObject); - - setValue(index, v); - } - - int elementIndex = parentModel->m_modelObjects.indexOf(m_owner); - int roleIndex = parentModel->m_roles.indexOf(QString::fromLatin1(name(index).constData())); - - if (elementIndex != -1 && roleIndex != -1) { - - QVector<int> roles; - roles << roleIndex; - - parentModel->emitItemsChanged(elementIndex, 1, roles); - } -} - -QQuickListModelParser::ListInstruction *QQuickListModelParser::ListModelData::instructions() const -{ - return (QQuickListModelParser::ListInstruction *)((char *)this + sizeof(ListModelData)); -} - -/*! - \qmltype ListModel - \instantiates QQuickListModel - \inqmlmodule QtQuick 2 - \brief Defines a free-form list data source - \ingroup qtquick-models - - The ListModel is a simple container of ListElement definitions, each containing data roles. - The contents can be defined dynamically, or explicitly in QML. - - The number of elements in the model can be obtained from its \l count property. - A number of familiar methods are also provided to manipulate the contents of the - model, including append(), insert(), move(), remove() and set(). These methods - accept dictionaries as their arguments; these are translated to ListElement objects - by the model. - - Elements can be manipulated via the model using the setProperty() method, which - allows the roles of the specified element to be set and changed. - - \section1 Example Usage - - The following example shows a ListModel containing three elements, with the roles - "name" and "cost". - - \div {class="float-right"} - \inlineimage listmodel.png - \enddiv - - \snippet qml/listmodel/listmodel.qml 0 - - Roles (properties) in each element must begin with a lower-case letter and - should be common to all elements in a model. The ListElement documentation - provides more guidelines for how elements should be defined. - - Since the example model contains an \c id property, it can be referenced - by views, such as the ListView in this example: - - \snippet qml/listmodel/listmodel-simple.qml 0 - \dots 8 - \snippet qml/listmodel/listmodel-simple.qml 1 - - It is possible for roles to contain list data. In the following example we - create a list of fruit attributes: - - \snippet qml/listmodel/listmodel-nested.qml model - - The delegate displays all the fruit attributes: - - \div {class="float-right"} - \inlineimage listmodel-nested.png - \enddiv - - \snippet qml/listmodel/listmodel-nested.qml delegate - - \section1 Modifying List Models - - The content of a ListModel may be created and modified using the clear(), - append(), set(), insert() and setProperty() methods. For example: - - \snippet qml/listmodel/listmodel-modify.qml delegate - - Note that when creating content dynamically the set of available properties - cannot be changed once set. Whatever properties are first added to the model - are the only permitted properties in the model. - - \section1 Using Threaded List Models with WorkerScript - - ListModel can be used together with WorkerScript access a list model - from multiple threads. This is useful if list modifications are - synchronous and take some time: the list operations can be moved to a - different thread to avoid blocking of the main GUI thread. - - Here is an example that uses WorkerScript to periodically append the - current time to a list model: - - \snippet quick/threading/threadedlistmodel/timedisplay.qml 0 - - The included file, \tt dataloader.js, looks like this: - - \snippet quick/threading/threadedlistmodel/dataloader.js 0 - - The timer in the main example sends messages to the worker script by calling - \l WorkerScript::sendMessage(). When this message is received, - \l{WorkerScript::onMessage}{WorkerScript.onMessage()} is invoked in \c dataloader.js, - which appends the current time to the list model. - - Note the call to sync() from the \l{WorkerScript::onMessage}{WorkerScript.onMessage()} - handler. You must call sync() or else the changes made to the list from the external - thread will not be reflected in the list model in the main thread. - - \sa {qml-data-models}{Data Models}, {declarative/threading/threadedlistmodel}{Threaded ListModel example}, QtQml -*/ - -QQuickListModel::QQuickListModel(QObject *parent) -: QAbstractListModel(parent) -{ - m_mainThread = true; - m_primary = true; - m_agent = 0; - m_uid = uidCounter.fetchAndAddOrdered(1); - m_dynamicRoles = false; - - m_layout = new ListLayout; - m_listModel = new ListModel(m_layout, this, -1); - - m_engine = 0; -} - -QQuickListModel::QQuickListModel(const QQuickListModel *owner, ListModel *data, QV8Engine *eng, QObject *parent) -: QAbstractListModel(parent) -{ - m_mainThread = owner->m_mainThread; - m_primary = false; - m_agent = owner->m_agent; - - Q_ASSERT(owner->m_dynamicRoles == false); - m_dynamicRoles = false; - m_layout = 0; - m_listModel = data; - - m_engine = eng; -} - -QQuickListModel::QQuickListModel(QQuickListModel *orig, QQuickListModelWorkerAgent *agent) -: QAbstractListModel(agent) -{ - m_mainThread = false; - m_primary = true; - m_agent = agent; - m_dynamicRoles = orig->m_dynamicRoles; - - m_layout = new ListLayout(orig->m_layout); - m_listModel = new ListModel(m_layout, this, orig->m_listModel->getUid()); - - if (m_dynamicRoles) - sync(orig, this, 0); - else - ListModel::sync(orig->m_listModel, m_listModel, 0); - - m_engine = 0; -} - -QQuickListModel::~QQuickListModel() -{ - for (int i=0 ; i < m_modelObjects.count() ; ++i) - delete m_modelObjects[i]; - - if (m_primary) { - m_listModel->destroy(); - delete m_listModel; - - if (m_mainThread && m_agent) { - m_agent->modelDestroyed(); - m_agent->release(); - } - } - - m_listModel = 0; - - delete m_layout; - m_layout = 0; -} - -QQuickListModel *QQuickListModel::createWithOwner(QQuickListModel *newOwner) -{ - QQuickListModel *model = new QQuickListModel; - - model->m_mainThread = newOwner->m_mainThread; - model->m_engine = newOwner->m_engine; - model->m_agent = newOwner->m_agent; - model->m_dynamicRoles = newOwner->m_dynamicRoles; - - if (model->m_mainThread && model->m_agent) - model->m_agent->addref(); - - QQmlEngine::setContextForObject(model, QQmlEngine::contextForObject(newOwner)); - - return model; -} - -QV8Engine *QQuickListModel::engine() const -{ - if (m_engine == 0) { - m_engine = QQmlEnginePrivate::getV8Engine(qmlEngine(this)); - } - - return m_engine; -} - -void QQuickListModel::sync(QQuickListModel *src, QQuickListModel *target, QHash<int, QQuickListModel *> *targetModelHash) -{ - Q_ASSERT(src->m_dynamicRoles && target->m_dynamicRoles); - - target->m_uid = src->m_uid; - if (targetModelHash) - targetModelHash->insert(target->m_uid, target); - target->m_roles = src->m_roles; - - // Build hash of elements <-> uid for each of the lists - QHash<int, ElementSync> elementHash; - for (int i=0 ; i < target->m_modelObjects.count() ; ++i) { - DynamicRoleModelNode *e = target->m_modelObjects.at(i); - int uid = e->getUid(); - ElementSync sync; - sync.target = e; - elementHash.insert(uid, sync); - } - for (int i=0 ; i < src->m_modelObjects.count() ; ++i) { - DynamicRoleModelNode *e = src->m_modelObjects.at(i); - int uid = e->getUid(); - - QHash<int, ElementSync>::iterator it = elementHash.find(uid); - if (it == elementHash.end()) { - ElementSync sync; - sync.src = e; - elementHash.insert(uid, sync); - } else { - ElementSync &sync = it.value(); - sync.src = e; - } - } - - // Get list of elements that are in the target but no longer in the source. These get deleted first. - QHash<int, ElementSync>::iterator it = elementHash.begin(); - QHash<int, ElementSync>::iterator end = elementHash.end(); - while (it != end) { - const ElementSync &s = it.value(); - if (s.src == 0) { - int targetIndex = target->m_modelObjects.indexOf(s.target); - target->m_modelObjects.remove(targetIndex, 1); - delete s.target; - } - ++it; - } - - // Clear the target list, and append in correct order from the source - target->m_modelObjects.clear(); - for (int i=0 ; i < src->m_modelObjects.count() ; ++i) { - DynamicRoleModelNode *srcElement = src->m_modelObjects.at(i); - it = elementHash.find(srcElement->getUid()); - const ElementSync &s = it.value(); - DynamicRoleModelNode *targetElement = s.target; - if (targetElement == 0) { - targetElement = new DynamicRoleModelNode(target, srcElement->getUid()); - } - DynamicRoleModelNode::sync(srcElement, targetElement, targetModelHash); - target->m_modelObjects.append(targetElement); - } -} - -void QQuickListModel::emitItemsChanged(int index, int count, const QVector<int> &roles) -{ - if (count <= 0) - return; - - if (m_mainThread) { - emit dataChanged(createIndex(index, 0), createIndex(index + count - 1, 0), roles);; - } else { - int uid = m_dynamicRoles ? getUid() : m_listModel->getUid(); - m_agent->data.changedChange(uid, index, count, roles); - } -} - -void QQuickListModel::emitItemsRemoved(int index, int count) -{ - if (count <= 0) - return; - - if (m_mainThread) { - beginRemoveRows(QModelIndex(), index, index + count - 1); - endRemoveRows(); - emit countChanged(); - } else { - int uid = m_dynamicRoles ? getUid() : m_listModel->getUid(); - if (index == 0 && count == this->count()) - m_agent->data.clearChange(uid); - m_agent->data.removeChange(uid, index, count); - } -} - -void QQuickListModel::emitItemsInserted(int index, int count) -{ - if (count <= 0) - return; - - if (m_mainThread) { - beginInsertRows(QModelIndex(), index, index + count - 1); - endInsertRows(); - emit countChanged(); - } else { - int uid = m_dynamicRoles ? getUid() : m_listModel->getUid(); - m_agent->data.insertChange(uid, index, count); - } -} - -void QQuickListModel::emitItemsMoved(int from, int to, int n) -{ - if (n <= 0) - return; - - if (m_mainThread) { - beginMoveRows(QModelIndex(), from, from + n - 1, QModelIndex(), to > from ? to + n : to); - endMoveRows(); - } else { - int uid = m_dynamicRoles ? getUid() : m_listModel->getUid(); - m_agent->data.moveChange(uid, from, n, to); - } -} - -QQuickListModelWorkerAgent *QQuickListModel::agent() -{ - if (m_agent) - return m_agent; - - m_agent = new QQuickListModelWorkerAgent(this); - return m_agent; -} - -QModelIndex QQuickListModel::index(int row, int column, const QModelIndex &parent) const -{ - return row >= 0 && row < count() && column == 0 && !parent.isValid() - ? createIndex(row, column) - : QModelIndex(); -} - -int QQuickListModel::rowCount(const QModelIndex &parent) const -{ - return !parent.isValid() ? count() : 0; -} - -QVariant QQuickListModel::data(const QModelIndex &index, int role) const -{ - return data(index.row(), role); -} - -QVariant QQuickListModel::data(int index, int role) const -{ - QVariant v; - - if (index >= count() || index < 0) - return v; - - if (m_dynamicRoles) - v = m_modelObjects[index]->getValue(m_roles[role]); - else - v = m_listModel->getProperty(index, role, this, engine()); - - return v; -} - -QHash<int, QByteArray> QQuickListModel::roleNames() const -{ - QHash<int, QByteArray> roleNames; - - if (m_dynamicRoles) { - for (int i = 0 ; i < m_roles.count() ; ++i) - roleNames.insert(i, m_roles.at(i).toUtf8()); - } else { - for (int i = 0 ; i < m_listModel->roleCount() ; ++i) { - const ListLayout::Role &r = m_listModel->getExistingRole(i); - roleNames.insert(i, r.name.toUtf8()); - } - } - - return roleNames; -} - -/*! - \qmlproperty bool QtQuick2::ListModel::dynamicRoles - - By default, the type of a role is fixed the first time - the role is used. For example, if you create a role called - "data" and assign a number to it, you can no longer assign - a string to the "data" role. However, when the dynamicRoles - property is enabled, the type of a given role is not fixed - and can be different between elements. - - The dynamicRoles property must be set before any data is - added to the ListModel, and must be set from the main - thread. - - A ListModel that has data statically defined (via the - ListElement QML syntax) cannot have the dynamicRoles - property enabled. - - There is a significant performance cost to using a - ListModel with dynamic roles enabled. The cost varies - from platform to platform but is typically somewhere - between 4-6x slower than using static role types. - - Due to the performance cost of using dynamic roles, - they are disabled by default. -*/ -void QQuickListModel::setDynamicRoles(bool enableDynamicRoles) -{ - if (m_mainThread && m_agent == 0) { - if (enableDynamicRoles) { - if (m_layout->roleCount()) - qmlInfo(this) << tr("unable to enable dynamic roles as this model is not empty!"); - else - m_dynamicRoles = true; - } else { - if (m_roles.count()) { - qmlInfo(this) << tr("unable to enable static roles as this model is not empty!"); - } else { - m_dynamicRoles = false; - } - } - } else { - qmlInfo(this) << tr("dynamic role setting must be made from the main thread, before any worker scripts are created"); - } -} - -/*! - \qmlproperty int QtQuick2::ListModel::count - The number of data entries in the model. -*/ -int QQuickListModel::count() const -{ - int count; - - if (m_dynamicRoles) - count = m_modelObjects.count(); - else { - count = m_listModel->elementCount(); - } - - return count; -} - -/*! - \qmlmethod QtQuick2::ListModel::clear() - - Deletes all content from the model. - - \sa append(), remove() -*/ -void QQuickListModel::clear() -{ - int cleared = count(); - - if (m_dynamicRoles) { - for (int i=0 ; i < m_modelObjects.count() ; ++i) - delete m_modelObjects[i]; - m_modelObjects.clear(); - } else { - m_listModel->clear(); - } - - emitItemsRemoved(0, cleared); -} - -/*! - \qmlmethod QtQuick2::ListModel::remove(int index, int count = 1) - - Deletes the content at \a index from the model. - - \sa clear() -*/ -void QQuickListModel::remove(QQmlV8Function *args) -{ - int argLength = args->Length(); - - if (argLength == 1 || argLength == 2) { - int index = (*args)[0]->Int32Value(); - int removeCount = (argLength == 2 ? ((*args)[1]->Int32Value()) : 1); - - if (index < 0 || index+removeCount > count() || removeCount <= 0) { - qmlInfo(this) << tr("remove: indices [%1 - %2] out of range [0 - %3]").arg(index).arg(index+removeCount).arg(count()); - return; - } - - if (m_dynamicRoles) { - for (int i=0 ; i < removeCount ; ++i) - delete m_modelObjects[index+i]; - m_modelObjects.remove(index, removeCount); - } else { - m_listModel->remove(index, removeCount); - } - - emitItemsRemoved(index, removeCount); - } else { - qmlInfo(this) << tr("remove: incorrect number of arguments"); - } -} - -/*! - \qmlmethod QtQuick2::ListModel::insert(int index, jsobject dict) - - Adds a new item to the list model at position \a index, with the - values in \a dict. - - \code - fruitModel.insert(2, {"cost": 5.95, "name":"Pizza"}) - \endcode - - The \a index must be to an existing item in the list, or one past - the end of the list (equivalent to append). - - \sa set(), append() -*/ - -void QQuickListModel::insert(QQmlV8Function *args) -{ - if (args->Length() == 2) { - - v8::Handle<v8::Value> arg0 = (*args)[0]; - int index = arg0->Int32Value(); - - if (index < 0 || index > count()) { - qmlInfo(this) << tr("insert: index %1 out of range").arg(index); - return; - } - - v8::Handle<v8::Value> arg1 = (*args)[1]; - - if (arg1->IsArray()) { - v8::Handle<v8::Array> objectArray = v8::Handle<v8::Array>::Cast(arg1); - int objectArrayLength = objectArray->Length(); - for (int i=0 ; i < objectArrayLength ; ++i) { - v8::Handle<v8::Object> argObject = objectArray->Get(i)->ToObject(); - - if (m_dynamicRoles) { - m_modelObjects.insert(index+i, DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this)); - } else { - m_listModel->insert(index+i, argObject, args->engine()); - } - } - emitItemsInserted(index, objectArrayLength); - } else if (arg1->IsObject()) { - v8::Handle<v8::Object> argObject = arg1->ToObject(); - - if (m_dynamicRoles) { - m_modelObjects.insert(index, DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this)); - } else { - m_listModel->insert(index, argObject, args->engine()); - } - - emitItemsInserted(index, 1); - } else { - qmlInfo(this) << tr("insert: value is not an object"); - } - } else { - qmlInfo(this) << tr("insert: value is not an object"); - } -} - -/*! - \qmlmethod QtQuick2::ListModel::move(int from, int to, int n) - - Moves \a n items \a from one position \a to another. - - The from and to ranges must exist; for example, to move the first 3 items - to the end of the list: - - \code - fruitModel.move(0, fruitModel.count - 3, 3) - \endcode - - \sa append() -*/ -void QQuickListModel::move(int from, int to, int n) -{ - if (n==0 || from==to) - return; - if (!canMove(from, to, n)) { - qmlInfo(this) << tr("move: out of range"); - return; - } - - if (m_dynamicRoles) { - - int realFrom = from; - int realTo = to; - int realN = n; - - if (from > to) { - // Only move forwards - flip if backwards moving - int tfrom = from; - int tto = to; - realFrom = tto; - realTo = tto+n; - realN = tfrom-tto; - } - - QPODVector<DynamicRoleModelNode *, 4> store; - for (int i=0 ; i < (realTo-realFrom) ; ++i) - store.append(m_modelObjects[realFrom+realN+i]); - for (int i=0 ; i < realN ; ++i) - store.append(m_modelObjects[realFrom+i]); - for (int i=0 ; i < store.count() ; ++i) - m_modelObjects[realFrom+i] = store[i]; - - } else { - m_listModel->move(from, to, n); - } - - emitItemsMoved(from, to, n); -} - -/*! - \qmlmethod QtQuick2::ListModel::append(jsobject dict) - - Adds a new item to the end of the list model, with the - values in \a dict. - - \code - fruitModel.append({"cost": 5.95, "name":"Pizza"}) - \endcode - - \sa set(), remove() -*/ -void QQuickListModel::append(QQmlV8Function *args) -{ - if (args->Length() == 1) { - v8::Handle<v8::Value> arg = (*args)[0]; - - if (arg->IsArray()) { - v8::Handle<v8::Array> objectArray = v8::Handle<v8::Array>::Cast(arg); - int objectArrayLength = objectArray->Length(); - - int index = count(); - for (int i=0 ; i < objectArrayLength ; ++i) { - v8::Handle<v8::Object> argObject = objectArray->Get(i)->ToObject(); - - if (m_dynamicRoles) { - m_modelObjects.append(DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this)); - } else { - m_listModel->append(argObject, args->engine()); - } - } - - emitItemsInserted(index, objectArrayLength); - } else if (arg->IsObject()) { - v8::Handle<v8::Object> argObject = arg->ToObject(); - - int index; - - if (m_dynamicRoles) { - index = m_modelObjects.count(); - m_modelObjects.append(DynamicRoleModelNode::create(args->engine()->variantMapFromJS(argObject), this)); - } else { - index = m_listModel->append(argObject, args->engine()); - } - - emitItemsInserted(index, 1); - } else { - qmlInfo(this) << tr("append: value is not an object"); - } - } else { - qmlInfo(this) << tr("append: value is not an object"); - } -} - -/*! - \qmlmethod object QtQuick2::ListModel::get(int index) - - Returns the item at \a index in the list model. This allows the item - data to be accessed or modified from JavaScript: - - \code - Component.onCompleted: { - fruitModel.append({"cost": 5.95, "name":"Jackfruit"}); - console.log(fruitModel.get(0).cost); - fruitModel.get(0).cost = 10.95; - } - \endcode - - The \a index must be an element in the list. - - Note that properties of the returned object that are themselves objects - will also be models, and this get() method is used to access elements: - - \code - fruitModel.append(..., "attributes": - [{"name":"spikes","value":"7mm"}, - {"name":"color","value":"green"}]); - fruitModel.get(0).attributes.get(1).value; // == "green" - \endcode - - \warning The returned object is not guaranteed to remain valid. It - should not be used in \l{Property Binding}{property bindings}. - - \sa append() -*/ -QQmlV8Handle QQuickListModel::get(int index) const -{ - v8::Handle<v8::Value> result = v8::Undefined(); - - if (index >= 0 && index < count()) { - QV8Engine *v8engine = engine(); - - if (m_dynamicRoles) { - DynamicRoleModelNode *object = m_modelObjects[index]; - result = v8engine->newQObject(object); - } else { - ModelObject *object = m_listModel->getOrCreateModelObject(const_cast<QQuickListModel *>(this), index); - result = v8engine->newQObject(object); - } - } - - return QQmlV8Handle::fromHandle(result); -} - -/*! - \qmlmethod QtQuick2::ListModel::set(int index, jsobject dict) - - Changes the item at \a index in the list model with the - values in \a dict. Properties not appearing in \a dict - are left unchanged. - - \code - fruitModel.set(3, {"cost": 5.95, "name":"Pizza"}) - \endcode - - If \a index is equal to count() then a new item is appended to the - list. Otherwise, \a index must be an element in the list. - - \sa append() -*/ -void QQuickListModel::set(int index, const QQmlV8Handle &handle) -{ - v8::Handle<v8::Value> valuemap = handle.toHandle(); - - if (!valuemap->IsObject() || valuemap->IsArray()) { - qmlInfo(this) << tr("set: value is not an object"); - return; - } - if (index > count() || index < 0) { - qmlInfo(this) << tr("set: index %1 out of range").arg(index); - return; - } - - v8::Handle<v8::Object> object = valuemap->ToObject(); - - if (index == count()) { - - if (m_dynamicRoles) { - m_modelObjects.append(DynamicRoleModelNode::create(engine()->variantMapFromJS(object), this)); - } else { - m_listModel->insert(index, object, engine()); - } - - emitItemsInserted(index, 1); - } else { - - QVector<int> roles; - - if (m_dynamicRoles) { - m_modelObjects[index]->updateValues(engine()->variantMapFromJS(object), roles); - } else { - m_listModel->set(index, object, &roles, engine()); - } - - if (roles.count()) - emitItemsChanged(index, 1, roles); - } -} - -/*! - \qmlmethod QtQuick2::ListModel::setProperty(int index, string property, variant value) - - Changes the \a property of the item at \a index in the list model to \a value. - - \code - fruitModel.setProperty(3, "cost", 5.95) - \endcode - - The \a index must be an element in the list. - - \sa append() -*/ -void QQuickListModel::setProperty(int index, const QString& property, const QVariant& value) -{ - if (count() == 0 || index >= count() || index < 0) { - qmlInfo(this) << tr("set: index %1 out of range").arg(index); - return; - } - - if (m_dynamicRoles) { - int roleIndex = m_roles.indexOf(property); - if (roleIndex == -1) { - roleIndex = m_roles.count(); - m_roles.append(property); - } - if (m_modelObjects[index]->setValue(property.toUtf8(), value)) { - QVector<int> roles; - roles << roleIndex; - emitItemsChanged(index, 1, roles); - } - } else { - int roleIndex = m_listModel->setOrCreateProperty(index, property, value); - if (roleIndex != -1) { - - QVector<int> roles; - roles << roleIndex; - - emitItemsChanged(index, 1, roles); - } - } -} - -/*! - \qmlmethod QtQuick2::ListModel::sync() - - Writes any unsaved changes to the list model after it has been modified - from a worker script. -*/ -void QQuickListModel::sync() -{ - // This is just a dummy method to make it look like sync() exists in - // ListModel (and not just QQuickListModelWorkerAgent) and to let - // us document sync(). - qmlInfo(this) << "List sync() can only be called from a WorkerScript"; -} - -bool QQuickListModelParser::compileProperty(const QQmlCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data) -{ - QList<QVariant> values = prop.assignedValues(); - for(int ii = 0; ii < values.count(); ++ii) { - const QVariant &value = values.at(ii); - - if(value.userType() == qMetaTypeId<QQmlCustomParserNode>()) { - QQmlCustomParserNode node = - qvariant_cast<QQmlCustomParserNode>(value); - - if (node.name() != listElementTypeName) { - const QMetaObject *mo = resolveType(node.name()); - if (mo != &QQuickListElement::staticMetaObject) { - error(node, QQuickListModel::tr("ListElement: cannot contain nested elements")); - return false; - } - listElementTypeName = node.name(); // cache right name for next time - } - - { - ListInstruction li; - li.type = ListInstruction::Push; - li.dataIdx = -1; - instr << li; - } - - QList<QQmlCustomParserProperty> props = node.properties(); - for(int jj = 0; jj < props.count(); ++jj) { - const QQmlCustomParserProperty &nodeProp = props.at(jj); - if (nodeProp.name().isEmpty()) { - error(nodeProp, QQuickListModel::tr("ListElement: cannot contain nested elements")); - return false; - } - if (nodeProp.name() == QStringLiteral("id")) { - error(nodeProp, QQuickListModel::tr("ListElement: cannot use reserved \"id\" property")); - return false; - } - - ListInstruction li; - int ref = data.count(); - data.append(nodeProp.name().toUtf8()); - data.append('\0'); - li.type = ListInstruction::Set; - li.dataIdx = ref; - instr << li; - - if(!compileProperty(nodeProp, instr, data)) - return false; - - li.type = ListInstruction::Pop; - li.dataIdx = -1; - instr << li; - } - - { - ListInstruction li; - li.type = ListInstruction::Pop; - li.dataIdx = -1; - instr << li; - } - - } else { - - QQmlScript::Variant variant = - qvariant_cast<QQmlScript::Variant>(value); - - int ref = data.count(); - - QByteArray d; - d += char(variant.type()); // type tag - if (variant.isString()) { - d += variant.asString().toUtf8(); - } else if (variant.isNumber()) { - d += QByteArray::number(variant.asNumber(),'g',20); - } else if (variant.isBoolean()) { - d += char(variant.asBoolean()); - } else if (variant.isScript()) { - if (definesEmptyList(variant.asScript())) { - d[0] = char(QQmlScript::Variant::Invalid); // marks empty list - } else { - QByteArray script = variant.asScript().toUtf8(); - bool ok; - int v = evaluateEnum(script, &ok); - if (!ok) { - using namespace QQmlJS; - AST::Node *node = variant.asAST(); - AST::StringLiteral *literal = 0; - if (AST::CallExpression *callExpr = AST::cast<AST::CallExpression *>(node)) { - if (AST::IdentifierExpression *idExpr = AST::cast<AST::IdentifierExpression *>(callExpr->base)) { - if (idExpr->name == QLatin1String("QT_TR_NOOP") || idExpr->name == QLatin1String("QT_TRID_NOOP")) { - if (callExpr->arguments && !callExpr->arguments->next) - literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->expression); - if (!literal) { - error(prop, QQuickListModel::tr("ListElement: improperly specified %1").arg(idExpr->name.toString())); - return false; - } - } else if (idExpr->name == QLatin1String("QT_TRANSLATE_NOOP")) { - if (callExpr->arguments && callExpr->arguments->next && !callExpr->arguments->next->next) - literal = AST::cast<AST::StringLiteral *>(callExpr->arguments->next->expression); - if (!literal) { - error(prop, QQuickListModel::tr("ListElement: improperly specified QT_TRANSLATE_NOOP")); - return false; - } - } - } - } - - if (literal) { - d[0] = char(QQmlScript::Variant::String); - d += literal->value.toUtf8(); - } else { - error(prop, QQuickListModel::tr("ListElement: cannot use script for property value")); - return false; - } - } else { - d[0] = char(QQmlScript::Variant::Number); - d += QByteArray::number(v); - } - } - } - d.append('\0'); - data.append(d); - - ListInstruction li; - li.type = ListInstruction::Value; - li.dataIdx = ref; - instr << li; - } - } - - return true; -} - -QByteArray QQuickListModelParser::compile(const QList<QQmlCustomParserProperty> &customProps) -{ - QList<ListInstruction> instr; - QByteArray data; - listElementTypeName = QString(); // unknown - - for(int ii = 0; ii < customProps.count(); ++ii) { - const QQmlCustomParserProperty &prop = customProps.at(ii); - if(!prop.name().isEmpty()) { // isn't default property - error(prop, QQuickListModel::tr("ListModel: undefined property '%1'").arg(prop.name())); - return QByteArray(); - } - - if(!compileProperty(prop, instr, data)) { - return QByteArray(); - } - } - - int size = sizeof(ListModelData) + - instr.count() * sizeof(ListInstruction) + - data.count(); - - QByteArray rv; - rv.resize(size); - - ListModelData *lmd = (ListModelData *)rv.data(); - lmd->dataOffset = sizeof(ListModelData) + - instr.count() * sizeof(ListInstruction); - lmd->instrCount = instr.count(); - for (int ii = 0; ii < instr.count(); ++ii) - lmd->instructions()[ii] = instr.at(ii); - ::memcpy(rv.data() + lmd->dataOffset, data.constData(), data.count()); - - return rv; -} - -void QQuickListModelParser::setCustomData(QObject *obj, const QByteArray &d) -{ - QQuickListModel *rv = static_cast<QQuickListModel *>(obj); - - QV8Engine *engine = QQmlEnginePrivate::getV8Engine(qmlEngine(rv)); - rv->m_engine = engine; - - const ListModelData *lmd = (const ListModelData *)d.constData(); - const char *data = ((const char *)lmd) + lmd->dataOffset; - - bool setRoles = false; - - QStack<DataStackElement> stack; - - for (int ii = 0; ii < lmd->instrCount; ++ii) { - const ListInstruction &instr = lmd->instructions()[ii]; - - switch(instr.type) { - case ListInstruction::Push: - { - Q_ASSERT(!rv->m_dynamicRoles); - - ListModel *subModel = 0; - - if (stack.count() == 0) { - subModel = rv->m_listModel; - } else { - const DataStackElement &e0 = stack.at(stack.size() - 1); - DataStackElement &e1 = stack[stack.size() - 2]; - - const ListLayout::Role &role = e1.model->getOrCreateListRole(e0.name); - if (role.type == ListLayout::Role::List) { - subModel = e1.model->getListProperty(e1.elementIndex, role); - - if (subModel == 0) { - subModel = new ListModel(role.subLayout, 0, -1); - QVariant vModel = QVariant::fromValue(subModel); - e1.model->setOrCreateProperty(e1.elementIndex, e0.name, vModel); - } - } - } - - DataStackElement e; - e.model = subModel; - e.elementIndex = subModel ? subModel->appendElement() : -1; - stack.push(e); - } - break; - - case ListInstruction::Pop: - stack.pop(); - break; - - case ListInstruction::Value: - { - const DataStackElement &e0 = stack.at(stack.size() - 1); - DataStackElement &e1 = stack[stack.size() - 2]; - - QString name = e0.name; - QVariant value; - - switch (QQmlScript::Variant::Type(data[instr.dataIdx])) { - case QQmlScript::Variant::Invalid: - { - const ListLayout::Role &role = e1.model->getOrCreateListRole(e0.name); - ListModel *emptyModel = new ListModel(role.subLayout, 0, -1); - value = QVariant::fromValue(emptyModel); - } - break; - case QQmlScript::Variant::Boolean: - value = bool(data[1 + instr.dataIdx]); - break; - case QQmlScript::Variant::Number: - value = QByteArray(data + 1 + instr.dataIdx).toDouble(); - break; - case QQmlScript::Variant::String: - value = QString::fromUtf8(data + 1 + instr.dataIdx); - break; - default: - Q_ASSERT("Format error in ListInstruction"); - } - - e1.model->setOrCreateProperty(e1.elementIndex, name, value); - setRoles = true; - } - break; - - case ListInstruction::Set: - { - DataStackElement e; - e.name = QString::fromUtf8(data + instr.dataIdx); - stack.push(e); - } - break; - } - } - - if (setRoles == false) - qmlInfo(obj) << "All ListElement declarations are empty, no roles can be created unless dynamicRoles is set."; -} - -bool QQuickListModelParser::definesEmptyList(const QString &s) -{ - if (s.startsWith(QLatin1Char('[')) && s.endsWith(QLatin1Char(']'))) { - for (int i=1; i<s.length()-1; i++) { - if (!s[i].isSpace()) - return false; - } - return true; - } - return false; -} - - -/*! - \qmltype ListElement - \instantiates QQuickListElement - \inqmlmodule QtQuick 2 - \brief Defines a data item in a ListModel - \ingroup qtquick-models - - List elements are defined inside ListModel definitions, and represent items in a - list that will be displayed using ListView or \l Repeater items. - - List elements are defined like other QML elements except that they contain - a collection of \e role definitions instead of properties. Using the same - syntax as property definitions, roles both define how the data is accessed - and include the data itself. - - The names used for roles must begin with a lower-case letter and should be - common to all elements in a given model. Values must be simple constants; either - strings (quoted and optionally within a call to QT_TR_NOOP), boolean values - (true, false), numbers, or enumeration values (such as AlignText.AlignHCenter). - - \section1 Referencing Roles - - The role names are used by delegates to obtain data from list elements. - Each role name is accessible in the delegate's scope, and refers to the - corresponding role in the current element. Where a role name would be - ambiguous to use, it can be accessed via the \l{ListView::}{model} - property (e.g., \c{model.cost} instead of \c{cost}). - - \section1 Example Usage - - The following model defines a series of list elements, each of which - contain "name" and "cost" roles and their associated values. - - \snippet qml/listmodel/listelements.qml model - - The delegate obtains the name and cost for each element by simply referring - to \c name and \c cost: - - \snippet qml/listmodel/listelements.qml view - - \sa ListModel -*/ - -QT_END_NAMESPACE diff --git a/src/qml/qml/qquicklistmodel_p.h b/src/qml/qml/qquicklistmodel_p.h deleted file mode 100644 index 8649238b80..0000000000 --- a/src/qml/qml/qquicklistmodel_p.h +++ /dev/null @@ -1,202 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKLISTMODEL_H -#define QQUICKLISTMODEL_H - -#include <qqml.h> -#include <private/qqmlcustomparser_p.h> - -#include <QtCore/QObject> -#include <QtCore/QStringList> -#include <QtCore/QHash> -#include <QtCore/QList> -#include <QtCore/QVariant> -#include <QtCore/qabstractitemmodel.h> - -#include <private/qv8engine_p.h> -#include <private/qpodvector_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QQuickListModelWorkerAgent; -class ListModel; -class ListLayout; - -class Q_QML_PRIVATE_EXPORT QQuickListModel : public QAbstractListModel -{ - Q_OBJECT - Q_PROPERTY(int count READ count NOTIFY countChanged) - Q_PROPERTY(bool dynamicRoles READ dynamicRoles WRITE setDynamicRoles) - -public: - QQuickListModel(QObject *parent=0); - ~QQuickListModel(); - - QModelIndex index(int row, int column, const QModelIndex &parent) const; - int rowCount(const QModelIndex &parent) const; - QVariant data(const QModelIndex &index, int role) const; - QHash<int,QByteArray> roleNames() const; - - QVariant data(int index, int role) const; - int count() const; - - Q_INVOKABLE void clear(); - Q_INVOKABLE void remove(QQmlV8Function *args); - Q_INVOKABLE void append(QQmlV8Function *args); - Q_INVOKABLE void insert(QQmlV8Function *args); - Q_INVOKABLE QQmlV8Handle get(int index) const; - Q_INVOKABLE void set(int index, const QQmlV8Handle &); - Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value); - Q_INVOKABLE void move(int from, int to, int count); - Q_INVOKABLE void sync(); - - QQuickListModelWorkerAgent *agent(); - - bool dynamicRoles() const { return m_dynamicRoles; } - void setDynamicRoles(bool enableDynamicRoles); - -Q_SIGNALS: - void countChanged(); - -private: - friend class QQuickListModelParser; - friend class QQuickListModelWorkerAgent; - friend class ModelObject; - friend class ModelNodeMetaObject; - friend class ListModel; - friend class ListElement; - friend class DynamicRoleModelNode; - friend class DynamicRoleModelNodeMetaObject; - - // Constructs a flat list model for a worker agent - QQuickListModel(QQuickListModel *orig, QQuickListModelWorkerAgent *agent); - QQuickListModel(const QQuickListModel *owner, ListModel *data, QV8Engine *eng, QObject *parent=0); - - QV8Engine *engine() const; - - inline bool canMove(int from, int to, int n) const { return !(from+n > count() || to+n > count() || from < 0 || to < 0 || n < 0); } - - QQuickListModelWorkerAgent *m_agent; - mutable QV8Engine *m_engine; - bool m_mainThread; - bool m_primary; - - bool m_dynamicRoles; - - ListLayout *m_layout; - ListModel *m_listModel; - - QVector<class DynamicRoleModelNode *> m_modelObjects; - QVector<QString> m_roles; - int m_uid; - - struct ElementSync - { - ElementSync() : src(0), target(0) {} - - DynamicRoleModelNode *src; - DynamicRoleModelNode *target; - }; - - int getUid() const { return m_uid; } - - static void sync(QQuickListModel *src, QQuickListModel *target, QHash<int, QQuickListModel *> *targetModelHash); - static QQuickListModel *createWithOwner(QQuickListModel *newOwner); - - void emitItemsChanged(int index, int count, const QVector<int> &roles); - void emitItemsRemoved(int index, int count); - void emitItemsInserted(int index, int count); - void emitItemsMoved(int from, int to, int n); -}; - -// ### FIXME -class QQuickListElement : public QObject -{ -Q_OBJECT -}; - -class QQuickListModelParser : public QQmlCustomParser -{ -public: - QQuickListModelParser() : QQmlCustomParser(QQmlCustomParser::AcceptsSignalHandlers) {} - QByteArray compile(const QList<QQmlCustomParserProperty> &); - void setCustomData(QObject *, const QByteArray &); - -private: - struct ListInstruction - { - enum { Push, Pop, Value, Set } type; - int dataIdx; - }; - struct ListModelData - { - int dataOffset; - int instrCount; - ListInstruction *instructions() const; - }; - bool compileProperty(const QQmlCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data); - - bool definesEmptyList(const QString &); - - QString listElementTypeName; - - struct DataStackElement - { - DataStackElement() : model(0), elementIndex(0) {} - - QString name; - ListModel *model; - int elementIndex; - }; -}; - -QT_END_NAMESPACE - -QML_DECLARE_TYPE(QQuickListModel) -QML_DECLARE_TYPE(QQuickListElement) - -QT_END_HEADER - -#endif // QQUICKLISTMODEL_H diff --git a/src/qml/qml/qquicklistmodel_p_p.h b/src/qml/qml/qquicklistmodel_p_p.h deleted file mode 100644 index ff312f98e5..0000000000 --- a/src/qml/qml/qquicklistmodel_p_p.h +++ /dev/null @@ -1,382 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKLISTMODEL_P_P_H -#define QQUICKLISTMODEL_P_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "qquicklistmodel_p.h" -#include <private/qqmlengine_p.h> -#include "qqmlopenmetaobject_p.h" -#include <qqml.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class DynamicRoleModelNode; - -class DynamicRoleModelNodeMetaObject : public QQmlOpenMetaObject -{ -public: - DynamicRoleModelNodeMetaObject(DynamicRoleModelNode *object); - ~DynamicRoleModelNodeMetaObject(); - - bool m_enabled; - -protected: - void propertyWrite(int index); - void propertyWritten(int index); - -private: - DynamicRoleModelNode *m_owner; -}; - -class DynamicRoleModelNode : public QObject -{ - Q_OBJECT -public: - DynamicRoleModelNode(QQuickListModel *owner, int uid); - - static DynamicRoleModelNode *create(const QVariantMap &obj, QQuickListModel *owner); - - void updateValues(const QVariantMap &object, QVector<int> &roles); - - QVariant getValue(const QString &name) - { - return m_meta->value(name.toUtf8()); - } - - bool setValue(const QByteArray &name, const QVariant &val) - { - return m_meta->setValue(name, val); - } - - void setNodeUpdatesEnabled(bool enable) - { - m_meta->m_enabled = enable; - } - - int getUid() const - { - return m_uid; - } - - static void sync(DynamicRoleModelNode *src, DynamicRoleModelNode *target, QHash<int, QQuickListModel *> *targetModelHash); - -private: - QQuickListModel *m_owner; - int m_uid; - DynamicRoleModelNodeMetaObject *m_meta; - - friend class DynamicRoleModelNodeMetaObject; -}; - -class ModelObject; - -class ModelNodeMetaObject : public QQmlOpenMetaObject -{ -public: - ModelNodeMetaObject(ModelObject *object); - ~ModelNodeMetaObject(); - - bool m_enabled; - -protected: - void propertyWritten(int index); - -private: - - ModelObject *m_obj; -}; - -class ModelObject : public QObject -{ - Q_OBJECT -public: - ModelObject(QQuickListModel *model, int elementIndex); - - void setValue(const QByteArray &name, const QVariant &val, bool force) - { - if (force) { - QVariant existingValue = m_meta->value(name); - if (existingValue.isValid()) { - (*m_meta)[name] = QVariant(); - } - } - m_meta->setValue(name, val); - } - - void setNodeUpdatesEnabled(bool enable) - { - m_meta->m_enabled = enable; - } - - void updateValues(); - void updateValues(const QVector<int> &roles); - - QQuickListModel *m_model; - int m_elementIndex; - -private: - ModelNodeMetaObject *m_meta; -}; - -class ListLayout -{ -public: - ListLayout() : currentBlock(0), currentBlockOffset(0) {} - ListLayout(const ListLayout *other); - ~ListLayout(); - - class Role - { - public: - - Role() : type(Invalid), blockIndex(-1), blockOffset(-1), index(-1), subLayout(0) {} - explicit Role(const Role *other); - ~Role(); - - // This enum must be kept in sync with the roleTypeNames variable in qdeclarativelistmodel.cpp - enum DataType - { - Invalid = -1, - - String, - Number, - Bool, - List, - QObject, - VariantMap, - DateTime, - - MaxDataType - }; - - QString name; - DataType type; - int blockIndex; - int blockOffset; - int index; - ListLayout *subLayout; - }; - - const Role *getRoleOrCreate(const QString &key, const QVariant &data); - const Role &getRoleOrCreate(v8::Handle<v8::String> key, Role::DataType type); - const Role &getRoleOrCreate(const QString &key, Role::DataType type); - - const Role &getExistingRole(int index) { return *roles.at(index); } - const Role *getExistingRole(const QString &key); - const Role *getExistingRole(v8::Handle<v8::String> key); - - int roleCount() const { return roles.count(); } - - static void sync(ListLayout *src, ListLayout *target); - -private: - const Role &createRole(const QString &key, Role::DataType type); - - int currentBlock; - int currentBlockOffset; - QVector<Role *> roles; - QStringHash<Role *> roleHash; -}; - -class ListElement -{ -public: - - ListElement(); - ListElement(int existingUid); - ~ListElement(); - - static void sync(ListElement *src, ListLayout *srcLayout, ListElement *target, ListLayout *targetLayout, QHash<int, ListModel *> *targetModelHash); - - enum - { - BLOCK_SIZE = 64 - sizeof(int) - sizeof(ListElement *) - sizeof(ModelObject *) - }; - -private: - - void destroy(ListLayout *layout); - - int setVariantProperty(const ListLayout::Role &role, const QVariant &d); - - int setJsProperty(const ListLayout::Role &role, v8::Handle<v8::Value> d, QV8Engine *eng); - - int setStringProperty(const ListLayout::Role &role, const QString &s); - int setDoubleProperty(const ListLayout::Role &role, double n); - int setBoolProperty(const ListLayout::Role &role, bool b); - int setListProperty(const ListLayout::Role &role, ListModel *m); - int setQObjectProperty(const ListLayout::Role &role, QObject *o); - int setVariantMapProperty(const ListLayout::Role &role, v8::Handle<v8::Object> o, QV8Engine *eng); - int setVariantMapProperty(const ListLayout::Role &role, QVariantMap *m); - int setDateTimeProperty(const ListLayout::Role &role, const QDateTime &dt); - - void setStringPropertyFast(const ListLayout::Role &role, const QString &s); - void setDoublePropertyFast(const ListLayout::Role &role, double n); - void setBoolPropertyFast(const ListLayout::Role &role, bool b); - void setQObjectPropertyFast(const ListLayout::Role &role, QObject *o); - void setListPropertyFast(const ListLayout::Role &role, ListModel *m); - void setVariantMapFast(const ListLayout::Role &role, v8::Handle<v8::Object> o, QV8Engine *eng); - void setDateTimePropertyFast(const ListLayout::Role &role, const QDateTime &dt); - - void clearProperty(const ListLayout::Role &role); - - QVariant getProperty(const ListLayout::Role &role, const QQuickListModel *owner, QV8Engine *eng); - ListModel *getListProperty(const ListLayout::Role &role); - QString *getStringProperty(const ListLayout::Role &role); - QObject *getQObjectProperty(const ListLayout::Role &role); - QQmlGuard<QObject> *getGuardProperty(const ListLayout::Role &role); - QVariantMap *getVariantMapProperty(const ListLayout::Role &role); - QDateTime *getDateTimeProperty(const ListLayout::Role &role); - - inline char *getPropertyMemory(const ListLayout::Role &role); - - int getUid() const { return uid; } - - char data[BLOCK_SIZE]; - ListElement *next; - - int uid; - ModelObject *m_objectCache; - - friend class ListModel; -}; - -class ListModel -{ -public: - - ListModel(ListLayout *layout, QQuickListModel *modelCache, int uid); - ~ListModel() {} - - void destroy(); - - int setOrCreateProperty(int elementIndex, const QString &key, const QVariant &data); - int setExistingProperty(int uid, const QString &key, v8::Handle<v8::Value> data, QV8Engine *eng); - - QVariant getProperty(int elementIndex, int roleIndex, const QQuickListModel *owner, QV8Engine *eng); - ListModel *getListProperty(int elementIndex, const ListLayout::Role &role); - - int roleCount() const - { - return m_layout->roleCount(); - } - - const ListLayout::Role &getExistingRole(int index) - { - return m_layout->getExistingRole(index); - } - - const ListLayout::Role &getOrCreateListRole(const QString &name) - { - return m_layout->getRoleOrCreate(name, ListLayout::Role::List); - } - - int elementCount() const - { - return elements.count(); - } - - void set(int elementIndex, v8::Handle<v8::Object> object, QVector<int> *roles, QV8Engine *eng); - void set(int elementIndex, v8::Handle<v8::Object> object, QV8Engine *eng); - - int append(v8::Handle<v8::Object> object, QV8Engine *eng); - void insert(int elementIndex, v8::Handle<v8::Object> object, QV8Engine *eng); - - void clear(); - void remove(int index, int count); - - int appendElement(); - void insertElement(int index); - - void move(int from, int to, int n); - - int getUid() const { return m_uid; } - - static void sync(ListModel *src, ListModel *target, QHash<int, ListModel *> *srcModelHash); - - ModelObject *getOrCreateModelObject(QQuickListModel *model, int elementIndex); - -private: - QPODVector<ListElement *, 4> elements; - ListLayout *m_layout; - int m_uid; - - QQuickListModel *m_modelCache; - - struct ElementSync - { - ElementSync() : src(0), target(0) {} - - ListElement *src; - ListElement *target; - }; - - void newElement(int index); - - void updateCacheIndices(); - - friend class ListElement; - friend class QQuickListModelWorkerAgent; -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(ListModel *); - -QT_END_HEADER - -#endif // QQUICKLISTMODEL_P_P_H - diff --git a/src/qml/qml/qquicklistmodelworkeragent.cpp b/src/qml/qml/qquicklistmodelworkeragent.cpp deleted file mode 100644 index e0ab882b92..0000000000 --- a/src/qml/qml/qquicklistmodelworkeragent.cpp +++ /dev/null @@ -1,259 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquicklistmodelworkeragent_p.h" -#include "qquicklistmodel_p_p.h" -#include <private/qqmldata_p.h> -#include <private/qqmlengine_p.h> -#include <qqmlinfo.h> - -#include <QtCore/qcoreevent.h> -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdebug.h> - - -QT_BEGIN_NAMESPACE - - -void QQuickListModelWorkerAgent::Data::clearChange(int uid) -{ - for (int i=0 ; i < changes.count() ; ++i) { - if (changes[i].modelUid == uid) { - changes.removeAt(i); - --i; - } - } -} - -void QQuickListModelWorkerAgent::Data::insertChange(int uid, int index, int count) -{ - Change c = { uid, Change::Inserted, index, count, 0, QVector<int>() }; - changes << c; -} - -void QQuickListModelWorkerAgent::Data::removeChange(int uid, int index, int count) -{ - Change c = { uid, Change::Removed, index, count, 0, QVector<int>() }; - changes << c; -} - -void QQuickListModelWorkerAgent::Data::moveChange(int uid, int index, int count, int to) -{ - Change c = { uid, Change::Moved, index, count, to, QVector<int>() }; - changes << c; -} - -void QQuickListModelWorkerAgent::Data::changedChange(int uid, int index, int count, const QVector<int> &roles) -{ - Change c = { uid, Change::Changed, index, count, 0, roles }; - changes << c; -} - -QQuickListModelWorkerAgent::QQuickListModelWorkerAgent(QQuickListModel *model) -: m_ref(1), m_orig(model), m_copy(new QQuickListModel(model, this)) -{ -} - -QQuickListModelWorkerAgent::~QQuickListModelWorkerAgent() -{ - mutex.lock(); - syncDone.wakeAll(); - mutex.unlock(); -} - -void QQuickListModelWorkerAgent::setV8Engine(QV8Engine *eng) -{ - m_copy->m_engine = eng; -} - -void QQuickListModelWorkerAgent::addref() -{ - m_ref.ref(); -} - -void QQuickListModelWorkerAgent::release() -{ - bool del = !m_ref.deref(); - - if (del) - deleteLater(); -} - -void QQuickListModelWorkerAgent::modelDestroyed() -{ - m_orig = 0; -} - -int QQuickListModelWorkerAgent::count() const -{ - return m_copy->count(); -} - -void QQuickListModelWorkerAgent::clear() -{ - m_copy->clear(); -} - -void QQuickListModelWorkerAgent::remove(QQmlV8Function *args) -{ - m_copy->remove(args); -} - -void QQuickListModelWorkerAgent::append(QQmlV8Function *args) -{ - m_copy->append(args); -} - -void QQuickListModelWorkerAgent::insert(QQmlV8Function *args) -{ - m_copy->insert(args); -} - -QQmlV8Handle QQuickListModelWorkerAgent::get(int index) const -{ - return m_copy->get(index); -} - -void QQuickListModelWorkerAgent::set(int index, const QQmlV8Handle &value) -{ - m_copy->set(index, value); -} - -void QQuickListModelWorkerAgent::setProperty(int index, const QString& property, const QVariant& value) -{ - m_copy->setProperty(index, property, value); -} - -void QQuickListModelWorkerAgent::move(int from, int to, int count) -{ - m_copy->move(from, to, count); -} - -void QQuickListModelWorkerAgent::sync() -{ - Sync *s = new Sync; - s->data = data; - s->list = m_copy; - data.changes.clear(); - - mutex.lock(); - QCoreApplication::postEvent(this, s); - syncDone.wait(&mutex); - mutex.unlock(); -} - -bool QQuickListModelWorkerAgent::event(QEvent *e) -{ - if (e->type() == QEvent::User) { - bool cc = false; - QMutexLocker locker(&mutex); - if (m_orig) { - Sync *s = static_cast<Sync *>(e); - const QList<Change> &changes = s->data.changes; - - cc = m_orig->count() != s->list->count(); - - QHash<int, QQuickListModel *> targetModelDynamicHash; - QHash<int, ListModel *> targetModelStaticHash; - - Q_ASSERT(m_orig->m_dynamicRoles == s->list->m_dynamicRoles); - if (m_orig->m_dynamicRoles) - QQuickListModel::sync(s->list, m_orig, &targetModelDynamicHash); - else - ListModel::sync(s->list->m_listModel, m_orig->m_listModel, &targetModelStaticHash); - - for (int ii = 0; ii < changes.count(); ++ii) { - const Change &change = changes.at(ii); - - QQuickListModel *model = 0; - if (m_orig->m_dynamicRoles) { - model = targetModelDynamicHash.value(change.modelUid); - } else { - ListModel *lm = targetModelStaticHash.value(change.modelUid); - if (lm) - model = lm->m_modelCache; - } - - if (model) { - switch (change.type) { - case Change::Inserted: - model->beginInsertRows( - QModelIndex(), change.index, change.index + change.count - 1); - model->endInsertRows(); - break; - case Change::Removed: - model->beginRemoveRows( - QModelIndex(), change.index, change.index + change.count - 1); - model->endRemoveRows(); - break; - case Change::Moved: - model->beginMoveRows( - QModelIndex(), - change.index, - change.index + change.count - 1, - QModelIndex(), - change.to > change.index ? change.to + change.count : change.to); - model->endMoveRows(); - break; - case Change::Changed: - emit model->dataChanged( - model->createIndex(change.index, 0), - model->createIndex(change.index + change.count - 1, 0), - change.roles); - break; - } - } - } - } - - syncDone.wakeAll(); - locker.unlock(); - - if (cc) - emit m_orig->countChanged(); - return true; - } - - return QObject::event(e); -} - -QT_END_NAMESPACE - diff --git a/src/qml/qml/qquicklistmodelworkeragent_p.h b/src/qml/qml/qquicklistmodelworkeragent_p.h deleted file mode 100644 index 7cff9be8f4..0000000000 --- a/src/qml/qml/qquicklistmodelworkeragent_p.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QQUICKLISTMODELWORKERAGENT_P_H -#define QQUICKLISTMODELWORKERAGENT_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <qqml.h> - -#include <QMutex> -#include <QWaitCondition> - -#include <private/qv8engine_p.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - - -class QQuickListModel; - -class QQuickListModelWorkerAgent : public QObject -{ - Q_OBJECT - Q_PROPERTY(int count READ count) - -public: - QQuickListModelWorkerAgent(QQuickListModel *); - ~QQuickListModelWorkerAgent(); - void setV8Engine(QV8Engine *eng); - - void addref(); - void release(); - - int count() const; - - Q_INVOKABLE void clear(); - Q_INVOKABLE void remove(QQmlV8Function *args); - Q_INVOKABLE void append(QQmlV8Function *args); - Q_INVOKABLE void insert(QQmlV8Function *args); - Q_INVOKABLE QQmlV8Handle get(int index) const; - Q_INVOKABLE void set(int index, const QQmlV8Handle &); - Q_INVOKABLE void setProperty(int index, const QString& property, const QVariant& value); - Q_INVOKABLE void move(int from, int to, int count); - Q_INVOKABLE void sync(); - - struct VariantRef - { - VariantRef() : a(0) {} - VariantRef(const VariantRef &r) : a(r.a) { if (a) a->addref(); } - VariantRef(QQuickListModelWorkerAgent *_a) : a(_a) { if (a) a->addref(); } - ~VariantRef() { if (a) a->release(); } - - VariantRef &operator=(const VariantRef &o) { - if (o.a) o.a->addref(); - if (a) a->release(); a = o.a; - return *this; - } - - QQuickListModelWorkerAgent *a; - }; - void modelDestroyed(); -protected: - virtual bool event(QEvent *); - -private: - friend class QQuickWorkerScriptEnginePrivate; - friend class QQuickListModel; - - struct Change - { - int modelUid; - enum { Inserted, Removed, Moved, Changed } type; - int index; // Inserted/Removed/Moved/Changed - int count; // Inserted/Removed/Moved/Changed - int to; // Moved - QVector<int> roles; - }; - - struct Data - { - QList<Change> changes; - - void clearChange(int uid); - void insertChange(int uid, int index, int count); - void removeChange(int uid, int index, int count); - void moveChange(int uid, int index, int count, int to); - void changedChange(int uid, int index, int count, const QVector<int> &roles); - }; - Data data; - - struct Sync : public QEvent { - Sync() : QEvent(QEvent::User) {} - Data data; - QQuickListModel *list; - }; - - QAtomicInt m_ref; - QQuickListModel *m_orig; - QQuickListModel *m_copy; - QMutex mutex; - QWaitCondition syncDone; -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QQuickListModelWorkerAgent::VariantRef) - -QT_END_HEADER - -#endif // QQUICKLISTMODELWORKERAGENT_P_H - diff --git a/src/qml/qml/qquickworkerscript.cpp b/src/qml/qml/qquickworkerscript.cpp deleted file mode 100644 index f7559f1d36..0000000000 --- a/src/qml/qml/qquickworkerscript.cpp +++ /dev/null @@ -1,740 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qquickworkerscript_p.h" -#include "qquicklistmodel_p.h" -#include "qquicklistmodelworkeragent_p.h" -#include "qqmlengine_p.h" -#include "qqmlexpression_p.h" - -#include <QtCore/qcoreevent.h> -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdebug.h> -#include <QtQml/qjsengine.h> -#include <QtCore/qmutex.h> -#include <QtCore/qwaitcondition.h> -#include <QtCore/qfile.h> -#include <QtCore/qdatetime.h> -#include <QtNetwork/qnetworkaccessmanager.h> -#include <QtQml/qqmlinfo.h> -#include <QtQml/qqmlfile.h> -#include "qqmlnetworkaccessmanagerfactory.h" - -#include <private/qv8engine_p.h> -#include <private/qv8worker_p.h> - -QT_BEGIN_NAMESPACE - -class WorkerDataEvent : public QEvent -{ -public: - enum Type { WorkerData = QEvent::User }; - - WorkerDataEvent(int workerId, const QByteArray &data); - virtual ~WorkerDataEvent(); - - int workerId() const; - QByteArray data() const; - -private: - int m_id; - QByteArray m_data; -}; - -class WorkerLoadEvent : public QEvent -{ -public: - enum Type { WorkerLoad = WorkerDataEvent::WorkerData + 1 }; - - WorkerLoadEvent(int workerId, const QUrl &url); - - int workerId() const; - QUrl url() const; - -private: - int m_id; - QUrl m_url; -}; - -class WorkerRemoveEvent : public QEvent -{ -public: - enum Type { WorkerRemove = WorkerLoadEvent::WorkerLoad + 1 }; - - WorkerRemoveEvent(int workerId); - - int workerId() const; - -private: - int m_id; -}; - -class WorkerErrorEvent : public QEvent -{ -public: - enum Type { WorkerError = WorkerRemoveEvent::WorkerRemove + 1 }; - - WorkerErrorEvent(const QQmlError &error); - - QQmlError error() const; - -private: - QQmlError m_error; -}; - -class QQuickWorkerScriptEnginePrivate : public QObject -{ - Q_OBJECT -public: - enum WorkerEventTypes { - WorkerDestroyEvent = QEvent::User + 100 - }; - - QQuickWorkerScriptEnginePrivate(QQmlEngine *eng); - - class WorkerEngine : public QV8Engine - { - public: - WorkerEngine(QQuickWorkerScriptEnginePrivate *parent); - ~WorkerEngine(); - - void init(); - virtual QNetworkAccessManager *networkAccessManager(); - - QQuickWorkerScriptEnginePrivate *p; - - v8::Local<v8::Function> sendFunction(int id); - void callOnMessage(v8::Handle<v8::Object> object, v8::Handle<v8::Value> arg); - private: - v8::Persistent<v8::Function> onmessage; - v8::Persistent<v8::Function> createsend; - QNetworkAccessManager *accessManager; - }; - - WorkerEngine *workerEngine; - static QQuickWorkerScriptEnginePrivate *get(QV8Engine *e) { - return static_cast<WorkerEngine *>(e)->p; - } - - QQmlEngine *qmlengine; - - QMutex m_lock; - QWaitCondition m_wait; - - struct WorkerScript { - WorkerScript(); - ~WorkerScript(); - - int id; - QUrl source; - bool initialized; - QQuickWorkerScript *owner; - v8::Persistent<v8::Object> object; - }; - - QHash<int, WorkerScript *> workers; - v8::Handle<v8::Object> getWorker(WorkerScript *); - - int m_nextId; - - static v8::Handle<v8::Value> sendMessage(const v8::Arguments &args); - -signals: - void stopThread(); - -protected: - virtual bool event(QEvent *); - -private: - void processMessage(int, const QByteArray &); - void processLoad(int, const QUrl &); - void reportScriptException(WorkerScript *, const QQmlError &error); -}; - -QQuickWorkerScriptEnginePrivate::WorkerEngine::WorkerEngine(QQuickWorkerScriptEnginePrivate *parent) -: QV8Engine(0), p(parent), accessManager(0) -{ -} - -QQuickWorkerScriptEnginePrivate::WorkerEngine::~WorkerEngine() -{ - qPersistentDispose(createsend); - qPersistentDispose(onmessage); - delete accessManager; -} - -void QQuickWorkerScriptEnginePrivate::WorkerEngine::init() -{ - initQmlGlobalObject(); -#define CALL_ONMESSAGE_SCRIPT \ - "(function(object, message) { "\ - "var isfunction = false; "\ - "try { "\ - "isfunction = object.WorkerScript.onMessage instanceof Function; "\ - "} catch (e) {}" \ - "if (isfunction) "\ - "object.WorkerScript.onMessage(message); "\ - "})" - -#define SEND_MESSAGE_CREATE_SCRIPT \ - "(function(method, engine) { "\ - "return (function(id) { "\ - "return (function(message) { "\ - "if (arguments.length) method(engine, id, message); "\ - "}); "\ - "}); "\ - "})" - - v8::HandleScope handle_scope; - v8::Context::Scope scope(context()); - - { - v8::Local<v8::Script> onmessagescript = v8::Script::New(v8::String::New(CALL_ONMESSAGE_SCRIPT)); - onmessage = qPersistentNew<v8::Function>(v8::Handle<v8::Function>::Cast(onmessagescript->Run())); - } - { - v8::Local<v8::Script> createsendscript = v8::Script::New(v8::String::New(SEND_MESSAGE_CREATE_SCRIPT)); - v8::Local<v8::Function> createsendconstructor = v8::Local<v8::Function>::Cast(createsendscript->Run()); - - v8::Handle<v8::Value> args[] = { - V8FUNCTION(QQuickWorkerScriptEnginePrivate::sendMessage, this) - }; - v8::Local<v8::Value> createsendvalue = createsendconstructor->Call(global(), 1, args); - - createsend = qPersistentNew<v8::Function>(v8::Handle<v8::Function>::Cast(createsendvalue)); - } -} - -// Requires handle and context scope -v8::Local<v8::Function> QQuickWorkerScriptEnginePrivate::WorkerEngine::sendFunction(int id) -{ - v8::Handle<v8::Value> args[] = { v8::Integer::New(id) }; - return v8::Local<v8::Function>::Cast(createsend->Call(global(), 1, args)); -} - -// Requires handle and context scope -void QQuickWorkerScriptEnginePrivate::WorkerEngine::callOnMessage(v8::Handle<v8::Object> object, - v8::Handle<v8::Value> arg) -{ - v8::Handle<v8::Value> args[] = { object, arg }; - onmessage->Call(global(), 2, args); -} - -QNetworkAccessManager *QQuickWorkerScriptEnginePrivate::WorkerEngine::networkAccessManager() -{ - if (!accessManager) { - if (p->qmlengine && p->qmlengine->networkAccessManagerFactory()) { - accessManager = p->qmlengine->networkAccessManagerFactory()->create(p); - } else { - accessManager = new QNetworkAccessManager(p); - } - } - return accessManager; -} - -QQuickWorkerScriptEnginePrivate::QQuickWorkerScriptEnginePrivate(QQmlEngine *engine) -: workerEngine(0), qmlengine(engine), m_nextId(0) -{ -} - -v8::Handle<v8::Value> QQuickWorkerScriptEnginePrivate::sendMessage(const v8::Arguments &args) -{ - WorkerEngine *engine = (WorkerEngine*)V8ENGINE(); - - int id = args[1]->Int32Value(); - - QByteArray data = QV8Worker::serialize(args[2], engine); - - QMutexLocker locker(&engine->p->m_lock); - WorkerScript *script = engine->p->workers.value(id); - if (!script) - return v8::Undefined(); - - if (script->owner) - QCoreApplication::postEvent(script->owner, new WorkerDataEvent(0, data)); - - return v8::Undefined(); -} - -// Requires handle scope and context scope -v8::Handle<v8::Object> QQuickWorkerScriptEnginePrivate::getWorker(WorkerScript *script) -{ - if (!script->initialized) { - script->initialized = true; - - script->object = qPersistentNew<v8::Object>(workerEngine->contextWrapper()->urlScope(script->source)); - - workerEngine->contextWrapper()->setReadOnly(script->object, false); - - v8::Local<v8::Object> api = v8::Object::New(); - api->Set(v8::String::New("sendMessage"), workerEngine->sendFunction(script->id)); - - script->object->Set(v8::String::New("WorkerScript"), api); - - workerEngine->contextWrapper()->setReadOnly(script->object, true); - } - - return script->object; -} - -bool QQuickWorkerScriptEnginePrivate::event(QEvent *event) -{ - if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) { - WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event); - processMessage(workerEvent->workerId(), workerEvent->data()); - return true; - } else if (event->type() == (QEvent::Type)WorkerLoadEvent::WorkerLoad) { - WorkerLoadEvent *workerEvent = static_cast<WorkerLoadEvent *>(event); - processLoad(workerEvent->workerId(), workerEvent->url()); - return true; - } else if (event->type() == (QEvent::Type)WorkerDestroyEvent) { - emit stopThread(); - return true; - } else if (event->type() == (QEvent::Type)WorkerRemoveEvent::WorkerRemove) { - WorkerRemoveEvent *workerEvent = static_cast<WorkerRemoveEvent *>(event); - workers.remove(workerEvent->workerId()); - return true; - } else { - return QObject::event(event); - } -} - -void QQuickWorkerScriptEnginePrivate::processMessage(int id, const QByteArray &data) -{ - WorkerScript *script = workers.value(id); - if (!script) - return; - - v8::HandleScope handle_scope; - v8::Context::Scope scope(workerEngine->context()); - - v8::Handle<v8::Value> value = QV8Worker::deserialize(data, workerEngine); - - v8::TryCatch tc; - workerEngine->callOnMessage(script->object, value); - - if (tc.HasCaught()) { - QQmlError error; - QQmlExpressionPrivate::exceptionToError(tc.Message(), error); - reportScriptException(script, error); - } -} - -void QQuickWorkerScriptEnginePrivate::processLoad(int id, const QUrl &url) -{ - if (url.isRelative()) - return; - - QString fileName = QQmlFile::urlToLocalFileOrQrc(url); - - QFile f(fileName); - if (f.open(QIODevice::ReadOnly)) { - QByteArray data = f.readAll(); - QString sourceCode = QString::fromUtf8(data); - QQmlScript::Parser::extractPragmas(sourceCode); - - v8::HandleScope handle_scope; - v8::Context::Scope scope(workerEngine->context()); - - WorkerScript *script = workers.value(id); - if (!script) - return; - script->source = url; - v8::Handle<v8::Object> activation = getWorker(script); - if (activation.IsEmpty()) - return; - - // XXX ??? - // workerEngine->baseUrl = url; - - v8::TryCatch tc; - v8::Local<v8::Script> program = workerEngine->qmlModeCompile(sourceCode, url.toString()); - - if (!tc.HasCaught()) - program->Run(activation); - - if (tc.HasCaught()) { - QQmlError error; - QQmlExpressionPrivate::exceptionToError(tc.Message(), error); - reportScriptException(script, error); - } - } else { - qWarning().nospace() << "WorkerScript: Cannot find source file " << url.toString(); - } -} - -void QQuickWorkerScriptEnginePrivate::reportScriptException(WorkerScript *script, - const QQmlError &error) -{ - QQuickWorkerScriptEnginePrivate *p = QQuickWorkerScriptEnginePrivate::get(workerEngine); - - QMutexLocker locker(&p->m_lock); - if (script->owner) - QCoreApplication::postEvent(script->owner, new WorkerErrorEvent(error)); -} - -WorkerDataEvent::WorkerDataEvent(int workerId, const QByteArray &data) -: QEvent((QEvent::Type)WorkerData), m_id(workerId), m_data(data) -{ -} - -WorkerDataEvent::~WorkerDataEvent() -{ -} - -int WorkerDataEvent::workerId() const -{ - return m_id; -} - -QByteArray WorkerDataEvent::data() const -{ - return m_data; -} - -WorkerLoadEvent::WorkerLoadEvent(int workerId, const QUrl &url) -: QEvent((QEvent::Type)WorkerLoad), m_id(workerId), m_url(url) -{ -} - -int WorkerLoadEvent::workerId() const -{ - return m_id; -} - -QUrl WorkerLoadEvent::url() const -{ - return m_url; -} - -WorkerRemoveEvent::WorkerRemoveEvent(int workerId) -: QEvent((QEvent::Type)WorkerRemove), m_id(workerId) -{ -} - -int WorkerRemoveEvent::workerId() const -{ - return m_id; -} - -WorkerErrorEvent::WorkerErrorEvent(const QQmlError &error) -: QEvent((QEvent::Type)WorkerError), m_error(error) -{ -} - -QQmlError WorkerErrorEvent::error() const -{ - return m_error; -} - -QQuickWorkerScriptEngine::QQuickWorkerScriptEngine(QQmlEngine *parent) -: QThread(parent), d(new QQuickWorkerScriptEnginePrivate(parent)) -{ - d->m_lock.lock(); - connect(d, SIGNAL(stopThread()), this, SLOT(quit()), Qt::DirectConnection); - start(QThread::LowestPriority); - d->m_wait.wait(&d->m_lock); - d->moveToThread(this); - d->m_lock.unlock(); -} - -QQuickWorkerScriptEngine::~QQuickWorkerScriptEngine() -{ - d->m_lock.lock(); - QCoreApplication::postEvent(d, new QEvent((QEvent::Type)QQuickWorkerScriptEnginePrivate::WorkerDestroyEvent)); - d->m_lock.unlock(); - - //We have to force to cleanup the main thread's event queue here - //to make sure the main GUI release all pending locks/wait conditions which - //some worker script/agent are waiting for (QQuickListModelWorkerAgent::sync() for example). - while (!isFinished()) { - // We can't simply wait here, because the worker thread will not terminate - // until the main thread processes the last data event it generates - QCoreApplication::processEvents(); - yieldCurrentThread(); - } - - d->deleteLater(); -} - -QQuickWorkerScriptEnginePrivate::WorkerScript::WorkerScript() -: id(-1), initialized(false), owner(0) -{ -} - -QQuickWorkerScriptEnginePrivate::WorkerScript::~WorkerScript() -{ - qPersistentDispose(object); -} - -int QQuickWorkerScriptEngine::registerWorkerScript(QQuickWorkerScript *owner) -{ - typedef QQuickWorkerScriptEnginePrivate::WorkerScript WorkerScript; - WorkerScript *script = new WorkerScript; - - script->id = d->m_nextId++; - script->owner = owner; - - d->m_lock.lock(); - d->workers.insert(script->id, script); - d->m_lock.unlock(); - - return script->id; -} - -void QQuickWorkerScriptEngine::removeWorkerScript(int id) -{ - QQuickWorkerScriptEnginePrivate::WorkerScript* script = d->workers.value(id); - if (script) { - script->owner = 0; - QCoreApplication::postEvent(d, new WorkerRemoveEvent(id)); - } -} - -void QQuickWorkerScriptEngine::executeUrl(int id, const QUrl &url) -{ - QCoreApplication::postEvent(d, new WorkerLoadEvent(id, url)); -} - -void QQuickWorkerScriptEngine::sendMessage(int id, const QByteArray &data) -{ - QCoreApplication::postEvent(d, new WorkerDataEvent(id, data)); -} - -void QQuickWorkerScriptEngine::run() -{ - d->m_lock.lock(); - - d->workerEngine = new QQuickWorkerScriptEnginePrivate::WorkerEngine(d); - d->workerEngine->init(); - - d->m_wait.wakeAll(); - - d->m_lock.unlock(); - - exec(); - - qDeleteAll(d->workers); - d->workers.clear(); - - delete d->workerEngine; d->workerEngine = 0; -} - - -/*! - \qmltype WorkerScript - \instantiates QQuickWorkerScript - \ingroup qtquick-threading - \inqmlmodule QtQuick 2 - \brief Enables the use of threads in a Qt Quick application - - Use WorkerScript to run operations in a new thread. - This is useful for running operations in the background so - that the main GUI thread is not blocked. - - Messages can be passed between the new thread and the parent thread - using \l sendMessage() and the \l {WorkerScript::onMessage}{onMessage()} handler. - - An example: - - \snippet qml/workerscript/workerscript.qml 0 - - The above worker script specifies a JavaScript file, "script.js", that handles - the operations to be performed in the new thread. Here is \c script.js: - - \quotefile qml/workerscript/script.js - - When the user clicks anywhere within the rectangle, \c sendMessage() is - called, triggering the \tt WorkerScript.onMessage() handler in - \tt script.js. This in turn sends a reply message that is then received - by the \tt onMessage() handler of \tt myWorker. - - - \section3 Restrictions - - Since the \c WorkerScript.onMessage() function is run in a separate thread, the - JavaScript file is evaluated in a context separate from the main QML engine. This means - that unlike an ordinary JavaScript file that is imported into QML, the \c script.js - in the above example cannot access the properties, methods or other attributes - of the QML item, nor can it access any context properties set on the QML object - through QQmlContext. - - Additionally, there are restrictions on the types of values that can be passed to and - from the worker script. See the sendMessage() documentation for details. - - Worker script can not use \l {qtqml-javascript-imports.html}{.import} syntax. - - \sa {declarative/threading/workerscript}{WorkerScript example}, - {declarative/threading/threadedlistmodel}{Threaded ListModel example} -*/ -QQuickWorkerScript::QQuickWorkerScript(QObject *parent) -: QObject(parent), m_engine(0), m_scriptId(-1), m_componentComplete(true) -{ -} - -QQuickWorkerScript::~QQuickWorkerScript() -{ - if (m_scriptId != -1) m_engine->removeWorkerScript(m_scriptId); -} - -/*! - \qmlproperty url WorkerScript::source - - This holds the url of the JavaScript file that implements the - \tt WorkerScript.onMessage() handler for threaded operations. -*/ -QUrl QQuickWorkerScript::source() const -{ - return m_source; -} - -void QQuickWorkerScript::setSource(const QUrl &source) -{ - if (m_source == source) - return; - - m_source = source; - - if (engine()) - m_engine->executeUrl(m_scriptId, m_source); - - emit sourceChanged(); -} - -/*! - \qmlmethod WorkerScript::sendMessage(jsobject message) - - Sends the given \a message to a worker script handler in another - thread. The other worker script handler can receive this message - through the onMessage() handler. - - The \c message object may only contain values of the following - types: - - \list - \li boolean, number, string - \li JavaScript objects and arrays - \li ListModel objects (any other type of QObject* is not allowed) - \endlist - - All objects and arrays are copied to the \c message. With the exception - of ListModel objects, any modifications by the other thread to an object - passed in \c message will not be reflected in the original object. -*/ -void QQuickWorkerScript::sendMessage(QQmlV8Function *args) -{ - if (!engine()) { - qWarning("QQuickWorkerScript: Attempt to send message before WorkerScript establishment"); - return; - } - - v8::Handle<v8::Value> argument = v8::Undefined(); - if (args->Length() != 0) - argument = (*args)[0]; - - m_engine->sendMessage(m_scriptId, QV8Worker::serialize(argument, args->engine())); -} - -void QQuickWorkerScript::classBegin() -{ - m_componentComplete = false; -} - -QQuickWorkerScriptEngine *QQuickWorkerScript::engine() -{ - if (m_engine) return m_engine; - if (m_componentComplete) { - QQmlEngine *engine = qmlEngine(this); - if (!engine) { - qWarning("QQuickWorkerScript: engine() called without qmlEngine() set"); - return 0; - } - - m_engine = QQmlEnginePrivate::get(engine)->getWorkerScriptEngine(); - m_scriptId = m_engine->registerWorkerScript(this); - - if (m_source.isValid()) - m_engine->executeUrl(m_scriptId, m_source); - - return m_engine; - } - return 0; -} - -void QQuickWorkerScript::componentComplete() -{ - m_componentComplete = true; - engine(); // Get it started now. -} - -/*! - \qmlsignal WorkerScript::onMessage(jsobject msg) - - This handler is called when a message \a msg is received from a worker - script in another thread through a call to sendMessage(). -*/ - -bool QQuickWorkerScript::event(QEvent *event) -{ - if (event->type() == (QEvent::Type)WorkerDataEvent::WorkerData) { - QQmlEngine *engine = qmlEngine(this); - if (engine) { - WorkerDataEvent *workerEvent = static_cast<WorkerDataEvent *>(event); - QV8Engine *v8engine = QQmlEnginePrivate::get(engine)->v8engine(); - v8::HandleScope handle_scope; - v8::Context::Scope scope(v8engine->context()); - v8::Handle<v8::Value> value = QV8Worker::deserialize(workerEvent->data(), v8engine); - emit message(QQmlV8Handle::fromHandle(value)); - } - return true; - } else if (event->type() == (QEvent::Type)WorkerErrorEvent::WorkerError) { - WorkerErrorEvent *workerEvent = static_cast<WorkerErrorEvent *>(event); - QQmlEnginePrivate::warning(qmlEngine(this), workerEvent->error()); - return true; - } else { - return QObject::event(event); - } -} - -QT_END_NAMESPACE - -#include <qquickworkerscript.moc> - diff --git a/src/qml/qml/rewriter/textwriter_p.h b/src/qml/qml/rewriter/textwriter_p.h index 5c22a62a02..fdfd955d9f 100644 --- a/src/qml/qml/rewriter/textwriter_p.h +++ b/src/qml/qml/rewriter/textwriter_p.h @@ -47,7 +47,6 @@ #include <QtCore/QString> #include <QtCore/QList> -QT_BEGIN_HEADER QT_QML_BEGIN_NAMESPACE namespace QQmlJS { @@ -92,6 +91,4 @@ public: } // end of namespace QQmlJS QT_QML_END_NAMESPACE -QT_END_HEADER - #endif // TEXTWRITER_H diff --git a/src/qml/qml/v4/qv4bindings_p.h b/src/qml/qml/v4/qv4bindings_p.h index 6ea548c642..adb05ba1f4 100644 --- a/src/qml/qml/v4/qv4bindings_p.h +++ b/src/qml/qml/v4/qv4bindings_p.h @@ -59,8 +59,6 @@ #include "private/qv4instruction_p.h" #include "private/qpointervaluepair_p.h" -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE struct QV4Program; @@ -170,7 +168,5 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QV4BINDINGS_P_H diff --git a/src/qml/qml/v4/qv4compiler_p.h b/src/qml/qml/v4/qv4compiler_p.h index c5175b2bbd..5b6cee2a55 100644 --- a/src/qml/qml/v4/qv4compiler_p.h +++ b/src/qml/qml/v4/qv4compiler_p.h @@ -61,8 +61,6 @@ Q_DECLARE_METATYPE(v8::Handle<v8::Value>) -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QQmlTypeNameCache; @@ -103,7 +101,5 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QV4COMPILER_P_H diff --git a/src/qml/qml/v4/qv4compiler_p_p.h b/src/qml/qml/v4/qv4compiler_p_p.h index c2d6b8c362..58ec521a97 100644 --- a/src/qml/qml/v4/qv4compiler_p_p.h +++ b/src/qml/qml/v4/qv4compiler_p_p.h @@ -59,8 +59,6 @@ #include <private/qqmlimport_p.h> #include <private/qqmlengine_p.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE template <typename _Key, typename _Value> @@ -243,7 +241,5 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QV4COMPILER_P_P_H diff --git a/src/qml/qml/v4/qv4instruction_p.h b/src/qml/qml/v4/qv4instruction_p.h index be3b4bef1e..9797abf69d 100644 --- a/src/qml/qml/v4/qv4instruction_p.h +++ b/src/qml/qml/v4/qv4instruction_p.h @@ -60,8 +60,6 @@ #include <private/qqmlpropertycache_p.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE #define FOR_EACH_V4_INSTR(F) \ @@ -481,7 +479,5 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QV4INSTRUCTION_P_H diff --git a/src/qml/qml/v4/qv4ir_p.h b/src/qml/qml/v4/qv4ir_p.h index 08cfe43091..701f76d9e4 100644 --- a/src/qml/qml/v4/qv4ir_p.h +++ b/src/qml/qml/v4/qv4ir_p.h @@ -69,8 +69,6 @@ # undef CONST #endif -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QTextStream; @@ -614,6 +612,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QV4IR_P_H diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp index 50d799c8d9..4aa257d54a 100644 --- a/src/qml/qml/v4/qv4irbuilder.cpp +++ b/src/qml/qml/v4/qv4irbuilder.cpp @@ -358,7 +358,19 @@ bool QV4IRBuilder::visit(AST::StatementSourceElement *) } // object literals -bool QV4IRBuilder::visit(AST::PropertyNameAndValueList *) +bool QV4IRBuilder::visit(AST::PropertyAssignmentList *) +{ + Q_ASSERT(!"unreachable"); + return false; +} + +bool QV4IRBuilder::visit(AST::PropertyNameAndValue *) +{ + Q_ASSERT(!"unreachable"); + return false; +} + +bool QV4IRBuilder::visit(AST::PropertyGetterSetter *) { Q_ASSERT(!"unreachable"); return false; diff --git a/src/qml/qml/v4/qv4irbuilder_p.h b/src/qml/qml/v4/qv4irbuilder_p.h index 3aee38b269..86baae463d 100644 --- a/src/qml/qml/v4/qv4irbuilder_p.h +++ b/src/qml/qml/v4/qv4irbuilder_p.h @@ -46,8 +46,6 @@ #include "qv4ir_p.h" -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QV4IRBuilder : public QQmlJS::AST::Visitor @@ -139,7 +137,9 @@ protected: virtual bool visit(QQmlJS::AST::StatementSourceElement *ast); // object literals - virtual bool visit(QQmlJS::AST::PropertyNameAndValueList *ast); + virtual bool visit(QQmlJS::AST::PropertyAssignmentList *ast); + virtual bool visit(QQmlJS::AST::PropertyNameAndValue *ast); + virtual bool visit(QQmlJS::AST::PropertyGetterSetter *ast); virtual bool visit(QQmlJS::AST::IdentifierPropertyName *ast); virtual bool visit(QQmlJS::AST::StringLiteralPropertyName *ast); virtual bool visit(QQmlJS::AST::NumericLiteralPropertyName *ast); @@ -236,6 +236,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QV4IRBUILDER_P_H diff --git a/src/qml/qml/v4/qv4program_p.h b/src/qml/qml/v4/qv4program_p.h index d04ada487e..fb23e863af 100644 --- a/src/qml/qml/v4/qv4program_p.h +++ b/src/qml/qml/v4/qv4program_p.h @@ -60,8 +60,6 @@ # pragma warning( disable : 4200 ) #endif -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE struct QV4Program { @@ -126,7 +124,5 @@ QV4Program::BindingReferenceList *QV4Program::signalTable(int signalIndex) const QT_END_NAMESPACE -QT_END_HEADER - #endif // QV4PROGRAM_P_H diff --git a/src/qml/qml/v8/qjsengine.h b/src/qml/qml/v8/qjsengine.h index 23ee289d6c..0a575f84e9 100644 --- a/src/qml/qml/v8/qjsengine.h +++ b/src/qml/qml/v8/qjsengine.h @@ -49,8 +49,6 @@ #include <QtCore/qobject.h> #include <QtQml/qjsvalue.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -137,6 +135,4 @@ inline QVariant qjsvalue_cast<QVariant>(const QJSValue &value) QT_END_NAMESPACE -QT_END_HEADER - #endif // QJSENGINE_H diff --git a/src/qml/qml/v8/qjsvalue.h b/src/qml/qml/v8/qjsvalue.h index 0a57e3533e..efd52ce880 100644 --- a/src/qml/qml/v8/qjsvalue.h +++ b/src/qml/qml/v8/qjsvalue.h @@ -48,8 +48,6 @@ #include <QtCore/qsharedpointer.h> #include <QtCore/qshareddata.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -157,6 +155,4 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QJSValue) -QT_END_HEADER - #endif diff --git a/src/qml/qml/v8/qjsvalueiterator.h b/src/qml/qml/v8/qjsvalueiterator.h index e9a67738ab..b4f90a44b7 100644 --- a/src/qml/qml/v8/qjsvalueiterator.h +++ b/src/qml/qml/v8/qjsvalueiterator.h @@ -46,8 +46,6 @@ #include <QtQml/qjsvalue.h> #include <QtCore/qscopedpointer.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE @@ -77,6 +75,4 @@ private: QT_END_NAMESPACE -QT_END_HEADER - #endif // QSCRIPTVALUEITERATOR_H diff --git a/src/qml/qml/v8/qv8bindings_p.h b/src/qml/qml/v8/qv8bindings_p.h index f3e62faa3b..98b367ac72 100644 --- a/src/qml/qml/v8/qv8bindings_p.h +++ b/src/qml/qml/v8/qv8bindings_p.h @@ -61,8 +61,6 @@ #include <private/qflagpointer_p.h> #include <private/qqmlbinding_p.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE class QQmlCompiledData; @@ -158,8 +156,6 @@ void QV8Bindings::release() QT_END_NAMESPACE -QT_END_HEADER - #endif // QV8BINDINGS_P_H diff --git a/src/qml/qml/v8/qv8domerrors_p.h b/src/qml/qml/v8/qv8domerrors_p.h index 0542863c32..8fd1ccb6d6 100644 --- a/src/qml/qml/v8/qv8domerrors_p.h +++ b/src/qml/qml/v8/qv8domerrors_p.h @@ -55,8 +55,6 @@ #include <QtCore/qglobal.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE // From DOM-Level-3-Core spec // http://www.w3.org/TR/DOM-Level-3-Core/core.html @@ -89,6 +87,4 @@ void qt_add_domexceptions(QV8Engine *engine); QT_END_NAMESPACE -QT_END_HEADER - #endif // QV8DOMERRORS_P_H diff --git a/src/qml/qml/v8/qv8engine.cpp b/src/qml/qml/v8/qv8engine.cpp index 2619c1a484..e80da46fc9 100644 --- a/src/qml/qml/v8/qv8engine.cpp +++ b/src/qml/qml/v8/qv8engine.cpp @@ -54,6 +54,7 @@ #include <private/qqmllocale_p.h> #include <private/qqmlglobal_p.h> #include <private/qqmlmemoryprofiler_p.h> +#include <private/qqmlplatform_p.h> #include "qscript_impl_p.h" #include "qv8domerrors_p.h" @@ -125,6 +126,7 @@ QV8Engine::QV8Engine(QJSEngine* qq, ContextOwnership ownership) , m_ownsV8Context(ownership == CreateNewContext) , m_xmlHttpRequestData(0) , m_listModelData(0) + , m_platform(0) , m_application(0) { QML_MEMORY_SCOPE_STRING("QV8Engine::QV8Engine"); @@ -561,7 +563,7 @@ QVariant QV8Engine::toBasicVariant(v8::Handle<v8::Value> value) struct StaticQtMetaObject : public QObject { static const QMetaObject *get() - { return &static_cast<StaticQtMetaObject*> (0)->staticQtMetaObject; } + { return &staticQtMetaObject; } }; void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global) @@ -629,6 +631,7 @@ void QV8Engine::initializeGlobal(v8::Handle<v8::Object> global) qt->Set(v8::String::New("binding"), V8FUNCTION(binding, this)); if (m_engine) { + qt->SetAccessor(v8::String::New("platform"), getPlatform, 0, v8::External::New(this)); qt->SetAccessor(v8::String::New("application"), getApplication, 0, v8::External::New(this)); #ifndef QT_NO_IM qt->SetAccessor(v8::String::New("inputMethod"), getInputMethod, 0, v8::External::New(this)); @@ -1446,9 +1449,19 @@ int QV8Engine::consoleCountHelper(const QString &file, quint16 line, quint16 col return number; } +v8::Handle<v8::Value> QV8Engine::getPlatform(v8::Local<v8::String>, const v8::AccessorInfo &info) +{ + QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Cast(*info.Data())->Value()); + if (!engine->m_platform) { + // Only allocate a platform object once + engine->m_platform = new QQmlPlatform(engine->m_engine); + } + return engine->newQObject(engine->m_platform); +} + v8::Handle<v8::Value> QV8Engine::getApplication(v8::Local<v8::String>, const v8::AccessorInfo &info) { - QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Unwrap(info.Data())); + QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Cast(*info.Data())->Value()); if (!engine->m_application) { // Only allocate an application object once engine->m_application = QQml_guiProvider()->application(engine->m_engine); @@ -1459,7 +1472,7 @@ v8::Handle<v8::Value> QV8Engine::getApplication(v8::Local<v8::String>, const v8: #ifndef QT_NO_IM v8::Handle<v8::Value> QV8Engine::getInputMethod(v8::Local<v8::String>, const v8::AccessorInfo &info) { - QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Unwrap(info.Data())); + QV8Engine *engine = reinterpret_cast<QV8Engine*>(v8::External::Cast(*info.Data())->Value()); return engine->newQObject(QQml_guiProvider()->inputMethod(), CppOwnership); } #endif diff --git a/src/qml/qml/v8/qv8engine_p.h b/src/qml/qml/v8/qv8engine_p.h index 43c978c757..5ae0963178 100644 --- a/src/qml/qml/v8/qv8engine_p.h +++ b/src/qml/qml/v8/qv8engine_p.h @@ -102,8 +102,8 @@ QT_BEGIN_NAMESPACE // a handle, qFatal() is called. // #define QML_GLOBAL_HANDLE_DEBUGGING -#define V8ENGINE() ((QV8Engine *)v8::External::Unwrap(args.Data())) -#define V8FUNCTION(function, engine) v8::FunctionTemplate::New(function, v8::External::Wrap((QV8Engine*)engine))->GetFunction() +#define V8ENGINE() ((QV8Engine *)v8::External::Cast(*args.Data())->Value()) +#define V8FUNCTION(function, engine) v8::FunctionTemplate::New(function, v8::External::New((QV8Engine*)engine))->GetFunction() #define V8THROW_ERROR(string) { \ v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \ return v8::Handle<v8::Value>(); \ @@ -112,7 +112,7 @@ QT_BEGIN_NAMESPACE v8::ThrowException(v8::Exception::TypeError(v8::String::New(string))); \ return v8::Handle<v8::Value>(); \ } -#define V8ENGINE_ACCESSOR() ((QV8Engine *)v8::External::Unwrap(info.Data())); +#define V8ENGINE_ACCESSOR() ((QV8Engine *)v8::External::Cast(*info.Data())->Value()); #define V8THROW_ERROR_SETTER(string) { \ v8::ThrowException(v8::Exception::Error(v8::String::New(string))); \ return; \ @@ -427,6 +427,7 @@ public: void addRelationshipForGC(QObject *object, v8::Persistent<v8::Value> handle); void addRelationshipForGC(QObject *object, QObject *other); + static v8::Handle<v8::Value> getPlatform(v8::Local<v8::String> property, const v8::AccessorInfo &info); static v8::Handle<v8::Value> getApplication(v8::Local<v8::String> property, const v8::AccessorInfo &info); #ifndef QT_NO_IM static v8::Handle<v8::Value> getInputMethod(v8::Local<v8::String> property, const v8::AccessorInfo &info); @@ -480,6 +481,7 @@ protected: QHash<QString, quint32> m_consoleCount; + QObject *m_platform; QObject *m_application; QVariant toBasicVariant(v8::Handle<v8::Value>); @@ -627,8 +629,10 @@ v8::Handle<v8::String> QV8Engine::bindingFlagKey() const // unqualified name in QV8ContextWrapper. bool QV8Engine::startsWithUpper(v8::Handle<v8::String> string) { - uint16_t c = string->GetCharacter(0); - return (c >= 'A' && c <= 'Z') || + v8::String::Value value(string); + Q_ASSERT(*value != NULL); + uint16_t c = **value; + return (c >= 'A' && c <= 'Z') || (c > 127 && QChar::category(c) == QChar::Letter_Uppercase); } diff --git a/src/qml/qml/v8/qv8qobjectwrapper.cpp b/src/qml/qml/v8/qv8qobjectwrapper.cpp index 4539401a3b..0982f177d3 100644 --- a/src/qml/qml/v8/qv8qobjectwrapper.cpp +++ b/src/qml/qml/v8/qv8qobjectwrapper.cpp @@ -277,7 +277,7 @@ static v8::Handle<v8::Value> GenericValueGetter(v8::Local<v8::String>, const v8: if (QQmlData::wasDeleted(object)) return v8::Undefined(); QQmlPropertyData *property = - (QQmlPropertyData *)v8::External::Unwrap(info.Data()); + (QQmlPropertyData *)v8::External::Cast(*info.Data())->Value(); QQmlEngine *engine = resource->engine->engine(); QQmlEnginePrivate *ep = engine?QQmlEnginePrivate::get(engine):0; @@ -894,7 +894,7 @@ static void FastValueSetter(v8::Local<v8::String>, v8::Local<v8::Value> value, QObject *object = resource->object; QQmlPropertyData *property = - (QQmlPropertyData *)v8::External::Unwrap(info.Data()); + (QQmlPropertyData *)v8::External::Cast(*info.Data())->Value(); int index = property->coreIndex; @@ -1029,7 +1029,7 @@ v8::Local<v8::Object> QQmlPropertyCache::newQObject(QObject *object, QV8Engine * // this type and the property accessor checks if the object is 0 (deleted) before // dereferencing the pointer. ft->InstanceTemplate()->SetAccessor(engine->toString(iter.key()), fastgetter, fastsetter, - v8::External::Wrap(property)); + v8::External::New(property)); } } diff --git a/src/qml/qml/v8/qv8sqlerrors_p.h b/src/qml/qml/v8/qv8sqlerrors_p.h index b2ffbf9233..8a612d69ab 100644 --- a/src/qml/qml/v8/qv8sqlerrors_p.h +++ b/src/qml/qml/v8/qv8sqlerrors_p.h @@ -55,8 +55,6 @@ #include <QtCore/qglobal.h> -QT_BEGIN_HEADER - QT_BEGIN_NAMESPACE #define SQLEXCEPTION_UNKNOWN_ERR 1 #define SQLEXCEPTION_DATABASE_ERR 2 @@ -72,6 +70,4 @@ void qt_add_sqlexceptions(QV8Engine *engine); QT_END_NAMESPACE -QT_END_HEADER - #endif // QV8SQLERRORS_P_H diff --git a/src/qml/qml/v8/qv8worker.cpp b/src/qml/qml/v8/qv8worker.cpp index bf3379b312..9556e146ef 100644 --- a/src/qml/qml/v8/qv8worker.cpp +++ b/src/qml/qml/v8/qv8worker.cpp @@ -41,8 +41,8 @@ #include "qv8worker_p.h" -#include <private/qquicklistmodel_p.h> -#include <private/qquicklistmodelworkeragent_p.h> +#include <private/qqmllistmodel_p.h> +#include <private/qqmllistmodelworkeragent_p.h> QT_BEGIN_NAMESPACE @@ -242,9 +242,9 @@ void QV8Worker::serialize(QByteArray &data, v8::Handle<v8::Value> v, QV8Engine * } else if (engine->isQObject(v)) { // XXX TODO: Generalize passing objects between the main thread and worker scripts so // that others can trivially plug in their elements. - QQuickListModel *lm = qobject_cast<QQuickListModel *>(engine->toQObject(v)); + QQmlListModel *lm = qobject_cast<QQmlListModel *>(engine->toQObject(v)); if (lm && lm->agent()) { - QQuickListModelWorkerAgent *agent = lm->agent(); + QQmlListModelWorkerAgent *agent = lm->agent(); agent->addref(); push(data, valueheader(WorkerListModel)); push(data, (void *)agent); @@ -347,10 +347,10 @@ v8::Handle<v8::Value> QV8Worker::deserialize(const char *&data, QV8Engine *engin case WorkerListModel: { void *ptr = popPtr(data); - QQuickListModelWorkerAgent *agent = (QQuickListModelWorkerAgent *)ptr; + QQmlListModelWorkerAgent *agent = (QQmlListModelWorkerAgent *)ptr; v8::Handle<v8::Value> rv = engine->newQObject(agent); if (rv->IsObject()) { - QQuickListModelWorkerAgent::VariantRef ref(agent); + QQmlListModelWorkerAgent::VariantRef ref(agent); QVariant var = qVariantFromValue(ref); rv->ToObject()->SetHiddenValue(v8::String::New("qml::ref"), engine->fromVariant(var)); } |