diff options
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qqmlcodegenerator.cpp | 35 | ||||
-rw-r--r-- | src/qml/compiler/qqmlcodegenerator_p.h | 12 |
2 files changed, 34 insertions, 13 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp index ab9958335e..dda8cd5b17 100644 --- a/src/qml/compiler/qqmlcodegenerator.cpp +++ b/src/qml/compiler/qqmlcodegenerator.cpp @@ -77,6 +77,7 @@ void QmlObject::init(MemoryPool *pool, int typeNameIndex, int id, const AST::Sou qmlSignals = pool->New<PoolList<Signal> >(); bindings = pool->New<PoolList<Binding> >(); functions = pool->New<PoolList<Function> >(); + declarationsOverride = 0; } void QmlObject::dump(DebugStream &out) @@ -222,7 +223,7 @@ bool QQmlCodeGenerator::visit(AST::UiObjectDefinition *node) int idx = defineQMLObject(node); appendBinding(node->qualifiedTypeNameId->identifierToken, emptyStringIndex, idx); } else { - int idx = defineQMLObject(/*qualfied type name id*/0, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer); + int idx = defineQMLObject(/*qualfied type name id*/0, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, /*declarations should go here*/_object); appendBinding(node->qualifiedTypeNameId, idx); } return false; @@ -315,7 +316,7 @@ bool QQmlCodeGenerator::sanityCheckFunctionNames() return true; } -int QQmlCodeGenerator::defineQMLObject(AST::UiQualifiedId *qualifiedTypeNameId, const AST::SourceLocation &location, AST::UiObjectInitializer *initializer) +int QQmlCodeGenerator::defineQMLObject(AST::UiQualifiedId *qualifiedTypeNameId, const AST::SourceLocation &location, AST::UiObjectInitializer *initializer, QmlObject *declarationsOverride) { QmlObject *obj = New<QmlObject>(); _objects.append(obj); @@ -323,12 +324,16 @@ int QQmlCodeGenerator::defineQMLObject(AST::UiQualifiedId *qualifiedTypeNameId, qSwap(_object, obj); _object->init(pool, registerString(asString(qualifiedTypeNameId)), emptyStringIndex, location); + _object->declarationsOverride = declarationsOverride; - QSet<QString> propertyNames; - QSet<QString> signalNames; + // A new object is also a boundary for property declarations. + QmlProperty *declaration = 0; + qSwap(_propertyDeclaration, declaration); accept(initializer); + qSwap(_propertyDeclaration, declaration); + sanityCheckFunctionNames(); qSwap(_object, obj); @@ -515,6 +520,8 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node) static const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) / sizeof(propTypeNameToTypes[0]); + QmlObject *declarationsTarget = _object->declarationsOverride ? _object->declarationsOverride : _object; + if (node->type == AST::UiPublicMember::Signal) { Signal *signal = New<Signal>(); QString signalName = node->name.toString(); @@ -590,7 +597,7 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node) if (illegalNames.contains(signalName)) COMPILE_EXCEPTION(node->identifierToken, tr("Illegal signal name")); - _object->qmlSignals->append(signal); + declarationsTarget->qmlSignals->append(signal); } else { const QStringRef &memberType = node->memberType; const QStringRef &name = node->name; @@ -712,7 +719,7 @@ bool QQmlCodeGenerator::visit(AST::UiPublicMember *node) qSwap(_propertyDeclaration, property); } - _object->properties->append(property); + declarationsTarget->properties->append(property); if (node->isDefaultMember) { if (_object->indexOfDefaultProperty != -1) { @@ -747,7 +754,8 @@ bool QQmlCodeGenerator::visit(AST::UiSourceElement *node) f->location.line = loc.startLine; f->location.column = loc.startColumn; f->index = _functions.size() - 1; - _object->functions->append(f); + QmlObject *functionDeclarationsTarget = _object->declarationsOverride ? _object->declarationsOverride : _object; + functionDeclarationsTarget->functions->append(f); } else { QQmlError error; error.setDescription(QCoreApplication::translate("QQmlParser","JavaScript declaration outside Script element")); @@ -882,7 +890,7 @@ void QQmlCodeGenerator::appendBinding(const AST::SourceLocation &nameLocation, i binding->location.column = nameLocation.startColumn; binding->flags = 0; setBindingValue(binding, value); - _object->bindings->append(binding); + bindingsTarget()->append(binding); } void QQmlCodeGenerator::appendBinding(const AST::SourceLocation &nameLocation, int propertyNameIndex, int objectIndex, bool isListItem, bool isOnAssignment) @@ -918,7 +926,14 @@ void QQmlCodeGenerator::appendBinding(const AST::SourceLocation &nameLocation, i binding->flags |= QV4::CompiledData::Binding::IsOnAssignment; binding->value.objectIndex = objectIndex; - _object->bindings->append(binding); + bindingsTarget()->append(binding); +} + +PoolList<Binding> *QQmlCodeGenerator::bindingsTarget() const +{ + if (_propertyDeclaration && _object->declarationsOverride) + return _object->declarationsOverride->bindings; + return _object->bindings; } bool QQmlCodeGenerator::setId(AST::Statement *value) @@ -1003,7 +1018,7 @@ bool QQmlCodeGenerator::resolveQualifiedId(AST::UiQualifiedId **nameToResolve, Q else binding->type = QV4::CompiledData::Binding::Type_GroupProperty; - int objIndex = defineQMLObject(0, AST::SourceLocation(), 0); + int objIndex = defineQMLObject(0, AST::SourceLocation(), 0, 0); binding->value.objectIndex = objIndex; (*object)->bindings->append(binding); diff --git a/src/qml/compiler/qqmlcodegenerator_p.h b/src/qml/compiler/qqmlcodegenerator_p.h index 56b0df5d8f..b2c17405a2 100644 --- a/src/qml/compiler/qqmlcodegenerator_p.h +++ b/src/qml/compiler/qqmlcodegenerator_p.h @@ -155,6 +155,10 @@ struct QmlObject PoolList<Binding> *bindings; PoolList<Function> *functions; + // If set, then declarations for this object (and init bindings for these) should go into the + // specified object. Used for declarations inside group properties. + QmlObject *declarationsOverride; + // caches to quickly find duplicates QSet<QString> propertyNames; QSet<QString> signalNames; @@ -243,9 +247,9 @@ public: void accept(AST::Node *node); // returns index in _objects - int defineQMLObject(AST::UiQualifiedId *qualifiedTypeNameId, const AST::SourceLocation &location, AST::UiObjectInitializer *initializer); - int defineQMLObject(AST::UiObjectDefinition *node) - { return defineQMLObject(node->qualifiedTypeNameId, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer); } + int defineQMLObject(AST::UiQualifiedId *qualifiedTypeNameId, const AST::SourceLocation &location, AST::UiObjectInitializer *initializer, QmlObject *declarationsOverride = 0); + int defineQMLObject(AST::UiObjectDefinition *node, QmlObject *declarationsOverride = 0) + { return defineQMLObject(node->qualifiedTypeNameId, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, declarationsOverride); } static QString asString(AST::UiQualifiedId *node); QStringRef asStringRef(AST::Node *node); @@ -266,6 +270,8 @@ public: void appendBinding(const AST::SourceLocation &nameLocation, int propertyNameIndex, AST::Statement *value); void appendBinding(const AST::SourceLocation &nameLocation, int propertyNameIndex, int objectIndex, bool isListItem = false, bool isOnAssignment = false); + PoolList<Binding> *bindingsTarget() const; + bool setId(AST::Statement *value); // resolves qualified name (font.pixelSize for example) and returns the last name along |