summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAaron Kennedy <aaron.kennedy@nokia.com>2009-09-10 00:25:29 (GMT)
committerAaron Kennedy <aaron.kennedy@nokia.com>2009-09-10 00:25:29 (GMT)
commitc494da05e1d3cb597990098e9713a0af5364c828 (patch)
tree519373879fb480f267943a8f38de9b4494474aac
parent2dc6bbf1e6e146a4fbbf802236a8619204464a76 (diff)
parent487c18cebc3fac5db3506bc8c64417feeb85c6b9 (diff)
downloadQt-c494da05e1d3cb597990098e9713a0af5364c828.zip
Qt-c494da05e1d3cb597990098e9713a0af5364c828.tar.gz
Qt-c494da05e1d3cb597990098e9713a0af5364c828.tar.bz2
Merge branch 'kinetic-declarativeui' of git@scm.dev.nokia.troll.no:qt/kinetic into kinetic-declarativeui
-rw-r--r--src/declarative/qml/qmlcompiler.cpp11
-rw-r--r--src/declarative/qml/qmlcustomparser.cpp51
-rw-r--r--src/declarative/qml/qmlcustomparser_p.h19
-rw-r--r--src/declarative/qml/qmlcustomparser_p_p.h9
-rw-r--r--src/declarative/util/qmllistmodel.cpp16
-rw-r--r--src/declarative/util/qmlpropertychanges.cpp7
-rw-r--r--tests/auto/declarative/qmlparser/customParserIdNotAllowed.errors.txt1
-rw-r--r--tests/auto/declarative/qmlparser/customParserIdNotAllowed.qml5
-rw-r--r--tests/auto/declarative/qmlparser/tst_qmlparser.cpp4
9 files changed, 92 insertions, 31 deletions
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index b8e9d47..f02dad5 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -761,12 +761,13 @@ bool QmlCompiler::buildObject(Object *obj, const BindingContext &ctxt)
// Compile custom parser parts
if (isCustomParser && !customProps.isEmpty()) {
- // ### Check for failure
- bool ok = false;
QmlCustomParser *cp = output->types.at(obj->type).type->customParser();
- obj->custom = cp->compile(customProps, &ok);
- if(!ok)
- COMPILE_EXCEPTION(obj, "Failure compiling custom type");
+ cp->clearErrors();
+ obj->custom = cp->compile(customProps);
+ foreach (QmlError err, cp->errors()) {
+ err.setUrl(output->url);
+ exceptions << err;
+ }
}
return true;
diff --git a/src/declarative/qml/qmlcustomparser.cpp b/src/declarative/qml/qmlcustomparser.cpp
index b543978..dbcbeb1 100644
--- a/src/declarative/qml/qmlcustomparser.cpp
+++ b/src/declarative/qml/qmlcustomparser.cpp
@@ -70,7 +70,7 @@ using namespace QmlParser;
*/
/*
- \fn QByteArray QmlCustomParser::compile(QXmlStreamReader& reader, bool *ok)
+ \fn QByteArray QmlCustomParser::compile(QXmlStreamReader& reader)
Upon entry to this function, \a reader is positioned on a
QXmlStreamReader::StartElement with the name specified when the
@@ -80,7 +80,7 @@ using namespace QmlParser;
EndElement matching the initial start element is reached, or until
error.
- On return, \c *ok indicates success.
+ Errors must be reported via the error() functions.
The returned QByteArray contains data meaningful only to the
custom parser; the type engine will pass this same data to
@@ -109,6 +109,7 @@ QmlCustomParserNodePrivate::fromObject(QmlParser::Object *root)
{
QmlCustomParserNode rootNode;
rootNode.d->name = root->typeName;
+ rootNode.d->location = root->location.start;
for(QHash<QByteArray, Property *>::Iterator iter = root->properties.begin();
iter != root->properties.end();
@@ -128,6 +129,7 @@ QmlCustomParserNodePrivate::fromProperty(QmlParser::Property *p)
QmlCustomParserProperty prop;
prop.d->name = p->name;
prop.d->isList = (p->values.count() > 1);
+ prop.d->location = p->location.start;
if (p->value) {
QmlCustomParserNode node = fromObject(p->value);
@@ -167,6 +169,7 @@ QmlCustomParserNode &QmlCustomParserNode::operator=(const QmlCustomParserNode &o
{
d->name = other.d->name;
d->properties = other.d->properties;
+ d->location = other.d->location;
return *this;
}
@@ -185,6 +188,11 @@ QList<QmlCustomParserProperty> QmlCustomParserNode::properties() const
return d->properties;
}
+QmlParser::Location QmlCustomParserNode::location() const
+{
+ return d->location;
+}
+
QmlCustomParserProperty::QmlCustomParserProperty()
: d(new QmlCustomParserPropertyPrivate)
{
@@ -201,6 +209,7 @@ QmlCustomParserProperty &QmlCustomParserProperty::operator=(const QmlCustomParse
d->name = other.d->name;
d->isList = other.d->isList;
d->values = other.d->values;
+ d->location = other.d->location;
return *this;
}
@@ -219,19 +228,49 @@ bool QmlCustomParserProperty::isList() const
return d->isList;
}
+QmlParser::Location QmlCustomParserProperty::location() const
+{
+ return d->location;
+}
+
QList<QVariant> QmlCustomParserProperty::assignedValues() const
{
return d->values;
}
-QByteArray QmlCustomParser::compile(const QList<QmlCustomParserProperty> &, bool *ok)
+void QmlCustomParser::clearErrors()
{
- Q_UNUSED(ok);
- return QByteArray();
+ exceptions.clear();
}
-void QmlCustomParser::setCustomData(QObject *, const QByteArray &)
+/*!
+ Reports an error in parsing \a prop, with the given \a description.
+
+ An error is generated referring to the position of \a node in the source file.
+*/
+void QmlCustomParser::error(const QmlCustomParserProperty& prop, const QString& description)
+{
+ QmlError error;
+ QString exceptionDescription;
+ error.setLine(prop.location().line);
+ error.setColumn(prop.location().column);
+ error.setDescription(description);
+ exceptions << error;
+}
+
+/*!
+ Reports an error in parsing \a node, with the given \a description.
+
+ An error is generated referring to the position of \a node in the source file.
+*/
+void QmlCustomParser::error(const QmlCustomParserNode& node, const QString& description)
{
+ QmlError error;
+ QString exceptionDescription;
+ error.setLine(node.location().line);
+ error.setColumn(node.location().column);
+ error.setDescription(description);
+ exceptions << error;
}
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlcustomparser_p.h b/src/declarative/qml/qmlcustomparser_p.h
index 74bd15c..5be0680 100644
--- a/src/declarative/qml/qmlcustomparser_p.h
+++ b/src/declarative/qml/qmlcustomparser_p.h
@@ -57,6 +57,8 @@
#include <QtCore/qxmlstream.h>
#include <QtDeclarative/qfxglobal.h>
#include <QtDeclarative/qmlmetatype.h>
+#include <QtDeclarative/qmlerror.h>
+#include <private/qmlparser_p.h>
QT_BEGIN_HEADER
@@ -74,6 +76,7 @@ public:
~QmlCustomParserProperty();
QByteArray name() const;
+ QmlParser::Location location() const;
bool isList() const;
// Will be one of QmlParser::Variant, QmlCustomParserProperty or
@@ -96,6 +99,7 @@ public:
~QmlCustomParserNode();
QByteArray name() const;
+ QmlParser::Location location() const;
QList<QmlCustomParserProperty> properties() const;
@@ -109,8 +113,19 @@ class Q_DECLARATIVE_EXPORT QmlCustomParser
public:
virtual ~QmlCustomParser() {}
- virtual QByteArray compile(const QList<QmlCustomParserProperty> &, bool *ok);
- virtual void setCustomData(QObject *, const QByteArray &);
+ void clearErrors();
+
+ virtual QByteArray compile(const QList<QmlCustomParserProperty> &)=0;
+ virtual void setCustomData(QObject *, const QByteArray &)=0;
+
+ QList<QmlError> errors() const { return exceptions; }
+
+protected:
+ void error(const QmlCustomParserProperty&, const QString& description);
+ void error(const QmlCustomParserNode&, const QString& description);
+
+private:
+ QList<QmlError> exceptions;
};
#define QML_DEFINE_CUSTOM_TYPE(URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MAJ_TO, NAME, TYPE, CUSTOMTYPE) \
template<> QmlPrivate::InstanceType QmlPrivate::Define<TYPE *,(VERSION_MAJ), (VERSION_MIN_FROM), (VERSION_MAJ_TO)>::instance(qmlRegisterCustomType<TYPE>(#URI, VERSION_MAJ, VERSION_MIN_FROM, VERSION_MAJ_TO, #NAME, #TYPE, new CUSTOMTYPE));
diff --git a/src/declarative/qml/qmlcustomparser_p_p.h b/src/declarative/qml/qmlcustomparser_p_p.h
index 0011c3b..25023d3 100644
--- a/src/declarative/qml/qmlcustomparser_p_p.h
+++ b/src/declarative/qml/qmlcustomparser_p_p.h
@@ -55,20 +55,16 @@
#include <QtCore/qglobal.h>
#include "qmlcustomparser_p.h"
+#include "qmlparser_p.h"
QT_BEGIN_NAMESPACE
-namespace QmlParser
-{
- class Object;
- class Property;
-};
-
class QmlCustomParserNodePrivate
{
public:
QByteArray name;
QList<QmlCustomParserProperty> properties;
+ QmlParser::Location location;
static QmlCustomParserNode fromObject(QmlParser::Object *);
static QmlCustomParserProperty fromProperty(QmlParser::Property *);
@@ -82,6 +78,7 @@ public:
QByteArray name;
bool isList;
+ QmlParser::Location location;
QList<QVariant> values;
};
diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp
index f988d81..19499a1 100644
--- a/src/declarative/util/qmllistmodel.cpp
+++ b/src/declarative/util/qmllistmodel.cpp
@@ -634,7 +634,7 @@ void QmlListModel::set(int index, const QString& property, const QVariant& value
class QmlListModelParser : public QmlCustomParser
{
public:
- QByteArray compile(const QList<QmlCustomParserProperty> &, bool *ok);
+ QByteArray compile(const QList<QmlCustomParserProperty> &);
bool compileProperty(const QmlCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data);
void setCustomData(QObject *, const QByteArray &);
};
@@ -659,8 +659,14 @@ bool QmlListModelParser::compileProperty(const QmlCustomParserProperty &prop, QL
QList<QmlCustomParserProperty> props = node.properties();
for(int jj = 0; jj < props.count(); ++jj) {
const QmlCustomParserProperty &nodeProp = props.at(jj);
- if(nodeProp.name() == "")
+ if (nodeProp.name() == "") {
+ error(nodeProp, QLatin1String("Cannot use default property in ListModel"));
return false;
+ }
+ if (nodeProp.name() == "id") {
+ error(nodeProp, QLatin1String("Cannot use reserved \"id\" property in ListModel"));
+ return false;
+ }
ListInstruction li;
int ref = data.count();
@@ -706,21 +712,19 @@ bool QmlListModelParser::compileProperty(const QmlCustomParserProperty &prop, QL
return true;
}
-QByteArray QmlListModelParser::compile(const QList<QmlCustomParserProperty> &customProps, bool *ok)
+QByteArray QmlListModelParser::compile(const QList<QmlCustomParserProperty> &customProps)
{
- *ok = true;
QList<ListInstruction> instr;
QByteArray data;
for(int ii = 0; ii < customProps.count(); ++ii) {
const QmlCustomParserProperty &prop = customProps.at(ii);
if(prop.name() != "") { // isn't default property
- *ok = false;
+ error(prop, QLatin1String("Cannot use default property"));
return QByteArray();
}
if(!compileProperty(prop, instr, data)) {
- *ok = false;
return QByteArray();
}
}
diff --git a/src/declarative/util/qmlpropertychanges.cpp b/src/declarative/util/qmlpropertychanges.cpp
index b5e204f..1fe1731 100644
--- a/src/declarative/util/qmlpropertychanges.cpp
+++ b/src/declarative/util/qmlpropertychanges.cpp
@@ -106,7 +106,7 @@ class QmlPropertyChangesParser : public QmlCustomParser
public:
void compileList(QList<QPair<QByteArray, QVariant> > &list, const QByteArray &pre, const QmlCustomParserProperty &prop);
- virtual QByteArray compile(const QList<QmlCustomParserProperty> &, bool *ok);
+ virtual QByteArray compile(const QList<QmlCustomParserProperty> &);
virtual void setCustomData(QObject *, const QByteArray &);
};
@@ -137,11 +137,8 @@ QmlPropertyChangesParser::compileList(QList<QPair<QByteArray, QVariant> > &list,
}
QByteArray
-QmlPropertyChangesParser::compile(const QList<QmlCustomParserProperty> &props,
- bool *ok)
+QmlPropertyChangesParser::compile(const QList<QmlCustomParserProperty> &props)
{
- *ok = true;
-
QList<QPair<QByteArray, QVariant> > data;
for(int ii = 0; ii < props.count(); ++ii)
compileList(data, QByteArray(), props.at(ii));
diff --git a/tests/auto/declarative/qmlparser/customParserIdNotAllowed.errors.txt b/tests/auto/declarative/qmlparser/customParserIdNotAllowed.errors.txt
new file mode 100644
index 0000000..d28c0bd
--- /dev/null
+++ b/tests/auto/declarative/qmlparser/customParserIdNotAllowed.errors.txt
@@ -0,0 +1 @@
+4:19:Cannot use reserved "id" property in ListModel
diff --git a/tests/auto/declarative/qmlparser/customParserIdNotAllowed.qml b/tests/auto/declarative/qmlparser/customParserIdNotAllowed.qml
new file mode 100644
index 0000000..e607768
--- /dev/null
+++ b/tests/auto/declarative/qmlparser/customParserIdNotAllowed.qml
@@ -0,0 +1,5 @@
+import Qt 4.6
+ListModel {
+ ListElement { a: 10 }
+ ListElement { id: Foo; a: 12 }
+}
diff --git a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
index 93666aa..b8bd0e7 100644
--- a/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
+++ b/tests/auto/declarative/qmlparser/tst_qmlparser.cpp
@@ -160,6 +160,8 @@ void tst_qmlparser::errors_data()
QTest::newRow("finalOverride") << "finalOverride.qml" << "finalOverride.errors.txt" << false;
QTest::newRow("importNamespaceConflict") << "importNamespaceConflict.qml" << "importNamespaceConflict.errors.txt" << false;
+
+ QTest::newRow("customParserIdNotAllowed") << "customParserIdNotAllowed.qml" << "customParserIdNotAllowed.errors.txt" << false;
}
void tst_qmlparser::errors()
@@ -312,7 +314,7 @@ void tst_qmlparser::assignTypeExtremes()
QCOMPARE(object->intProperty(), -0x77359400);
}
-// Tests that custom parser tyeps can be instantiated
+// Tests that custom parser types can be instantiated
void tst_qmlparser::customParserTypes()
{
QmlComponent component(&engine, TEST_FILE("customParserTypes.qml"));