aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp10
-rw-r--r--src/qml/compiler/qqmlcodegenerator_p.h2
-rw-r--r--src/qml/qml/qqmlobjectcreator.cpp86
-rw-r--r--src/qml/qml/qqmlobjectcreator_p.h8
-rw-r--r--src/qml/qml/qqmltypeloader.cpp79
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);