diff options
-rw-r--r-- | src/declarative/debugger/qmldebugger.cpp | 29 | ||||
-rw-r--r-- | src/declarative/qml/qml.pri | 1 | ||||
-rw-r--r-- | src/declarative/qml/qmlbindablevalue.cpp | 61 | ||||
-rw-r--r-- | src/declarative/qml/qmlbindablevalue.h | 6 | ||||
-rw-r--r-- | src/declarative/qml/qmlbindablevalue_p.h | 63 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiledcomponent.cpp | 74 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiledcomponent_p.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler.cpp | 93 | ||||
-rw-r--r-- | src/declarative/qml/qmlcompiler_p.h | 11 | ||||
-rw-r--r-- | src/declarative/qml/qmldom.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 138 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine_p.h | 27 | ||||
-rw-r--r-- | src/declarative/qml/qmlexpression.h | 1 | ||||
-rw-r--r-- | src/declarative/qml/qmlinstruction_p.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlparser.cpp | 88 | ||||
-rw-r--r-- | src/declarative/qml/qmlparser_p.h | 35 | ||||
-rw-r--r-- | src/declarative/qml/qmlscriptparser.cpp | 98 | ||||
-rw-r--r-- | tools/qmlviewer/main.cpp | 1 | ||||
-rw-r--r-- | tools/qmlviewer/qmlviewer.cpp | 50 | ||||
-rw-r--r-- | tools/qmlviewer/qmlviewer.h | 6 |
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: |