diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qqmlcodegenerator.cpp | 10 | ||||
-rw-r--r-- | src/qml/compiler/qqmlcodegenerator_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 86 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmltypeloader.cpp | 79 |
5 files changed, 103 insertions, 82 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp index 19ccb6d0fd..a4da07ab66 100644 --- a/src/qml/compiler/qqmlcodegenerator.cpp +++ b/src/qml/compiler/qqmlcodegenerator.cpp @@ -736,6 +736,10 @@ bool QQmlCodeGenerator::visit(AST::UiSourceElement *node) if (AST::FunctionDeclaration *funDecl = AST::cast<AST::FunctionDeclaration *>(node->sourceElement)) { _functions << funDecl; Function *f = New<Function>(); + f->functionDeclaration = funDecl; + AST::SourceLocation loc = funDecl->firstSourceLocation(); + f->location.line = loc.startLine; + f->location.column = loc.startColumn; f->index = _functions.size() - 1; _object->functions->append(f); } else { @@ -1616,14 +1620,16 @@ SignalHandlerConverter::SignalHandlerConverter(QQmlEnginePrivate *enginePrivate, bool SignalHandlerConverter::convertSignalHandlerExpressionsToFunctionDeclarations() { - foreach (QmlObject *obj, parsedQML->objects) { + for (int objectIndex = 0; objectIndex < parsedQML->objects.count(); ++objectIndex) { + QmlObject * const obj = parsedQML->objects.at(objectIndex); QString elementName = stringAt(obj->inheritedTypeNameIndex); if (elementName.isEmpty()) continue; QQmlCompiledData::TypeReference &tr = unit->resolvedTypes[obj->inheritedTypeNameIndex]; if (tr.type && tr.type->customParser()) continue; - QQmlPropertyCache *cache = tr.createPropertyCache(QQmlEnginePrivate::get(enginePrivate)); + QQmlPropertyCache *cache = unit->propertyCaches.value(objectIndex); + Q_ASSERT(cache); if (!convertSignalHandlerExpressionsToFunctionDeclarations(obj, elementName, cache)) return false; } diff --git a/src/qml/compiler/qqmlcodegenerator_p.h b/src/qml/compiler/qqmlcodegenerator_p.h index 83ff716176..18193eea2b 100644 --- a/src/qml/compiler/qqmlcodegenerator_p.h +++ b/src/qml/compiler/qqmlcodegenerator_p.h @@ -135,6 +135,8 @@ struct Binding : public QV4::CompiledData::Binding struct Function { + AST::FunctionDeclaration *functionDeclaration; + QV4::CompiledData::Location location; int index; // index in parsedQML::functions Function *next; }; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index e6bf36bbf1..69ccd4c0ce 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -77,6 +77,14 @@ QQmlCompilePass::QQmlCompilePass(const QUrl &url, const QV4::CompiledData::QmlUn { } +QQmlCompilePass::QQmlCompilePass(const QUrl &url, const QStringList &stringTable) + : url(url) + , qmlUnit(0) + , stringTable(stringTable) +{ + +} + void QQmlCompilePass::recordError(const QV4::CompiledData::Location &location, const QString &description) { QQmlError error; @@ -95,32 +103,32 @@ void QQmlCompilePass::recordError(const QV4::CompiledData::Location &location, c static QAtomicInt classIndexCounter(0); -QQmlPropertyCacheCreator::QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QV4::CompiledData::QmlUnit *unit, const QUrl &url, const QQmlImports *imports, +QQmlPropertyCacheCreator::QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QStringList &stringTable, const QUrl &url, const QQmlImports *imports, QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes) - : QQmlCompilePass(url, unit) + : QQmlCompilePass(url, stringTable) , enginePrivate(enginePrivate) , imports(imports) , resolvedTypes(resolvedTypes) { } -bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQmlPropertyCache **resultCache, QByteArray *vmeMetaObjectData) +bool QQmlPropertyCacheCreator::create(const QtQml::QmlObject *obj, QQmlPropertyCache **resultCache, QByteArray *vmeMetaObjectData) { Q_ASSERT(!stringAt(obj->inheritedTypeNameIndex).isEmpty()); QQmlCompiledData::TypeReference typeRef = resolvedTypes->value(obj->inheritedTypeNameIndex); QQmlPropertyCache *baseTypeCache = typeRef.createPropertyCache(QQmlEnginePrivate::get(enginePrivate)); Q_ASSERT(baseTypeCache); - if (obj->nProperties == 0 && obj->nSignals == 0 && obj->nFunctions == 0) { + if (obj->properties->count == 0 && obj->qmlSignals->count == 0 && obj->functions->count == 0) { *resultCache = baseTypeCache; vmeMetaObjectData->clear(); return true; } QQmlPropertyCache *cache = baseTypeCache->copyAndReserve(QQmlEnginePrivate::get(enginePrivate), - obj->nProperties, - obj->nFunctions + obj->nProperties + obj->nSignals, - obj->nSignals + obj->nProperties); + obj->properties->count, + obj->functions->count + obj->properties->count + obj->qmlSignals->count, + obj->qmlSignals->count + obj->properties->count); *resultCache = cache; vmeMetaObjectData->clear(); @@ -177,9 +185,7 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml int aliasCount = 0; int varPropCount = 0; - const QV4::CompiledData::Property *p = obj->propertyTable(); - for (quint32 i = 0; i < obj->nProperties; ++i, ++p) { - + for (QtQml::QmlProperty *p = obj->properties->first; p; p = p->next) { if (p->type == QV4::CompiledData::Property::Alias) aliasCount++; else if (p->type == QV4::CompiledData::Property::Var) @@ -196,8 +202,8 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml typedef QQmlVMEMetaData VMD; QByteArray &dynamicData = *vmeMetaObjectData = QByteArray(sizeof(QQmlVMEMetaData) - + obj->nProperties * sizeof(VMD::PropertyData) - + obj->nFunctions * sizeof(VMD::MethodData) + + obj->properties->count * sizeof(VMD::PropertyData) + + obj->functions->count * sizeof(VMD::MethodData) + aliasCount * sizeof(VMD::AliasData), 0); int effectivePropertyIndex = cache->propertyIndexCacheStart; @@ -233,8 +239,7 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml if (ii == NSS_Var && varPropCount == 0) continue; else if (ii == NSS_Alias && aliasCount == 0) continue; - const QV4::CompiledData::Property *p = obj->propertyTable(); - for (quint32 i = 0; i < obj->nProperties; ++i, ++p) { + for (QtQml::QmlProperty *p = obj->properties->first; p; p = p->next) { if ((ii == NSS_Normal && (p->type == QV4::CompiledData::Property::Alias || p->type == QV4::CompiledData::Property::Var)) || ((ii == NSS_Var) && (p->type != QV4::CompiledData::Property::Var)) || @@ -252,9 +257,8 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml } // Dynamic signals - for (uint i = 0; i < obj->nSignals; ++i) { - const QV4::CompiledData::Signal *s = obj->signalAt(i); - const int paramCount = s->nParameters; + for (QtQml::Signal *s = obj->qmlSignals->first; s; s = s->next) { + const int paramCount = s->parameters->count; QList<QByteArray> names; QVarLengthArray<int, 10> paramTypes(paramCount?(paramCount + 1):0); @@ -262,8 +266,8 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml if (paramCount) { paramTypes[0] = paramCount; - for (int i = 0; i < paramCount; ++i) { - const QV4::CompiledData::Parameter *param = s->parameterAt(i); + QtQml::SignalParameter *param = s->parameters->first; + for (int i = 0; i < paramCount; ++i, param = param->next) { names.append(stringAt(param->nameIndex).toUtf8()); if (param->type < builtinTypeCount) { // built-in type @@ -311,27 +315,26 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml // Dynamic slots - const quint32 *functionIndex = obj->functionOffsetTable(); - for (quint32 i = 0; i < obj->nFunctions; ++i, ++functionIndex) { - const QV4::CompiledData::Function *s = qmlUnit->header.functionAt(*functionIndex); - int paramCount = s->nFormals; + for (QtQml::Function *s = obj->functions->first; s; s = s->next) { + AST::FunctionDeclaration *astFunction = s->functionDeclaration; quint32 flags = QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMEFunction; - if (paramCount) + if (astFunction->formals) flags |= QQmlPropertyData::HasArguments; - QString slotName = stringAt(s->nameIndex); + QString slotName = astFunction->name.toString(); if (seenSignals.contains(slotName)) COMPILE_EXCEPTION(s, tr("Duplicate method name: invalid override of property change signal or superclass signal")); // Note: we don't append slotName to the seenSignals list, since we don't // protect against overriding change signals or methods with properties. - const quint32 *formalsIndices = s->formalsTable(); QList<QByteArray> parameterNames; - parameterNames.reserve(paramCount); - for (int i = 0; i < paramCount; ++i) - parameterNames << stringAt(formalsIndices[i]).toUtf8(); + AST::FormalParameterList *param = astFunction->formals; + while (param) { + parameterNames << param->name.toUtf8(); + param = param->next; + } cache->appendMethod(slotName, flags, effectiveMethodIndex++, parameterNames); } @@ -339,8 +342,8 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml // Dynamic properties (except var and aliases) int effectiveSignalIndex = cache->signalHandlerIndexCacheStart; - /* const QV4::CompiledData::Property* */ p = obj->propertyTable(); - for (quint32 i = 0; i < obj->nProperties; ++i, ++p) { + int propertyIdx = 0; + for (QtQml::QmlProperty *p = obj->properties->first; p; p = p->next, ++propertyIdx) { if (p->type == QV4::CompiledData::Property::Alias || p->type == QV4::CompiledData::Property::Var) @@ -403,7 +406,7 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml QString propertyName = stringAt(p->nameIndex); - if (i == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName; + if (propertyIdx == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName; cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, propertyType, effectiveSignalIndex); @@ -415,8 +418,8 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml } // Now do var properties - /* const QV4::CompiledData::Property* */ p = obj->propertyTable(); - for (quint32 i = 0; i < obj->nProperties; ++i, ++p) { + propertyIdx = 0; + for (QtQml::QmlProperty *p = obj->properties->first; p; p = p->next, ++propertyIdx) { if (p->type != QV4::CompiledData::Property::Var) continue; @@ -431,7 +434,7 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml ((QQmlVMEMetaData *)dynamicData.data())->varPropertyCount++; QString propertyName = stringAt(p->nameIndex); - if (i == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName; + if (propertyIdx == obj->indexOfDefaultProperty) cache->_defaultPropertyName = propertyName; cache->appendProperty(propertyName, propertyFlags, effectivePropertyIndex++, QMetaType::QVariant, effectiveSignalIndex); @@ -442,12 +445,17 @@ bool QQmlPropertyCacheCreator::create(const QV4::CompiledData::Object *obj, QQml ((QQmlVMEMetaData *)dynamicData.data())->aliasCount = aliasCount; // Dynamic slot data - comes after the property data - /*const quint32* */functionIndex = obj->functionOffsetTable(); - for (quint32 i = 0; i < obj->nFunctions; ++i, ++functionIndex) { - const QV4::CompiledData::Function *s = qmlUnit->header.functionAt(*functionIndex); + for (QtQml::Function *s = obj->functions->first; s; s = s->next) { + AST::FunctionDeclaration *astFunction = s->functionDeclaration; + int formalsCount = 0; + AST::FormalParameterList *param = astFunction->formals; + while (param) { + formalsCount++; + param = param->next; + } VMD::MethodData methodData = { /* runtimeFunctionIndex*/ 0, // ### - int(s->nFormals), + formalsCount, /* s->location.start.line */0 }; // ### VMD *vmd = (QQmlVMEMetaData *)dynamicData.data(); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index e33e47edcc..d395f0238f 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -54,25 +54,27 @@ class QQmlAbstractBinding; struct QQmlCompilePass { QQmlCompilePass(const QUrl &url, const QV4::CompiledData::QmlUnit *unit); + QQmlCompilePass(const QUrl &url, const QStringList &stringTable); QList<QQmlError> errors; + QString stringAt(int idx) const { return qmlUnit ? qmlUnit->header.stringAt(idx): stringTable.at(idx); } protected: - QString stringAt(int idx) const { return qmlUnit->header.stringAt(idx); } void recordError(const QV4::CompiledData::Location &location, const QString &description); const QUrl url; const QV4::CompiledData::QmlUnit *qmlUnit; + const QStringList stringTable; }; class QQmlPropertyCacheCreator : public QQmlCompilePass { Q_DECLARE_TR_FUNCTIONS(QQmlPropertyCacheCreator) public: - QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QV4::CompiledData::QmlUnit *qmlUnit, + QQmlPropertyCacheCreator(QQmlEnginePrivate *enginePrivate, const QStringList &stringTable, const QUrl &url, const QQmlImports *imports, QHash<int, QQmlCompiledData::TypeReference> *resolvedTypes); - bool create(const QV4::CompiledData::Object *obj, QQmlPropertyCache **cache, QByteArray *vmeMetaObjectData); + bool create(const QtQml::QmlObject *obj, QQmlPropertyCache **cache, QByteArray *vmeMetaObjectData); protected: QQmlEnginePrivate *enginePrivate; diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp index 1a4c8f015d..5b6d91475b 100644 --- a/src/qml/qml/qqmltypeloader.cpp +++ b/src/qml/qml/qqmltypeloader.cpp @@ -2338,6 +2338,46 @@ void QQmlTypeData::compile() m_compiledData->resolvedTypes.insert(resolvedType.key(), ref); } + // Build property caches and VME meta object data + + const int objectCount = parsedQML->objects.count(); + m_compiledData->datas.reserve(objectCount); + m_compiledData->propertyCaches.reserve(objectCount); + + QQmlPropertyCacheCreator propertyCacheBuilder(enginePrivate, + parsedQML->jsGenerator.strings, m_compiledData->url, + &m_imports, &m_compiledData->resolvedTypes); + + for (int i = 0; i < objectCount; ++i) { + const QtQml::QmlObject *obj = parsedQML->objects.at(i); + + QByteArray vmeMetaObjectData; + QQmlPropertyCache *propertyCache = 0; + + // If the object has no type, then it's probably a nested object definition as part + // of a group property. + const bool objectHasType = !propertyCacheBuilder.stringAt(obj->inheritedTypeNameIndex).isEmpty(); + if (objectHasType) { + if (!propertyCacheBuilder.create(obj, &propertyCache, &vmeMetaObjectData)) { + setError(propertyCacheBuilder.errors); + m_compiledData->release(); + m_compiledData = 0; + return; + } + } + + m_compiledData->datas << vmeMetaObjectData; + if (propertyCache) + propertyCache->addref(); + m_compiledData->propertyCaches << propertyCache; + + if (i == parsedQML->indexOfRootObject) { + Q_ASSERT(propertyCache); + m_compiledData->rootPropertyCache = propertyCache; + propertyCache->addref(); + } + } + { SignalHandlerConverter converter(QQmlEnginePrivate::get(engine), parsedQML.data(), @@ -2399,46 +2439,9 @@ void QQmlTypeData::compile() QList<QQmlError> errors; - // Build property caches and VME meta object data - - m_compiledData->datas.reserve(qmlUnit->nObjects); - m_compiledData->propertyCaches.reserve(qmlUnit->nObjects); - - QQmlPropertyCacheCreator propertyCacheBuilder(enginePrivate, - qmlUnit, m_compiledData->url, - &m_imports, &m_compiledData->resolvedTypes); - - for (quint32 i = 0; i < qmlUnit->nObjects; ++i) { - const QV4::CompiledData::Object *obj = qmlUnit->objectAt(i); - - QByteArray vmeMetaObjectData; - QQmlPropertyCache *propertyCache = 0; - - // If the object has no type, then it's probably a nested object definition as part - // of a group property. - const bool objectHasType = !parsedQML->jsGenerator.strings.at(obj->inheritedTypeNameIndex).isEmpty(); - if (objectHasType) { - if (!propertyCacheBuilder.create(obj, &propertyCache, &vmeMetaObjectData)) { - errors << propertyCacheBuilder.errors; - break; - } - } - - m_compiledData->datas << vmeMetaObjectData; - if (propertyCache) - propertyCache->addref(); - m_compiledData->propertyCaches << propertyCache; - - if (i == qmlUnit->indexOfRootObject) { - Q_ASSERT(propertyCache); - m_compiledData->rootPropertyCache = propertyCache; - propertyCache->addref(); - } - } - // Resolve component boundaries and aliases - if (errors.isEmpty()) { + { // Scan for components, determine their scopes and resolve aliases within the scope. QQmlComponentAndAliasResolver resolver(m_compiledData->url, m_compiledData->qmlUnit, m_compiledData->resolvedTypes, m_compiledData->propertyCaches, &m_compiledData->datas, &m_compiledData->objectIndexToIdForRoot, &m_compiledData->objectIndexToIdPerComponent); |