aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2016-06-15 13:27:20 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2016-06-16 19:05:40 +0000
commitf2c97b4e307a62b831f68a0278551d4375170336 (patch)
treee4cfa8d09551f3fe6684c3b874357a633b7e0523 /src/qml/compiler
parent12d2b60218542e900076aebfce73a229a8b29ae1 (diff)
PropertyCacheCreator traversal cleanup
Replace the direct linked list object traversal with iterators. This will allow for re-use of the code against the QV4::CompiledData structures when they get the same interface. Change-Id: I901fd3377ef0f0317e5d9278cface37d80f93abf Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp10
-rw-r--r--src/qml/compiler/qqmlirbuilder_p.h34
-rw-r--r--src/qml/compiler/qqmlpropertycachecreator.cpp42
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h7
4 files changed, 68 insertions, 25 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index ce879a874a..4fa63e3c84 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -911,6 +911,16 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node)
f->location.column = loc.startColumn;
f->index = index;
f->nameIndex = registerString(funDecl->name.toString());
+
+ int formalsCount = 0;
+ for (QQmlJS::AST::FormalParameterList *it = funDecl->formals; it; it = it->next)
+ ++formalsCount;
+ f->formals.allocate(pool, formalsCount);
+
+ int i = 0;
+ for (QQmlJS::AST::FormalParameterList *it = funDecl->formals; it; it = it->next, ++i)
+ f->formals[i] = registerString(it->name.toString());
+
_object->appendFunction(f);
} else {
recordError(node->firstSourceLocation(), QCoreApplication::translate("QQmlParser","JavaScript declaration outside Script element"));
diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h
index 2409050f7d..a29727fc9e 100644
--- a/src/qml/compiler/qqmlirbuilder_p.h
+++ b/src/qml/compiler/qqmlirbuilder_p.h
@@ -175,6 +175,14 @@ struct PoolList
return ptr;
}
+ T &operator*() {
+ return *ptr;
+ }
+
+ const T &operator*() const {
+ return *ptr;
+ }
+
void operator++() {
ptr = ptr->next;
}
@@ -204,6 +212,12 @@ public:
, count(0)
{}
+ void allocate(QQmlJS::MemoryPool *pool, int size)
+ {
+ count = size;
+ data = reinterpret_cast<T*>(pool->allocate(count * sizeof(T)));
+ }
+
void allocate(QQmlJS::MemoryPool *pool, const QVector<T> &vector)
{
count = vector.count();
@@ -244,6 +258,9 @@ public:
return i;
return -1;
}
+
+ const T *begin() const { return data; }
+ const T *end() const { return data + count; }
};
struct Object;
@@ -261,6 +278,10 @@ struct Signal
QStringList parameterStringList(const QV4::Compiler::StringTableGenerator *stringPool) const;
+ int parameterCount() const { return parameters->count; }
+ PoolList<SignalParameter>::Iterator parametersBegin() const { return parameters->begin(); }
+ PoolList<SignalParameter>::Iterator parametersEnd() const { return parameters->end(); }
+
Signal *next;
};
@@ -290,6 +311,13 @@ struct Function
QV4::CompiledData::Location location;
int nameIndex;
quint32 index; // index in parsedQML::functions
+ FixedPoolArray<int> formals;
+
+ // --- QQmlPropertyCacheCreator interface
+ const int *formalsBegin() const { return formals.begin(); }
+ const int *formalsEnd() const { return formals.end(); }
+ // ---
+
Function *next;
};
@@ -342,6 +370,12 @@ public:
PoolList<Binding>::Iterator bindingsEnd() const { return bindings->end(); }
PoolList<Property>::Iterator propertiesBegin() const { return properties->begin(); }
PoolList<Property>::Iterator propertiesEnd() const { return properties->end(); }
+ PoolList<Alias>::Iterator aliasesBegin() const { return aliases->begin(); }
+ PoolList<Alias>::Iterator aliasesEnd() const { return aliases->end(); }
+ PoolList<Signal>::Iterator signalsBegin() const { return qmlSignals->begin(); }
+ PoolList<Signal>::Iterator signalsEnd() const { return qmlSignals->end(); }
+ PoolList<Function>::Iterator functionsBegin() const { return functions->begin(); }
+ PoolList<Function>::Iterator functionsEnd() const { return functions->end(); }
// If set, then declarations for this object (and init bindings for these) should go into the
// specified object. Used for declarations inside group properties.
diff --git a/src/qml/compiler/qqmlpropertycachecreator.cpp b/src/qml/compiler/qqmlpropertycachecreator.cpp
index 5e696652bd..a0bcba01ce 100644
--- a/src/qml/compiler/qqmlpropertycachecreator.cpp
+++ b/src/qml/compiler/qqmlpropertycachecreator.cpp
@@ -104,7 +104,7 @@ QQmlCompileError QQmlPropertyCacheCreator::buildMetaObjectRecursively(int object
bool needVMEMetaObject = obj->propertyCount() != 0 || obj->aliasCount() != 0 || obj->signalCount() != 0 || obj->functionCount() != 0;
if (!needVMEMetaObject) {
- for (const QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
+ for (auto binding = obj->bindingsBegin(), end = obj->bindingsEnd(); binding != end; ++binding) {
if (binding->type == QV4::CompiledData::Binding::Type_Object && (binding->flags & QV4::CompiledData::Binding::IsOnAssignment)) {
// If the on assignment is inside a group property, we need to distinguish between QObject based
// group properties and value type group properties. For the former the base type is derived from
@@ -148,9 +148,9 @@ QQmlCompileError QQmlPropertyCacheCreator::buildMetaObjectRecursively(int object
}
if (QQmlPropertyCache *thisCache = propertyCaches.at(objectIndex)) {
- for (const QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next)
+ for (auto binding = obj->bindingsBegin(), end = obj->bindingsEnd(); binding != end; ++binding)
if (binding->type >= QV4::CompiledData::Binding::Type_Object) {
- InstantiationContext context(objectIndex, binding, stringAt(binding->propertyNameIndex), thisCache);
+ InstantiationContext context(objectIndex, &(*binding), stringAt(binding->propertyNameIndex), thisCache);
QQmlCompileError error = buildMetaObjectRecursively(binding->value.objectIndex, context);
if (error.isSet())
return error;
@@ -280,7 +280,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con
QmlIR::PropertyResolver resolver(baseTypeCache);
- for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next) {
+ for (auto p = obj->propertiesBegin(), end = obj->propertiesEnd(); p != end; ++p) {
if (p->type == QV4::CompiledData::Property::Var)
varPropCount++;
@@ -290,7 +290,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con
return QQmlCompileError(p->location, tr("Cannot override FINAL property"));
}
- for (const QmlIR::Alias *a = obj->firstAlias(); a; a = a->next) {
+ for (auto a = obj->aliasesBegin(), end = obj->aliasesEnd(); a != end; ++a) {
bool notInRevision = false;
QQmlPropertyData *d = resolver.property(stringAt(a->nameIndex), &notInRevision);
if (d && d->isFinal())
@@ -324,7 +324,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con
}
// Set up notify signals for properties - first normal, then alias
- for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next) {
+ for (auto p = obj->propertiesBegin(), end = obj->propertiesEnd(); p != end; ++p) {
quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction |
QQmlPropertyData::IsVMESignal;
@@ -334,7 +334,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con
cache->appendSignal(changedSigName, flags, effectiveMethodIndex++);
}
- for (const QmlIR::Alias *a = obj->firstAlias(); a; a = a->next) {
+ for (auto a = obj->aliasesBegin(), end = obj->aliasesEnd(); a != end; ++a) {
quint32 flags = QQmlPropertyData::IsSignal | QQmlPropertyData::IsFunction |
QQmlPropertyData::IsVMESignal;
@@ -345,8 +345,8 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con
}
// Dynamic signals
- for (const QmlIR::Signal *s = obj->firstSignal(); s; s = s->next) {
- const int paramCount = s->parameters->count;
+ for (auto s = obj->signalsBegin(), end = obj->signalsEnd(); s != end; ++s) {
+ const int paramCount = s->parameterCount();
QList<QByteArray> names;
names.reserve(paramCount);
@@ -355,8 +355,8 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con
if (paramCount) {
paramTypes[0] = paramCount;
- QmlIR::SignalParameter *param = s->parameters->first;
- for (int i = 0; i < paramCount; ++i, param = param->next) {
+ int i = 0;
+ for (auto param = s->parametersBegin(), end = s->parametersEnd(); param != end; ++param, ++i) {
names.append(stringAt(param->nameIndex).toUtf8());
if (param->type < builtinTypeCount) {
// built-in type
@@ -402,25 +402,19 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con
// Dynamic slots
- for (const QmlIR::Function *s = obj->firstFunction(); s; s = s->next) {
- QQmlJS::AST::FunctionDeclaration *astFunction = s->functionDeclaration;
-
+ for (auto function = compiler->objectFunctionsBegin(obj), end = compiler->objectFunctionsEnd(obj); function != end; ++function) {
quint32 flags = QQmlPropertyData::IsFunction | QQmlPropertyData::IsVMEFunction;
- if (astFunction->formals)
- flags |= QQmlPropertyData::HasArguments;
-
- QString slotName = astFunction->name.toString();
+ const QString slotName = stringAt(function->nameIndex);
if (seenSignals.contains(slotName))
- return QQmlCompileError(s->location, tr("Duplicate method name: invalid override of property change signal or superclass signal"));
+ return QQmlCompileError(function->location, 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.
QList<QByteArray> parameterNames;
- QQmlJS::AST::FormalParameterList *param = astFunction->formals;
- while (param) {
- parameterNames << param->name.toUtf8();
- param = param->next;
+ for (auto formal = function->formalsBegin(), end = function->formalsEnd(); formal != end; ++formal) {
+ flags |= QQmlPropertyData::HasArguments;
+ parameterNames << stringAt(*formal).toUtf8();
}
cache->appendMethod(slotName, flags, effectiveMethodIndex++, parameterNames);
@@ -430,7 +424,7 @@ QQmlCompileError QQmlPropertyCacheCreator::createMetaObject(int objectIndex, con
// Dynamic properties
int effectiveSignalIndex = cache->signalHandlerIndexCacheStart;
int propertyIdx = 0;
- for (const QmlIR::Property *p = obj->firstProperty(); p; p = p->next, ++propertyIdx) {
+ for (auto p = obj->propertiesBegin(), end = obj->propertiesEnd(); p != end; ++p, ++propertyIdx) {
int propertyType = 0;
quint32 propertyFlags = 0;
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index 1e01f72228..351c4f7294 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -80,12 +80,17 @@ struct QQmlTypeCompiler
public:
QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document);
+ // --- interface used by QQmlPropertyCacheCreator
+ QString stringAt(int idx) const;
+ QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsBegin(const QmlIR::Object *object) const { return object->functionsBegin(); }
+ QmlIR::PoolList<QmlIR::Function>::Iterator objectFunctionsEnd(const QmlIR::Object *object) const { return object->functionsEnd(); }
+ // ---
+
QV4::CompiledData::CompilationUnit *compile();
QList<QQmlError> compilationErrors() const { return errors; }
void recordError(const QQmlError &error);
- QString stringAt(int idx) const;
int registerString(const QString &str);
QV4::IR::Module *jsIRModule() const;