summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/qml/qml.pri8
-rw-r--r--src/declarative/qml/qmlcompiler.cpp297
-rw-r--r--src/declarative/qml/qmlcompiler_p.h10
-rw-r--r--src/declarative/qml/qmlcomponent.cpp41
-rw-r--r--src/declarative/qml/qmlcomponent.h5
-rw-r--r--src/declarative/qml/qmlcomponent_p.h4
-rw-r--r--src/declarative/qml/qmlcompositetypemanager.cpp23
-rw-r--r--src/declarative/qml/qmlcompositetypemanager_p.h4
-rw-r--r--src/declarative/qml/qmlcustomparser_p.h17
-rw-r--r--src/declarative/qml/qmldom.cpp25
-rw-r--r--src/declarative/qml/qmldom.h2
-rw-r--r--src/declarative/qml/qmldom_p.h2
-rw-r--r--src/declarative/qml/qmlerror.cpp227
-rw-r--r--src/declarative/qml/qmlerror.h (renamed from src/declarative/qml/qmlxmlparser_p.h)55
-rw-r--r--src/declarative/qml/qmlinstruction.cpp3
-rw-r--r--src/declarative/qml/qmlinstruction_p.h5
-rw-r--r--src/declarative/qml/qmlparser.cpp11
-rw-r--r--src/declarative/qml/qmlparser_p.h7
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp119
-rw-r--r--src/declarative/qml/qmlscriptparser_p.h11
-rw-r--r--src/declarative/qml/qmlvme.cpp45
-rw-r--r--src/declarative/qml/qmlvme_p.h5
-rw-r--r--src/declarative/qml/qmlxmlparser.cpp391
-rw-r--r--src/declarative/util/qfxview.cpp79
-rw-r--r--src/declarative/util/qfxview.h3
-rw-r--r--src/declarative/util/qmllistmodel.cpp180
26 files changed, 507 insertions, 1072 deletions
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 9067039..5198264 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -8,7 +8,6 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlcontext.cpp \
qml/qmlcustomparser.cpp \
qml/qmlpropertyvaluesource.cpp \
- qml/qmlxmlparser.cpp \
qml/qmlproxymetaobject.cpp \
qml/qmlvme.cpp \
qml/qmlcompiler.cpp \
@@ -22,7 +21,8 @@ SOURCES += qml/qmlparser.cpp \
qml/qmlclassfactory.cpp \
qml/qmlparserstatus.cpp \
qml/qmlcompositetypemanager.cpp \
- qml/qmlinfo.cpp
+ qml/qmlinfo.cpp \
+ qml/qmlerror.cpp
HEADERS += qml/qmlparser_p.h \
qml/qmlinstruction_p.h \
@@ -36,7 +36,6 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlcustomparser_p_p.h \
qml/qmlpropertyvaluesource.h \
qml/qmlboundsignal_p.h \
- qml/qmlxmlparser_p.h \
qml/qmlparserstatus.h \
qml/qmlproxymetaobject_p.h \
qml/qmlcompiledcomponent_p.h \
@@ -58,7 +57,8 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlcontext_p.h \
qml/qmlcompositetypemanager_p.h \
qml/qmllist.h \
- qml/qmldeclarativedata_p.h
+ qml/qmldeclarativedata_p.h \
+ qml/qmlerror.h
# for qtscript debugger
QT += scripttools
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index c9bdfec..b8f3921 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -64,17 +64,6 @@
#include "qmlscriptparser_p.h"
QT_BEGIN_NAMESPACE
-/*
- New properties and signals can be added to any QObject type from QML.
- <QObject>
- <properties><Property name="myProperty" /></properties>
- <signals><Signal name="mySignal" /></signals>
- </QObject
- The special names used as magical properties (in the above case "properties"
- and "signals") are defined here.
-*/
-#define PROPERTIES_NAME "properties"
-#define SIGNALS_NAME "signals"
using namespace QmlParser;
@@ -147,7 +136,7 @@ int QmlCompiledData::indexForInt(int *data, int count)
}
QmlCompiler::QmlCompiler()
-: exceptionLine(-1), output(0)
+: exceptionLine(-1), exceptionColumn(-1), output(0)
{
}
@@ -156,14 +145,19 @@ bool QmlCompiler::isError() const
return exceptionLine != -1;
}
-qint64 QmlCompiler::errorLine() const
+QList<QmlError> QmlCompiler::errors() const
{
- return exceptionLine;
-}
+ QList<QmlError> rv;
+
+ if(isError()) {
+ QmlError error;
+ error.setDescription(exceptionDescription);
+ error.setLine(exceptionLine);
+ error.setColumn(exceptionColumn);
+ rv << error;
+ }
-QString QmlCompiler::errorDescription() const
-{
- return exceptionDescription;
+ return rv;
}
bool QmlCompiler::isValidId(const QString &val)
@@ -437,9 +431,19 @@ void QmlCompiler::reset(QmlCompiledComponent *cc, bool deleteMemory)
cc->bytecode.clear();
}
+#define COMPILE_EXCEPTION2(token, desc) \
+ { \
+ exceptionLine = token->line; \
+ exceptionColumn = token->column; \
+ QDebug d(&exceptionDescription); \
+ d << desc; \
+ return false; \
+ }
+
#define COMPILE_EXCEPTION(desc) \
{ \
exceptionLine = obj->line; \
+ exceptionColumn = obj->column; \
QDebug d(&exceptionDescription); \
d << desc; \
return false; \
@@ -532,47 +536,14 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
ctxt = 0;
- // Only use magical "properties" and "signals" properties if the type
- // doesn't have already have them
- bool ignoreProperties = false;
- bool ignoreSignals = false;
- if (obj->metatype && obj->metatype->indexOfProperty(PROPERTIES_NAME) != -1)
- ignoreProperties = true;
- if (obj->metatype && obj->metatype->indexOfProperty(SIGNALS_NAME) != -1)
- ignoreSignals = true;
-
- Property *propertiesProperty = ignoreProperties?0:obj->getProperty(PROPERTIES_NAME, false);
- Property *signalsProperty = ignoreSignals?0:obj->getProperty(SIGNALS_NAME, false);
-
- if (propertiesProperty) {
- obj->dynamicPropertiesProperty = propertiesProperty;
- obj->properties.remove(PROPERTIES_NAME);
- }
- if (signalsProperty) {
- obj->dynamicSignalsProperty = signalsProperty;
- obj->properties.remove(SIGNALS_NAME);
- }
-
int createInstrIdx = output->bytecode.count();
- if (obj->type != -1 && output->types.at(obj->type).parser) {
- QByteArray data = obj->custom;
- int ref = output->indexForByteArray(data);
-
- QmlInstruction create;
- create.type = QmlInstruction::CreateCustomObject;
- create.line = obj->line;
- create.createCustom.type = obj->type;
- create.createCustom.data = ref;
- output->bytecode << create;
- } else {
- // Create the object
- QmlInstruction create;
- create.type = QmlInstruction::CreateObject;
- create.line = obj->line;
- create.create.data = -1;
- create.create.type = obj->type;
- output->bytecode << create;
- }
+ // Create the object
+ QmlInstruction create;
+ create.type = QmlInstruction::CreateObject;
+ create.line = obj->line;
+ create.create.data = -1;
+ create.create.type = obj->type;
+ output->bytecode << create;
COMPILE_CHECK(compileDynamicPropertiesAndSignals(obj));
@@ -599,9 +570,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
QList<QmlCustomParserProperty> customProps;
foreach(Property *prop, obj->properties) {
- if (!ignoreProperties && prop->name == PROPERTIES_NAME) {
- } else if (!ignoreSignals && prop->name == SIGNALS_NAME) {
- } else if (prop->name.length() >= 3 && prop->name.startsWith("on") &&
+ if (prop->name.length() >= 3 && prop->name.startsWith("on") &&
('A' <= prop->name.at(2) && 'Z' >= prop->name.at(2))) {
if (!isCustomParser) {
COMPILE_CHECK(compileSignal(prop, obj));
@@ -1215,10 +1184,10 @@ bool QmlCompiler::compilePropertyLiteralAssignment(QmlParser::Property *prop,
//### we are restricted to a rather generic message here. If we can find a way to move
// the exception into generateStoreInstruction we could potentially have better messages.
// (the problem is that both compile and run exceptions can be generated, though)
- COMPILE_EXCEPTION("Cannot assign value" << v->primitive << "to property" << obj->metaObject()->property(prop->index).name());
+ COMPILE_EXCEPTION2(v, "Cannot assign value" << v->primitive << "to property" << obj->metaObject()->property(prop->index).name());
doassign = false;
} else if (r == ReadOnly) {
- COMPILE_EXCEPTION("Cannot assign value" << v->primitive << "to the read-only property" << obj->metaObject()->property(prop->index).name());
+ COMPILE_EXCEPTION2(v, "Cannot assign value" << v->primitive << "to the read-only property" << obj->metaObject()->property(prop->index).name());
} else {
doassign = true;
}
@@ -1243,209 +1212,9 @@ bool QmlCompiler::compilePropertyLiteralAssignment(QmlParser::Property *prop,
return true;
}
-bool QmlCompiler::findDynamicProperties(QmlParser::Property *prop,
- QmlParser::Object *obj)
-{
- QList<Object::DynamicProperty> definedProperties;
-
- struct TypeNameToType {
- const char *name;
- Object::DynamicProperty::Type type;
- } propTypeNameToTypes[] = {
- { "", Object::DynamicProperty::Variant },
- { "int", Object::DynamicProperty::Int },
- { "bool", Object::DynamicProperty::Bool },
- { "double", Object::DynamicProperty::Real },
- { "real", Object::DynamicProperty::Real },
- { "string", Object::DynamicProperty::String },
- { "color", Object::DynamicProperty::Color },
- { "date", Object::DynamicProperty::Date },
- { "variant", Object::DynamicProperty::Variant }
- };
- const int propTypeNameToTypesCount = sizeof(propTypeNameToTypes) /
- sizeof(propTypeNameToTypes[0]);
-
-
- if (prop->value)
- COMPILE_EXCEPTION("Invalid property specification");
-
- bool seenDefault = false;
- for (int ii = 0; ii < prop->values.count(); ++ii) {
- QmlParser::Value *val = prop->values.at(ii);
- if (!val->object)
- COMPILE_EXCEPTION("Invalid property specification");
-
- QmlParser::Object *obj = val->object;
- if (obj->type == -1 || output->types.at(obj->type).className != "Property")
- COMPILE_EXCEPTION("Use Property tag to specify properties");
-
-
- enum Seen { None = 0, Name = 0x01,
- Type = 0x02, Value = 0x04,
- ValueChanged = 0x08,
- Default = 0x10 } seen = None;
-
- Object::DynamicProperty propDef;
-
- for (QHash<QByteArray, QmlParser::Property *>::ConstIterator iter =
- obj->properties.begin();
- iter != obj->properties.end();
- ++iter) {
-
- QmlParser::Property *property = *iter;
- if (property->name == "name") {
- if (seen & Name)
- COMPILE_EXCEPTION("May only specify Property name once");
- seen = (Seen)(seen | Name);
-
- if (property->value || property->values.count() != 1 ||
- property->values.at(0)->object)
- COMPILE_EXCEPTION("Invalid Property name");
-
- propDef.name = property->values.at(0)->primitive.toLatin1();
-
- } else if (property->name == "type") {
- if (seen & Type)
- COMPILE_EXCEPTION("May only specify Property type once");
- seen = (Seen)(seen | Type);
-
- if (property->value || property->values.count() != 1 ||
- property->values.at(0)->object)
- COMPILE_EXCEPTION("Invalid Property type");
-
- QString type = property->values.at(0)->primitive.toLower();
- bool found = false;
- for (int ii = 0; !found && ii < propTypeNameToTypesCount; ++ii) {
- if (type == QLatin1String(propTypeNameToTypes[ii].name)){
- found = true;
- propDef.type = propTypeNameToTypes[ii].type;
- }
-
- }
-
- if (!found)
- COMPILE_EXCEPTION("Invalid Property type");
-
- } else if (property->name == "value") {
- if (seen & Value)
- COMPILE_EXCEPTION("May only specify Property value once");
- seen = (Seen)(seen | Value);
-
- propDef.defaultValue = property;
- } else if (property->name == "onValueChanged") {
- if (seen & ValueChanged)
- COMPILE_EXCEPTION("May only specify Property onValueChanged once");
- seen = (Seen)(seen | ValueChanged);
-
- if (property->value || property->values.count() != 1 ||
- property->values.at(0)->object)
- COMPILE_EXCEPTION("Invalid Property onValueChanged");
-
- propDef.onValueChanged = property->values.at(0)->primitive;
-
- } else if (property->name == "default") {
- if (seen & Default)
- COMPILE_EXCEPTION("May only specify Property default once");
- seen = (Seen)(seen | Default);
- if (property->value || property->values.count() != 1 ||
- property->values.at(0)->object)
- COMPILE_EXCEPTION("Invalid Property default");
-
- bool defaultValue =
- QmlStringConverters::boolFromString(property->values.at(0)->primitive);
- propDef.isDefaultProperty = defaultValue;
- if (defaultValue) {
- if (seenDefault)
- COMPILE_EXCEPTION("Only one property may be the default");
- seenDefault = true;
- }
-
- } else {
- COMPILE_EXCEPTION("Invalid Property property");
- }
-
- }
- if (obj->defaultProperty) {
- if (seen & Value)
- COMPILE_EXCEPTION("May only specify Property value once");
-
- seen = (Seen)(seen | Value);
- propDef.defaultValue = obj->defaultProperty;
- }
-
- if (!(seen & Name))
- COMPILE_EXCEPTION("Must specify Property name");
-
- definedProperties << propDef;
- }
-
- obj->dynamicProperties << definedProperties;
- return true;
-}
-
-bool QmlCompiler::findDynamicSignals(QmlParser::Property *sigs,
- QmlParser::Object *obj)
-{
- QList<Object::DynamicSignal> definedSignals;
-
- if (sigs->value)
- COMPILE_EXCEPTION("Invalid signal specification");
-
- for (int ii = 0; ii < sigs->values.count(); ++ii) {
- QmlParser::Value *val = sigs->values.at(ii);
- if (!val->object)
- COMPILE_EXCEPTION("Invalid signal specification");
-
- QmlParser::Object *obj = val->object;
- if (obj->type == -1 || output->types.at(obj->type).className != "Signal")
- COMPILE_EXCEPTION("Use Signal tag to specify signals");
-
- enum Seen { None = 0, Name = 0x01 } seen = None;
- Object::DynamicSignal sigDef;
-
- for (QHash<QByteArray, QmlParser::Property *>::ConstIterator iter =
- obj->properties.begin();
- iter != obj->properties.end();
- ++iter) {
-
- QmlParser::Property *property = *iter;
- if (property->name == "name") {
- if (seen & Name)
- COMPILE_EXCEPTION("May only specify Signal name once");
- seen = (Seen)(seen | Name);
-
- if (property->value || property->values.count() != 1 ||
- property->values.at(0)->object)
- COMPILE_EXCEPTION("Invalid Signal name");
-
- sigDef.name = property->values.at(0)->primitive.toLatin1();
-
- } else {
- COMPILE_EXCEPTION("Invalid Signal property");
- }
-
- }
-
- if (obj->defaultProperty)
- COMPILE_EXCEPTION("Invalid Signal property");
-
- if (!(seen & Name))
- COMPILE_EXCEPTION("Must specify Signal name");
-
- definedSignals << sigDef;
- }
-
- obj->dynamicSignals << definedSignals;
- return true;
-}
-
bool QmlCompiler::compileDynamicPropertiesAndSignals(QmlParser::Object *obj)
{
- if (obj->dynamicPropertiesProperty)
- findDynamicProperties(obj->dynamicPropertiesProperty, obj);
- if (obj->dynamicSignalsProperty)
- findDynamicSignals(obj->dynamicSignalsProperty, obj);
-
+ // ### FIXME - Check that there is only one default property etc.
if (obj->dynamicProperties.isEmpty() && obj->dynamicSignals.isEmpty())
return true;
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index 9a0ce1c..4acdcfa 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -45,6 +45,7 @@
#include <QtCore/qbytearray.h>
#include <QtCore/qset.h>
#include <qml.h>
+#include <qmlerror.h>
#include <private/qmlinstruction_p.h>
#include <private/qmlcompositetypemanager_p.h>
class QStringList;
@@ -115,8 +116,7 @@ public:
bool compile(QmlEngine *, QmlCompositeTypeData *, QmlCompiledComponent *);
bool isError() const;
- qint64 errorLine() const;
- QString errorDescription() const;
+ QList<QmlError> errors() const;
static bool isValidId(const QString &);
static bool isBinding(const QString &);
@@ -163,11 +163,6 @@ private:
QmlParser::Value *value,
int ctxt);
- bool findDynamicProperties(QmlParser::Property *prop,
- QmlParser::Object *obj);
- bool findDynamicSignals(QmlParser::Property *sigs,
- QmlParser::Object *obj);
-
bool compileDynamicPropertiesAndSignals(QmlParser::Object *obj);
void compileBinding(const QString &, QmlParser::Property *prop,
int ctxt, const QMetaObject *, qint64);
@@ -176,6 +171,7 @@ private:
QSet<QString> ids;
qint64 exceptionLine;
+ qint64 exceptionColumn;
QString exceptionDescription;
QmlCompiledData *output;
};
diff --git a/src/declarative/qml/qmlcomponent.cpp b/src/declarative/qml/qmlcomponent.cpp
index c316f03..b1beb9c 100644
--- a/src/declarative/qml/qmlcomponent.cpp
+++ b/src/declarative/qml/qmlcomponent.cpp
@@ -60,17 +60,6 @@
QT_BEGIN_NAMESPACE
class QByteArray;
-bool QmlComponentPrivate::isXml(const QByteArray &ba)
-{
- for (int i = 0; i < ba.size(); ++i) {
- char c = ba.at(i);
- if (c == ' ' || c == '\n' || c == '\r' || c == '\t')
- continue;
- return (c == '<');
- }
- return true;
-}
-
/*!
\class QmlComponent
\brief The QmlComponent class encapsulates a QML component description.
@@ -137,9 +126,7 @@ void QmlComponentPrivate::fromTypeData(QmlCompositeTypeData *data)
if (!c) {
Q_ASSERT(data->status == QmlCompositeTypeData::Error);
- errorDescription = data->errorDescription;
- qWarning().nospace() << "QmlComponent: "
- << data->errorDescription.toLatin1().constData();
+ errors = data->errors;
} else {
@@ -192,10 +179,10 @@ QmlComponent::Status QmlComponent::status() const
if (d->typeData)
return Loading;
+ else if (!d->errors.isEmpty())
+ return Error;
else if (d->engine && d->cc)
return Ready;
- else if (!d->errorDescription.isEmpty())
- return Error;
else
return Null;
}
@@ -353,13 +340,17 @@ void QmlComponent::loadUrl(const QUrl &url)
emit statusChanged(status());
}
-QString QmlComponent::errorDescription() const
+/*!
+ Return the list of errors that occured during the last compile or create
+ operation. An empty list is returned if isError() is not set.
+*/
+QList<QmlError> QmlComponent::errors() const
{
Q_D(const QmlComponent);
if (isError())
- return d->errorDescription;
+ return d->errors;
else
- return QString();
+ return QList<QmlError>();
}
/*!
@@ -448,7 +439,7 @@ QObject *QmlComponent::beginCreate(QmlContext *context)
}
if (!isReady()) {
- qWarning("QmlComponent: Cannot create un-ready component");
+ qWarning("QmlComponent: Component is not ready");
return 0;
}
@@ -466,15 +457,9 @@ QObject *QmlComponent::beginCreate(QmlContext *context)
QmlVME vme;
QObject *rv = vme.run(ctxt, d->cc, d->start, d->count);
- if (vme.isError()) {
- qWarning().nospace()
-#ifdef QML_VERBOSEERRORS_ENABLED
- << "QmlComponent: "
-#endif
- << vme.errorDescription().toLatin1().constData() << " @"
- << d->url.toString().toLatin1().constData() << ":" << vme.errorLine();
- }
+ if (vme.isError())
+ d->errors = vme.errors();
ctxt->deactivate();
diff --git a/src/declarative/qml/qmlcomponent.h b/src/declarative/qml/qmlcomponent.h
index 0493c1f..90f7467 100644
--- a/src/declarative/qml/qmlcomponent.h
+++ b/src/declarative/qml/qmlcomponent.h
@@ -46,7 +46,7 @@
#include <QtCore/qstring.h>
#include <QtDeclarative/qfxglobal.h>
#include <QtDeclarative/qml.h>
-
+#include <QtDeclarative/qmlerror.h>
QT_BEGIN_HEADER
@@ -77,7 +77,8 @@ public:
bool isReady() const;
bool isError() const;
bool isLoading() const;
- QString errorDescription() const;
+
+ QList<QmlError> errors() const;
QUrl url() const;
diff --git a/src/declarative/qml/qmlcomponent_p.h b/src/declarative/qml/qmlcomponent_p.h
index bb5f7bb..6a5345e 100644
--- a/src/declarative/qml/qmlcomponent_p.h
+++ b/src/declarative/qml/qmlcomponent_p.h
@@ -47,6 +47,7 @@
#include <QList>
#include "private/qobject_p.h"
#include "private/qmlcompositetypemanager_p.h"
+#include <qmlerror.h>
#include "qmlcomponent.h"
class QmlComponent;
class QmlEngine;
@@ -68,7 +69,7 @@ public:
void fromTypeData(QmlCompositeTypeData *data);
- QString errorDescription;
+ QList<QmlError> errors;
QUrl url;
int start;
@@ -81,7 +82,6 @@ public:
QmlEngine *engine;
void clear();
- static bool isXml(const QByteArray &);
};
#endif // QMLCOMPONENT_P_H
diff --git a/src/declarative/qml/qmlcompositetypemanager.cpp b/src/declarative/qml/qmlcompositetypemanager.cpp
index 7f2cc58..fbe40bf 100644
--- a/src/declarative/qml/qmlcompositetypemanager.cpp
+++ b/src/declarative/qml/qmlcompositetypemanager.cpp
@@ -105,10 +105,9 @@ QmlCompositeTypeData::toCompiledComponent(QmlEngine *engine)
QmlCompiler compiler;
if (!compiler.compile(engine, this, compiledComponent)) {
status = Error;
- errorDescription = compiler.errorDescription() +
- QLatin1String("@") +
- url + QLatin1String(":") +
- QString::number(compiler.errorLine());
+ errors = compiler.errors();
+ for(int ii = 0; ii < errors.count(); ++ii)
+ errors[ii].setUrl(url);
compiledComponent->release();
compiledComponent = 0;
}
@@ -188,7 +187,10 @@ void QmlCompositeTypeManager::replyFinished()
reply->url().toString();
unit->status = QmlCompositeTypeData::Error;
- unit->errorDescription = errorDescription;
+ // ### FIXME
+ QmlError error;
+ error.setDescription(errorDescription);
+ unit->errors << error;
doComplete(unit);
} else {
@@ -215,7 +217,10 @@ void QmlCompositeTypeManager::loadSource(QmlCompositeTypeData *unit)
// ### - Fill in error
errorDescription = QLatin1String("File error for URL ") + url.toString();
unit->status = QmlCompositeTypeData::Error;
- unit->errorDescription = errorDescription;
+ // ### FIXME
+ QmlError error;
+ error.setDescription(errorDescription);
+ unit->errors << error;
doComplete(unit);
}
@@ -234,7 +239,7 @@ void QmlCompositeTypeManager::setData(QmlCompositeTypeData *unit,
if (!unit->data.parse(data, url)) {
unit->status = QmlCompositeTypeData::Error;
- unit->errorDescription = unit->data.errorDescription();
+ unit->errors << unit->data.errors();
doComplete(unit);
} else {
@@ -273,7 +278,7 @@ void QmlCompositeTypeManager::checkComplete(QmlCompositeTypeData *unit)
if (u->status == QmlCompositeTypeData::Error) {
unit->status = QmlCompositeTypeData::Error;
- unit->errorDescription = u->errorDescription;
+ unit->errors = u->errors;
doComplete(unit);
return;
} else if (u->status == QmlCompositeTypeData::Waiting) {
@@ -334,7 +339,7 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit)
case QmlCompositeTypeData::Invalid:
case QmlCompositeTypeData::Error:
unit->status = QmlCompositeTypeData::Error;
- unit->errorDescription = urlUnit->errorDescription;
+ unit->errors = urlUnit->errors;
doComplete(unit);
return;
diff --git a/src/declarative/qml/qmlcompositetypemanager_p.h b/src/declarative/qml/qmlcompositetypemanager_p.h
index bc86fcf..e4028d5 100644
--- a/src/declarative/qml/qmlcompositetypemanager_p.h
+++ b/src/declarative/qml/qmlcompositetypemanager_p.h
@@ -45,6 +45,7 @@
#include <qglobal.h>
#include <private/qmlscriptparser_p.h>
#include <private/qmlrefcount_p.h>
+#include <qmlerror.h>
QT_BEGIN_NAMESPACE
@@ -65,7 +66,8 @@ struct QmlCompositeTypeData : public QmlRefCount
Waiting
};
Status status;
- QString errorDescription;
+
+ QList<QmlError> errors;
QString url;
QList<QmlCompositeTypeData *> dependants;
diff --git a/src/declarative/qml/qmlcustomparser_p.h b/src/declarative/qml/qmlcustomparser_p.h
index 0e6a619..e4e6089 100644
--- a/src/declarative/qml/qmlcustomparser_p.h
+++ b/src/declarative/qml/qmlcustomparser_p.h
@@ -98,26 +98,9 @@ class Q_DECLARATIVE_EXPORT QmlCustomParser
public:
virtual ~QmlCustomParser() {}
- virtual QByteArray compile(QXmlStreamReader&, bool *ok)=0;
virtual QByteArray compile(const QList<QmlCustomParserProperty> &, bool *ok);
- virtual QVariant create(const QByteArray &)=0;
virtual void setCustomData(QObject *, const QByteArray &);
-
- struct Register {
- Register(const char *name, QmlCustomParser *parser) {
- qmlRegisterCustomParser(name, parser);
- }
- };
- template<typename T>
- struct Define {
- static Register instance;
- };
};
-#define QML_DEFINE_CUSTOM_PARSER(name, parserClass) \
- template<> QmlCustomParser::Register QmlCustomParser::Define<parserClass>::instance(# name, new parserClass);
-#define QML_DEFINE_CUSTOM_PARSER_NS(namespacestring, name, parserClass) \
- template<> QmlCustomParser::Register QmlCustomParser::Define<parserClass>::instance(namespacestring "/" # name, new parserClass);
-
#define QML_DEFINE_CUSTOM_TYPE(TYPE, NAME, CUSTOMTYPE) \
template<> QmlPrivate::InstanceType QmlPrivate::Define<TYPE *>::instance(qmlRegisterCustomType<TYPE>(#NAME, #TYPE, new CUSTOMTYPE));
diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp
index 5380740..08755b1 100644
--- a/src/declarative/qml/qmldom.cpp
+++ b/src/declarative/qml/qmldom.cpp
@@ -70,6 +70,7 @@ QmlDomDocumentPrivate::~QmlDomDocumentPrivate()
/*!
\class QmlDomDocument
+ \internal
\brief The QmlDomDocument class represents the root of a QML document
A QML document is a self-contained snippet of QML, usually contained in a
@@ -152,7 +153,7 @@ bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data)
{
Q_UNUSED(engine);
- d->error = QString();
+ d->errors.clear();
QmlCompiledComponent component;
QmlCompiler compiler;
@@ -160,11 +161,13 @@ bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data)
QmlCompositeTypeData *td = ((QmlEnginePrivate *)QmlEnginePrivate::get(engine))->typeManager.getImmediate(data, QUrl());;
if(td->status == QmlCompositeTypeData::Error) {
- d->error = td->errorDescription;
+ d->errors = td->errors;
td->release();
return false;
} else if(td->status == QmlCompositeTypeData::Waiting) {
- d->error = QLatin1String("QmlDomDocument supports local types only");
+ QmlError error;
+ error.setDescription(QLatin1String("QmlDomDocument supports local types only"));
+ d->errors << error;
td->release();
return false;
}
@@ -172,7 +175,7 @@ bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data)
compiler.compile(engine, td, &component);
if (compiler.isError()) {
- d->error = compiler.errorDescription();
+ d->errors = compiler.errors();
td->release();
return false;
}
@@ -188,14 +191,14 @@ bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data)
/*!
- Returns the last load error. The load error will be reset after a
+ Returns the last load errors. The load errors will be reset after a
successful call to load().
\sa load()
*/
-QString QmlDomDocument::loadError() const
+QList<QmlError> QmlDomDocument::errors() const
{
- return d->error;
+ return d->errors;
}
/*!
@@ -249,6 +252,7 @@ QmlDomPropertyPrivate::~QmlDomPropertyPrivate()
/*!
\class QmlDomProperty
+ \internal
\brief The QmlDomProperty class represents one property assignment in the
QML DOM tree
@@ -450,6 +454,7 @@ QmlDomObjectPrivate::properties(QmlParser::Property *property) const
/*!
\class QmlDomObject
+ \internal
\brief The QmlDomObject class represents an object instantiation.
Each object instantiated in a QML file has a corresponding QmlDomObject
@@ -734,6 +739,7 @@ QmlDomBasicValuePrivate::~QmlDomBasicValuePrivate()
/*!
\class QmlDomValueLiteral
+ \internal
\brief The QmlDomValueLiteral class represents a literal value.
A literal value is a simple value, written inline with the QML. In the
@@ -806,6 +812,7 @@ void QmlDomValueLiteral::setLiteral(const QString &value)
/*!
\class QmlDomValueBinding
+ \internal
\brief The QmlDomValueBinding class represents a property binding.
A property binding is an ECMAScript expression assigned to a property. In
@@ -875,6 +882,7 @@ void QmlDomValueBinding::setBinding(const QString &expression)
/*!
\class QmlDomValueValueSource
+ \internal
\brief The QmlDomValueValueSource class represents a value source assignment value.
In QML, value sources are special value generating types that may be
@@ -983,6 +991,7 @@ QmlDomValuePrivate::~QmlDomValuePrivate()
/*!
\class QmlDomValue
+ \internal
\brief The QmlDomValue class represents a generic Qml value.
QmlDomValue's can be assigned to QML \l {QmlDomProperty}{properties}. In
@@ -1234,6 +1243,7 @@ QmlDomList QmlDomValue::toList() const
/*!
\class QmlDomList
+ \internal
\brief The QmlDomList class represents a list of values assigned to a QML property.
Lists of values can be assigned to properties. For example, the following
@@ -1323,6 +1333,7 @@ void QmlDomList::setValues(const QList<QmlDomValue> &values)
/*!
\class QmlDomComponent
+ \internal
\brief The QmlDomComponent class represents sub-component within a QML document.
Sub-components are QmlComponents defined within a QML document. The
diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h
index 47a89d9..74ed27c 100644
--- a/src/declarative/qml/qmldom.h
+++ b/src/declarative/qml/qmldom.h
@@ -44,6 +44,7 @@
#include <QtCore/qlist.h>
#include <QtCore/qshareddata.h>
+#include <QtDeclarative/qmlerror.h>
QT_BEGIN_HEADER
@@ -71,6 +72,7 @@ public:
int version() const;
+ QList<QmlError> errors() const;
QString loadError() const;
bool load(QmlEngine *, const QByteArray &);
QByteArray save() const;
diff --git a/src/declarative/qml/qmldom_p.h b/src/declarative/qml/qmldom_p.h
index 8ea56bf..4c3ca44 100644
--- a/src/declarative/qml/qmldom_p.h
+++ b/src/declarative/qml/qmldom_p.h
@@ -57,7 +57,7 @@ public:
QmlDomDocumentPrivate(const QmlDomDocumentPrivate &);
~QmlDomDocumentPrivate();
- QString error;
+ QList<QmlError> errors;
QmlParser::Object *root;
};
diff --git a/src/declarative/qml/qmlerror.cpp b/src/declarative/qml/qmlerror.cpp
new file mode 100644
index 0000000..2ed3500
--- /dev/null
+++ b/src/declarative/qml/qmlerror.cpp
@@ -0,0 +1,227 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: Qt Software Information (qt-info@nokia.com)
+**
+** This file is part of the QtDeclarative module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the either Technology Preview License Agreement or the
+** Beta Release License Agreement.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain
+** additional rights. These rights are described in the Nokia Qt LGPL
+** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
+** package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at qt-sales@nokia.com.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qmlerror.h"
+#include <QtCore/qdebug.h>
+#include <QtCore/qfile.h>
+#include <QtCore/qstringlist.h>
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \class QmlError
+ \brief The QmlError class encapsulates a QML error
+*/
+class QmlErrorPrivate
+{
+public:
+ QmlErrorPrivate();
+
+ QUrl url;
+ QString description;
+ int line;
+ int column;
+};
+
+QmlErrorPrivate::QmlErrorPrivate()
+: line(-1), column(-1)
+{
+}
+
+/*!
+ Create an empty error object.
+*/
+QmlError::QmlError()
+: d(new QmlErrorPrivate)
+{
+}
+
+/*!
+ Create a copy of \a other.
+*/
+QmlError::QmlError(const QmlError &other)
+: d(new QmlErrorPrivate)
+{
+ *this = other;
+}
+
+/*!
+ Assign \a other to this error object.
+*/
+QmlError &QmlError::operator=(const QmlError &other)
+{
+ d->url = other.d->url;
+ d->description = other.d->description;
+ d->line = other.d->line;
+ d->column = other.d->column;
+ return *this;
+}
+
+/*!
+ \internal
+*/
+QmlError::~QmlError()
+{
+ delete d; d = 0;
+}
+
+/*!
+ Return the url for the file that caused this error.
+*/
+QUrl QmlError::url() const
+{
+ return d->url;
+}
+
+/*!
+ Set the \a url for the file that caused this error.
+*/
+void QmlError::setUrl(const QUrl &url)
+{
+ d->url = url;
+}
+
+/*!
+ Return the error description.
+*/
+QString QmlError::description() const
+{
+ return d->description;
+}
+
+/*!
+ Set the error \a description.
+*/
+void QmlError::setDescription(const QString &description)
+{
+ d->description = description;
+}
+
+/*!
+ Return the error line number.
+*/
+int QmlError::line() const
+{
+ return d->line;
+}
+
+/*!
+ Set the error \a line number.
+*/
+void QmlError::setLine(int line)
+{
+ d->line = line;
+}
+
+/*!
+ Return the error column number.
+*/
+int QmlError::column() const
+{
+ return d->column;
+}
+
+/*!
+ Set the error \a column number.
+*/
+void QmlError::setColumn(int column)
+{
+ d->column = column;
+}
+
+/*!
+ \relates QmlError
+ \fn QDebug operator<<(QDebug debug, const QmlError &error)
+
+ Output a human readable version of \a error to \a debug.
+*/
+
+QDebug operator<<(QDebug debug, const QmlError &error)
+{
+ QUrl url = error.url();
+
+ QString output;
+
+ output = url.toString() + QLatin1String(":") +
+ QString::number(error.line());
+
+ if(error.column() != -1)
+ output += QLatin1String(":") + QString::number(error.column());
+
+ output += QLatin1String(": ") + error.description();
+
+ debug << qPrintable(output) << "\n";
+
+ if (error.line() > 0 && error.column() > 0 &&
+ url.scheme() == QLatin1String("file")) {
+ QString file = url.toLocalFile();
+ QFile f(file);
+ if (f.open(QIODevice::ReadOnly)) {
+ QByteArray data = f.readAll();
+ QTextStream stream(data, QIODevice::ReadOnly);
+ const QString code = stream.readAll();
+ const QStringList lines = code.split(QLatin1Char('\n'));
+
+ if (lines.count() >= error.line()) {
+ const QString &line = lines.at(error.line() - 1);
+ debug << qPrintable(line) << "\n";
+
+ int column = qMax(0, error.column() - 1);
+ column = qMin(column, line.length());
+
+ QByteArray ind;
+ ind.reserve(column);
+ for (int i = 0; i < column; ++i) {
+ const QChar ch = line.at(i);
+ if (ch.isSpace())
+ ind.append(ch.unicode());
+ else
+ ind.append(' ');
+ }
+ ind.append('^');
+ debug << ind.constData();
+ }
+ }
+ }
+ return debug;
+}
+
+QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlxmlparser_p.h b/src/declarative/qml/qmlerror.h
index 9b45e28..57d2f8f 100644
--- a/src/declarative/qml/qmlxmlparser_p.h
+++ b/src/declarative/qml/qmlerror.h
@@ -39,12 +39,11 @@
**
****************************************************************************/
-#ifndef QMLXMLPARSER_P_H
-#define QMLXMLPARSER_P_H
+#ifndef QMLERROR_H
+#define QMLERROR_H
-#include <QList>
-#include <QUrl>
-#include <qml.h>
+#include <QtCore/qurl.h>
+#include <QtCore/qstring.h>
QT_BEGIN_HEADER
@@ -52,38 +51,32 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
-namespace QmlParser {
- class Object;
-}
-
-class QByteArray;
-class QmlXmlParser
+class QDebug;
+class QmlErrorPrivate;
+class Q_DECLARATIVE_EXPORT QmlError
{
public:
- QmlXmlParser();
- ~QmlXmlParser();
-
- bool parse(const QByteArray &data, const QUrl &url=QUrl());
- QString errorDescription() const;
-
- QMap<QString,QString> nameSpacePaths() const;
- QStringList types() const;
-
- QmlParser::Object *tree() const;
- QmlParser::Object *takeTree();
-
- void clear();
-
+ QmlError();
+ QmlError(const QmlError &);
+ QmlError &operator=(const QmlError &);
+ ~QmlError();
+
+ QUrl url() const;
+ void setUrl(const QUrl &);
+ QString description() const;
+ void setDescription(const QString &);
+ int line() const;
+ void setLine(int);
+ int column() const;
+ void setColumn(int);
private:
- QMap<QString,QString> _nameSpacePaths;
- QmlParser::Object *root;
- QStringList _typeNames;
- QString _error;
+ QmlErrorPrivate *d;
};
+QDebug Q_DECLARATIVE_EXPORT operator<<(QDebug debug, const QmlError &error);
+
QT_END_NAMESPACE
QT_END_HEADER
-#endif // QMLXMLPARSER_P_H
-
+#endif // QMLERROR_H
diff --git a/src/declarative/qml/qmlinstruction.cpp b/src/declarative/qml/qmlinstruction.cpp
index 82924c8..52677c2 100644
--- a/src/declarative/qml/qmlinstruction.cpp
+++ b/src/declarative/qml/qmlinstruction.cpp
@@ -58,9 +58,6 @@ void QmlCompiledComponent::dump(QmlInstruction *instr, int idx)
case QmlInstruction::CreateObject:
qWarning() << idx << "\t" << line << "\t" << "CREATE\t\t\t" << instr->create.type << "\t\t\t" << types.at(instr->create.type).className;
break;
- case QmlInstruction::CreateCustomObject:
- qWarning() << idx << "\t" << line << "\t" << "CREATE_CUSTOM\t\t" << instr->createCustom.type << "\t" << instr->createCustom.data << "\t\t" << types.at(instr->create.type).className;
- break;
case QmlInstruction::SetId:
qWarning() << idx << "\t" << line << "\t" << "SETID\t\t\t" << instr->setId.value << "\t" << instr->setId.save << "\t\t" << primitives.at(instr->setId.value);
break;
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index 922fc61..462f9e4 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -63,7 +63,6 @@ public:
// top of the stack.
Init, /* init */
CreateObject, /* create */
- CreateCustomObject, /* createCustom */
SetId, /* setId */
SetDefault,
CreateComponent, /* createComponent */
@@ -180,10 +179,6 @@ public:
int data;
} storeMeta;
struct {
- int type;
- int data;
- } createCustom;
- struct {
int value;
int save;
} setId;
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index ecb6f0b..d862315 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -63,8 +63,7 @@ QT_BEGIN_NAMESPACE
using namespace QmlParser;
QmlParser::Object::Object()
-: type(-1), metatype(0), extObject(0), defaultProperty(0), line(-1),
- dynamicPropertiesProperty(0), dynamicSignalsProperty(0)
+: type(-1), metatype(0), extObject(0), defaultProperty(0), line(-1), column(-1)
{
}
@@ -73,8 +72,6 @@ QmlParser::Object::~Object()
if (defaultProperty) defaultProperty->release();
foreach(Property *prop, properties)
prop->release();
- if (dynamicPropertiesProperty) dynamicPropertiesProperty->release();
- if (dynamicSignalsProperty) dynamicSignalsProperty->release();
}
const QMetaObject *Object::metaObject() const
@@ -127,12 +124,12 @@ QmlParser::Object::DynamicSignal::DynamicSignal(const DynamicSignal &o)
}
QmlParser::Property::Property()
-: type(0), index(-1), value(0), isDefault(true), line(-1)
+: type(0), index(-1), value(0), isDefault(true), line(-1), column(-1)
{
}
QmlParser::Property::Property(const QByteArray &n)
-: type(0), index(-1), value(0), name(n), isDefault(false), line(-1)
+: type(0), index(-1), value(0), name(n), isDefault(false), line(-1), column(-1)
{
}
@@ -161,7 +158,7 @@ void QmlParser::Property::addValue(Value *v)
}
QmlParser::Value::Value()
-: type(Unknown), object(0), line(-1)
+: type(Unknown), object(0), line(-1), column(-1)
{
}
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index e29cdbf..aeacee8 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -103,6 +103,7 @@ namespace QmlParser
QHash<QByteArray, Property *> properties;
qint64 line;
+ qint64 column;
struct DynamicProperty {
DynamicProperty();
@@ -123,10 +124,6 @@ namespace QmlParser
QByteArray name;
};
- // The "properties" property
- Property *dynamicPropertiesProperty;
- // The "signals" property
- Property *dynamicSignalsProperty;
// The list of dynamic properties described in the "properties" property
QList<DynamicProperty> dynamicProperties;
// The list of dynamic signals described in the "signals" property
@@ -167,6 +164,7 @@ namespace QmlParser
Object *object;
qint64 line;
+ qint64 column;
};
class Property : public QmlRefCount
@@ -197,6 +195,7 @@ namespace QmlParser
bool isDefault;
qint64 line;
+ qint64 column;
};
}
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index 8039b5c..81315c3 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -1,6 +1,5 @@
#include "qmlscriptparser_p.h"
-#include "qmlxmlparser_p.h"
#include "qmlparser_p.h"
#include "parser/javascriptengine_p.h"
@@ -65,10 +64,12 @@ protected:
Object *defineObjectBinding(int line,
AST::UiQualifiedId *propertyName,
const QString &objectType,
+ AST::SourceLocation typeLocation,
AST::UiObjectInitializer *initializer = 0);
Object *defineObjectBinding_helper(int line,
AST::UiQualifiedId *propertyName,
const QString &objectType,
+ AST::SourceLocation typeLocation,
AST::UiObjectInitializer *initializer = 0);
QString getPrimitive(const QByteArray &propertyName, AST::ExpressionNode *expr);
void defineProperty(const QString &propertyName, int line, const QString &primitive);
@@ -194,11 +195,17 @@ QString ProcessAST::asString(AST::UiQualifiedId *node) const
Object *ProcessAST::defineObjectBinding_helper(int line,
AST::UiQualifiedId *propertyName,
const QString &objectType,
+ AST::SourceLocation typeLocation,
AST::UiObjectInitializer *initializer)
{
bool isType = !objectType.isEmpty() && objectType.at(0).isUpper() && !objectType.contains(QLatin1Char('.'));
+
if (!isType) {
- qWarning() << "bad name for a class"; // ### FIXME
+ QmlError error;
+ error.setDescription("Expected type name");
+ error.setLine(typeLocation.startLine);
+ error.setColumn(typeLocation.startColumn);
+ _parser->_errors << error;
return false;
}
@@ -235,7 +242,7 @@ Object *ProcessAST::defineObjectBinding_helper(int line,
if (!_parser->scriptFile().isEmpty()) {
_stateStack.pushObject(obj);
- Object *scriptObject= defineObjectBinding(line, 0, QLatin1String("Script"));
+ Object *scriptObject= defineObjectBinding(line, 0, QLatin1String("Script"), AST::SourceLocation());
_stateStack.pushObject(scriptObject);
defineProperty(QLatin1String("src"), line, _parser->scriptFile());
_stateStack.pop(); // scriptObject
@@ -264,11 +271,12 @@ Object *ProcessAST::defineObjectBinding_helper(int line,
Object *ProcessAST::defineObjectBinding(int line,
AST::UiQualifiedId *qualifiedId,
const QString &objectType,
+ AST::SourceLocation typeLocation,
AST::UiObjectInitializer *initializer)
{
if (objectType == QLatin1String("Connection")) {
- Object *obj = defineObjectBinding_helper(line, 0, QLatin1String("Connection"));
+ Object *obj = defineObjectBinding_helper(line, 0, objectType, typeLocation);
_stateStack.pushObject(obj);
@@ -297,7 +305,7 @@ Object *ProcessAST::defineObjectBinding(int line,
return obj;
}
- return defineObjectBinding_helper(line, qualifiedId, objectType, initializer);
+ return defineObjectBinding_helper(line, qualifiedId, objectType, typeLocation, initializer);
}
void ProcessAST::defineProperty(const QString &propertyName, int line, const QString &primitive)
@@ -372,7 +380,11 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
}
if(!typeFound) {
- qWarning() << "Unknown property type" << memberType; // ### FIXME
+ QmlError error;
+ error.setDescription("Expected property type");
+ error.setLine(node->typeToken.startLine);
+ error.setColumn(node->typeToken.startColumn);
+ _parser->_errors << error;
return false;
}
@@ -402,6 +414,7 @@ bool ProcessAST::visit(AST::UiObjectDefinition *node)
defineObjectBinding(node->identifierToken.startLine,
0,
node->name->asString(),
+ node->identifierToken,
node->initializer);
return false;
@@ -414,6 +427,7 @@ bool ProcessAST::visit(AST::UiObjectBinding *node)
defineObjectBinding(node->identifierToken.startLine,
node->qualifiedId,
node->name->asString(),
+ node->identifierToken,
node->initializer);
return false;
@@ -476,7 +490,8 @@ bool ProcessAST::visit(AST::UiScriptBinding *node)
Value *v = new Value;
v->primitive = primitive;
- v->line = node->colonToken.startLine;
+ v->line = node->statement->firstSourceLocation().startLine;
+ v->column = node->statement->firstSourceLocation().startColumn;
prop->addValue(v);
while (propertyCount--)
@@ -507,7 +522,11 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
{
QmlParser::Object *obj = currentObject();
if (! (obj && obj->typeName == "Script")) {
- // ### warning
+ QmlError error;
+ error.setDescription("JavaScript declaration outside Script element");
+ error.setLine(node->firstSourceLocation().startLine);
+ error.setColumn(node->firstSourceLocation().startColumn);
+ _parser->_errors << error;
return false;
}
@@ -535,7 +554,7 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
QmlScriptParser::QmlScriptParser()
- : root(0), _errorLine(-1)
+: root(0)
{
}
@@ -546,21 +565,6 @@ QmlScriptParser::~QmlScriptParser()
bool QmlScriptParser::parse(const QByteArray &data, const QUrl &url)
{
- if (QmlComponentPrivate::isXml(data)) {
- // parse using the XML parser.
- QmlXmlParser xmlParser;
- if (xmlParser.parse(data, url)) {
- _nameSpacePaths = xmlParser.nameSpacePaths();
- root = xmlParser.takeTree();
- _typeNames = xmlParser.types();
- return true;
- }
-
- _error = xmlParser.errorDescription();
- _errorLine = 0; // ### FIXME
- return false;
- }
-
const QString fileName = url.toString();
QTextStream stream(data, QIODevice::ReadOnly);
@@ -576,61 +580,34 @@ bool QmlScriptParser::parse(const QByteArray &data, const QUrl &url)
lexer.setCode(code, /*line = */ 1);
driver.setLexer(&lexer);
- if (! parser.parse(&driver)) {
- _error = parser.errorMessage();
- _errorLine = parser.errorLineNumber();
-
- const QStringList lines = code.split(QLatin1Char('\n'));
+ if (! parser.parse(&driver) || !_errors.isEmpty()) {
+ // Extract errors from the parser
foreach (const JavaScriptParser::DiagnosticMessage &m, parser.diagnosticMessages()) {
if (m.isWarning())
continue;
- qWarning().nospace() << qPrintable(fileName) << ":"
- << m.line << ":"
- << m.column << ": "
- << "error: "
- << qPrintable(m.message);
-
- const QString textLine = lines.at(m.line - 1);
-
- qWarning() << qPrintable(textLine);
+ QmlError error;
+ error.setUrl(url);
+ error.setDescription(m.message);
+ error.setLine(m.line);
+ error.setColumn(m.column);
+ _errors << error;
- int column = qMax(0, m.column - 1);
- column = qMin(column, textLine.length()); // paranoia check
-
- QByteArray ind;
- ind.reserve(column);
-
- for (int i = 0; i < column; ++i) {
- const QChar ch = textLine.at(i);
- if (ch.isSpace())
- ind.append(ch.unicode());
- else
- ind.append(' ');
- }
- ind.append('^');
- qWarning() << ind.constData();
}
-
- return false;
}
- ProcessAST process(this);
- process(code, parser.ast());
-
- return true;
-}
+ if (_errors.isEmpty()) {
+ ProcessAST process(this);
+ process(code, parser.ast());
-QString QmlScriptParser::errorDescription() const
-{
- return _error;
-}
+ // Set the url for process errors
+ for(int ii = 0; ii < _errors.count(); ++ii)
+ _errors[ii].setUrl(url);
+ }
-int QmlScriptParser::errorLine() const
-{
- return _errorLine;
+ return _errors.isEmpty();
}
QMap<QString,QString> QmlScriptParser::nameSpacePaths() const
@@ -648,6 +625,11 @@ Object *QmlScriptParser::tree() const
return root;
}
+QList<QmlError> QmlScriptParser::errors() const
+{
+ return _errors;
+}
+
void QmlScriptParser::clear()
{
if (root) {
@@ -656,9 +638,8 @@ void QmlScriptParser::clear()
}
_nameSpacePaths.clear();
_typeNames.clear();
- _error.clear();
+ _errors.clear();
_scriptFile.clear();
- _errorLine = 0;
}
int QmlScriptParser::findOrCreateTypeId(const QString &name)
diff --git a/src/declarative/qml/qmlscriptparser_p.h b/src/declarative/qml/qmlscriptparser_p.h
index 0d89268..4155bba 100644
--- a/src/declarative/qml/qmlscriptparser_p.h
+++ b/src/declarative/qml/qmlscriptparser_p.h
@@ -3,6 +3,7 @@
#include <QtCore/QList>
#include <QtCore/QUrl>
+#include <QtDeclarative/qmlerror.h>
#include <qml.h>
QT_BEGIN_HEADER
@@ -23,8 +24,6 @@ public:
~QmlScriptParser();
bool parse(const QByteArray &data, const QUrl &url = QUrl());
- QString errorDescription() const;
- int errorLine() const;
QMap<QString,QString> nameSpacePaths() const;
QStringList types() const;
@@ -33,6 +32,8 @@ public:
void clear();
+ QList<QmlError> errors() const;
+
// ### private:
int findOrCreateTypeId(const QString &name);
void setTree(QmlParser::Object *tree);
@@ -42,12 +43,12 @@ public:
void addNamespacePath(const QString &path);
-private:
+// ### private:
+ QList<QmlError> _errors;
+
QMap<QString,QString> _nameSpacePaths;
QmlParser::Object *root;
QStringList _typeNames;
- QString _error;
- int _errorLine;
QString _scriptFile;
};
diff --git a/src/declarative/qml/qmlvme.cpp b/src/declarative/qml/qmlvme.cpp
index e6235e4..ad3d1d5 100644
--- a/src/declarative/qml/qmlvme.cpp
+++ b/src/declarative/qml/qmlvme.cpp
@@ -176,9 +176,14 @@ QmlVME::QmlVME()
#define VME_EXCEPTION(desc) \
{ \
- exceptionLine = instr.line; \
- QDebug d(&exceptionDescription); \
- d << desc; \
+ QString str; \
+ QDebug d(&str); \
+ d << desc; \
+ QmlError error; \
+ error.setDescription(str); \
+ error.setLine(instr.line); \
+ error.setUrl(comp->url); \
+ vmeErrors << error; \
break; \
}
@@ -224,6 +229,8 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
QStack<QmlMetaProperty> pushedProperties;
QObject **savedObjects = 0;
+ vmeErrors.clear();
+
if (start == -1) start = 0;
if (count == -1) count = comp->bytecode.count();
@@ -270,27 +277,6 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
}
break;
- case QmlInstruction::CreateCustomObject:
- {
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxCompilerTimer<QFxCompiler::InstrCreateCustomObject> cc;
-#endif
- QVariant v =
- types.at(instr.createCustom.type).parser->create(datas.at(instr.createCustom.data));
- // XXX
- QObject *o = QmlMetaType::toQObject(v);
- if (!o)
- VME_EXCEPTION("Unable to create" << types.at(instr.create.type).className);
- QmlEngine::setContextForObject(o, QmlContext::activeContext());
-
- if (!stack.isEmpty()) {
- QObject *parent = stack.top();
- o->setParent(parent);
- }
- stack.push(o);
- }
- break;
-
case QmlInstruction::SetId:
{
#ifdef Q_ENABLE_PERFORMANCE_LOG
@@ -1072,17 +1058,12 @@ QObject *QmlVME::run(QmlContext *ctxt, QmlCompiledComponent *comp, int start, in
bool QmlVME::isError() const
{
- return exceptionLine != -1;
-}
-
-qint64 QmlVME::errorLine() const
-{
- return exceptionLine;
+ return !vmeErrors.isEmpty();
}
-QString QmlVME::errorDescription() const
+QList<QmlError> QmlVME::errors() const
{
- return exceptionDescription;
+ return vmeErrors;
}
void QmlVME::runStoreInstruction(QStack<QObject *> &stack,
diff --git a/src/declarative/qml/qmlvme_p.h b/src/declarative/qml/qmlvme_p.h
index 2a3be06..86cd040 100644
--- a/src/declarative/qml/qmlvme_p.h
+++ b/src/declarative/qml/qmlvme_p.h
@@ -44,6 +44,7 @@
#include <QString>
#include <QStack>
+#include <qmlerror.h>
class QObject;
QT_BEGIN_NAMESPACE
@@ -60,13 +61,13 @@ public:
QObject *run(QmlContext *, QmlCompiledComponent *, int start = -1, int end = -1);
bool isError() const;
- qint64 errorLine() const;
- QString errorDescription() const;
+ QList<QmlError> errors() const;
private:
void runStoreInstruction(QStack<QObject *> &stack,
QmlInstruction &, QmlCompiledData *);
+ QList<QmlError> vmeErrors;
qint64 exceptionLine;
QString exceptionDescription;
};
diff --git a/src/declarative/qml/qmlxmlparser.cpp b/src/declarative/qml/qmlxmlparser.cpp
deleted file mode 100644
index 35d2c0e..0000000
--- a/src/declarative/qml/qmlxmlparser.cpp
+++ /dev/null
@@ -1,391 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
-** Contact: Qt Software Information (qt-info@nokia.com)
-**
-** This file is part of the QtDeclarative module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the either Technology Preview License Agreement or the
-** Beta Release License Agreement.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain
-** additional rights. These rights are described in the Nokia Qt LGPL
-** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
-** package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-** If you are unsure which license is appropriate for your use, please
-** contact the sales department at qt-sales@nokia.com.
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qmlxmlparser_p.h"
-#include "qmlcustomparser_p.h"
-#include <qfxperf.h>
-#include <QXmlStreamReader>
-#include <QStack>
-#include "qmlparser_p.h"
-#include <private/qmlparser_p.h>
-#include <QtCore/qdebug.h>
-
-QT_BEGIN_NAMESPACE
-using namespace QmlParser;
-
-struct QmlXmlParserState {
- QmlXmlParserState() : object(0), property(0) {}
- QmlXmlParserState(Object *o) : object(o), property(0) {}
- QmlXmlParserState(Object *o, Property *p) : object(o), property(p) {}
-
- Object *object;
- Property *property;
-};
-
-struct QmlXmlParserStateStack : public QStack<QmlXmlParserState>
-{
- void pushObject(Object *obj)
- {
- push(QmlXmlParserState(obj));
- }
-
- void pushProperty(const QString &name, int lineNumber)
- {
- const QmlXmlParserState &state = top();
- if (state.property) {
- QmlXmlParserState s(state.property->getValue(),
- state.property->getValue()->getProperty(name.toLatin1()));
- s.property->line = lineNumber;
- push(s);
- } else {
- QmlXmlParserState s(state.object,
- state.object->getProperty(name.toLatin1()));
- s.property->line = lineNumber;
- push(s);
- }
- }
-};
-
-QmlXmlParser::~QmlXmlParser()
-{
- if (root)
- root->release();
-}
-
-QmlXmlParser::QmlXmlParser()
-: root(0)
-{
-}
-
-static QString flatXml(QXmlStreamReader& reader)
-{
- QString result;
- int depth=0;
- QStringRef ns = reader.namespaceUri();
- while (depth>=0) {
- switch (reader.tokenType()) {
- case QXmlStreamReader::StartElement:
- result += QLatin1Char('<');
- result += reader.name();
- if (reader.namespaceUri() != ns || depth==0) {
- result += QLatin1String(" xmlns=\"");
- result += reader.namespaceUri();
- result += QLatin1Char('"');
- }
- foreach(QXmlStreamAttribute attr, reader.attributes()) {
- result += QLatin1Char(' ');
- result += attr.name();
- result += QLatin1String("=\"");
- result += attr.value(); // XXX escape
- result += QLatin1Char('"');
- }
- result += QLatin1Char('>');
- ++depth;
- break;
- case QXmlStreamReader::EndElement:
- result += QLatin1String("</");
- result += reader.name();
- result += QLatin1Char('>');
- --depth;
- break;
- case QXmlStreamReader::Characters:
- result += reader.text();
- break;
- default:
- reader.raiseError(QLatin1String("Only StartElement, EndElement, and Characters permitted"));
- break;
- }
- if (depth>=0)
- reader.readNext();
- }
- return result;
-}
-
-bool QmlXmlParser::parse(const QByteArray &data, const QUrl &url)
-{
-#ifdef Q_ENABLE_PERFORMANCE_LOG
- QFxPerfTimer<QFxPerf::XmlParsing> pt;
-#endif
-
- QString fileDisplayName;
- if (url.isEmpty()) {
- fileDisplayName = QLatin1String("<unspecified file>");
- } else if (url.scheme() == QLatin1String("file")) {
- fileDisplayName = url.toLocalFile();
- } else {
- fileDisplayName = url.toString();
- }
- if (data.isEmpty()) {
- _error = QLatin1String("No Qml was specified for parsing @") + fileDisplayName;
- return false;
- }
-
- QmlXmlParserStateStack states;
-
- QXmlStreamReader reader;
- reader.addData(data);
-
- while(!reader.atEnd()) {
- switch(reader.readNext()) {
- case QXmlStreamReader::Invalid:
- case QXmlStreamReader::NoToken:
- case QXmlStreamReader::StartDocument:
- case QXmlStreamReader::EndDocument:
- break;
-
- case QXmlStreamReader::StartElement:
- {
- QString name = reader.name().toString();
- QString nameSpace = reader.namespaceUri().toString();
- int line = reader.lineNumber();
- bool isType = name.at(0).isUpper() && !name.contains(QLatin1Char('.'));
- QString qualifiedname;
- if (!nameSpace.isEmpty()) {
- qualifiedname = nameSpace;
- qualifiedname += QLatin1Char('/');
- }
- qualifiedname += name;
- QByteArray qualifiednameL1 = qualifiedname.toLatin1();
- QXmlStreamAttributes attrs = reader.attributes();
-
- if (isType) {
- // Class
- int typeId = _typeNames.indexOf(qualifiedname);
- if (typeId == -1) {
- typeId = _typeNames.count();
- _typeNames.append(qualifiedname);
- }
-
- Object *obj = new Object;
- obj->type = typeId;
- obj->typeName = qualifiednameL1;
- obj->line = line;
-
- QmlCustomParser *customparser = QmlMetaType::customParser(qualifiednameL1);
- if (customparser) {
- bool ok;
- obj->custom = customparser->compile(reader, &ok);
- if (reader.tokenType() != QXmlStreamReader::EndElement) {
- reader.raiseError(QLatin1String("Parser for ") + qualifiedname + QLatin1String(" did not end on end element"));
- ok = false;
- }
- if (!ok) {
- delete obj;
- break;
- }
- }
-
-
- if (!root) {
- root = obj;
- states.pushObject(obj);
- } else {
- const QmlXmlParserState &state = states.top();
- Value *v = new Value;
- v->object = obj;
- v->line = line;
- if (state.property)
- state.property->addValue(v);
- else
- state.object->getDefaultProperty()->addValue(v);
- states.pushObject(obj);
- }
- } else {
- // Property
- if (!root) {
- reader.raiseError(QLatin1String("Can't have a property with no object"));
- break;
- }
- QStringList str = name.split(QLatin1Char('.'));
- for (int ii = 0; ii < str.count(); ++ii) {
- QString s = str.at(ii);
- states.pushProperty(s, line);
- }
- if (!nameSpace.isEmpty()) {
- // Pass non-QML as flat text property value
- const QmlXmlParserState &state = states.top();
- Value *v = new Value;
- v->primitive = flatXml(reader);
- v->line = line;
- state.property->addValue(v);
- }
- }
-
- // (even custom parsed content gets properties set)
- foreach(QXmlStreamAttribute attr, attrs) {
- QStringList str = attr.name().toString().split(QLatin1Char('.'));
-
- for (int ii = 0; ii < str.count(); ++ii) {
- QString s = str.at(ii);
- states.pushProperty(s, line);
- }
-
- const QmlXmlParserState &state = states.top();
- Value *v = new Value;
- v->primitive = attr.value().toString();
- v->line = reader.lineNumber();
- state.property->addValue(v);
-
- for (int ii = str.count() - 1; ii >= 0; --ii)
- states.pop();
- }
- }
-
- // Custom parsers and namespaced properties move
- // the reader to the end element, so we handle that
- // BEFORE continuing.
- //
- if (reader.tokenType()!=QXmlStreamReader::EndElement)
- break;
- // ELSE fallthrough to EndElement...
- case QXmlStreamReader::EndElement:
- {
- QString name = reader.name().toString();
- Q_ASSERT(!name.isEmpty());
- if (name.at(0).isUpper() && !name.contains(QLatin1Char('.'))) {
- // Class
- states.pop();
- } else {
- // Property
- QStringList str = name.split(QLatin1Char('.'));
- for (int ii = 0; ii < str.count(); ++ii)
- states.pop();
- }
- }
- break;
- case QXmlStreamReader::Characters:
- if (!reader.isWhitespace()) {
- const QmlXmlParserState &state = states.top();
- Value *v = new Value;
- v->primitive = reader.text().toString();
- v->line = reader.lineNumber();
- if (state.property)
- state.property->addValue(v);
- else
- state.object->getDefaultProperty()->addValue(v);
- }
- break;
-
- case QXmlStreamReader::Comment:
- case QXmlStreamReader::DTD:
- case QXmlStreamReader::EntityReference:
- break;
- case QXmlStreamReader::ProcessingInstruction:
- if (reader.processingInstructionTarget() == QLatin1String("qtfx")) {
- QString str = reader.processingInstructionData().toString();
- QString token, data;
- int idx = str.indexOf(QLatin1Char(':'));
- if (-1 != idx) {
- token = str.left(idx);
- data = str.mid(idx + 1);
- } else {
- token = str;
- }
- token = token.trimmed();
- data = data.trimmed();
-
- // <?qtfx namespacepath: namespace=path>
-
- if (token == QLatin1String("namespacepath")) {
- int eq=data.indexOf(QLatin1Char('='));
- if (eq>=0) {
- _nameSpacePaths.insertMulti(data.left(eq),data.mid(eq+1));
- }
- } else {
- str = str.trimmed();
- qWarning().nospace() << "Unknown processing instruction " << str.toLatin1().constData() << " @" << fileDisplayName.toLatin1().constData() << ":" << reader.lineNumber();
- }
- }
- break;
- }
- }
-
- if (reader.hasError()) {
- if (root) {
- root->release();
- root = 0;
- }
- _error = reader.errorString() + QLatin1String(" @") + fileDisplayName +
- QLatin1String(":") + QString::number(reader.lineNumber());
- }
-
- return root != 0;
-}
-
-QMap<QString,QString> QmlXmlParser::nameSpacePaths() const
-{
- return _nameSpacePaths;
-}
-
-QStringList QmlXmlParser::types() const
-{
- return _typeNames;
-}
-
-QmlParser::Object *QmlXmlParser::tree() const
-{
- return root;
-}
-
-QmlParser::Object *QmlXmlParser::takeTree()
-{
- QmlParser::Object *r = root;
- root = 0;
- return r;
-}
-
-QString QmlXmlParser::errorDescription() const
-{
- return _error;
-}
-
-void QmlXmlParser::clear()
-{
- if (root) {
- root->release();
- root = 0;
- }
- _nameSpacePaths.clear();
- _typeNames.clear();
- _error.clear();
-}
-
-QT_END_NAMESPACE
diff --git a/src/declarative/util/qfxview.cpp b/src/declarative/util/qfxview.cpp
index cac73a0..f71b87e 100644
--- a/src/declarative/util/qfxview.cpp
+++ b/src/declarative/util/qfxview.cpp
@@ -233,8 +233,6 @@ QmlContext* QFxView::rootContext()
*/
void QFxView::execute()
{
- rootContext()->activate();
-
if (d->qml.isEmpty()) {
d->component = new QmlComponent(&d->engine, d->source, this);
} else {
@@ -249,6 +247,45 @@ void QFxView::execute()
}
/*!
+ \internal
+*/
+void QFxView::printErrorLine(const QmlError &error)
+{
+ QUrl url = error.url();
+ if (error.line() > 0 && error.column() > 0 &&
+ url.scheme() == QLatin1String("file")) {
+ QString file = url.toLocalFile();
+ QFile f(file);
+ if (f.open(QIODevice::ReadOnly)) {
+ QByteArray data = f.readAll();
+ QTextStream stream(data, QIODevice::ReadOnly);
+ const QString code = stream.readAll();
+ const QStringList lines = code.split(QLatin1Char('\n'));
+
+ if (lines.count() >= error.line()) {
+ const QString &line = lines.at(error.line() - 1);
+ qWarning() << qPrintable(line);
+
+ int column = qMax(0, error.column() - 1);
+ column = qMin(column, line.length());
+
+ QByteArray ind;
+ ind.reserve(column);
+ for (int i = 0; i < column; ++i) {
+ const QChar ch = line.at(i);
+ if (ch.isSpace())
+ ind.append(ch.unicode());
+ else
+ ind.append(' ');
+ }
+ ind.append('^');
+ qWarning() << ind.constData();
+ }
+ }
+ }
+}
+
+/*!
\internal
*/
void QFxView::continueExecute()
@@ -260,8 +297,26 @@ void QFxView::continueExecute()
return;
}
+ if(d->component->isError()) {
+ QList<QmlError> errors = d->component->errors();
+ foreach (const QmlError &error, errors) {
+ qWarning() << error;
+ }
+
+ return;
+ }
+
QObject *obj = d->component->create();
- rootContext()->deactivate();
+
+ if(d->component->isError()) {
+ QList<QmlError> errors = d->component->errors();
+ foreach (const QmlError &error, errors) {
+ qWarning() << error;
+ }
+
+ return;
+ }
+
if (obj) {
if (QFxItem *item = qobject_cast<QFxItem *>(obj)) {
item->QSimpleCanvasItem::setParent(QSimpleCanvas::root());
@@ -330,7 +385,25 @@ QFxItem* QFxView::addItem(const QString &qml, QFxItem* parent)
return 0;
QmlComponent component(&d->engine, qml.toUtf8(), QUrl());
+ if(d->component->isError()) {
+ QList<QmlError> errors = d->component->errors();
+ foreach (const QmlError &error, errors) {
+ qWarning() << error;
+ }
+
+ return 0;
+ }
+
QObject *obj = component.create();
+ if(d->component->isError()) {
+ QList<QmlError> errors = d->component->errors();
+ foreach (const QmlError &error, errors) {
+ qWarning() << error;
+ }
+
+ return 0;
+ }
+
if (obj){
QFxItem *item = static_cast<QFxItem *>(obj);
if (!parent)
diff --git a/src/declarative/util/qfxview.h b/src/declarative/util/qfxview.h
index d2cacf4..f575f27 100644
--- a/src/declarative/util/qfxview.h
+++ b/src/declarative/util/qfxview.h
@@ -57,7 +57,7 @@ QT_MODULE(Declarative)
class QFxItem;
class QmlEngine;
class QmlContext;
-class Canvas;
+class QmlError;
class QFxViewPrivate;
class Q_DECLARATIVE_EXPORT QFxView : public QSimpleCanvas
@@ -84,6 +84,7 @@ public:
void dumpRoot();
+ static void printErrorLine(const QmlError &);
Q_SIGNALS:
void sceneResized(QSize size);
diff --git a/src/declarative/util/qmllistmodel.cpp b/src/declarative/util/qmllistmodel.cpp
index 4837180..6ad0cb9 100644
--- a/src/declarative/util/qmllistmodel.cpp
+++ b/src/declarative/util/qmllistmodel.cpp
@@ -190,8 +190,6 @@ ModelObject::ModelObject(ModelNode *node)
{
}
-QML_DECLARE_TYPE(ListModel);
-QML_DEFINE_TYPE(ListModel,ListModel);
ListModel::ListModel(QObject *parent)
: QListModelInterface(parent), _rolesOk(false), _root(0)
{
@@ -304,14 +302,10 @@ int ListModel::count() const
class ListModelParser : public QmlCustomParser
{
public:
- virtual QByteArray compile(QXmlStreamReader& reader, bool *);
QByteArray compile(const QList<QmlCustomParserProperty> &, bool *ok);
- virtual QVariant create(const QByteArray &);
-
bool compileProperty(const QmlCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data);
void setCustomData(QObject *, const QByteArray &);
};
-QML_DEFINE_CUSTOM_PARSER(ListModel, ListModelParser);
bool ListModelParser::compileProperty(const QmlCustomParserProperty &prop, QList<ListInstruction> &instr, QByteArray &data)
{
@@ -462,13 +456,10 @@ void ListModelParser::setCustomData(QObject *obj, const QByteArray &d)
}
}
-class ListModel2 : public ListModel
-{
-Q_OBJECT
-};
-QML_DECLARE_TYPE(ListModel2);
-QML_DEFINE_CUSTOM_TYPE(ListModel2, ListModel2, ListModelParser);
+QML_DECLARE_TYPE(ListModel);
+QML_DEFINE_CUSTOM_TYPE(ListModel, ListModel, ListModelParser);
+// ### FIXME
class ListElement : public QObject
{
Q_OBJECT
@@ -512,170 +503,5 @@ ModelNode::~ModelNode()
if (modelCache) { delete modelCache; modelCache = 0; }
}
-QByteArray ListModelParser::compile(QXmlStreamReader& reader, bool *ok)
-{
- *ok = true;
-
- QByteArray data;
- QList<ListInstruction> instr;
- int depth=0;
-
- while(!reader.atEnd() && depth >= 0) {
- switch(reader.readNext()) {
- case QXmlStreamReader::StartElement:
- {
- QStringRef name = reader.name();
- bool isType = name.at(0).isUpper();
-
- if (isType) {
- ListInstruction li;
- li.type = ListInstruction::Push;
- li.dataIdx = -1;
- instr << li;
-
- for (int i = 0; i < reader.attributes().count(); ++i) {
- const QXmlStreamAttribute &attr = reader.attributes().at(i);
- QStringRef attrName = attr.name();
- QStringRef attrValue = attr.value();
-
- ListInstruction li;
- int ref = data.count();
- data.append(attrName.toString().toLatin1());
- data.append('\0');
- li.type = ListInstruction::Set;
- li.dataIdx = ref;
- instr << li;
-
- ref = data.count();
- data.append(attrValue.toString().toLatin1());
- data.append('\0');
- li.type = ListInstruction::Value;
- li.dataIdx = ref;
- instr << li;
-
- li.type = ListInstruction::Pop;
- li.dataIdx = -1;
- instr << li;
- }
- } else {
- ListInstruction li;
- int ref = data.count();
- data.append(name.toString().toLatin1());
- data.append('\0');
- li.type = ListInstruction::Set;
- li.dataIdx = ref;
- instr << li;
- }
- }
- ++depth;
- break;
- case QXmlStreamReader::EndElement:
- {
- ListInstruction li;
- li.type = ListInstruction::Pop;
- li.dataIdx = -1;
- instr << li;
- --depth;
- }
- break;
- case QXmlStreamReader::Characters:
- if (!reader.isWhitespace()) {
- int ref = data.count();
- QByteArray d = reader.text().toString().toLatin1();
- d.append('\0');
- data.append(d);
-
- ListInstruction li;
- li.type = ListInstruction::Value;
- li.dataIdx = ref;
- instr << li;
- }
- break;
-
- case QXmlStreamReader::Invalid:
- case QXmlStreamReader::NoToken:
- case QXmlStreamReader::StartDocument:
- case QXmlStreamReader::EndDocument:
- case QXmlStreamReader::Comment:
- case QXmlStreamReader::DTD:
- case QXmlStreamReader::EntityReference:
- case QXmlStreamReader::ProcessingInstruction:
- break;
- }
- }
-
- if (reader.hasError())
- *ok = true;
-
- if (!*ok)
- return QByteArray();
-
- int size = sizeof(ListModelData) +
- instr.count() * sizeof(ListInstruction) +
- data.count();
-
- QByteArray rv;
- rv.resize(size);
-
- ListModelData *lmd = (ListModelData *)rv.data();
- lmd->dataOffset = sizeof(ListModelData) +
- instr.count() * sizeof(ListInstruction);
- lmd->instrCount = instr.count();
- for (int ii = 0; ii < instr.count(); ++ii)
- lmd->instructions()[ii] = instr.at(ii);
- ::memcpy(rv.data() + lmd->dataOffset, data.constData(), data.count());
-
- return rv;
-}
-
-QVariant ListModelParser::create(const QByteArray &d)
-{
- ListModel *rv = new ListModel;
- ModelNode *root = new ModelNode;
- rv->_root = root;
- QStack<ModelNode *> nodes;
- nodes << root;
-
- const ListModelData *lmd = (const ListModelData *)d.constData();
- const char *data = ((const char *)lmd) + lmd->dataOffset;
-
- for (int ii = 0; ii < lmd->instrCount; ++ii) {
- const ListInstruction &instr = lmd->instructions()[ii];
-
- switch(instr.type) {
- case ListInstruction::Push:
- {
- ModelNode *n = nodes.top();
- ModelNode *n2 = new ModelNode;
- n->values << qVariantFromValue(n2);
- nodes.push(n2);
- }
- break;
-
- case ListInstruction::Pop:
- nodes.pop();
- break;
-
- case ListInstruction::Value:
- {
- ModelNode *n = nodes.top();
- n->values.append(QByteArray(data + instr.dataIdx));
- }
- break;
-
- case ListInstruction::Set:
- {
- ModelNode *n = nodes.top();
- ModelNode *n2 = new ModelNode;
- n->properties.insert(QLatin1String(data + instr.dataIdx), n2);
- nodes.push(n2);
- }
- break;
- }
- }
-
- return QVariant::fromValue(rv);
-}
-
QT_END_NAMESPACE
#include "qmllistmodel.moc"