From 7c1093d3e8eba6b8ab92c6503fde0c941550125d Mon Sep 17 00:00:00 2001 From: Aaron Kennedy Date: Wed, 6 May 2009 22:27:17 +1000 Subject: Improve parser line/column tracking --- src/declarative/qml/qmlcompiledcomponent.cpp | 74 --------------------- src/declarative/qml/qmlcompiledcomponent_p.h | 3 - src/declarative/qml/qmlcompiler.cpp | 77 +++++++++++----------- src/declarative/qml/qmldom.cpp | 2 +- src/declarative/qml/qmlinstruction_p.h | 3 + src/declarative/qml/qmlparser.cpp | 88 ++++++++++++++++++++++--- src/declarative/qml/qmlparser_p.h | 31 ++++++--- src/declarative/qml/qmlscriptparser.cpp | 98 +++++++++++++++++++--------- 8 files changed, 210 insertions(+), 166 deletions(-) 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::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..8eb5fa1 100644 --- a/src/declarative/qml/qmlcompiler.cpp +++ b/src/declarative/qml/qmlcompiler.cpp @@ -434,8 +434,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 +443,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 +541,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 +552,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 +560,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 +611,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 +619,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 +661,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 +675,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 oldIds = ids; @@ -732,7 +732,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 +755,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 +878,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 +888,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 +908,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 +919,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 +941,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 +961,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 +974,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 +985,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 +1004,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 +1012,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 +1020,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 +1085,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 +1100,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 +1113,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 +1126,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 +1147,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 +1165,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 +1285,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 +1300,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/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/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::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..5910705 100644 --- a/src/declarative/qml/qmlparser_p.h +++ b/src/declarative/qml/qmlparser_p.h @@ -69,6 +69,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 +116,7 @@ namespace QmlParser Property *defaultProperty; QHash properties; - qint64 line; - qint64 column; - - qint64 endLine; - qint64 endColumn; + LocationSpan location; struct DynamicProperty { DynamicProperty(); @@ -141,6 +150,8 @@ namespace QmlParser QList dynamicSignals; // The list of dynamic slots QList dynamicSlots; + + void dump(int = 0) const; }; class Value : public QmlRefCount @@ -176,8 +187,9 @@ namespace QmlParser // Object value Object *object; - qint64 line; - qint64 column; + LocationSpan location; + + void dump(int = 0) const; }; class Property : public QmlRefCount @@ -207,8 +219,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 8be0e5a..94a5ad2 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); } -- cgit v0.12