summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKai Koehne <kai.koehne@nokia.com>2009-08-24 07:53:15 (GMT)
committerKai Koehne <kai.koehne@nokia.com>2009-08-24 07:58:09 (GMT)
commit40c12237b506bda373f5218c13e356de025c3716 (patch)
treea2a47b3af244374aaa4923ffa3541c72ed15f9c6
parent494d2d9041b7277f6d22146593ff01c7c7f7021b (diff)
downloadQt-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.cpp19
-rw-r--r--src/declarative/qml/qmldom.cpp15
-rw-r--r--src/declarative/qml/qmldom.h3
-rw-r--r--src/declarative/qml/qmlengine.cpp108
-rw-r--r--src/declarative/qml/qmlengine_p.h18
-rw-r--r--src/declarative/qml/qmlparser.cpp2
-rw-r--r--src/declarative/qml/qmlparser_p.h5
-rw-r--r--src/declarative/qml/qmlscriptparser.cpp1
-rw-r--r--tests/auto/declarative/qmldom/tst_qmldom.cpp2
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()