aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2014-02-04 10:21:33 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-02-04 18:29:04 +0100
commit50269fc37a6a50864bf08b25327a05f2ab885a1a (patch)
treee04689e2afc058c404b70dbf0ccc4266df36664a
parent63b8285a2d528be82015133bd72a91c17c3a460b (diff)
[new compiler] Fix order of alias vs non-alias bindings
qqmlecmascript's alias binding tests expect bindings on non-aliases to be bound before bindings on aliases, as the latter may override parts of the former. Change-Id: I23d25c2b7a449f0ed4672ef6865c4a7ef0ed0129 Reviewed-by: Lars Knoll <lars.knoll@digia.com>
-rw-r--r--src/qml/compiler/qqmlcodegenerator.cpp3
-rw-r--r--src/qml/compiler/qqmltypecompiler.cpp36
-rw-r--r--src/qml/compiler/qqmltypecompiler_p.h12
-rw-r--r--src/qml/compiler/qv4compileddata_p.h6
4 files changed, 55 insertions, 2 deletions
diff --git a/src/qml/compiler/qqmlcodegenerator.cpp b/src/qml/compiler/qqmlcodegenerator.cpp
index 04db46667e..f933465100 100644
--- a/src/qml/compiler/qqmlcodegenerator.cpp
+++ b/src/qml/compiler/qqmlcodegenerator.cpp
@@ -1280,10 +1280,11 @@ QV4::CompiledData::QmlUnit *QmlUnitGenerator::generate(ParsedQML &output, const
}
char *bindingPtr = objectPtr + objectToWrite->offsetToBindings;
- bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isValueBinding);
+ bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isValueBindingNoAlias);
bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isSignalHandler);
bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isAttachedProperty);
bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isGroupProperty);
+ bindingPtr = writeBindings(bindingPtr, o, runtimeFunctionIndices, &QV4::CompiledData::Binding::isValueBindingToAlias);
Q_ASSERT((bindingPtr - objectToWrite->offsetToBindings - objectPtr) / sizeof(QV4::CompiledData::Binding) == unsigned(o->bindingCount()));
quint32 *signalOffsetTable = reinterpret_cast<quint32*>(objectPtr + objectToWrite->offsetToSignals);
diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp
index 6197ddf5d0..ea99c51bcf 100644
--- a/src/qml/compiler/qqmltypecompiler.cpp
+++ b/src/qml/compiler/qqmltypecompiler.cpp
@@ -156,6 +156,11 @@ bool QQmlTypeCompiler::compile()
return false;
}
+ {
+ QQmlAliasAnnotator annotator(this);
+ annotator.annotateBindingsToAliases();
+ }
+
// Collect imported scripts
const QList<QQmlTypeData::ScriptReference> &scripts = typeData->resolvedScripts();
compiledData->scripts.reserve(scripts.count());
@@ -963,6 +968,37 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &e
return -1;
}
+
+QQmlAliasAnnotator::QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler)
+ : QQmlCompilePass(typeCompiler)
+ , qmlObjects(*typeCompiler->qmlObjects())
+ , propertyCaches(typeCompiler->propertyCaches())
+{
+}
+
+void QQmlAliasAnnotator::annotateBindingsToAliases()
+{
+ for (int i = 0; i < qmlObjects.count(); ++i) {
+ QQmlPropertyCache *propertyCache = propertyCaches.at(i);
+ if (!propertyCache)
+ continue;
+
+ const QmlObject *obj = qmlObjects.at(i);
+
+ PropertyResolver resolver(propertyCache);
+ QQmlPropertyData *defaultProperty = obj->indexOfDefaultProperty != -1 ? propertyCache->parent()->defaultProperty() : propertyCache->defaultProperty();
+
+ for (QtQml::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
+ if (!binding->isValueBinding())
+ continue;
+ bool notInRevision = false;
+ QQmlPropertyData *pd = binding->propertyNameIndex != 0 ? resolver.property(stringAt(binding->propertyNameIndex), &notInRevision) : defaultProperty;
+ if (pd && pd->isAlias())
+ binding->flags |= QV4::CompiledData::Binding::IsBindingToAlias;
+ }
+ }
+}
+
QQmlComponentAndAliasResolver::QQmlComponentAndAliasResolver(QQmlTypeCompiler *typeCompiler)
: QQmlCompilePass(typeCompiler)
, enginePrivate(typeCompiler->enginePrivate())
diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h
index 51ac36667e..2e97d13481 100644
--- a/src/qml/compiler/qqmltypecompiler_p.h
+++ b/src/qml/compiler/qqmltypecompiler_p.h
@@ -163,6 +163,18 @@ private:
QHash<int, QQmlCompiledData::TypeReference *> *resolvedTypes;
};
+// Annotate properties bound to aliases with a flag
+class QQmlAliasAnnotator : public QQmlCompilePass
+{
+public:
+ QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler);
+
+ void annotateBindingsToAliases();
+private:
+ const QList<QtQml::QmlObject*> &qmlObjects;
+ const QVector<QQmlPropertyCache *> propertyCaches;
+};
+
class QQmlComponentAndAliasResolver : public QQmlCompilePass
{
Q_DECLARE_TR_FUNCTIONS(QQmlAnonymousComponentResolver)
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index edb1737648..94ea4bdc90 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -302,7 +302,8 @@ struct Q_QML_EXPORT Binding
IsOnAssignment = 0x4,
InitializerForReadOnlyDeclaration = 0x8,
IsResolvedEnum = 0x10,
- IsListItem = 0x20
+ IsListItem = 0x20,
+ IsBindingToAlias = 0x40
};
quint32 flags : 16;
@@ -329,6 +330,9 @@ struct Q_QML_EXPORT Binding
return true;
}
+ bool isValueBindingNoAlias() const { return isValueBinding() && !(flags & IsBindingToAlias); }
+ bool isValueBindingToAlias() const { return isValueBinding() && (flags & IsBindingToAlias); }
+
bool isSignalHandler() const
{
if (flags & IsSignalHandlerExpression || flags & IsSignalHandlerObject) {