summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/declarative/debugger/qmldebugger.cpp29
-rw-r--r--src/declarative/qml/qml.pri1
-rw-r--r--src/declarative/qml/qmlbindablevalue.cpp61
-rw-r--r--src/declarative/qml/qmlbindablevalue.h6
-rw-r--r--src/declarative/qml/qmlbindablevalue_p.h63
-rw-r--r--src/declarative/qml/qmlcompiledcomponent.cpp74
-rw-r--r--src/declarative/qml/qmlcompiledcomponent_p.h3
-rw-r--r--src/declarative/qml/qmlcompiler.cpp93
-rw-r--r--src/declarative/qml/qmlcompiler_p.h11
-rw-r--r--src/declarative/qml/qmldom.cpp2
-rw-r--r--src/declarative/qml/qmlengine.cpp138
-rw-r--r--src/declarative/qml/qmlengine_p.h27
-rw-r--r--src/declarative/qml/qmlexpression.h1
-rw-r--r--src/declarative/qml/qmlinstruction_p.h3
-rw-r--r--src/declarative/qml/qmlparser.cpp88
-rw-r--r--src/declarative/qml/qmlparser_p.h35
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp98
-rw-r--r--tools/qmlviewer/main.cpp1
-rw-r--r--tools/qmlviewer/qmlviewer.cpp50
-rw-r--r--tools/qmlviewer/qmlviewer.h6
20 files changed, 547 insertions, 243 deletions
diff --git a/src/declarative/debugger/qmldebugger.cpp b/src/declarative/debugger/qmldebugger.cpp
index 1f7fd68..033a15f 100644
--- a/src/declarative/debugger/qmldebugger.cpp
+++ b/src/declarative/debugger/qmldebugger.cpp
@@ -46,6 +46,7 @@
#include <QtDeclarative/qmlbindablevalue.h>
#include <private/qmlboundsignal_p.h>
#include <private/qmlcontext_p.h>
+#include <private/qmlengine_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qfile.h>
#include <QtCore/qurl.h>
@@ -98,13 +99,35 @@ public:
int startLine;
int endLine;
QUrl url;
+
+ QPointer<QmlBindableValue> bindableValue;
};
void QmlDebugger::itemPressed(QTreeWidgetItem *i)
{
QmlDebuggerItem *item = static_cast<QmlDebuggerItem *>(i);
- if(item->url.scheme() == QLatin1String("file")) {
+ if(item->bindableValue) {
+
+ QString str;
+
+ QmlExpressionPrivate *p = item->bindableValue->d;
+ if(p->log) {
+ QString str;
+ QDebug d(&str);
+ for(int ii = 0; ii < p->log->count(); ++ii) {
+ d << p->log->at(ii).result() << "\n";
+ QStringList warnings = p->log->at(ii).warnings();
+ foreach(const QString &warning, warnings)
+ d << " " << warning << "\n";
+ }
+ m_text->setPlainText(str);
+
+ } else {
+ m_text->setPlainText("No history");
+ }
+
+ } else if(item->url.scheme() == QLatin1String("file")) {
QString f = item->url.toLocalFile();
QFile file(f);
file.open(QIODevice::ReadOnly);
@@ -160,6 +183,7 @@ static bool makeItem(QObject *obj, QmlDebuggerItem *item)
if(QmlBindableValue *bv = qobject_cast<QmlBindableValue *>(obj)) {
text = bv->property().name() + ": " + bv->expression();
item->setForeground(0, Qt::green);
+ item->bindableValue = bv;
} else if(QmlBoundSignal *bs = qobject_cast<QmlBoundSignal *>(obj)) {
QMetaMethod method = obj->parent()->metaObject()->method(bs->index());
QByteArray sig = method.signature();
@@ -203,6 +227,9 @@ static bool makeItem(QObject *obj, QmlDebuggerItem *item)
} else {
item->setExpanded(true);
}
+
+ if(!context)
+ item->setForeground(0, Qt::lightGray);
}
item->setText(0, text);
diff --git a/src/declarative/qml/qml.pri b/src/declarative/qml/qml.pri
index 5198264..99e30e4 100644
--- a/src/declarative/qml/qml.pri
+++ b/src/declarative/qml/qml.pri
@@ -29,6 +29,7 @@ HEADERS += qml/qmlparser_p.h \
qml/qmlvmemetaobject_p.h \
qml/qml.h \
qml/qmlbindablevalue.h \
+ qml/qmlbindablevalue_p.h \
qml/qmlmetaproperty.h \
qml/qmlcomponent.h \
qml/qmlcomponent_p.h \
diff --git a/src/declarative/qml/qmlbindablevalue.cpp b/src/declarative/qml/qmlbindablevalue.cpp
index b312b40..3950f82 100644
--- a/src/declarative/qml/qmlbindablevalue.cpp
+++ b/src/declarative/qml/qmlbindablevalue.cpp
@@ -41,6 +41,7 @@
#include <qml.h>
#include "qmlbindablevalue.h"
+#include "qmlbindablevalue_p.h"
#include <qmlcontext.h>
#include <QVariant>
#include <qfxperf.h>
@@ -50,20 +51,25 @@
QT_BEGIN_NAMESPACE
DEFINE_BOOL_CONFIG_OPTION(scriptWarnings, QML_SCRIPT_WARNINGS);
+QmlBindableValuePrivate::QmlBindableValuePrivate()
+: inited(false)
+{
+}
+
QML_DEFINE_NOCREATE_TYPE(QmlBindableValue);
QmlBindableValue::QmlBindableValue(QObject *parent)
-: QmlPropertyValueSource(parent), _inited(false)
+: QmlPropertyValueSource(*new QmlBindableValuePrivate, parent)
{
qFatal("QmlBindableValue: Default constructor not supported");
}
QmlBindableValue::QmlBindableValue(void *data, QmlRefCount *rc, QObject *obj, QObject *parent)
-: QmlPropertyValueSource(parent), QmlExpression(QmlContext::activeContext(), data, rc, obj), _inited(false)
+: QmlPropertyValueSource(*new QmlBindableValuePrivate, parent), QmlExpression(QmlContext::activeContext(), data, rc, obj)
{
}
QmlBindableValue::QmlBindableValue(const QString &str, QObject *obj, bool sse, QObject *parent)
-: QmlPropertyValueSource(parent), QmlExpression(QmlContext::activeContext(), str, obj, sse), _inited(false)
+: QmlPropertyValueSource(*new QmlBindableValuePrivate, parent), QmlExpression(QmlContext::activeContext(), str, obj, sse)
{
}
@@ -73,16 +79,25 @@ QmlBindableValue::~QmlBindableValue()
void QmlBindableValue::setTarget(const QmlMetaProperty &prop)
{
- _property = prop;
+ Q_D(QmlBindableValue);
+ d->property = prop;
update();
}
+QmlMetaProperty QmlBindableValue::property() const
+{
+ Q_D(const QmlBindableValue);
+ return d->property;
+}
+
void QmlBindableValue::init()
{
- if (_inited)
+ Q_D(QmlBindableValue);
+
+ if (d->inited)
return;
- _inited = true;
+ d->inited = true;
update();
}
@@ -95,20 +110,22 @@ void QmlBindableValue::setExpression(const QString &expr)
Q_DECLARE_METATYPE(QList<QObject *>);
void QmlBindableValue::update()
{
+ Q_D(QmlBindableValue);
+
#ifdef Q_ENABLE_PERFORMANCE_LOG
QFxPerfTimer<QFxPerf::BindableValueUpdate> bu;
#endif
- if (!_inited)
+ if (!d->inited)
return;
- if (_property.propertyCategory() == QmlMetaProperty::List) {
+ if (d->property.propertyCategory() == QmlMetaProperty::List) {
QVariant value = this->value();
- int listType = QmlMetaType::listType(_property.propertyType());
+ int listType = QmlMetaType::listType(d->property.propertyType());
if (value.userType() == qMetaTypeId<QList<QObject *> >()) {
const QList<QObject *> &list =
qvariant_cast<QList<QObject *> >(value);
- QVariant listVar = _property.read();
+ QVariant listVar = d->property.read();
QmlMetaType::clear(listVar);
for (int ii = 0; ii < list.count(); ++ii) {
QVariant v = QmlMetaType::fromObject(list.at(ii), listType);
@@ -117,14 +134,14 @@ void QmlBindableValue::update()
} else if (value.type() == uint(listType) ||
value.userType() == listType) {
- QVariant listVar = _property.read();
+ QVariant listVar = d->property.read();
QmlMetaType::clear(listVar);
QmlMetaType::append(listVar, value);
}
- } else if (_property.propertyCategory() == QmlMetaProperty::QmlList) {
+ } else if (d->property.propertyCategory() == QmlMetaProperty::QmlList) {
// XXX - optimize!
QVariant value = this->value();
- QVariant list = _property.read();
+ QVariant list = d->property.read();
QmlPrivate::ListInterface *li =
*(QmlPrivate::ListInterface **)list.constData();
@@ -153,20 +170,20 @@ void QmlBindableValue::update()
void *d = (void *)&obj;
li->append(d);
}
- } else if (_property.propertyCategory() == QmlMetaProperty::Bindable) {
+ } else if (d->property.propertyCategory() == QmlMetaProperty::Bindable) {
// NOTE: We assume that only core properties can have
// propertyType == Bindable
- int idx = _property.coreIndex();
+ int idx = d->property.coreIndex();
Q_ASSERT(idx != -1);
void *a[1];
QmlBindableValue *t = this;
a[0] = (void *)&t;
- _property.object()->qt_metacall(QMetaObject::WriteProperty,
- idx, a);
+ d->property.object()->qt_metacall(QMetaObject::WriteProperty,
+ idx, a);
- } else if (_property.propertyCategory() == QmlMetaProperty::Object) {
+ } else if (d->property.propertyCategory() == QmlMetaProperty::Object) {
QVariant value = this->value();
if ((int)value.type() != qMetaTypeId<QObject *>()) {
@@ -186,17 +203,17 @@ void QmlBindableValue::update()
// NOTE: We assume that only core properties can have
// propertyType == Object
- int idx = _property.coreIndex();
+ int idx = d->property.coreIndex();
Q_ASSERT(idx != -1);
void *a[1];
a[0] = (void *)&obj;
- _property.object()->qt_metacall(QMetaObject::WriteProperty,
+ d->property.object()->qt_metacall(QMetaObject::WriteProperty,
idx, a);
- } else if (_property.propertyCategory() == QmlMetaProperty::Normal) {
+ } else if (d->property.propertyCategory() == QmlMetaProperty::Normal) {
QVariant value = this->value();
- _property.write(value);
+ d->property.write(value);
}
}
diff --git a/src/declarative/qml/qmlbindablevalue.h b/src/declarative/qml/qmlbindablevalue.h
index 578fc12..c4ef64a 100644
--- a/src/declarative/qml/qmlbindablevalue.h
+++ b/src/declarative/qml/qmlbindablevalue.h
@@ -56,6 +56,7 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Declarative)
class QmlExpression;
class QmlContext;
+class QmlBindableValuePrivate;
class Q_DECLARATIVE_EXPORT QmlBindableValue : public QmlPropertyValueSource,
public QmlExpression
{
@@ -67,7 +68,7 @@ public:
~QmlBindableValue();
virtual void setTarget(const QmlMetaProperty &);
- QmlMetaProperty property() const { return _property; }
+ QmlMetaProperty property() const;
Q_CLASSINFO("DefaultProperty", "expression");
Q_PROPERTY(QString expression READ expression WRITE setExpression);
@@ -82,8 +83,7 @@ protected:
virtual void valueChanged();
private:
- bool _inited;
- QmlMetaProperty _property;
+ Q_DECLARE_PRIVATE(QmlBindableValue)
};
QML_DECLARE_TYPE(QmlBindableValue);
diff --git a/src/declarative/qml/qmlbindablevalue_p.h b/src/declarative/qml/qmlbindablevalue_p.h
new file mode 100644
index 0000000..b6de5b7
--- /dev/null
+++ b/src/declarative/qml/qmlbindablevalue_p.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef QMLBINDABLEVALUE_P_H
+#define QMLBINDABLEVALUE_P_H
+
+#include <private/qobject_p.h>
+#include <qmlbindablevalue.h>
+#include <qmlmetaproperty.h>
+
+QT_BEGIN_NAMESPACE
+
+class QmlBindableValuePrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QmlBindableValue);
+public:
+ QmlBindableValuePrivate();
+
+ bool inited;
+ QmlMetaProperty property;
+};
+
+QT_END_NAMESPACE
+
+#endif // QMLBINDABLEVALUE_P_H
diff --git a/src/declarative/qml/qmlcompiledcomponent.cpp b/src/declarative/qml/qmlcompiledcomponent.cpp
index 2c76f0c..c69af44 100644
--- a/src/declarative/qml/qmlcompiledcomponent.cpp
+++ b/src/declarative/qml/qmlcompiledcomponent.cpp
@@ -76,80 +76,6 @@ void QmlCompiledComponent::dumpInstructions()
qWarning() << "-------------------------------------------------------------------------------";
}
-void QmlCompiledComponent::dump(int indent, Property *p)
-{
- QByteArray ba(indent * 4, ' ');
- for (int ii = 0; ii < p->values.count(); ++ii)
- dump(indent, p->values.at(ii));
- if (p->value)
- dump(indent, p->value);
-}
-
-void QmlCompiledComponent::dump(int indent, Object *o)
-{
- QByteArray ba(indent * 4, ' ');
- if (o->type != -1) {
- qWarning() << ba.constData() << "Object:" << types.at(o->type).className;
- } else {
- qWarning() << ba.constData() << "Object: fetched";
- }
-
- for (QHash<QByteArray, Property *>::ConstIterator iter = o->properties.begin();
- iter != o->properties.end();
- ++iter) {
- qWarning() << ba.constData() << " Property" << iter.key();
- dump(indent + 1, *iter);
- }
-
- if (o->defaultProperty) {
- qWarning() << ba.constData() << " Default property";
- dump(indent + 1, o->defaultProperty);
- }
-}
-
-void QmlCompiledComponent::dump(int indent, Value *v)
-{
- QByteArray type;
- switch(v->type) {
- default:
- case Value::Unknown:
- type = "Unknown";
- break;
- case Value::Literal:
- type = "Literal";
- break;
- case Value::PropertyBinding:
- type = "PropertyBinding";
- break;
- case Value::ValueSource:
- type = "ValueSource";
- break;
- case Value::CreatedObject:
- type = "CreatedObject";
- break;
- case Value::SignalObject:
- type = "SignalObject";
- break;
- case Value::SignalExpression:
- type = "SignalExpression";
- break;
- case Value::Component:
- type = "Component";
- break;
- case Value::Id:
- type = "Id";
- break;
- };
-
- QByteArray ba(indent * 4, ' ');
- if (v->object) {
- qWarning() << ba.constData() << "Value (" << type << "):";
- dump(indent + 1, v->object);
- } else {
- qWarning() << ba.constData() << "Value (" << type << "):" << v->primitive;
- }
-}
-
void QmlCompiledComponent::dumpPre()
{
if (!(dumpStatus & DumpPre)) {
diff --git a/src/declarative/qml/qmlcompiledcomponent_p.h b/src/declarative/qml/qmlcompiledcomponent_p.h
index 883ad64..c5e1226 100644
--- a/src/declarative/qml/qmlcompiledcomponent_p.h
+++ b/src/declarative/qml/qmlcompiledcomponent_p.h
@@ -67,9 +67,6 @@ public:
private:
enum DumpStatus { NoDump = 0x00, DumpPre = 0x01, DumpPost = 0x02 } dumpStatus;
void dumpInstructions();
- void dump(int indent, QmlParser::Property *p);
- void dump(int indent, QmlParser::Object *o);
- void dump(int indent, QmlParser::Value *v);
void dump(QmlInstruction *, int idx = -1);
friend class QmlCompiler;
friend class QmlDomDocument;
diff --git a/src/declarative/qml/qmlcompiler.cpp b/src/declarative/qml/qmlcompiler.cpp
index 9ae1278..13fc332 100644
--- a/src/declarative/qml/qmlcompiler.cpp
+++ b/src/declarative/qml/qmlcompiler.cpp
@@ -136,6 +136,22 @@ int QmlCompiledData::indexForInt(int *data, int count)
return idx;
}
+int QmlCompiledData::indexForLocation(const QmlParser::Location &l)
+{
+ // ### FIXME
+ int rv = locations.count();
+ locations << l;
+ return rv;
+}
+
+int QmlCompiledData::indexForLocation(const QmlParser::LocationSpan &l)
+{
+ // ### FIXME
+ int rv = locations.count();
+ locations << l.start << l.end;
+ return rv;
+}
+
QmlCompiler::QmlCompiler()
: exceptionLine(-1), exceptionColumn(-1), output(0)
{
@@ -434,8 +450,8 @@ void QmlCompiler::reset(QmlCompiledComponent *cc, bool deleteMemory)
#define COMPILE_EXCEPTION2(token, desc) \
{ \
- exceptionLine = token->line; \
- exceptionColumn = token->column; \
+ exceptionLine = token->location.start.line; \
+ exceptionColumn = token->location.start.column; \
QDebug d(&exceptionDescription); \
d << desc; \
return false; \
@@ -443,8 +459,8 @@ void QmlCompiler::reset(QmlCompiledComponent *cc, bool deleteMemory)
#define COMPILE_EXCEPTION(desc) \
{ \
- exceptionLine = obj->line; \
- exceptionColumn = obj->column; \
+ exceptionLine = obj->location.start.line; \
+ exceptionColumn = obj->location.start.column; \
QDebug d(&exceptionDescription); \
d << desc; \
return false; \
@@ -541,7 +557,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
// Create the object
QmlInstruction create;
create.type = QmlInstruction::CreateObject;
- create.line = obj->line;
+ create.line = obj->location.start.line;
create.create.data = -1;
create.create.type = obj->type;
output->bytecode << create;
@@ -552,7 +568,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
if (output->types.at(obj->type).component) {
QmlInstruction begin;
begin.type = QmlInstruction::TryBeginObject;
- begin.line = obj->line;
+ begin.line = obj->location.start.line;
output->bytecode << begin;
} else {
int cast = QmlMetaType::qmlParserStatusCast(QmlMetaType::type(output->types.at(obj->type).className));
@@ -560,7 +576,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
QmlInstruction begin;
begin.type = QmlInstruction::BeginObject;
begin.begin.castValue = cast;
- begin.line = obj->line;
+ begin.line = obj->location.start.line;
output->bytecode << begin;
}
}
@@ -611,7 +627,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
if (output->types.at(obj->type).component) {
QmlInstruction complete;
complete.type = QmlInstruction::TryCompleteObject;
- complete.line = obj->line;
+ complete.line = obj->location.start.line;
output->bytecode << complete;
} else {
int cast = QmlMetaType::qmlParserStatusCast(QmlMetaType::type(output->types.at(obj->type).className));
@@ -619,7 +635,7 @@ bool QmlCompiler::compileObject(Object *obj, int ctxt)
QmlInstruction complete;
complete.type = QmlInstruction::CompleteObject;
complete.complete.castValue = cast;
- complete.line = obj->line;
+ complete.line = obj->location.start.line;
output->bytecode << complete;
}
}
@@ -661,7 +677,7 @@ bool QmlCompiler::compileComponent(Object *obj, int ctxt)
int pref = output->indexForString(val);
QmlInstruction id;
id.type = QmlInstruction::SetId;
- id.line = idProp->line;
+ id.line = idProp->location.start.line;
id.setId.value = pref;
id.setId.save = -1;
output->bytecode << id;
@@ -675,14 +691,14 @@ bool QmlCompiler::compileComponentFromRoot(Object *obj, int ctxt)
output->bytecode.push_back(QmlInstruction());
QmlInstruction &create = output->bytecode.last();
create.type = QmlInstruction::CreateComponent;
- create.line = obj->line;
- create.createComponent.endLine = obj->endLine;
+ create.line = obj->location.start.line;
+ create.createComponent.endLine = obj->location.end.line;
int count = output->bytecode.count();
QmlInstruction init;
init.type = QmlInstruction::Init;
init.init.dataSize = 0;
- init.line = obj->line;
+ init.line = obj->location.start.line;
output->bytecode << init;
QSet<QString> oldIds = ids;
@@ -732,7 +748,7 @@ bool QmlCompiler::compileSignal(Property *prop, Object *obj)
if (rv) {
QmlInstruction assign;
assign.type = QmlInstruction::AssignSignalObject;
- assign.line = prop->values.at(0)->line;
+ assign.line = prop->values.at(0)->location.start.line;
assign.assignSignalObject.signal = pr;
output->bytecode << assign;
@@ -755,7 +771,7 @@ bool QmlCompiler::compileSignal(Property *prop, Object *obj)
QmlInstruction assign;
assign.type = QmlInstruction::AssignSignal;
- assign.line = prop->values.at(0)->line;
+ assign.line = prop->values.at(0)->location.start.line;
assign.assignSignal.signal = pr;
assign.assignSignal.value = idx;
@@ -878,7 +894,7 @@ bool QmlCompiler::compileIdProperty(QmlParser::Property *prop,
assign.type = QmlInstruction::StoreString;
assign.storeString.propertyIndex = prop->index;
assign.storeString.value = pref;
- assign.line = prop->values.at(0)->line;
+ assign.line = prop->values.at(0)->location.start.line;
output->bytecode << assign;
prop->values.at(0)->type = Value::Id;
@@ -888,10 +904,9 @@ bool QmlCompiler::compileIdProperty(QmlParser::Property *prop,
QmlInstruction id;
id.type = QmlInstruction::SetId;
- id.line = prop->values.at(0)->line;
+ id.line = prop->values.at(0)->location.start.line;
id.setId.value = pref;
id.setId.save = -1;
- id.line = prop->values.at(0)->line;
output->bytecode << id;
obj->id = val.toLatin1();
@@ -909,7 +924,7 @@ bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop,
QmlInstruction fetch;
fetch.type = QmlInstruction::FetchAttached;
- fetch.line = prop->line;
+ fetch.line = prop->location.start.line;
int id = QmlMetaType::attachedPropertiesFuncId(prop->name);
if (id == -1)
COMPILE_EXCEPTION("Non-existant attached property object" << prop->name);
@@ -920,7 +935,7 @@ bool QmlCompiler::compileAttachedProperty(QmlParser::Property *prop,
QmlInstruction pop;
pop.type = QmlInstruction::PopFetchedObject;
- pop.line = prop->line;
+ pop.line = prop->location.start.line;
output->bytecode << pop;
return true;
@@ -942,14 +957,14 @@ bool QmlCompiler::compileNestedProperty(QmlParser::Property *prop,
fetch.type = QmlInstruction::ResolveFetchObject;
fetch.fetch.property = output->indexForByteArray(prop->name);
}
- fetch.line = prop->line;
+ fetch.line = prop->location.start.line;
output->bytecode << fetch;
COMPILE_CHECK(compileFetchedObject(prop->value, ctxt + 1));
QmlInstruction pop;
pop.type = QmlInstruction::PopFetchedObject;
- pop.line = prop->line;
+ pop.line = prop->location.start.line;
output->bytecode << pop;
return true;
@@ -962,7 +977,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
int t = prop->type;
if (QmlMetaType::isQmlList(t)) {
QmlInstruction fetch;
- fetch.line = prop->line;
+ fetch.line = prop->location.start.line;
fetch.type = QmlInstruction::FetchQmlList;
fetch.fetchQmlList.property = prop->index;
fetch.fetchQmlList.type = QmlMetaType::qmlListType(t);
@@ -975,7 +990,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
COMPILE_CHECK(compileObject(v->object, ctxt));
QmlInstruction assign;
assign.type = QmlInstruction::AssignObjectList;
- assign.line = prop->line;
+ assign.line = prop->location.start.line;
assign.assignObject.property = output->indexForByteArray(prop->name);
assign.assignObject.castValue = 0;
output->bytecode << assign;
@@ -986,14 +1001,14 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
QmlInstruction pop;
pop.type = QmlInstruction::PopQList;
- pop.line = prop->line;
+ pop.line = prop->location.start.line;
output->bytecode << pop;
} else {
Q_ASSERT(QmlMetaType::isList(t));
QmlInstruction fetch;
fetch.type = QmlInstruction::FetchQList;
- fetch.line = prop->line;
+ fetch.line = prop->location.start.line;
fetch.fetch.property = prop->index;
output->bytecode << fetch;
@@ -1005,7 +1020,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
COMPILE_CHECK(compileObject(v->object, ctxt));
QmlInstruction assign;
assign.type = QmlInstruction::AssignObjectList;
- assign.line = v->line;
+ assign.line = v->location.start.line;
assign.assignObject.property = output->indexForByteArray(prop->name);
assign.assignObject.castValue = 0;
output->bytecode << assign;
@@ -1013,7 +1028,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
if (assignedBinding)
COMPILE_EXCEPTION("Can only assign one binding to lists");
- compileBinding(v->primitive, prop, ctxt, obj->metaObject(), v->line);
+ compileBinding(v->primitive, prop, ctxt, obj->metaObject(), v->location.start.line);
v->type = Value::PropertyBinding;
} else {
COMPILE_EXCEPTION("Cannot assign primitives to lists");
@@ -1021,7 +1036,7 @@ bool QmlCompiler::compileListProperty(QmlParser::Property *prop,
}
QmlInstruction pop;
- pop.line = prop->line;
+ pop.line = prop->location.start.line;
pop.type = QmlInstruction::PopQList;
output->bytecode << pop;
}
@@ -1086,7 +1101,7 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop,
QmlInstruction assign;
assign.type = QmlInstruction::AssignObject;
- assign.line = v->object->line;
+ assign.line = v->object->location.start.line;
assign.assignObject.castValue = 0;
if (prop->isDefault)
assign.assignObject.property = -1;
@@ -1101,7 +1116,7 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop,
QmlInstruction assign;
assign.type = QmlInstruction::StoreObject;
- assign.line = v->object->line;
+ assign.line = v->object->location.start.line;
assign.storeObject.propertyIndex = prop->index;
// XXX - this cast may not be 0
assign.storeObject.cast = 0;
@@ -1114,7 +1129,7 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop,
QmlInstruction assign;
assign.type = QmlInstruction::StoreObject;
- assign.line = v->object->line;
+ assign.line = v->object->location.start.line;
assign.storeObject.propertyIndex = prop->index;
// XXX - this cast may not be 0
assign.storeObject.cast = 0;
@@ -1127,13 +1142,13 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop,
if (prop->index != -1) {
QmlInstruction assign;
assign.type = QmlInstruction::StoreValueSource;
- assign.line = v->object->line;
+ assign.line = v->object->location.start.line;
assign.assignValueSource.property = prop->index;
output->bytecode << assign;
} else {
QmlInstruction assign;
assign.type = QmlInstruction::AssignValueSource;
- assign.line = v->object->line;
+ assign.line = v->object->location.start.line;
assign.assignValueSource.property = output->indexForByteArray(prop->name);;
output->bytecode << assign;
}
@@ -1148,7 +1163,7 @@ bool QmlCompiler::compilePropertyObjectAssignment(QmlParser::Property *prop,
QmlInstruction assign;
assign.type = QmlInstruction::AssignObject;
- assign.line = v->object->line;
+ assign.line = v->object->location.start.line;
assign.assignObject.property = output->indexForByteArray(prop->name);
assign.assignObject.castValue = 0;
output->bytecode << assign;
@@ -1166,14 +1181,14 @@ bool QmlCompiler::compilePropertyLiteralAssignment(QmlParser::Property *prop,
{
if (isBinding(v->primitive)) {
- compileBinding(v->primitive, prop, ctxt, obj->metaObject(), v->line);
+ compileBinding(v->primitive, prop, ctxt, obj->metaObject(), v->location.start.line);
v->type = Value::PropertyBinding;
} else {
QmlInstruction assign;
- assign.line = v->line;
+ assign.line = v->location.start.line;
bool doassign = true;
if (prop->index != -1) {
@@ -1286,7 +1301,7 @@ bool QmlCompiler::compileDynamicMeta(QmlParser::Object *obj)
store.type = QmlInstruction::StoreMetaObject;
store.storeMeta.data = output->mos.count() - 1;
store.storeMeta.slotData = slotStart;
- store.line = obj->line;
+ store.line = obj->location.start.line;
output->bytecode << store;
for (int ii = 0; ii < obj->dynamicProperties.count(); ++ii) {
@@ -1301,7 +1316,7 @@ bool QmlCompiler::compileDynamicMeta(QmlParser::Object *obj)
if (!p.onValueChanged.isEmpty()) {
QmlInstruction assign;
assign.type = QmlInstruction::AssignSignal;
- assign.line = obj->line;
+ assign.line = obj->location.start.line;
assign.assignSignal.signal =
output->indexForByteArray(p.name + "Changed()");
assign.assignSignal.value =
diff --git a/src/declarative/qml/qmlcompiler_p.h b/src/declarative/qml/qmlcompiler_p.h
index e2b8388..b885e7b 100644
--- a/src/declarative/qml/qmlcompiler_p.h
+++ b/src/declarative/qml/qmlcompiler_p.h
@@ -48,6 +48,8 @@
#include <qmlerror.h>
#include <private/qmlinstruction_p.h>
#include <private/qmlcompositetypemanager_p.h>
+#include <private/qmlparser_p.h>
+
class QStringList;
QT_BEGIN_NAMESPACE
@@ -56,12 +58,6 @@ class QmlComponent;
class QmlCompiledComponent;
class QmlContext;
-namespace QmlParser {
- class Object;
- class Property;
- class Value;
-};
-
class QmlCompiledData
{
public:
@@ -98,6 +94,7 @@ public:
QList<CustomTypeData> customTypeData;
QList<QByteArray> datas;
QList<QMetaObject *> mos;
+ QList<QmlParser::Location> locations;
QList<QmlInstruction> bytecode;
private:
@@ -106,6 +103,8 @@ private:
int indexForByteArray(const QByteArray &);
int indexForFloat(float *, int);
int indexForInt(int *, int);
+ int indexForLocation(const QmlParser::Location &);
+ int indexForLocation(const QmlParser::LocationSpan &);
};
class Q_DECLARATIVE_EXPORT QmlCompiler
diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp
index 08755b1..689446b 100644
--- a/src/declarative/qml/qmldom.cpp
+++ b/src/declarative/qml/qmldom.cpp
@@ -181,7 +181,7 @@ bool QmlDomDocument::load(QmlEngine *engine, const QByteArray &data)
}
if (td->data.tree()) {
- component.dump(0, td->data.tree());
+ td->data.tree()->dump();
d->root = td->data.tree();
d->root->addref();
}
diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp
index 7dcab6f..be5226e 100644
--- a/src/declarative/qml/qmlengine.cpp
+++ b/src/declarative/qml/qmlengine.cpp
@@ -74,10 +74,7 @@
QT_BEGIN_NAMESPACE
-DEFINE_BOOL_CONFIG_OPTION(bindValueDebug, QML_BINDVALUE_DEBUG);
-#ifdef QT_SCRIPTTOOLS_LIB
-DEFINE_BOOL_CONFIG_OPTION(debuggerEnabled, QML_DEBUGGER);
-#endif
+DEFINE_BOOL_CONFIG_OPTION(qmlDebugger, QML_DEBUGGER);
Q_DECLARE_METATYPE(QmlMetaProperty);
@@ -171,7 +168,7 @@ void QmlEnginePrivate::init()
objectClass = new QmlObjectScriptClass(q);
rootContext = new QmlContext(q);
#ifdef QT_SCRIPTTOOLS_LIB
- if (debuggerEnabled()){
+ if (qmlDebugger()){
debugger = new QScriptEngineDebugger(q);
debugger->attachTo(&scriptEngine);
}
@@ -723,17 +720,17 @@ QmlEngine *QmlEngine::activeEngine()
QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b)
-: q(b), ctxt(0), sseData(0), proxy(0), me(0), trackChange(false)
+: q(b), ctxt(0), sseData(0), proxy(0), me(0), trackChange(false), log(0)
{
}
QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, void *expr, QmlRefCount *rc)
-: q(b), ctxt(0), sse((const char *)expr, rc), sseData(0), proxy(0), me(0), trackChange(true)
+: q(b), ctxt(0), sse((const char *)expr, rc), sseData(0), proxy(0), me(0), trackChange(true), log(0)
{
}
QmlExpressionPrivate::QmlExpressionPrivate(QmlExpression *b, const QString &expr, bool ssecompile)
-: q(b), ctxt(0), expression(expr), sseData(0), proxy(0), me(0), trackChange(true)
+: q(b), ctxt(0), expression(expr), sseData(0), proxy(0), me(0), trackChange(true), log(0)
{
if (ssecompile) {
#ifdef Q_ENABLE_PERFORMANCE_LOG
@@ -748,6 +745,7 @@ QmlExpressionPrivate::~QmlExpressionPrivate()
sse.deleteScriptState(sseData);
sseData = 0;
delete proxy;
+ delete log;
}
/*!
@@ -884,8 +882,6 @@ void BindExpressionProxy::changed()
*/
QVariant QmlExpression::value()
{
- if (bindValueDebug())
- qWarning() << "QmlEngine: Evaluating:" << expression();
QVariant rv;
if (!d->ctxt || (!d->sse.isValid() && d->expression.isEmpty()))
return rv;
@@ -990,34 +986,51 @@ QVariant QmlExpression::value()
if (changedIndex == -1)
changedIndex = BindExpressionProxy::staticMetaObject.indexOfSlot("changed()");
- if (bindValueDebug())
- qWarning() << " Depends on:";
-
- for (int ii = 0; ii < ep->capturedProperties.count(); ++ii) {
- const QmlMetaProperty &prop =
- ep->capturedProperties.at(ii);
-
- if (prop.hasChangedNotifier()) {
- prop.connectNotifier(d->proxy, changedIndex);
- if (bindValueDebug())
- qWarning() << " property"
- << prop.name()
- << prop.object()
- << prop.object()->metaObject()->superClass()->className();
- } else if (bindValueDebug()) {
- qWarning() << " non-subscribable property"
- << prop.name()
- << prop.object()
- << prop.object()->metaObject()->superClass()->className();
+ if(qmlDebugger()) {
+ QmlExpressionLog log;
+ log.setExpression(expression());
+ log.setResult(rv);
+
+ for (int ii = 0; ii < ep->capturedProperties.count(); ++ii) {
+ const QmlMetaProperty &prop =
+ ep->capturedProperties.at(ii);
+
+ if (prop.hasChangedNotifier()) {
+ prop.connectNotifier(d->proxy, changedIndex);
+ } else {
+ QString warn = QLatin1String("Expression depends on property without a NOTIFY signal: ") + QLatin1String(prop.object()->metaObject()->className()) + QLatin1String(".") + prop.name();
+ log.addWarning(warn);
+ }
+ }
+ d->addLog(log);
+
+ } else {
+ for (int ii = 0; ii < ep->capturedProperties.count(); ++ii) {
+ const QmlMetaProperty &prop =
+ ep->capturedProperties.at(ii);
+
+ if (prop.hasChangedNotifier())
+ prop.connectNotifier(d->proxy, changedIndex);
}
}
+ } else {
+ QmlExpressionLog log;
+ log.setExpression(expression());
+ log.setResult(rv);
+ d->addLog(log);
+ }
+
+ } else {
+ if(qmlDebugger()) {
+ QmlExpressionLog log;
+ log.setExpression(expression());
+ log.setResult(rv);
+ d->addLog(log);
}
}
+
ep->capturedProperties.clear();
- if (bindValueDebug())
- qWarning() << " Result:" << rv
- << "(SSE: " << d->sse.isValid() << ")";
return rv;
}
@@ -1396,4 +1409,65 @@ void QmlObjectScriptClass::setProperty(QScriptValue &object,
scriptEngine->currentContext()->setActivationObject(oldact);
}
+void QmlExpressionPrivate::addLog(const QmlExpressionLog &l)
+{
+ if (!log)
+ log = new QList<QmlExpressionLog>();
+ log->append(l);
+}
+
+QmlExpressionLog::QmlExpressionLog()
+{
+}
+
+QmlExpressionLog::QmlExpressionLog(const QmlExpressionLog &o)
+: m_expression(o.m_expression),
+ m_result(o.m_result),
+ m_warnings(o.m_warnings)
+{
+}
+
+QmlExpressionLog::~QmlExpressionLog()
+{
+}
+
+QmlExpressionLog &QmlExpressionLog::operator=(const QmlExpressionLog &o)
+{
+ m_expression = o.m_expression;
+ m_result = o.m_result;
+ m_warnings = o.m_warnings;
+ return *this;
+}
+
+
+QString QmlExpressionLog::expression() const
+{
+ return m_expression;
+}
+
+void QmlExpressionLog::setExpression(const QString &e)
+{
+ m_expression = e;
+}
+
+QStringList QmlExpressionLog::warnings() const
+{
+ return m_warnings;
+}
+
+void QmlExpressionLog::addWarning(const QString &w)
+{
+ m_warnings << w;
+}
+
+QVariant QmlExpressionLog::result() const
+{
+ return m_result;
+}
+
+void QmlExpressionLog::setResult(const QVariant &r)
+{
+ m_result = r;
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h
index b72c680..7d5176e 100644
--- a/src/declarative/qml/qmlengine_p.h
+++ b/src/declarative/qml/qmlengine_p.h
@@ -192,6 +192,30 @@ public:
const QScriptValue &value);
};
+class QmlExpressionLog
+{
+public:
+ QmlExpressionLog();
+ QmlExpressionLog(const QmlExpressionLog &);
+ ~QmlExpressionLog();
+
+ QmlExpressionLog &operator=(const QmlExpressionLog &);
+
+ QString expression() const;
+ void setExpression(const QString &);
+
+ QStringList warnings() const;
+ void addWarning(const QString &);
+
+ QVariant result() const;
+ void setResult(const QVariant &);
+
+private:
+ QString m_expression;
+ QVariant m_result;
+ QStringList m_warnings;
+};
+
class QmlExpressionPrivate
{
public:
@@ -208,6 +232,9 @@ public:
BindExpressionProxy *proxy;
QObject *me;
bool trackChange;
+
+ void addLog(const QmlExpressionLog &);
+ QList<QmlExpressionLog> *log;
};
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlexpression.h b/src/declarative/qml/qmlexpression.h
index 4f9502b..0ab5d9c 100644
--- a/src/declarative/qml/qmlexpression.h
+++ b/src/declarative/qml/qmlexpression.h
@@ -85,6 +85,7 @@ protected:
private:
friend class BindExpressionProxy;
+ friend class QmlDebugger;
QmlExpressionPrivate *d;
};
diff --git a/src/declarative/qml/qmlinstruction_p.h b/src/declarative/qml/qmlinstruction_p.h
index e9c81d6..02e084d 100644
--- a/src/declarative/qml/qmlinstruction_p.h
+++ b/src/declarative/qml/qmlinstruction_p.h
@@ -165,6 +165,9 @@ public:
// NoOp - Do nothing
NoOp
};
+ QmlInstruction()
+ : type(NoOp), line(0) {}
+
Type type;
unsigned short line;
union {
diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp
index a6cb2ca..2bd41e2 100644
--- a/src/declarative/qml/qmlparser.cpp
+++ b/src/declarative/qml/qmlparser.cpp
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
using namespace QmlParser;
QmlParser::Object::Object()
-: type(-1), metatype(0), extObjectData(0), defaultProperty(0), line(-1), column(-1), endLine(-1), endColumn(-1)
+: type(-1), metatype(0), extObjectData(0), defaultProperty(0)
{
}
@@ -132,13 +132,35 @@ QmlParser::Object::DynamicSlot::DynamicSlot(const DynamicSlot &o)
{
}
+void QmlParser::Object::dump(int indent) const
+{
+ QByteArray ba(indent * 4, ' ');
+ if (type != -1) {
+ qWarning() << ba.constData() << "Object:" << typeName;
+ } else {
+ qWarning() << ba.constData() << "Object: fetched";
+ }
+
+ for (QHash<QByteArray, Property *>::ConstIterator iter = properties.begin();
+ iter != properties.end();
+ ++iter) {
+ qWarning() << ba.constData() << " Property" << iter.key();
+ (*iter)->dump(indent + 1);
+ }
+
+ if (defaultProperty) {
+ qWarning() << ba.constData() << " Default property";
+ defaultProperty->dump(indent + 1);
+ }
+}
+
QmlParser::Property::Property()
-: type(0), index(-1), value(0), isDefault(true), line(-1), column(-1)
+: type(0), index(-1), value(0), isDefault(true)
{
}
QmlParser::Property::Property(const QByteArray &n)
-: type(0), index(-1), value(0), name(n), isDefault(false), line(-1), column(-1)
+: type(0), index(-1), value(0), name(n), isDefault(false)
{
}
@@ -157,17 +179,20 @@ Object *QmlParser::Property::getValue()
void QmlParser::Property::addValue(Value *v)
{
- if (::getenv("DUI_DEBUG")) {
- if (v->object)
- qDebug() << "Property" << name << "addValue Object(" << v->object->typeName << ")";
- else
- qDebug() << "Property" << name << "addValue" << v->primitive;
- }
values << v;
}
+void QmlParser::Property::dump(int indent) const
+{
+ QByteArray ba(indent * 4, ' ');
+ for (int ii = 0; ii < values.count(); ++ii)
+ values.at(ii)->dump(indent);
+ if (value)
+ value->dump(indent);
+}
+
QmlParser::Value::Value()
-: type(Unknown), object(0), line(-1), column(-1)
+: type(Unknown), object(0)
{
}
@@ -176,4 +201,47 @@ QmlParser::Value::~Value()
if (object) object->release();
}
+void QmlParser::Value::dump(int indent) const
+{
+ QByteArray type;
+ switch(this->type) {
+ default:
+ case Value::Unknown:
+ type = "Unknown";
+ break;
+ case Value::Literal:
+ type = "Literal";
+ break;
+ case Value::PropertyBinding:
+ type = "PropertyBinding";
+ break;
+ case Value::ValueSource:
+ type = "ValueSource";
+ break;
+ case Value::CreatedObject:
+ type = "CreatedObject";
+ break;
+ case Value::SignalObject:
+ type = "SignalObject";
+ break;
+ case Value::SignalExpression:
+ type = "SignalExpression";
+ break;
+ case Value::Component:
+ type = "Component";
+ break;
+ case Value::Id:
+ type = "Id";
+ break;
+ };
+
+ QByteArray ba(indent * 4, ' ');
+ if (object) {
+ qWarning() << ba.constData() << "Value (" << type << "):";
+ object->dump(indent + 1);
+ } else {
+ qWarning() << ba.constData() << "Value (" << type << "):" << primitive;
+ }
+}
+
QT_END_NAMESPACE
diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h
index aa22928..31f8702 100644
--- a/src/declarative/qml/qmlparser_p.h
+++ b/src/declarative/qml/qmlparser_p.h
@@ -45,10 +45,8 @@
#include <QByteArray>
#include <QList>
#include <qml.h>
-#include "qmlcomponent_p.h"
#include <private/qmlrefcount_p.h>
-#include "qmlcompiledcomponent_p.h"
-
+#include <private/qobject_p.h>
QT_BEGIN_HEADER
@@ -69,6 +67,19 @@ QT_MODULE(Declarative)
*/
namespace QmlParser
{
+ struct Location
+ {
+ Location() : line(-1), column(-1) {}
+ int line;
+ int column;
+ };
+
+ struct LocationSpan
+ {
+ Location start;
+ Location end;
+ };
+
class Property;
class Object : public QmlRefCount
{
@@ -103,11 +114,7 @@ namespace QmlParser
Property *defaultProperty;
QHash<QByteArray, Property *> properties;
- qint64 line;
- qint64 column;
-
- qint64 endLine;
- qint64 endColumn;
+ LocationSpan location;
struct DynamicProperty {
DynamicProperty();
@@ -141,6 +148,8 @@ namespace QmlParser
QList<DynamicSignal> dynamicSignals;
// The list of dynamic slots
QList<DynamicSlot> dynamicSlots;
+
+ void dump(int = 0) const;
};
class Value : public QmlRefCount
@@ -176,8 +185,9 @@ namespace QmlParser
// Object value
Object *object;
- qint64 line;
- qint64 column;
+ LocationSpan location;
+
+ void dump(int = 0) const;
};
class Property : public QmlRefCount
@@ -207,8 +217,9 @@ namespace QmlParser
// True if this property was accessed as the default property.
bool isDefault;
- qint64 line;
- qint64 column;
+ LocationSpan location;
+
+ void dump(int = 0) const;
};
}
diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp
index d4962ba..4385601 100644
--- a/src/declarative/qml/qmlscriptparser.cpp
+++ b/src/declarative/qml/qmlscriptparser.cpp
@@ -37,18 +37,19 @@ class ProcessAST: protected AST::Visitor
push(State(obj));
}
- void pushProperty(const QString &name, int lineNumber)
+ void pushProperty(const QString &name, const LocationSpan &location)
{
const State &state = top();
if (state.property) {
State s(state.property->getValue(),
state.property->getValue()->getProperty(name.toLatin1()));
- s.property->line = lineNumber;
+ s.property->location = location;
push(s);
} else {
State s(state.object,
state.object->getProperty(name.toLatin1()));
- s.property->line = lineNumber;
+
+ s.property->location = location;
push(s);
}
}
@@ -65,14 +66,19 @@ protected:
AST::UiQualifiedId *propertyName,
const QString &objectType,
AST::SourceLocation typeLocation,
+ LocationSpan location,
AST::UiObjectInitializer *initializer = 0);
Object *defineObjectBinding_helper(int line,
AST::UiQualifiedId *propertyName,
const QString &objectType,
AST::SourceLocation typeLocation,
+ LocationSpan location,
AST::UiObjectInitializer *initializer = 0);
QString getPrimitive(const QByteArray &propertyName, AST::ExpressionNode *expr);
- void defineProperty(const QString &propertyName, int line, const QString &primitive);
+ void defineProperty(const QString &propertyName, const LocationSpan &location, const QString &primitive);
+
+ LocationSpan location(AST::SourceLocation start, AST::SourceLocation end);
+ LocationSpan location(AST::UiQualifiedId *);
using AST::Visitor::visit;
using AST::Visitor::endVisit;
@@ -192,18 +198,21 @@ QString ProcessAST::asString(AST::UiQualifiedId *node) const
return s;
}
-Object *ProcessAST::defineObjectBinding_helper(int line,
- AST::UiQualifiedId *propertyName,
- const QString &objectType,
- AST::SourceLocation typeLocation,
- AST::UiObjectInitializer *initializer)
+Object *
+ProcessAST::defineObjectBinding_helper(int line,
+ AST::UiQualifiedId *propertyName,
+ const QString &objectType,
+ AST::SourceLocation typeLocation,
+ LocationSpan location,
+ AST::UiObjectInitializer *initializer)
{
bool isType = !objectType.isEmpty() && objectType.at(0).isUpper() && !objectType.contains(QLatin1Char('.'));
int propertyCount = 0;
for (; propertyName; propertyName = propertyName->next){
++propertyCount;
- _stateStack.pushProperty(propertyName->name->asString(), propertyName->identifierToken.startLine);
+ _stateStack.pushProperty(propertyName->name->asString(),
+ this->location(propertyName));
}
if (!isType) {
@@ -217,7 +226,8 @@ Object *ProcessAST::defineObjectBinding_helper(int line,
return 0;
}
- _stateStack.pushProperty(objectType, line);
+ _stateStack.pushProperty(objectType,
+ this->location(propertyName));
accept(initializer);
_stateStack.pop();
@@ -233,18 +243,14 @@ Object *ProcessAST::defineObjectBinding_helper(int line,
_scope.append(objectType);
obj->typeName = qualifiedNameId().toLatin1();
_scope.removeLast();
- obj->line = line;
-
- if(initializer) {
- obj->endLine = initializer->rbraceToken.startLine;
- obj->endColumn = initializer->rbraceToken.startColumn;
- }
+ obj->location = location;
if (propertyCount) {
+
Property *prop = currentProperty();
Value *v = new Value;
v->object = obj;
- v->line = line;
+ v->location = obj->location;
prop->addValue(v);
while (propertyCount--)
@@ -258,7 +264,7 @@ Object *ProcessAST::defineObjectBinding_helper(int line,
const State state = _stateStack.top();
Value *v = new Value;
v->object = obj;
- v->line = line;
+ v->location = obj->location;
if (state.property)
state.property->addValue(v);
else
@@ -278,11 +284,12 @@ Object *ProcessAST::defineObjectBinding(int line,
AST::UiQualifiedId *qualifiedId,
const QString &objectType,
AST::SourceLocation typeLocation,
+ LocationSpan location,
AST::UiObjectInitializer *initializer)
{
if (objectType == QLatin1String("Connection")) {
- Object *obj = defineObjectBinding_helper(line, 0, objectType, typeLocation);
+ Object *obj = defineObjectBinding_helper(line, 0, objectType, typeLocation, location);
_stateStack.pushObject(obj);
@@ -300,7 +307,10 @@ Object *ProcessAST::defineObjectBinding(int line,
} else {
script = asString(scriptBinding->statement);
}
- defineProperty(QLatin1String("script"), line, script);
+
+ LocationSpan l = this->location(scriptBinding->statement->firstSourceLocation(),
+ scriptBinding->statement->lastSourceLocation());
+ defineProperty(QLatin1String("script"), l, script);
} else {
accept(it->member);
}
@@ -311,15 +321,30 @@ Object *ProcessAST::defineObjectBinding(int line,
return obj;
}
- return defineObjectBinding_helper(line, qualifiedId, objectType, typeLocation, initializer);
+ return defineObjectBinding_helper(line, qualifiedId, objectType, typeLocation, location, initializer);
}
-void ProcessAST::defineProperty(const QString &propertyName, int line, const QString &primitive)
+LocationSpan ProcessAST::location(AST::UiQualifiedId *id)
{
- _stateStack.pushProperty(propertyName, line);
+ return location(id->identifierToken, id->identifierToken);
+}
+
+LocationSpan ProcessAST::location(AST::SourceLocation start, AST::SourceLocation end)
+{
+ LocationSpan rv;
+ rv.start.line = start.startLine;
+ rv.start.column = start.startColumn;
+ rv.end.line = end.startLine;
+ rv.end.column = end.startColumn + end.length - 1;
+ return rv;
+}
+
+void ProcessAST::defineProperty(const QString &propertyName, const LocationSpan &location, const QString &primitive)
+{
+ _stateStack.pushProperty(propertyName, location);
Value *value = new Value;
value->primitive = primitive;
- value->line = line;
+ value->location = location;
currentProperty()->addValue(value);
_stateStack.pop();
}
@@ -396,6 +421,8 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
if (node->expression) { // default value
property.defaultValue = new Property;
Value *value = new Value;
+ value->location = location(node->expression->firstSourceLocation(),
+ node->expression->lastSourceLocation());
value->primitive = getPrimitive("value", node->expression);
property.defaultValue->values << value;
}
@@ -410,11 +437,14 @@ bool ProcessAST::visit(AST::UiPublicMember *node)
// UiObjectMember: T_IDENTIFIER UiObjectInitializer ;
bool ProcessAST::visit(AST::UiObjectDefinition *node)
{
+ LocationSpan l = location(node->firstSourceLocation(),
+ node->lastSourceLocation());;
defineObjectBinding(node->identifierToken.startLine,
0,
node->name->asString(),
node->identifierToken,
+ l,
node->initializer);
return false;
@@ -424,10 +454,14 @@ bool ProcessAST::visit(AST::UiObjectDefinition *node)
// UiObjectMember: UiQualifiedId T_COLON T_IDENTIFIER UiObjectInitializer ;
bool ProcessAST::visit(AST::UiObjectBinding *node)
{
+ LocationSpan l;
+ l = location(node->identifierToken, node->initializer->rbraceToken);
+
defineObjectBinding(node->identifierToken.startLine,
node->qualifiedId,
node->name->asString(),
node->identifierToken,
+ l,
node->initializer);
return false;
@@ -467,7 +501,8 @@ bool ProcessAST::visit(AST::UiScriptBinding *node)
AST::UiQualifiedId *propertyName = node->qualifiedId;
for (; propertyName; propertyName = propertyName->next){
++propertyCount;
- _stateStack.pushProperty(propertyName->name->asString(), propertyName->identifierToken.startLine);
+ _stateStack.pushProperty(propertyName->name->asString(),
+ location(propertyName));
}
Property *prop = currentProperty();
@@ -490,8 +525,9 @@ bool ProcessAST::visit(AST::UiScriptBinding *node)
Value *v = new Value;
v->primitive = primitive;
- v->line = node->statement->firstSourceLocation().startLine;
- v->column = node->statement->firstSourceLocation().startColumn;
+ v->location = location(node->statement->firstSourceLocation(),
+ node->statement->lastSourceLocation());
+
prop->addValue(v);
while (propertyCount--)
@@ -507,7 +543,8 @@ bool ProcessAST::visit(AST::UiArrayBinding *node)
AST::UiQualifiedId *propertyName = node->qualifiedId;
for (; propertyName; propertyName = propertyName->next){
++propertyCount;
- _stateStack.pushProperty(propertyName->name->asString(), propertyName->identifierToken.startLine);
+ _stateStack.pushProperty(propertyName->name->asString(),
+ location(propertyName));
}
accept(node->members);
@@ -564,8 +601,9 @@ bool ProcessAST::visit(AST::UiSourceElement *node)
}
Value *value = new Value;
+ value->location = location(node->firstSourceLocation(),
+ node->lastSourceLocation());
value->primitive = source;
- value->line = line;
obj->getDefaultProperty()->addValue(value);
}
diff --git a/tools/qmlviewer/main.cpp b/tools/qmlviewer/main.cpp
index 26ff213..b588111 100644
--- a/tools/qmlviewer/main.cpp
+++ b/tools/qmlviewer/main.cpp
@@ -18,7 +18,6 @@
#include "qfxtestengine.h"
#include <QApplication>
-
void usage()
{
qWarning("Usage: qmlviewer [options] <filename>");
diff --git a/tools/qmlviewer/qmlviewer.cpp b/tools/qmlviewer/qmlviewer.cpp
index 094d779..dbbe233 100644
--- a/tools/qmlviewer/qmlviewer.cpp
+++ b/tools/qmlviewer/qmlviewer.cpp
@@ -32,10 +32,14 @@
#include <QFileInfo>
#include <QVBoxLayout>
#include <QProcess>
+#include <QMenuBar>
#include <QMenu>
+#include <QAction>
+#include <QFileDialog>
+#include <QTimer>
QmlViewer::QmlViewer(QFxTestEngine::TestMode testMode, const QString &testDir, QWidget *parent, Qt::WindowFlags flags)
- : QWidget(parent, flags), frame_stream(0)
+ : QMainWindow(parent, flags), frame_stream(0)
{
testEngine = 0;
devicemode = false;
@@ -44,10 +48,12 @@ QmlViewer::QmlViewer(QFxTestEngine::TestMode testMode, const QString &testDir, Q
record_autotime = 0;
record_period = 20;
- int width=240;
- int height=320;
+ int width = 240;
+ int height = 320;
+
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_NoSystemBackground);
+ createMenuBar();
canvas = new QFxView(this);
if(testMode != QFxTestEngine::NoTest)
@@ -56,6 +62,27 @@ QmlViewer::QmlViewer(QFxTestEngine::TestMode testMode, const QString &testDir, Q
QObject::connect(canvas, SIGNAL(sceneResized(QSize)), this, SLOT(sceneResized(QSize)));
canvas->setFixedSize(width, height);
resize(width, height);
+ setCentralWidget(canvas);
+}
+
+void QmlViewer::createMenuBar()
+{
+ QMenu *fileMenu = menuBar()->addMenu(tr("&File"));
+
+ QAction *openAction = new QAction(tr("&Open..."), this);
+ openAction->setShortcut(QKeySequence("Ctrl+O"));
+ connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
+ fileMenu->addAction(openAction);
+
+ QAction *reloadAction = new QAction(tr("&Reload"), this);
+ reloadAction->setShortcut(QKeySequence("Ctrl+R"));
+ connect(reloadAction, SIGNAL(triggered()), this, SLOT(reload()));
+ fileMenu->addAction(reloadAction);
+
+ QMenu *helpMenu = menuBar()->addMenu(tr("&Help"));
+ QAction *aboutAction = new QAction(tr("&About Qt..."), this);
+ connect(aboutAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
+ helpMenu->addAction(aboutAction);
}
void QmlViewer::reload()
@@ -63,6 +90,15 @@ void QmlViewer::reload()
openQml(currentFileName);
}
+void QmlViewer::open()
+{
+ QString fileName = QFileDialog::getOpenFileName(this, tr("Open QML file"), "", tr("QML Files (*.qml)"));
+ if (!fileName.isEmpty()) {
+ openQml(fileName);
+ QTimer::singleShot(0, this, SLOT(reload()));
+ }
+}
+
void QmlViewer::openQml(const QString& fileName)
{
setWindowTitle(tr("%1 - Qt Declarative UI Viewer").arg(fileName));
@@ -187,7 +223,6 @@ void PreviewDeviceSkin::populateContextMenu(QMenu *menu)
connect(menu->addAction(tr("&Close")), SIGNAL(triggered()), parentWidget(), SLOT(close()));
}
-
void QmlViewer::setSkin(const QString& skinDirectory)
{
DeviceSkinParameters parameters;
@@ -239,10 +274,11 @@ void QmlViewer::sceneResized(QSize size)
}
}
-void QmlViewer::resizeEvent(QResizeEvent *)
+void QmlViewer::resizeEvent(QResizeEvent *e)
{
- if (!skin)
- canvas->setFixedSize(width(),height());
+ QMainWindow::resizeEvent(e);
+ //if (!skin)
+ //canvas->setFixedSize(width(),height());
}
void QmlViewer::keyPressEvent(QKeyEvent *event)
diff --git a/tools/qmlviewer/qmlviewer.h b/tools/qmlviewer/qmlviewer.h
index fc65ebf..b4117a2 100644
--- a/tools/qmlviewer/qmlviewer.h
+++ b/tools/qmlviewer/qmlviewer.h
@@ -14,7 +14,7 @@
#ifndef QMLVIEWER_H
#define QMLVIEWER_H
-#include <QWidget>
+#include <QMainWindow>
#include <QBasicTimer>
#include <QTime>
#include <qfxtestengine.h>
@@ -25,12 +25,13 @@ class QFxView;
class PreviewDeviceSkin;
class QFxTestEngine;
-class QmlViewer : public QWidget
+class QmlViewer : public QMainWindow
{
Q_OBJECT
public:
QmlViewer(QFxTestEngine::TestMode = QFxTestEngine::NoTest, const QString &testDir = QString(), QWidget *parent=0, Qt::WindowFlags flags=0);
+ void createMenuBar();
void setRecordDither(const QString& s) { record_dither = s; }
void setRecordPeriod(int ms);
void setRecordFile(const QString&);
@@ -45,6 +46,7 @@ public:
public slots:
void sceneResized(QSize size);
void openQml(const QString& fileName);
+ void open();
void reload();
protected: