From 4a60aa7f05ba112a69a4b1b724ccac52b65a9a03 Mon Sep 17 00:00:00 2001 From: Fawzi Mohamed Date: Mon, 14 Jul 2014 18:38:27 +0200 Subject: [PATCH] qmljs: uniform property info CppComponent has extra information on properties that makes sense also for ObjectValues, change the processProperty method to pass in an extra struct with that info (and that can be later extended). Change-Id: If09b178a4095bed03ff59bfb2164088309d2c8e2 Reviewed-by: Thomas Hartmann --- src/libs/qmljs/qmljsdescribevalue.cpp | 13 ++- src/libs/qmljs/qmljsinterpreter.cpp | 81 ++++++++++++++++--- src/libs/qmljs/qmljsinterpreter.h | 54 ++++++++++++- .../designercore/metainfo/nodemetainfo.cpp | 2 +- .../qmljseditor/qmljscompletionassist.cpp | 2 +- 5 files changed, 134 insertions(+), 18 deletions(-) diff --git a/src/libs/qmljs/qmljsdescribevalue.cpp b/src/libs/qmljs/qmljsdescribevalue.cpp index c0c8f2785f1..9213646a843 100644 --- a/src/libs/qmljs/qmljsdescribevalue.cpp +++ b/src/libs/qmljs/qmljsdescribevalue.cpp @@ -187,9 +187,18 @@ public: return true; } - bool processProperty(const QString &name, const Value *value) QTC_OVERRIDE + bool processProperty(const QString &name, const Value *value, const PropertyInfo &pInfo) QTC_OVERRIDE { - return dump(name, value); + d.dumpNewline(); + d.dump(name); + d.openContext(":"); + d.dump("<"); + d.dump(pInfo.toString()); + d.dump(">"); + d.dumpNewline(); // avoid? + value->accept(&d); + d.closeContext(""); + return true; } bool processEnumerator(const QString &name, const Value *value) QTC_OVERRIDE { diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index fbf5725a02b..b02fda890b3 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -107,7 +107,7 @@ public: const Value *value() const { return m_value; } - virtual bool processProperty(const QString &name, const Value *value) + virtual bool processProperty(const QString &name, const Value *value, const PropertyInfo &) { return process(name, value); } @@ -186,6 +186,45 @@ uint qHash(const FakeMetaObjectWithOrigin &fmoo) return qHash(fmoo.fakeMetaObject); } +PropertyInfo::PropertyInfo(uint flags) + : flags(flags) +{ } + +QString PropertyInfo::toString() const +{ + bool join = false; + QString res; + if (isReadable()) { + res += QLatin1String("Readable"); + join = true; + } + if (isWriteable()) { + if (join) + res += QLatin1String("|"); + res += QLatin1String("Writeable"); + join = true; + } + if (isList()) { + if (join) + res += QLatin1String("|"); + res += QLatin1String("ListType"); + join = true; + } + if (canBePointer()) { + if (join) + res += QLatin1String("|"); + res += QLatin1String("Pointer"); + join = true; + } + if (canBeValue()) { + if (join) + res += QLatin1String("|"); + res += QLatin1String("Value"); + join = true; + } + return res; +} + } // namespace QmlJS CppComponentValue::CppComponentValue(FakeMetaObject::ConstPtr metaObject, const QString &className, @@ -303,7 +342,17 @@ void CppComponentValue::processMembers(MemberProcessor *processor) const continue; const QString propertyName = prop.name(); - processor->processProperty(propertyName, valueForCppName(prop.typeName())); + uint propertyFlags = PropertyInfo::Readable; + if (isWritable(propertyName)) + propertyFlags |= PropertyInfo::Writeable; + if (isListProperty(propertyName)) + propertyFlags |= PropertyInfo::ListType; + if (isPointer(propertyName)) + propertyFlags |= PropertyInfo::PointerType; + else + propertyFlags |= PropertyInfo::ValueType; + processor->processProperty(propertyName, valueForCppName(prop.typeName()), + PropertyInfo(propertyFlags)); // every property always has a onXyzChanged slot, even if the NOTIFY // signal has a different name @@ -951,7 +1000,7 @@ MemberProcessor::~MemberProcessor() { } -bool MemberProcessor::processProperty(const QString &, const Value *) +bool MemberProcessor::processProperty(const QString &, const Value *, const PropertyInfo &) { return true; } @@ -1024,7 +1073,12 @@ void ObjectValue::setPrototype(const Value *prototype) void ObjectValue::setMember(const QString &name, const Value *value) { - m_members[name] = value; + m_members[name].value = value; +} + +void ObjectValue::setPropertyInfo(const QString &name, const PropertyInfo &propertyInfo) +{ + m_members[name].propertyInfo = propertyInfo; } void ObjectValue::removeMember(const QString &name) @@ -1063,12 +1117,12 @@ bool ObjectValue::checkPrototype(const ObjectValue *, QSet void ObjectValue::processMembers(MemberProcessor *processor) const { - QHashIterator it(m_members); + QHashIterator it(m_members); while (it.hasNext()) { it.next(); - if (! processor->processProperty(it.key(), it.value())) + if (! processor->processProperty(it.key(), it.value().value, it.value().propertyInfo)) break; } } @@ -1077,7 +1131,7 @@ const Value *ObjectValue::lookupMember(const QString &name, const Context *conte const ObjectValue **foundInObject, bool examinePrototypes) const { - if (const Value *m = m_members.value(name)) { + if (const Value *m = m_members.value(name).value) { if (foundInObject) *foundInObject = this; return m; @@ -1849,7 +1903,10 @@ bool ASTObjectValue::getSourceLocation(QString *fileName, int *line, int *column void ASTObjectValue::processMembers(MemberProcessor *processor) const { foreach (ASTPropertyReference *ref, m_properties) { - processor->processProperty(ref->ast()->name.toString(), ref); + uint pFlags = PropertyInfo::Readable; + if (!ref->ast()->isReadonlyMember) + pFlags |= PropertyInfo::Writeable; + processor->processProperty(ref->ast()->name.toString(), ref, PropertyInfo(pFlags)); // ### Should get a different value? processor->processGeneratedSlot(ref->onChangedSlotName(), ref); } @@ -2334,7 +2391,7 @@ void TypeScope::processMembers(MemberProcessor *processor) const continue; if (!info.as().isEmpty()) - processor->processProperty(info.as(), import); + processor->processProperty(info.as(), import, PropertyInfo(PropertyInfo::Readable)); else import->processMembers(processor); } @@ -2387,7 +2444,7 @@ void JSImportScope::processMembers(MemberProcessor *processor) const const ImportInfo &info = i.info; if (info.type() == ImportType::File || info.type() == ImportType::QrcFile) - processor->processProperty(info.as(), import); + processor->processProperty(info.as(), import, PropertyInfo(PropertyInfo::Readable)); } } @@ -2513,9 +2570,9 @@ class MemberDumper: public MemberProcessor public: MemberDumper() {} - virtual bool processProperty(const QString &name, const Value *) + virtual bool processProperty(const QString &name, const Value *, const PropertyInfo &pInfo) { - qCDebug(qmljsLog) << "property: " << name; + qCDebug(qmljsLog) << "property: " << name << " flags:" << pInfo.toString(); return true; } diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index 230d9f03f0b..0a374ce7bb2 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -388,6 +388,44 @@ public: const UrlValue *asUrlValue() const QTC_OVERRIDE; }; +class PropertyInfo { +public: + enum PropertyFlag { + Readable = 1, + Writeable = 2, + ListType = 4, + PointerType= 8, + ValueType = 16, + PointerOrValue = PointerType|ValueType, + Default = Readable|Writeable|PointerOrValue + }; + + PropertyInfo(uint flags = Default); + uint flags; + bool isPointer() const { + return (flags & PointerOrValue) == PointerType; + } + bool isValue() const { + return (flags & PointerOrValue) == ValueType; + } + bool canBePointer() const { + return (flags & PointerType) != 0; + } + bool canBeValue() const { + return (flags & ValueType) != 0; + } + bool isReadable() const { + return (flags & Readable) != 0; + } + bool isWriteable() const { + return (flags & Writeable) != 0; + } + bool isList() const { + return (flags & ListType) != 0; + } + QString toString() const; +}; + class QMLJS_EXPORT MemberProcessor { MemberProcessor(const MemberProcessor &other); @@ -398,7 +436,8 @@ public: virtual ~MemberProcessor(); // Returns false to stop the processor. - virtual bool processProperty(const QString &name, const Value *value); + virtual bool processProperty(const QString &name, const Value *value, + const PropertyInfo &propertyInfo); virtual bool processEnumerator(const QString &name, const Value *value); virtual bool processSignal(const QString &name, const Value *value); virtual bool processSlot(const QString &name, const Value *value); @@ -440,6 +479,16 @@ public: void accept(ValueVisitor *) const QTC_OVERRIDE; }; +class QMLJS_EXPORT PropertyData { +public: + const Value *value; + PropertyInfo propertyInfo; + PropertyData(const Value *value = 0, + PropertyInfo propertyInfo = PropertyInfo(PropertyInfo::Default)) + : value(value), propertyInfo(propertyInfo) + { } +}; + class QMLJS_EXPORT ObjectValue: public Value { public: @@ -462,6 +511,7 @@ public: virtual void processMembers(MemberProcessor *processor) const; virtual void setMember(const QString &name, const Value *value); + virtual void setPropertyInfo(const QString &name, const PropertyInfo &propertyInfo); virtual void removeMember(const QString &name); virtual const Value *lookupMember(const QString &name, const Context *context, @@ -484,7 +534,7 @@ private: private: ValueOwner *m_valueOwner; - QHash m_members; + QHash m_members; QString m_className; QString m_originId; diff --git a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp index 3eee5fe7c08..303376aea2e 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/nodemetainfo.cpp @@ -278,7 +278,7 @@ class PropertyMemberProcessor : public MemberProcessor public: PropertyMemberProcessor(const ContextPtr &context) : m_context(context) {} - bool processProperty(const QString &name, const Value *value) + bool processProperty(const QString &name, const Value *value, const QmlJS::PropertyInfo &) { PropertyName propertyName = name.toUtf8(); const ASTPropertyReference *ref = value_cast(value); diff --git a/src/plugins/qmljseditor/qmljscompletionassist.cpp b/src/plugins/qmljseditor/qmljscompletionassist.cpp index 015ee485a25..a3eebd02dee 100644 --- a/src/plugins/qmljseditor/qmljscompletionassist.cpp +++ b/src/plugins/qmljseditor/qmljscompletionassist.cpp @@ -245,7 +245,7 @@ private: (*_propertyProcessor)(_currentObject, name, value); } - bool processProperty(const QString &name, const Value *value) QTC_OVERRIDE + bool processProperty(const QString &name, const Value *value, const PropertyInfo &) QTC_OVERRIDE { process(name, value); return true;