diff --git a/src/libs/languageutils/fakemetaobject.cpp b/src/libs/languageutils/fakemetaobject.cpp index 29392e09640a82a8dbfcc9e29fe27f766b37eddd..41b153c2ed135135dfaf7759a1b4d1e8dd34fc40 100644 --- a/src/libs/languageutils/fakemetaobject.cpp +++ b/src/libs/languageutils/fakemetaobject.cpp @@ -64,11 +64,13 @@ FakeMetaMethod::FakeMetaMethod(const QString &name, const QString &returnType) , m_returnType(returnType) , m_methodTy(FakeMetaMethod::Method) , m_methodAccess(FakeMetaMethod::Public) + , m_revision(0) {} FakeMetaMethod::FakeMetaMethod() : m_methodTy(FakeMetaMethod::Method) , m_methodAccess(FakeMetaMethod::Public) + , m_revision(0) {} QString FakeMetaMethod::methodName() const @@ -98,9 +100,21 @@ void FakeMetaMethod::setMethodType(int methodType) int FakeMetaMethod::access() const { return m_methodAccess; } +int FakeMetaMethod::revision() const +{ return m_revision; } -FakeMetaProperty::FakeMetaProperty(const QString &name, const QString &type, bool isList, bool isWritable, bool isPointer) - : m_propertyName(name), m_type(type), m_isList(isList), m_isWritable(isWritable), m_isPointer(isPointer) +void FakeMetaMethod::setRevision(int r) +{ m_revision = r; } + + +FakeMetaProperty::FakeMetaProperty(const QString &name, const QString &type, bool isList, + bool isWritable, bool isPointer, int revision) + : m_propertyName(name) + , m_type(type) + , m_isList(isList) + , m_isWritable(isWritable) + , m_isPointer(isPointer) + , m_revision(revision) {} QString FakeMetaProperty::name() const @@ -118,6 +132,9 @@ bool FakeMetaProperty::isWritable() const bool FakeMetaProperty::isPointer() const { return m_isPointer; } +int FakeMetaProperty::revision() const +{ return m_revision; } + FakeMetaObject::FakeMetaObject() { diff --git a/src/libs/languageutils/fakemetaobject.h b/src/libs/languageutils/fakemetaobject.h index df8eb4dd89d8e6d952cee59bfd3a27130a4e5064..1fca983607296ece883bb8e562fdb1f6b4646c12 100644 --- a/src/libs/languageutils/fakemetaobject.h +++ b/src/libs/languageutils/fakemetaobject.h @@ -94,6 +94,9 @@ public: int access() const; + int revision() const; + void setRevision(int r); + private: QString m_name; QString m_returnType; @@ -101,6 +104,7 @@ private: QStringList m_paramTypes; int m_methodTy; int m_methodAccess; + int m_revision; }; class LANGUAGEUTILS_EXPORT FakeMetaProperty { @@ -109,9 +113,10 @@ class LANGUAGEUTILS_EXPORT FakeMetaProperty { bool m_isList; bool m_isWritable; bool m_isPointer; + int m_revision; public: - FakeMetaProperty(const QString &name, const QString &type, bool isList, bool isWritable, bool isPointer); + FakeMetaProperty(const QString &name, const QString &type, bool isList, bool isWritable, bool isPointer, int revision); QString name() const; QString typeName() const; @@ -119,6 +124,7 @@ public: bool isList() const; bool isWritable() const; bool isPointer() const; + int revision() const; }; class LANGUAGEUTILS_EXPORT FakeMetaObject { diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 1530e307f05b62157032cb5b5cf3c8823e4e06f9..c8354a88fa3b27615a2fcfe5669d2a858a48fad9 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -151,438 +151,6 @@ public: } }; -class QmlXmlReader -{ - Q_DECLARE_TR_FUNCTIONS(QmlJS::Interpreter::QmlXmlReader) - -public: - QmlXmlReader(QIODevice *dev) - : _xml(dev) - , _objects(0) - {} - - QmlXmlReader(const QByteArray &data) - : _xml(data) - {} - - bool operator()(QMap<QString, FakeMetaObject::Ptr> *objects) { - Q_ASSERT(objects); - _objects = objects; - - if (_xml.readNextStartElement()) { - if (_xml.name() == "module") - readModule(); - else - _xml.raiseError(tr("The file is not module file.")); - } - - return !_xml.error(); - } - - QString errorMessage() const { - return _xml.errorString(); - } - -private: - void unexpectedElement(const QStringRef &child, const QString &parent) { - _xml.raiseError(tr("Unexpected element <%1> in <%2>").arg(child.toString(), parent)); - } - - void ignoreAttr(const QXmlStreamAttribute &attr) { - qDebug() << "** ignoring attribute" << attr.name().toString() - << "in tag" << _xml.name(); - } - - void invalidAttr(const QString &value, const QString &attrName, const QString &tag) { - _xml.raiseError(tr("invalid value '%1' for attribute %2 in <%3>").arg(value, attrName, tag)); - } - - void noValidAttr(const QString &attrName, const QString &tag) { - _xml.raiseError(tr("<%1> has no valid %2 attribute").arg(tag, attrName)); - } - - void readModule() - { - Q_ASSERT(_xml.isStartElement() && _xml.name() == QLatin1String("module")); - - foreach (const QXmlStreamAttribute &attr, _xml.attributes()) - ignoreAttr(attr); - - while (_xml.readNextStartElement()) { - if (_xml.name() == QLatin1String("type")) - readType(); - else - unexpectedElement(_xml.name(), QLatin1String("module")); - } - } - - void readType() - { - const QLatin1String tag("type"); - Q_ASSERT(_xml.isStartElement() && _xml.name() == tag); - - bool doInsert = true; - QString name, defaultPropertyName; - ComponentVersion version; - QString extends; - QString id; - foreach (const QXmlStreamAttribute &attr, _xml.attributes()) { - if (attr.name() == QLatin1String("name")) { - id = attr.value().toString(); - if (id.isEmpty()) { - invalidAttr(name, QLatin1String("name"), tag); - return; - } - } else if (attr.name() == QLatin1String("defaultProperty")) { - defaultPropertyName = attr.value().toString(); - } else if (attr.name() == QLatin1String("extends")) { - if (! attr.value().isEmpty()) - extends = attr.value().toString(); - - if (extends == name) { - invalidAttr(extends, QLatin1String("extends"), tag); - doInsert = false; - } - } else { - ignoreAttr(attr); - } - } - - FakeMetaObject::Ptr metaObject = FakeMetaObject::Ptr(new FakeMetaObject); - if (! extends.isEmpty()) - metaObject->setSuperclassName(extends); - if (! defaultPropertyName.isEmpty()) - metaObject->setDefaultPropertyName(defaultPropertyName); - - while (_xml.readNextStartElement()) { - if (_xml.name() == QLatin1String("property")) - readProperty(metaObject); - else if (_xml.name() == QLatin1String("enum")) - readEnum(metaObject); - else if (_xml.name() == QLatin1String("signal")) - readSignal(metaObject); - else if (_xml.name() == QLatin1String("method")) - readMethod(metaObject); - else if (_xml.name() == QLatin1String("exports")) - readExports(metaObject); - else - unexpectedElement(_xml.name(), tag); - } - - metaObject->addExport(id, QString(), ComponentVersion()); - - if (doInsert) - _objects->insert(id, metaObject); - } - - bool split(const QString &name, QString *packageName, QString *className) { - int dotIdx = name.lastIndexOf(QLatin1Char('.')); - if (dotIdx != -1) { - if (packageName) - *packageName = name.left(dotIdx); - if (className) - *className = name.mid(dotIdx + 1); - return true; - } else { - if (packageName) - packageName->clear(); - if (className) - *className = name; - return false; - } - } - - void readProperty(FakeMetaObject::Ptr metaObject) - { - const QLatin1String tag("property"); - Q_ASSERT(_xml.isStartElement() && _xml.name() == tag); - - QString name, type; - bool isList = false; - bool isWritable = false; - bool isPointer = false; - foreach (const QXmlStreamAttribute &attr, _xml.attributes()) { - if (attr.name() == QLatin1String("name")) { - name = attr.value().toString(); - } else if (attr.name() == QLatin1String("type")) { - type = attr.value().toString(); - } else if (attr.name() == QLatin1String("isList")) { - if (attr.value() == QLatin1String("true")) { - isList = true; - } else if (attr.value() == QLatin1String("false")) { - isList = false; - } else { - invalidAttr(attr.value().toString(), QLatin1String("isList"), tag); - return; - } - } else if (attr.name() == QLatin1String("isWritable")) { - if (attr.value() == QLatin1String("true")) { - isWritable = true; - } else if (attr.value() == QLatin1String("false")) { - isWritable = false; - } else { - invalidAttr(attr.value().toString(), QLatin1String("isWritable"), tag); - return; - } - } else if (attr.name() == QLatin1String("isPointer")) { - if (attr.value() == QLatin1String("true")) { - isPointer = true; - } else if (attr.value() == QLatin1String("false")) { - isPointer = false; - } else { - invalidAttr(attr.value().toString(), QLatin1String("isPointer"), tag); - return; - } - } else { - ignoreAttr(attr); - } - } - - if (name.isEmpty()) - noValidAttr(QLatin1String("name"), tag); - else if (type.isEmpty()) - noValidAttr(QLatin1String("type"), tag); - else - createProperty(metaObject, name, type, isList, isWritable, isPointer); - - while (_xml.readNextStartElement()) { - unexpectedElement(_xml.name(), tag); - } - } - - void createProperty(FakeMetaObject::Ptr metaObject, const QString &name, - const QString &type, bool isList, bool isWritable, bool isPointer) { - Q_ASSERT(metaObject); - - metaObject->addProperty(FakeMetaProperty(name, type, isList, isWritable, isPointer)); - } - - void readEnum(FakeMetaObject::Ptr metaObject) - { - Q_ASSERT(metaObject); - - QLatin1String tag("enum"); - Q_ASSERT(_xml.isStartElement() && _xml.name() == tag); - - QString name; - foreach (const QXmlStreamAttribute &attr, _xml.attributes()) { - if (attr.name() == QLatin1String("name")) { - name = attr.value().toString(); - } else { - ignoreAttr(attr); - } - } - - if (name.isEmpty()) { - noValidAttr(QLatin1String("name"), tag); - return; - } - - FakeMetaEnum metaEnum(name); - - while (_xml.readNextStartElement()) { - if (_xml.name() == QLatin1String("enumerator")) - readEnumerator(&metaEnum); - else - unexpectedElement(_xml.name(), tag); - } - - metaObject->addEnum(metaEnum); - } - - void readEnumerator(FakeMetaEnum *metaEnum) - { - Q_ASSERT(metaEnum); - - QLatin1String tag("enumerator"); - Q_ASSERT(_xml.isStartElement() && _xml.name() == tag); - - QString name; - int value = 0; - foreach (const QXmlStreamAttribute &attr, _xml.attributes()) { - if (attr.name() == QLatin1String("name")) { - name = attr.value().toString(); - } else if (attr.name() == QLatin1String("value")) { - const QString valueStr = attr.value().toString(); - bool ok = false; - value = valueStr.toInt(&ok); - if (!ok) { - invalidAttr(valueStr, QLatin1String("value"), tag); - } - } else { - ignoreAttr(attr); - } - } - - if (name.isEmpty()) - noValidAttr(QLatin1String("name"), tag); - else - metaEnum->addKey(name, value); - - while (_xml.readNextStartElement()) { - unexpectedElement(_xml.name(), tag); - } - } - - void readSignal(FakeMetaObject::Ptr metaObject) - { - Q_ASSERT(metaObject); - QLatin1String tag("signal"); - Q_ASSERT(_xml.isStartElement() && _xml.name() == tag); - - QString name; - foreach (const QXmlStreamAttribute &attr, _xml.attributes()) { - if (attr.name() == QLatin1String("name")) { - name = attr.value().toString(); - } else { - ignoreAttr(attr); - } - } - - if (name.isEmpty()) { - noValidAttr(QLatin1String("name"), tag); - return; - } - - FakeMetaMethod method(name); - method.setMethodType(FakeMetaMethod::Signal); - - while (_xml.readNextStartElement()) { - if (_xml.name() == QLatin1String("param")) { - readParam(&method); - } else { - unexpectedElement(_xml.name(), tag); - } - } - - metaObject->addMethod(method); - } - - void readParam(FakeMetaMethod *method) - { - Q_ASSERT(method); - QLatin1String tag("param"); - Q_ASSERT(_xml.isStartElement() && _xml.name() == tag); - - QString name, type; - foreach (const QXmlStreamAttribute &attr, _xml.attributes()) { - if (attr.name() == QLatin1String("name")) { - name = attr.value().toString(); - } else if (attr.name() == QLatin1String("type")) { - type = attr.value().toString(); - } else if (attr.name() == QLatin1String("isPointer")) { - } else { - ignoreAttr(attr); - } - } - - // note: name attribute is optional - if (type.isEmpty()) - noValidAttr(QLatin1String("type"), tag); - - method->addParameter(name, type); - - while (_xml.readNextStartElement()) { - unexpectedElement(_xml.name(), tag); - } - } - - void readMethod(FakeMetaObject::Ptr metaObject) - { - Q_ASSERT(metaObject); - QLatin1String tag("method"); - Q_ASSERT(_xml.isStartElement() && _xml.name() == tag); - - QString name, type; - foreach (const QXmlStreamAttribute &attr, _xml.attributes()) { - if (attr.name() == QLatin1String("name")) { - name = attr.value().toString(); - } else if (attr.name() == QLatin1String("type")) { - type = attr.value().toString(); - } else { - ignoreAttr(attr); - } - } - - // note: type attribute is optional, in which case it's a void method. - if (name.isEmpty()) { - noValidAttr(QLatin1String("name"), tag); - return; - } - - FakeMetaMethod method(name, type); - method.setMethodType(FakeMetaMethod::Slot); - - while (_xml.readNextStartElement()) { - if (_xml.name() == QLatin1String("param")) { - readParam(&method); - } else { - unexpectedElement(_xml.name(), tag); - } - } - - metaObject->addMethod(method); - } - - void readExports(FakeMetaObject::Ptr metaObject) - { - Q_ASSERT(metaObject); - QLatin1String tag("exports"); - QLatin1String childTag("export"); - Q_ASSERT(_xml.isStartElement() && _xml.name() == tag); - - while (_xml.readNextStartElement()) { - if (_xml.name() == childTag) { - QString type; - QString package; - ComponentVersion version; - foreach (const QXmlStreamAttribute &attr, _xml.attributes()) { - if (attr.name() == QLatin1String("module")) { - package = attr.value().toString(); - } else if (attr.name() == QLatin1String("type")) { - type = attr.value().toString(); - } else if (attr.name() == QLatin1String("version")) { - QString versionStr = attr.value().toString(); - int dotIdx = versionStr.indexOf('.'); - if (dotIdx == -1) { - bool ok = false; - const int major = versionStr.toInt(&ok); - if (!ok) { - invalidAttr(versionStr, QLatin1String("version"), childTag); - continue; - } - version = ComponentVersion(major, ComponentVersion::NoVersion); - } else { - bool ok = false; - const int major = versionStr.left(dotIdx).toInt(&ok); - if (!ok) { - invalidAttr(versionStr, QLatin1String("version"), childTag); - continue; - } - const int minor = versionStr.mid(dotIdx + 1).toInt(&ok); - if (!ok) { - invalidAttr(versionStr, QLatin1String("version"), childTag); - continue; - } - version = ComponentVersion(major, minor); - } - } else { - ignoreAttr(attr); - } - } - metaObject->addExport(type, package, version); - } else { - unexpectedElement(_xml.name(), childTag); - } - _xml.skipCurrentElement(); // the <export> tag should be empty anyhow - } - } - -private: - QXmlStreamReader _xml; - QMap<QString, FakeMetaObject::Ptr> *_objects; -}; - } // end of anonymous namespace QmlObjectValue::QmlObjectValue(FakeMetaObject::ConstPtr metaObject, const QString &className, diff --git a/src/libs/qmljs/qmljstypedescriptionreader.cpp b/src/libs/qmljs/qmljstypedescriptionreader.cpp index 3a3d1fc810a22659d799281ede8231c05e5d79db..c3a21d2f8e07a67f9f3789c966c2d5a393133f41 100644 --- a/src/libs/qmljs/qmljstypedescriptionreader.cpp +++ b/src/libs/qmljs/qmljstypedescriptionreader.cpp @@ -239,6 +239,8 @@ void TypeDescriptionReader::readSignalOrMethod(UiObjectDefinition *ast, bool isM fmm.setMethodName(readStringBinding(script)); } else if (name == "type") { fmm.setReturnType(readStringBinding(script)); + } else if (name == "revision") { + fmm.setRevision(readIntBinding(script)); } else { addError(script->firstSourceLocation(), "Expected only name and type script bindings"); return; @@ -265,6 +267,7 @@ void TypeDescriptionReader::readProperty(UiObjectDefinition *ast, FakeMetaObject bool isPointer = false; bool isReadonly = false; bool isList = false; + int revision = 0; for (UiObjectMemberList *it = ast->initializer->members; it; it = it->next) { UiObjectMember *member = it->member; @@ -285,8 +288,10 @@ void TypeDescriptionReader::readProperty(UiObjectDefinition *ast, FakeMetaObject isReadonly = readBoolBinding(script); } else if (id == "isList") { isList = readBoolBinding(script); + } else if (id == "revision") { + revision = readIntBinding(script); } else { - addError(script->firstSourceLocation(), "Expected only type, name, isPointer, isReadonly and isList script bindings"); + addError(script->firstSourceLocation(), "Expected only type, name, revision, isPointer, isReadonly and isList script bindings"); return; } } @@ -296,7 +301,7 @@ void TypeDescriptionReader::readProperty(UiObjectDefinition *ast, FakeMetaObject return; } - fmo->addProperty(FakeMetaProperty(name, type, isList, !isReadonly, isPointer)); + fmo->addProperty(FakeMetaProperty(name, type, isList, !isReadonly, isPointer, revision)); } void TypeDescriptionReader::readEnum(UiObjectDefinition *ast, FakeMetaObject::Ptr fmo) @@ -403,6 +408,41 @@ bool TypeDescriptionReader::readBoolBinding(AST::UiScriptBinding *ast) return trueLit; } +double TypeDescriptionReader::readNumericBinding(AST::UiScriptBinding *ast) +{ + if (!ast || !ast->statement) { + addError(ast->colonToken, "Expected numeric literal after colon"); + return 0; + } + + ExpressionStatement *expStmt = AST::cast<ExpressionStatement *>(ast->statement); + if (!expStmt) { + addError(ast->statement->firstSourceLocation(), "Expected numeric literal after colon"); + return 0; + } + + NumericLiteral *numericLit = AST::cast<NumericLiteral *>(expStmt->expression); + if (!numericLit) { + addError(expStmt->firstSourceLocation(), "Expected numeric literal after colon"); + return 0; + } + + return numericLit->value; +} + +int TypeDescriptionReader::readIntBinding(AST::UiScriptBinding *ast) +{ + double v = readNumericBinding(ast); + int i = (int)v; + + if (i != v) { + addError(ast->firstSourceLocation(), "Expected integer after colon"); + return 0; + } + + return i; +} + void TypeDescriptionReader::readExports(UiScriptBinding *ast, FakeMetaObject::Ptr fmo) { if (!ast || !ast->statement) { diff --git a/src/libs/qmljs/qmljstypedescriptionreader.h b/src/libs/qmljs/qmljstypedescriptionreader.h index c05d686091ef224602e926214fa4956370da1755..136bb04ed596a1b5785473b128b21e9de076ef24 100644 --- a/src/libs/qmljs/qmljstypedescriptionreader.h +++ b/src/libs/qmljs/qmljstypedescriptionreader.h @@ -76,6 +76,8 @@ private: QString readStringBinding(AST::UiScriptBinding *ast); bool readBoolBinding(AST::UiScriptBinding *ast); + double readNumericBinding(AST::UiScriptBinding *ast); + int readIntBinding(AST::UiScriptBinding *ast); void readExports(AST::UiScriptBinding *ast, LanguageUtils::FakeMetaObject::Ptr fmo); void readEnumValues(AST::UiScriptBinding *ast, LanguageUtils::FakeMetaEnum *fme); void addError(const AST::SourceLocation &loc, const QString &message); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index aaa954ce39a1ba631906dee4fd2dbdb824727ae1..9eb734f3518de99a977d6e95a8797deee3afdc09 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -1356,10 +1356,12 @@ static void populate(LanguageUtils::FakeMetaObject::Ptr fmo, Class *klass, const bool isList = false; // ### fixme const bool isWritable = propDecl->flags() & QtPropertyDeclaration::WriteFunction; const bool isPointer = type.type() && type.type()->isPointerType(); + const int revision = 0; // ### fixme FakeMetaProperty property( namePrinter(propDecl->name()), toQmlType(type), - isList, isWritable, isPointer); + isList, isWritable, isPointer, + revision); fmo->addProperty(property); } if (QtEnum *qtEnum = member->asQtEnum()) {