summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-08-25 03:46:34 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-08-25 03:46:34 (GMT)
commit15e37128223c9438be9372c35fac5981a440c94b (patch)
treee1701210a223b082a312248ce8b8bbd667b778b3
parentf69d8805291ee46856b21d9091693cdc139765b8 (diff)
downloadQt-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.
-rw-r--r--src/declarative/qml/qmlcompiler.cpp60
-rw-r--r--src/declarative/qml/qmlcompiler_p.h5
-rw-r--r--src/declarative/qml/qmlengine_p.h12
-rw-r--r--tests/auto/declarative/qmlparser/invalidID.5.errors.txt1
-rw-r--r--tests/auto/declarative/qmlparser/invalidID.5.qml6
-rw-r--r--tests/auto/declarative/qmlparser/tst_qmlparser.cpp2
6 files changed, 77 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*);
diff --git a/tests/auto/declarative/qmlparser/invalidID.5.errors.txt b/tests/auto/declarative/qmlparser/invalidID.5.errors.txt
new file mode 100644
index 0000000..b0a63a0
--- /dev/null
+++ b/tests/auto/declarative/qmlparser/invalidID.5.errors.txt
@@ -0,0 +1 @@
+4:9:id conflicts with namespace prefix
diff --git a/tests/auto/declarative/qmlparser/invalidID.5.qml b/tests/auto/declarative/qmlparser/invalidID.5.qml
new file mode 100644
index 0000000..0545b0d
--- /dev/null
+++ b/tests/auto/declarative/qmlparser/invalidID.5.qml
@@ -0,0 +1,6 @@
+import Test 1.0
+import Test 1.0 as Hello
+MyQmlObject {
+ id: Hello
+}
+
diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
index a9c4351..3047bb0 100644
--- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
+++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
@@ -135,6 +135,8 @@ void tst_qmlparser::errors_data()
QTest::newRow("invalidID.2") << "invalidID.2.qml" << "invalidID.2.errors.txt" << false;
QTest::newRow("invalidID.3") << "invalidID.3.qml" << "invalidID.3.errors.txt" << false;
QTest::newRow("invalidID.4") << "invalidID.4.qml" << "invalidID.4.errors.txt" << false;
+ QTest::newRow("invalidID.5") << "invalidID.5.qml" << "invalidID.5.errors.txt" << false;
+
QTest::newRow("unsupportedProperty") << "unsupportedProperty.qml" << "unsupportedProperty.errors.txt" << false;
QTest::newRow("nullDotProperty") << "nullDotProperty.qml" << "nullDotProperty.errors.txt" << true;