diff options
author | Kai Koehne <kai.koehne@nokia.com> | 2009-08-24 07:53:15 (GMT) |
---|---|---|
committer | Kai Koehne <kai.koehne@nokia.com> | 2009-08-24 07:58:09 (GMT) |
commit | 40c12237b506bda373f5218c13e356de025c3716 (patch) | |
tree | a2a47b3af244374aaa4923ffa3541c72ed15f9c6 | |
parent | 494d2d9041b7277f6d22146593ff01c7c7f7021b (diff) | |
download | Qt-40c12237b506bda373f5218c13e356de025c3716.zip Qt-40c12237b506bda373f5218c13e356de025c3716.tar.gz Qt-40c12237b506bda373f5218c13e356de025c3716.tar.bz2 |
Expose type library information in QmlDomObject
New QmlDomObject::objectTypeMajorVersion && objectTypeMinorVersion
accessors expose import library information.
-rw-r--r-- | src/declarative/qml/qmlcompositetypemanager.cpp | 19 | ||||
-rw-r--r-- | src/declarative/qml/qmldom.cpp | 15 | ||||
-rw-r--r-- | src/declarative/qml/qmldom.h | 3 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine.cpp | 108 | ||||
-rw-r--r-- | src/declarative/qml/qmlengine_p.h | 18 | ||||
-rw-r--r-- | src/declarative/qml/qmlparser.cpp | 2 | ||||
-rw-r--r-- | src/declarative/qml/qmlparser_p.h | 5 | ||||
-rw-r--r-- | src/declarative/qml/qmlscriptparser.cpp | 1 | ||||
-rw-r--r-- | tests/auto/declarative/qmldom/tst_qmldom.cpp | 2 |
9 files changed, 152 insertions, 21 deletions
diff --git a/src/declarative/qml/qmlcompositetypemanager.cpp b/src/declarative/qml/qmlcompositetypemanager.cpp index 0fb6c86..5bf2dc0 100644 --- a/src/declarative/qml/qmlcompositetypemanager.cpp +++ b/src/declarative/qml/qmlcompositetypemanager.cpp @@ -327,8 +327,23 @@ void QmlCompositeTypeManager::compile(QmlCompositeTypeData *unit) } QUrl url; - if (!QmlEnginePrivate::get(engine)->resolveType(unit->imports, typeName, &ref.type, &url)) { - // XXX could produce error message here. + QmlEnginePrivate::ImportedNamespace *s; + QByteArray localTypeName; + + QmlEnginePrivate::get(engine)->resolveNamespace(unit->imports, typeName, &s, &localTypeName); + if (QmlEnginePrivate::get(engine)->resolveTypeInNamespace(s, localTypeName, &ref.type, &url)) { + int majorVersion; + int minorVersion; + if (s->getTypeInfo(localTypeName, 0, &majorVersion, &minorVersion)) { + foreach (QmlParser::Object *obj, parserRef->refObjects) { + // store namespace for DOM + obj->majorVersion = majorVersion; + obj->minorVersion = minorVersion; + } + } + } else { + // try base url + url = unit->imports.baseUrl().resolved(QUrl(QLatin1String(typeName + ".qml"))); } if (ref.type) { diff --git a/src/declarative/qml/qmldom.cpp b/src/declarative/qml/qmldom.cpp index 22a8e49..bc35f93 100644 --- a/src/declarative/qml/qmldom.cpp +++ b/src/declarative/qml/qmldom.cpp @@ -776,6 +776,21 @@ QByteArray QmlDomObject::objectClassName() const return QByteArray(); } +int QmlDomObject::objectTypeMajorVersion() const +{ + if (d->object) + return d->object->majorVersion; + else + return -1; +} + +int QmlDomObject::objectTypeMinorVersion() const +{ + if (d->object) + return d->object->minorVersion; + else + return -1; +} /*! Returns the QML id assigned to this object, or an empty QByteArray if no id diff --git a/src/declarative/qml/qmldom.h b/src/declarative/qml/qmldom.h index 32ed2da..60e7b38 100644 --- a/src/declarative/qml/qmldom.h +++ b/src/declarative/qml/qmldom.h @@ -152,6 +152,9 @@ public: QByteArray objectType() const; QByteArray objectClassName() const; + int objectTypeMajorVersion() const; + int objectTypeMinorVersion() const; + QString objectId() const; void setObjectId(const QByteArray &); diff --git a/src/declarative/qml/qmlengine.cpp b/src/declarative/qml/qmlengine.cpp index 351bd8a..c56da6e 100644 --- a/src/declarative/qml/qmlengine.cpp +++ b/src/declarative/qml/qmlengine.cpp @@ -1072,7 +1072,7 @@ void QmlObjectScriptClass::setProperty(QScriptValue &object, } -struct QmlEnginePrivate::ImportedNamespace { +struct QmlImportedNamespacePrivate { QStringList urls; QList<int> majversions; QList<int> minversions; @@ -1177,10 +1177,10 @@ public: } else { url = base.resolved(QUrl(url)).toString(); } - s->urls.append(url); - s->majversions.append(vmaj); - s->minversions.append(vmin); - s->isLibrary.append(importType == QmlScriptParser::Import::Library); + s->d->urls.append(url); + s->d->majversions.append(vmaj); + s->d->minversions.append(vmin); + s->d->isLibrary.append(importType == QmlScriptParser::Import::Library); return true; } @@ -1202,7 +1202,7 @@ public: } QString unqualifiedtype = type.mid(slash+1); if (s) - return s->find(unqualifiedtype); + return s->d->find(unqualifiedtype); else return QUrl(); } @@ -1226,16 +1226,37 @@ public: } QByteArray unqualifiedtype = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) if (s) - return s->findBuiltin(unqualifiedtype,found); + return s->d->findBuiltin(unqualifiedtype,found); else return 0; - } + } QmlEnginePrivate::ImportedNamespace *findNamespace(const QString& type) { return set.value(type); } + void resolveNamespace(const QByteArray &type, QmlEnginePrivate::ImportedNamespace **ns, QByteArray *unqualifiedType) + { + QmlEnginePrivate::ImportedNamespace *s = 0; + int slash = type.indexOf('/'); + if (slash >= 0) { + while (!s) { + s = set.value(QString::fromLatin1(type.left(slash))); + int nslash = type.indexOf('/',slash+1); + if (nslash > 0) + slash = nslash; + else + break; + } + } else { + s = &unqualifiedset; + } + + *ns = s; + *unqualifiedType = slash < 0 ? type : type.mid(slash+1); // common-case opt (QString::mid works fine, but slower) + } + private: QmlEnginePrivate::ImportedNamespace unqualifiedset; QHash<QString,QmlEnginePrivate::ImportedNamespace* > set; @@ -1258,6 +1279,37 @@ void QmlEnginePrivate::Imports::setBaseUrl(const QUrl& url) base = url; } +QmlEnginePrivate::ImportedNamespace::ImportedNamespace() + : d(new QmlImportedNamespacePrivate) +{ +} + +QmlEnginePrivate::ImportedNamespace::~ImportedNamespace() +{ + delete d; +} + +bool QmlEnginePrivate::ImportedNamespace::getTypeInfo(const QByteArray &typeName, QString *uri, int *majorVersion, int *minorVersion) +{ + for (int i=0; i<d->urls.count(); ++i) { + int vmaj = d->majversions.at(i); + int vmin = d->minversions.at(i); + QByteArray qt = d->urls.at(i).toLatin1(); + qt += "/"; + qt += typeName; + if (QmlMetaType::qmlType(qt,vmaj,vmin)) { + if (uri) + *uri = d->urls.at(i); + if (majorVersion) + *majorVersion = d->majversions.at(i); + if (minorVersion) + *minorVersion = d->minversions.at(i); + return true; + } + } + return false; +} + /*! Adds \a path as a directory where installed QML components are defined in a URL-based directory structure. @@ -1312,11 +1364,6 @@ bool QmlEnginePrivate::addToImport(Imports* imports, const QString& uri, const Q */ bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& type, QmlType** type_return, QUrl* url_return, ImportedNamespace** ns_return) const { - if (ns_return) { - *ns_return = imports.d->findNamespace(QLatin1String(type)); - if (*ns_return) - return true; - } if (type_return) { QmlType* t = imports.d->findBuiltin(type); if (!t) t = QmlMetaType::qmlType(type,0,0); // Try global namespace @@ -1339,6 +1386,11 @@ bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& typ return true; } } + if (ns_return) { + *ns_return = imports.d->findNamespace(QLatin1String(type)); + if (*ns_return) + return true; + } if (qmlImportTrace()) qDebug() << "QmlEngine::resolveType" << type << " not found"; return false; @@ -1347,6 +1399,16 @@ bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& typ /*! \internal + Splits a fully qualified type name into the namespace and the unqualified type name. +*/ +void QmlEnginePrivate::resolveNamespace(const Imports& imports, const QByteArray &type, ImportedNamespace **ns, QByteArray *unqualifiedType) const +{ + imports.d->resolveNamespace(type, ns, unqualifiedType); +} + +/*! + \internal + Searching \e only in the namespace \a ns (previously returned in a call to resolveType(), \a type is found and returned to either a QmlType stored at \a type_return, or @@ -1354,14 +1416,28 @@ bool QmlEnginePrivate::resolveType(const Imports& imports, const QByteArray& typ If either return pointer is 0, the corresponding search is not done. */ -void QmlEnginePrivate::resolveTypeInNamespace(ImportedNamespace* ns, const QByteArray& type, QmlType** type_return, QUrl* url_return ) const +bool QmlEnginePrivate::resolveTypeInNamespace(ImportedNamespace* ns, const QByteArray& type, QmlType** type_return, QUrl* url_return ) const { if (type_return) { - *type_return = ns->findBuiltin(type); + QmlType* t = ns->d->findBuiltin(type); + if (!t) t = QmlMetaType::qmlType(type,0,0); // Try global namespace + if (t) { + *type_return = t; + if (qmlImportTrace()) + qDebug() << "QmlEngine::resolveTypeInNamespace" << type << "= (builtin)"; + return true; + } } if (url_return) { - *url_return = ns->find(QLatin1String(type)); + QUrl url = ns->d->find(QLatin1String(type)); + if (url.isValid()) { + if (url_return) *url_return = url; + if (qmlImportTrace()) + qDebug() << "QmlEngine::resolveType" << type << "=" << url; + return true; + } } + return false; } QT_END_NAMESPACE diff --git a/src/declarative/qml/qmlengine_p.h b/src/declarative/qml/qmlengine_p.h index 4142872..c84b3b5 100644 --- a/src/declarative/qml/qmlengine_p.h +++ b/src/declarative/qml/qmlengine_p.h @@ -195,10 +195,24 @@ public: QUrl base; QmlImportsPrivate *d; }; - struct ImportedNamespace; + + struct ImportedNamespace { + ImportedNamespace(); + ~ImportedNamespace(); + + bool getTypeInfo(const QByteArray &typeName, QString *uri, int *vmaj, int *vmin); + private: + friend class QmlImportsPrivate; + friend class QmlEnginePrivate; + class QmlImportedNamespacePrivate *d; + }; + bool addToImport(Imports*, const QString& uri, const QString& prefix, int vmaj, int vmin, QmlScriptParser::Import::Type importType) const; + bool resolveType(const Imports&, const QByteArray& type, QmlType** type_return, QUrl* url_return, ImportedNamespace** ns_return=0) const; - void resolveTypeInNamespace(ImportedNamespace*, const QByteArray& type, QmlType** type_return, QUrl* url_return ) const; + + void resolveNamespace(const Imports& imports, const QByteArray &type, ImportedNamespace **s, QByteArray *unqualifiedType) const; + bool resolveTypeInNamespace(ImportedNamespace*, const QByteArray& type, QmlType** type_return, QUrl* url_return ) const; static QScriptValue qmlScriptObject(QObject*, QmlEngine*); diff --git a/src/declarative/qml/qmlparser.cpp b/src/declarative/qml/qmlparser.cpp index 2a67c92..0f2a282 100644 --- a/src/declarative/qml/qmlparser.cpp +++ b/src/declarative/qml/qmlparser.cpp @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE using namespace QmlParser; QmlParser::Object::Object() -: type(-1), idIndex(-1), metatype(0), defaultProperty(0), parserStatusCast(-1) +: type(-1), majorVersion(-1), minorVersion(-1), idIndex(-1), metatype(0), defaultProperty(0), parserStatusCast(-1) { } diff --git a/src/declarative/qml/qmlparser_p.h b/src/declarative/qml/qmlparser_p.h index 120af75..8a92a9f 100644 --- a/src/declarative/qml/qmlparser_p.h +++ b/src/declarative/qml/qmlparser_p.h @@ -115,6 +115,11 @@ namespace QmlParser int type; // The url of this object if it is an external type. Used by the DOM QUrl url; + + // version information if type is defined in library or C++ + int majorVersion; + int minorVersion; + // The fully-qualified name of this type QByteArray typeName; // The class name diff --git a/src/declarative/qml/qmlscriptparser.cpp b/src/declarative/qml/qmlscriptparser.cpp index 187f640..418eba7 100644 --- a/src/declarative/qml/qmlscriptparser.cpp +++ b/src/declarative/qml/qmlscriptparser.cpp @@ -831,6 +831,7 @@ void QmlScriptParser::clear() root->release(); root = 0; } + _imports.clear(); qDeleteAll(_refTypes); _refTypes.clear(); _errors.clear(); diff --git a/tests/auto/declarative/qmldom/tst_qmldom.cpp b/tests/auto/declarative/qmldom/tst_qmldom.cpp index dd02bce..e1419cc 100644 --- a/tests/auto/declarative/qmldom/tst_qmldom.cpp +++ b/tests/auto/declarative/qmldom/tst_qmldom.cpp @@ -41,6 +41,8 @@ void tst_qmldom::loadSimple() QVERIFY(!rootObject.isComponent()); QVERIFY(!rootObject.isCustomType()); QVERIFY(rootObject.objectType() == "Qt/Item"); + QVERIFY(rootObject.objectTypeMajorVersion() == 4); + QVERIFY(rootObject.objectTypeMinorVersion() == 6); } void tst_qmldom::loadProperties() |