Use QFieldList to manage dynamic properties, signals and slots
authorAaron Kennedy <aaron.kennedy@nokia.com>
Thu, 21 Jul 2011 07:38:30 +0000 (17:38 +1000)
committerQt by Nokia <qt-info@nokia.com>
Tue, 30 Aug 2011 11:18:28 +0000 (13:18 +0200)
Change-Id: I27282a035a631dde30ee97412d3968ab525b2502
Reviewed-on: http://codereview.qt.nokia.com/3766
Reviewed-by: Roberto Raggi <roberto.raggi@nokia.com>
src/declarative/qml/qdeclarativecompiler.cpp
src/declarative/qml/qdeclarativeparser.cpp
src/declarative/qml/qdeclarativeparser_p.h
src/declarative/qml/qdeclarativescriptparser.cpp

index 31f5490..9c59787 100644 (file)
@@ -2383,15 +2383,18 @@ int QDeclarativeCompiler::rewriteBinding(const QString& expression, const QStrin
 // Ensures that the dynamic meta specification on obj is valid
 bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
 {
-    // XXX aakenned - inefficient copying of the string ref
-    QStringHash<bool> propNames;
-    QSet<QByteArray> methodNames;
     bool seenDefaultProperty = false;
 
+    // We use a coarse grain, 31 bit hash to check if there are duplicates.
+    // Calculating the hash for the names is not a waste as we have to test
+    // them against the illegalNames set anyway.
+    quint32 propNames = 0;
+    quint32 methodNames = 0;
+
     // Check properties
-    for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-        const QDeclarativeParser::Object::DynamicProperty &prop =
-            obj->dynamicProperties.at(ii);
+    int dpCount = obj->dynamicProperties.count();
+    for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+        const QDeclarativeParser::Object::DynamicProperty &prop = *p;
 
         if (prop.isDefaultProperty) {
             if (seenDefaultProperty)
@@ -2399,16 +2402,22 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
             seenDefaultProperty = true;
         }
 
-        if (propNames.contains(prop.name))
-            COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
+        quint32 hash = prop.name.hash();
+        quint32 bit = hash % 31;
+        if (propNames & (1 << bit)) {
+            for (Object::DynamicProperty *p2 = obj->dynamicProperties.first(); p2 != p; 
+                 p2 = obj->dynamicProperties.next(p2)) {
+                if (p2->name == prop.name)
+                    COMPILE_EXCEPTION(&prop, tr("Duplicate property name"));
+            }
+        }
+        propNames |= (1 << bit);
 
         if (QDeclarativeUtils::isUpper(prop.name.at(0)))
             COMPILE_EXCEPTION(&prop, tr("Property names cannot begin with an upper case letter"));
 
         if (enginePrivate->v8engine()->illegalNames().contains(prop.name))
             COMPILE_EXCEPTION(&prop, tr("Illegal property name"));
-
-        propNames.insert(prop.name.toString(), true);
     }
 
     for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
@@ -2455,17 +2464,16 @@ bool QDeclarativeCompiler::checkDynamicMeta(QDeclarativeParser::Object *obj)
 
 bool QDeclarativeCompiler::mergeDynamicMetaProperties(QDeclarativeParser::Object *obj)
 {
-    for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-        const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+    for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
 
-        if (!p.defaultValue || p.type == Object::DynamicProperty::Alias)
+        if (!p->defaultValue || p->type == Object::DynamicProperty::Alias)
             continue;
 
         Property *property = 0;
-        if (p.isDefaultProperty) {
+        if (p->isDefaultProperty) {
             property = obj->getDefaultProperty();
         } else {
-            property = obj->getProperty(p.name);
+            property = obj->getProperty(p->name);
             if (!property->values.isEmpty()) 
                 COMPILE_EXCEPTION(property, tr("Property value set multiple times"));
         }
@@ -2473,7 +2481,7 @@ bool QDeclarativeCompiler::mergeDynamicMetaProperties(QDeclarativeParser::Object
         if (property->value)
             COMPILE_EXCEPTION(property, tr("Invalid property nesting"));
 
-        property->values.append(p.defaultValue->values);
+        property->values.append(p->defaultValue->values);
     }
     return true;
 }
@@ -2496,21 +2504,20 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
     const Object::DynamicProperty *defaultProperty = 0;
     int aliasCount = 0;
 
-    for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-        const Object::DynamicProperty &p = obj->dynamicProperties.at(ii);
+    for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
 
-        if (p.type == Object::DynamicProperty::Alias)
+        if (p->type == Object::DynamicProperty::Alias)
             aliasCount++;
 
-        if (p.isDefaultProperty && 
-            (resolveAlias || p.type != Object::DynamicProperty::Alias))
-            defaultProperty = &p;
+        if (p->isDefaultProperty && 
+            (resolveAlias || p->type != Object::DynamicProperty::Alias))
+            defaultProperty = p;
 
         if (!resolveAlias) {
             // No point doing this for both the alias and non alias cases
-            QDeclarativePropertyCache::Data *d = property(obj, p.name);
+            QDeclarativePropertyCache::Data *d = property(obj, p->name);
             if (d && d->isFinal())
-                COMPILE_EXCEPTION(&p, tr("Cannot override FINAL property"));
+                COMPILE_EXCEPTION(p, tr("Cannot override FINAL property"));
         }
     }
 
@@ -2573,38 +2580,37 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
         typedef QDeclarativeVMEMetaData VMD;
 
         int effectivePropertyIndex = 0;
-        for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-            Object::DynamicProperty &p = obj->dynamicProperties[ii];
+        for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
 
             // Reserve space for name
-            p.nameRef = builder.newString(p.name.utf8length());
+            p->nameRef = builder.newString(p->name.utf8length());
 
             int propertyType = 0;
             bool readonly = false;
             QFastMetaBuilder::StringRef typeRef;
 
-            if (p.type == Object::DynamicProperty::Alias) {
+            if (p->type == Object::DynamicProperty::Alias) {
                 continue;
-            } else if (p.type < builtinTypeCount) {
-                Q_ASSERT(builtinTypes[p.type].dtype == p.type);
-                propertyType = builtinTypes[p.type].metaType;
-                if (typeRefs[p.type].isEmpty()) 
-                    typeRefs[p.type] = builder.newString(strlen(builtinTypes[p.type].cppType));
-                typeRef = typeRefs[p.type];
-                if (p.type == Object::DynamicProperty::Variant)
+            } else if (p->type < builtinTypeCount) {
+                Q_ASSERT(builtinTypes[p->type].dtype == p->type);
+                propertyType = builtinTypes[p->type].metaType;
+                if (typeRefs[p->type].isEmpty()) 
+                    typeRefs[p->type] = builder.newString(strlen(builtinTypes[p->type].cppType));
+                typeRef = typeRefs[p->type];
+                if (p->type == Object::DynamicProperty::Variant)
                     propertyType = qMetaTypeId<QVariant>();
 
             } else {
-                Q_ASSERT(p.type == Object::DynamicProperty::CustomList ||
-                         p.type == Object::DynamicProperty::Custom);
+                Q_ASSERT(p->type == Object::DynamicProperty::CustomList ||
+                         p->type == Object::DynamicProperty::Custom);
 
                 // XXX don't double resolve this in the case of an alias run
 
                 QByteArray customTypeName;
                 QDeclarativeType *qmltype = 0;
                 QString url;
-                if (!unit->imports().resolveType(p.customType.toUtf8(), &qmltype, &url, 0, 0, 0)) 
-                    COMPILE_EXCEPTION(&p, tr("Invalid property type"));
+                if (!unit->imports().resolveType(p->customType.toUtf8(), &qmltype, &url, 0, 0, 0)) 
+                    COMPILE_EXCEPTION(p, tr("Invalid property type"));
 
                 if (!qmltype) {
                     QDeclarativeTypeData *tdata = enginePrivate->typeLoader.get(QUrl(url));
@@ -2619,7 +2625,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
                     customTypeName = qmltype->typeName();
                 }
 
-                if (p.type == Object::DynamicProperty::Custom) {
+                if (p->type == Object::DynamicProperty::Custom) {
                     customTypeName += '*';
                     propertyType = QMetaType::QObjectStar;
                 } else {
@@ -2628,9 +2634,9 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
                     propertyType = qMetaTypeId<QDeclarativeListProperty<QObject> >();
                 }
 
-                p.resolvedCustomTypeName = pool->NewByteArray(customTypeName);
-                p.typeRef = builder.newString(customTypeName.length());
-                typeRef = p.typeRef;
+                p->resolvedCustomTypeName = pool->NewByteArray(customTypeName);
+                p->typeRef = builder.newString(customTypeName.length());
+                typeRef = p->typeRef;
             }
 
             if (buildData) {
@@ -2639,35 +2645,35 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
                 (vmd->propertyData() + effectivePropertyIndex)->propertyType = propertyType;
             }
 
-            if (p.type < builtinTypeCount)
-                builder.setProperty(effectivePropertyIndex, p.nameRef, typeRef, (QMetaType::Type)propertyType, 
+            if (p->type < builtinTypeCount)
+                builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, (QMetaType::Type)propertyType, 
                                     readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, 
                                     effectivePropertyIndex);
             else 
-                builder.setProperty(effectivePropertyIndex, p.nameRef, typeRef, 
+                builder.setProperty(effectivePropertyIndex, p->nameRef, typeRef, 
                                     readonly?QFastMetaBuilder::None:QFastMetaBuilder::Writable, 
                                     effectivePropertyIndex);
 
-            p.changedSignatureRef = builder.newString(p.name.utf8length() + strlen("Changed()"));
-            builder.setSignal(effectivePropertyIndex, p.changedSignatureRef);
+            p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()"));
+            builder.setSignal(effectivePropertyIndex, p->changedSignatureRef);
 
             effectivePropertyIndex++;
         }
         
         if (aliasCount) {
             int aliasIndex = 0;
-            for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-                Object::DynamicProperty &p = obj->dynamicProperties[ii];
-                if (p.type == Object::DynamicProperty::Alias) {
+            for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
+                if (p->type == Object::DynamicProperty::Alias) {
                     if (resolveAlias) {
                         Q_ASSERT(buildData);
                         ((QDeclarativeVMEMetaData *)dynamicData.data())->aliasCount++;
-                        COMPILE_CHECK(compileAlias(builder, dynamicData, obj, effectivePropertyIndex, aliasIndex, p));
+                        COMPILE_CHECK(compileAlias(builder, dynamicData, obj, effectivePropertyIndex, 
+                                                   aliasIndex, *p));
                     }
                     // Even if we aren't resolving the alias, we need a fake signal so that the 
                     // metaobject remains consistent across the resolve and non-resolve alias runs
-                    p.changedSignatureRef = builder.newString(p.name.utf8length() + strlen("Changed()"));
-                    builder.setSignal(effectivePropertyIndex, p.changedSignatureRef);
+                    p->changedSignatureRef = builder.newString(p->name.utf8length() + strlen("Changed()"));
+                    builder.setSignal(effectivePropertyIndex, p->changedSignatureRef);
                     effectivePropertyIndex++;
                     aliasIndex++;
                 }
@@ -2683,23 +2689,24 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
     }
 
     // Reserve dynamic signals
-    for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
-        Object::DynamicSignal &s = obj->dynamicSignals[ii];
+    int signalIndex = 0;
+    for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
 
-        int paramCount = s.parameterNames.count();
+        int paramCount = s->parameterNames.count();
 
-        int signatureSize = s.name.length() + 2 /* paren */;
+        int signatureSize = s->name.utf8length() + 2 /* paren */;
         int namesSize = 0;
-        if (paramCount) signatureSize += s.parameterTypesLength() + (paramCount - 1) /* commas */;
-        if (paramCount) namesSize += s.parameterNamesLength() + (paramCount - 1) /* commas */;
+        if (paramCount) signatureSize += s->parameterTypesLength() + (paramCount - 1) /* commas */;
+        if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1) /* commas */;
 
-        s.signatureRef = builder.newString(signatureSize);
-        if (namesSize) s.parameterNamesRef = builder.newString(namesSize);
+        s->signatureRef = builder.newString(signatureSize);
+        if (namesSize) s->parameterNamesRef = builder.newString(namesSize);
 
         if (buildData)
             ((QDeclarativeVMEMetaData *)dynamicData.data())->signalCount++;
         
-        builder.setSignal(ii + obj->dynamicProperties.count(), s.signatureRef, s.parameterNamesRef);
+        builder.setSignal(signalIndex + obj->dynamicProperties.count(), s->signatureRef, s->parameterNamesRef);
+        ++signalIndex;
     }
 
     // Reserve dynamic slots
@@ -2711,39 +2718,39 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
 
         typedef QDeclarativeVMEMetaData VMD;
 
-        for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
-            Object::DynamicSlot &s = obj->dynamicSlots[ii];
-            int paramCount = s.parameterNames.count();
+        int methodIndex = 0;
+        for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) {
+            int paramCount = s->parameterNames.count();
 
-            int signatureSize = s.name.length() + 2 /* paren */;
+            int signatureSize = s->name.utf8length() + 2 /* paren */;
             int namesSize = 0; 
             if (paramCount) signatureSize += (paramCount * strlen("QVariant") + (paramCount - 1));
-            if (paramCount) namesSize += s.parameterNamesLength() + (paramCount - 1 /* commas */); 
+            if (paramCount) namesSize += s->parameterNamesLength() + (paramCount - 1 /* commas */); 
 
-            s.signatureRef = builder.newString(signatureSize);
-            if (namesSize) s.parameterNamesRef = builder.newString(namesSize);
+            s->signatureRef = builder.newString(signatureSize);
+            if (namesSize) s->parameterNamesRef = builder.newString(namesSize);
 
-            builder.setMethod(ii, s.signatureRef, s.parameterNamesRef, typeRefs[0]);
+            builder.setMethod(methodIndex, s->signatureRef, s->parameterNamesRef, typeRefs[0]);
 
             if (buildData) {
                 QString funcScript;
-                funcScript.reserve(strlen("(function ") + s.name.length() + 1 /* lparen */ + 
-                        namesSize + 1 /* rparen */ + s.body.length() + 1 /* rparen */);
-                funcScript = QLatin1String("(function ") + s.name + QLatin1Char('(');
+                funcScript.reserve(strlen("(function ") + s->name.length() + 1 /* lparen */ + 
+                        namesSize + 1 /* rparen */ + s->body.length() + 1 /* rparen */);
+                funcScript = QLatin1String("(function ") + s->name.toString() + QLatin1Char('(');
                 for (int jj = 0; jj < paramCount; ++jj) {
                     if (jj) funcScript.append(QLatin1Char(','));
-                    funcScript.append(QLatin1String(s.parameterNames.at(jj)));
+                    funcScript.append(QLatin1String(s->parameterNames.at(jj)));
                 }
-                funcScript += QLatin1Char(')') + s.body + QLatin1Char(')');
+                funcScript += QLatin1Char(')') + s->body + QLatin1Char(')');
 
-                VMD::MethodData methodData = { s.parameterNames.count(), 0, 
+                VMD::MethodData methodData = { s->parameterNames.count(), 0, 
                                                funcScript.length(), 
-                                               s.location.start.line };
+                                               s->location.start.line };
 
                 VMD *vmd = (QDeclarativeVMEMetaData *)dynamicData.data();
                 vmd->methodCount++;
 
-                VMD::MethodData &md = *(vmd->methodData() + ii);
+                VMD::MethodData &md = *(vmd->methodData() + methodIndex);
                 md = methodData;
                 md.bodyOffset = dynamicData.size();
 
@@ -2751,6 +2758,7 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
                                    (funcScript.length() * sizeof(QChar)));
             }
 
+            methodIndex++;
         }
     }
 
@@ -2761,21 +2769,20 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
     }
 
     // Now allocate properties
-    for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
-        Object::DynamicProperty &p = obj->dynamicProperties[ii];
+    for (Object::DynamicProperty *p = obj->dynamicProperties.first(); p; p = obj->dynamicProperties.next(p)) {
 
-        char *d = p.changedSignatureRef.data();
-        p.name.writeUtf8(d);
-        strcpy(d + p.name.utf8length(), "Changed()");
+        char *d = p->changedSignatureRef.data();
+        p->name.writeUtf8(d);
+        strcpy(d + p->name.utf8length(), "Changed()");
 
-        if (p.type == Object::DynamicProperty::Alias && !resolveAlias)
+        if (p->type == Object::DynamicProperty::Alias && !resolveAlias)
             continue;
 
-        p.nameRef.load(p.name);
+        p->nameRef.load(p->name);
 
-        if (p.type >= builtinTypeCount) {
-            Q_ASSERT(p.resolvedCustomTypeName);
-            p.typeRef.load(*p.resolvedCustomTypeName);
+        if (p->type >= builtinTypeCount) {
+            Q_ASSERT(p->resolvedCustomTypeName);
+            p->typeRef.load(*p->resolvedCustomTypeName);
         }
     }
 
@@ -2784,21 +2791,19 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
         strcpy(defPropRef.data(), "DefaultProperty");
 
     // Now allocate signals
-    for (int ii = 0; ii < obj->dynamicSignals.count(); ++ii) {
-        Object::DynamicSignal &s = obj->dynamicSignals[ii];
+    for (Object::DynamicSignal *s = obj->dynamicSignals.first(); s; s = obj->dynamicSignals.next(s)) {
 
-        char *d = s.signatureRef.data();
-        char *d2 = s.parameterNamesRef.isEmpty()?0:s.parameterNamesRef.data();
-        strcpy(d, s.name.constData());
-        d += s.name.length();
+        char *d = s->signatureRef.data();
+        char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data();
+        s->name.writeUtf8(d); d += s->name.utf8length();
         *d++ = '('; 
 
-        for (int jj = 0; jj < s.parameterNames.count(); ++jj) {
+        for (int jj = 0; jj < s->parameterNames.count(); ++jj) {
             if (jj != 0) { *d++ = ','; *d2++ = ','; }
-            strcpy(d, s.parameterTypes.at(jj).constData());
-            d += s.parameterTypes.at(jj).length();
-            strcpy(d2, s.parameterNames.at(jj).constData());
-            d2 += s.parameterNames.at(jj).length();
+            strcpy(d, s->parameterTypes.at(jj).constData());
+            d += s->parameterTypes.at(jj).length();
+            strcpy(d2, s->parameterNames.at(jj).constData());
+            d2 += s->parameterNames.at(jj).length();
         }
         *d++ = ')';
         *d = 0;
@@ -2806,19 +2811,17 @@ bool QDeclarativeCompiler::buildDynamicMeta(QDeclarativeParser::Object *obj, Dyn
     }
 
     // Now allocate methods
-    for (int ii = 0; ii < obj->dynamicSlots.count(); ++ii) {
-        Object::DynamicSlot &s = obj->dynamicSlots[ii];
-        char *d = s.signatureRef.data();
-        char *d2 = s.parameterNamesRef.isEmpty()?0:s.parameterNamesRef.data();
-        strcpy(d, s.name.constData());
-        d += s.name.length();
+    for (Object::DynamicSlot *s = obj->dynamicSlots.first(); s; s = obj->dynamicSlots.next(s)) {
+        char *d = s->signatureRef.data();
+        char *d2 = s->parameterNamesRef.isEmpty()?0:s->parameterNamesRef.data();
+        s->name.writeUtf8(d); d += s->name.utf8length();
         *d++ = '('; 
-        for (int jj = 0; jj < s.parameterNames.count(); ++jj) {
+        for (int jj = 0; jj < s->parameterNames.count(); ++jj) {
             if (jj != 0) { *d++ = ','; *d2++ = ','; }
             strcpy(d, "QVariant");
             d += strlen("QVariant");
-            strcpy(d2, s.parameterNames.at(jj).constData());
-            d2 += s.parameterNames.at(jj).length();
+            strcpy(d2, s->parameterNames.at(jj).constData());
+            d2 += s->parameterNames.at(jj).length();
         }
         *d++ = ')';
         *d = 0;
@@ -2991,7 +2994,7 @@ bool QDeclarativeCompiler::compileAlias(QFastMetaBuilder &builder,
     VMD *vmd = (QDeclarativeVMEMetaData *)data.data();
     *(vmd->aliasData() + aliasIndex) = aliasData;
 
-    prop.nameRef = builder.newString(prop.name.length());
+    prop.nameRef = builder.newString(prop.name.utf8length());
     prop.resolvedCustomTypeName = pool->NewByteArray(typeName);
     prop.typeRef = builder.newString(typeName.length());
 
index 123bb7f..00bad1d 100644 (file)
@@ -176,28 +176,13 @@ Property *QDeclarativeParser::Object::getProperty(const QString &name, bool crea
 }
 
 QDeclarativeParser::Object::DynamicProperty::DynamicProperty()
-: isDefaultProperty(false), type(Variant), defaultValue(0), resolvedCustomTypeName(0)
-{
-}
-
-QDeclarativeParser::Object::DynamicProperty::DynamicProperty(const DynamicProperty &o)
-: isDefaultProperty(o.isDefaultProperty),
-  type(o.type),
-  customType(o.customType),
-  name(o.name),
-  defaultValue(o.defaultValue),
-  location(o.location),
-  resolvedCustomTypeName(o.resolvedCustomTypeName)
+: isDefaultProperty(false), type(Variant), defaultValue(0), nextProperty(0), 
+  resolvedCustomTypeName(0)
 {
 }
 
 QDeclarativeParser::Object::DynamicSignal::DynamicSignal()
-{
-}
-
-QDeclarativeParser::Object::DynamicSignal::DynamicSignal(const DynamicSignal &o)
-: name(o.name), parameterTypes(o.parameterTypes), 
-  parameterNames(o.parameterNames), location(o.location)
+: nextSignal(0)
 {
 }
 
@@ -218,11 +203,7 @@ int QDeclarativeParser::Object::DynamicSignal::parameterNamesLength() const
 }
 
 QDeclarativeParser::Object::DynamicSlot::DynamicSlot()
-{
-}
-
-QDeclarativeParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
-: name(o.name), body(o.body), parameterNames(o.parameterNames), location(o.location)
+: nextSlot(0)
 {
 }
 
index 18c93fe..86b06de 100644 (file)
@@ -365,9 +365,9 @@ namespace QDeclarativeParser
 
         LocationSpan location;
 
-        struct DynamicProperty {
+        struct DynamicProperty : public QDeclarativePool::POD 
+        {
             DynamicProperty();
-            DynamicProperty(const DynamicProperty &);
 
             enum Type { Variant, Int, Bool, Real, String, Url, Color, Time, 
                         Date, DateTime, Alias, Custom, CustomList };
@@ -380,49 +380,63 @@ namespace QDeclarativeParser
             QDeclarativeParser::Property *defaultValue;
             LocationSpan location;
 
+            // Used by Object::DynamicPropertyList
+            DynamicProperty *nextProperty;
+
             // Used by the compiler
             QByteArray *resolvedCustomTypeName;
             QFastMetaBuilder::StringRef typeRef;
             QFastMetaBuilder::StringRef nameRef;
             QFastMetaBuilder::StringRef changedSignatureRef;
         };
-        struct DynamicSignal {
+
+        struct DynamicSignal : public QDeclarativePool::Class
+        {
             DynamicSignal();
-            DynamicSignal(const DynamicSignal &);
 
-            QByteArray name;
+            QHashedStringRef name;
             QList<QHashedCStringRef> parameterTypes;
             QList<QByteArray> parameterNames;
 
             int parameterTypesLength() const;
             int parameterNamesLength() const;
 
+            // Used by Object::DynamicSignalList
+            DynamicSignal *nextSignal;
+
             // Used by the compiler
             QFastMetaBuilder::StringRef signatureRef;
             QFastMetaBuilder::StringRef parameterNamesRef;
         };
-        struct DynamicSlot {
+
+        struct DynamicSlot : public QDeclarativePool::Class
+        {
             DynamicSlot();
-            DynamicSlot(const DynamicSlot &);
 
-            QByteArray name;
+            QHashedStringRef name;
             QString body;
             QList<QByteArray> parameterNames;
             LocationSpan location;
 
             int parameterNamesLength() const;
 
+            // Used by Object::DynamicSlotList
+            DynamicSlot *nextSlot;
+
             // Used by the compiler
             QFastMetaBuilder::StringRef signatureRef;
             QFastMetaBuilder::StringRef parameterNamesRef;
         };
 
         // The list of dynamic properties
-        QList<DynamicProperty> dynamicProperties;
+        typedef QFieldList<DynamicProperty, &DynamicProperty::nextProperty> DynamicPropertyList;
+        DynamicPropertyList dynamicProperties;
         // The list of dynamic signals
-        QList<DynamicSignal> dynamicSignals;
+        typedef QFieldList<DynamicSignal, &DynamicSignal::nextSignal> DynamicSignalList;
+        DynamicSignalList dynamicSignals;
         // The list of dynamic slots
-        QList<DynamicSlot> dynamicSlots;
+        typedef QFieldList<DynamicSlot, &DynamicSlot::nextSlot> DynamicSlotList;
+        DynamicSlotList dynamicSlots;
 
         // Used by compiler
         QDeclarativeCompilerTypes::ComponentCompileState *componentCompileState;
index 458fd5e..7cca388 100644 (file)
@@ -539,8 +539,8 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
                                                 sizeof(propTypeNameToTypes[0]);
 
     if(node->type == AST::UiPublicMember::Signal) {
-        Object::DynamicSignal signal;
-        signal.name = node->name.toUtf8();
+        Object::DynamicSignal *signal = _parser->_pool.New<Object::DynamicSignal>();
+        signal->name = node->name;
 
         AST::UiParameterList *p = node->parameters;
         while (p) {
@@ -565,13 +565,13 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
                 return false;
             }
             
-            signal.parameterTypes << QHashedCStringRef(type->qtName, type->qtNameLength);
-            signal.parameterNames << p->name.toUtf8();
+            signal->parameterTypes << QHashedCStringRef(type->qtName, type->qtNameLength);
+            signal->parameterNames << p->name.toUtf8();
             p = p->finish();
         }
 
         signal.location = location(node->typeToken, node->semicolonToken);
-        _stateStack.top().object->dynamicSignals << signal;
+        _stateStack.top().object->dynamicSignals.append(signal);
     } else {
         const QStringRef &memberType = node->memberType;
         const QStringRef &name = node->name;
@@ -639,34 +639,34 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
 
         }
 
-        Object::DynamicProperty property;
-        property.isDefaultProperty = node->isDefaultMember;
-        property.type = type;
+        Object::DynamicProperty *property = _parser->_pool.New<Object::DynamicProperty>();
+        property->isDefaultProperty = node->isDefaultMember;
+        property->type = type;
         if (type >= Object::DynamicProperty::Custom) {
             QDeclarativeScriptParser::TypeReference *typeRef =
                 _parser->findOrCreateType(memberType.toString());
             typeRef->refObjects.append(_stateStack.top().object);
-            property.customType = memberType;
+            property->customType = memberType;
         }
 
-        property.name = QHashedStringRef(name);
-        property.location = location(node->firstSourceLocation(),
-                                     node->lastSourceLocation());
+        property->name = QHashedStringRef(name);
+        property->location = location(node->firstSourceLocation(),
+                                      node->lastSourceLocation());
 
         if (node->statement) { // default value
-            property.defaultValue = _parser->_pool.New<Property>();
-            property.defaultValue->parent = _stateStack.top().object;
-            property.defaultValue->location =
+            property->defaultValue = _parser->_pool.New<Property>();
+            property->defaultValue->parent = _stateStack.top().object;
+            property->defaultValue->location =
                     location(node->statement->firstSourceLocation(),
                              node->statement->lastSourceLocation());
             QDeclarativeParser::Value *value = _parser->_pool.New<QDeclarativeParser::Value>();
             value->location = location(node->statement->firstSourceLocation(),
                                        node->statement->lastSourceLocation());
             value->value = getVariant(node->statement);
-            property.defaultValue->values.append(value);
+            property->defaultValue->values.append(value);
         }
 
-        _stateStack.top().object->dynamicProperties << property;
+        _stateStack.top().object->dynamicProperties.append(property);
 
         // process QML-like initializers (e.g. property Object o: Object {})
         accept(node->binding);
@@ -827,12 +827,12 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
 
     if (AST::FunctionDeclaration *funDecl = AST::cast<AST::FunctionDeclaration *>(node->sourceElement)) {
 
-        Object::DynamicSlot slot;
-        slot.location = location(funDecl->firstSourceLocation(), funDecl->lastSourceLocation());
+        Object::DynamicSlot *slot = _parser->_pool.New<Object::DynamicSlot>();
+        slot->location = location(funDecl->firstSourceLocation(), funDecl->lastSourceLocation());
 
         AST::FormalParameterList *f = funDecl->formals;
         while (f) {
-            slot.parameterNames << f->name.toUtf8();
+            slot->parameterNames << f->name.toUtf8();
             f = f->finish();
         }
 
@@ -840,9 +840,9 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
         loc.offset = loc.end();
         loc.startColumn += 1;
         QString body = textAt(loc, funDecl->rbraceToken);
-        slot.name = funDecl->name.toUtf8();
-        slot.body = body;
-        obj->dynamicSlots << slot;
+        slot->name = funDecl->name;
+        slot->body = body;
+        obj->dynamicSlots.append(slot);
 
     } else {
         QDeclarativeError error;