diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-08-25 03:46:34 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2009-08-25 03:46:34 (GMT) |
commit | 15e37128223c9438be9372c35fac5981a440c94b (patch) | |
tree | e1701210a223b082a312248ce8b8bbd667b778b3 /src/declarative | |
parent | f69d8805291ee46856b21d9091693cdc139765b8 (diff) | |
download | Qt-15e37128223c9438be9372c35fac5981a440c94b.zip Qt-15e37128223c9438be9372c35fac5981a440c94b.tar.gz Qt-15e37128223c9438be9372c35fac5981a440c94b.tar.bz2 |
Add support for prefixed attached properties at compile time
To reduce possible confusion, an id used within a component may not
conflict with namespace prefixes.
Diffstat (limited to 'src/declarative')
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 60 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler_p.h | 5 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine_p.h | 12 |
3 files changed, 68 insertions, 9 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp index 1771cb4..3dcc448 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -1176,11 +1176,19 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop, } QmlType *type = 0; - QmlEnginePrivate::get(engine)->resolveType(unit->imports, prop->name, &type, 0); - // 0: attached properties not supported in QML component files - - if (!type || !type->attachedPropertiesType()) + QmlEnginePrivate::ImportedNamespace *typeNamespace = 0; + QmlEnginePrivate::get(engine)->resolveType(unit->imports, prop->name, + &type, 0, &typeNamespace); + + if (typeNamespace) { + // ### We might need to indicate that this property is a namespace + // for the DOM API + COMPILE_CHECK(buildPropertyInNamespace(typeNamespace, prop, obj, + ctxt)); + return true; + } else if (!type || !type->attachedPropertiesType()) { COMPILE_EXCEPTION(prop, "Non-existant attached object"); + } if (!prop->value) COMPILE_EXCEPTION(prop, "Invalid attached object assignment"); @@ -1265,6 +1273,40 @@ bool QmlCompiler::buildProperty(QmlParser::Property *prop, return true; } +bool +QmlCompiler::buildPropertyInNamespace(QmlEnginePrivate::ImportedNamespace *ns, + QmlParser::Property *nsProp, + QmlParser::Object *obj, + const BindingContext &ctxt) +{ + if (!nsProp->value) + COMPILE_EXCEPTION(nsProp, "Invalid use of namespace"); + + foreach (Property *prop, nsProp->value->properties) { + + if (!isAttachedPropertyName(prop->name)) + COMPILE_EXCEPTION(prop, "Not an attached property name"); + + // Setup attached property data + + QmlType *type = 0; + QmlEnginePrivate::get(engine)->resolveTypeInNamespace(ns, prop->name, + &type, 0); + + if (!type || !type->attachedPropertiesType()) + COMPILE_EXCEPTION(prop, "Non-existant attached object"); + + if (!prop->value) + COMPILE_EXCEPTION(prop, "Invalid attached object assignment"); + + Q_ASSERT(type->attachedPropertiesFunction()); + prop->index = type->index(); + prop->value->metatype = type->attachedPropertiesType(); + + COMPILE_CHECK(buildAttachedProperty(prop, obj, ctxt)); + } +} + void QmlCompiler::genValueProperty(QmlParser::Property *prop, QmlParser::Object *obj) { @@ -1407,11 +1449,19 @@ bool QmlCompiler::buildIdProperty(QmlParser::Property *prop, prop->values.at(0)->object) COMPILE_EXCEPTION(prop, "Invalid use of id property"); - QString val = prop->values.at(0)->primitive(); + QmlParser::Value *idValue = prop->values.at(0); + QString val = idValue->primitive(); if (!isValidId(val)) COMPILE_EXCEPTION(prop, val << "is not a valid object id"); + // We disallow id's that conflict with import prefixes + QmlEnginePrivate::ImportedNamespace *ns = 0; + QmlEnginePrivate::get(engine)->resolveType(unit->imports, val.toUtf8(), + 0, 0, &ns); + if (ns) + COMPILE_EXCEPTION(idValue, "id conflicts with namespace prefix"); + if (compileState.ids.contains(val)) COMPILE_EXCEPTION(prop, "id is not unique"); diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h index 58279c4..c42c2d9 100644 --- a/src/declarative/qml/qmlcompiler_p.h +++ b/src/declarative/qml/qmlcompiler_p.h @@ -60,6 +60,7 @@ #include <private/qmlinstruction_p.h> #include <private/qmlcompositetypemanager_p.h> #include <private/qmlparser_p.h> +#include <private/qmlengine_p.h> QT_BEGIN_NAMESPACE @@ -165,6 +166,10 @@ private: const BindingContext &); bool buildProperty(QmlParser::Property *prop, QmlParser::Object *obj, const BindingContext &); + bool buildPropertyInNamespace(QmlEnginePrivate::ImportedNamespace *ns, + QmlParser::Property *prop, + QmlParser::Object *obj, + const BindingContext &); bool buildIdProperty(QmlParser::Property *prop, QmlParser::Object *obj); bool buildAttachedProperty(QmlParser::Property *prop, QmlParser::Object *obj, diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index c84b3b5..18e3765 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -209,10 +209,14 @@ public: bool addToImport(Imports*, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const; - bool resolveType(const Imports&, const QByteArray& type, QmlType** type_return, QUrl* url_return, ImportedNamespace** ns_return=0) const; - - void resolveNamespace(const Imports& imports, const QByteArray &type, ImportedNamespace **s, QByteArray *unqualifiedType) const; - bool resolveTypeInNamespace(ImportedNamespace*, const QByteArray& type, QmlType** type_return, QUrl* url_return ) const; + bool resolveType(const Imports&, const QByteArray& type, + QmlType** type_return, QUrl* url_return, + ImportedNamespace** ns_return=0) const; + void resolveNamespace(const Imports& imports, const QByteArray &type, + ImportedNamespace **s, + QByteArray *unqualifiedType) const; + bool resolveTypeInNamespace(ImportedNamespace*, const QByteArray& type, + QmlType** type_return, QUrl* url_return ) const; static QScriptValue qmlScriptObject(QObject*, QmlEngine*); |