aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qml/qml/qqmlimport.cpp10
-rw-r--r--src/qml/qml/qqmltypeloader.cpp4
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp57
-rw-r--r--src/qml/qml/qqmltypenamecache_p.h8
-rw-r--r--tests/auto/qml/qqmllanguage/data/compositeTypeByName_anon_qmldir.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/compositeTypeByName_named_qmldir.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/data/quickTypeByName_anon.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/data/quickTypeByName_named.qml8
-rw-r--r--tests/auto/qml/qqmllanguage/data/simpleimportByName/SimpleType.qml4
-rw-r--r--tests/auto/qml/qqmllanguage/data/simpleimportByName/qmldir1
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp29
11 files changed, 139 insertions, 8 deletions
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index e69789d5f4..257c280e50 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -400,9 +400,8 @@ QUrl QQmlImports::baseUrl() const
document's imports into the \a cache for resolution elsewhere (e.g. in JS,
or when loading additional types).
- \note A current limitation of the implementation here is that only C++ types
- are added to the type cache. This is due to file imports not having a
- registered module.
+ \note This is for C++ types only. Composite types are handled separately,
+ as they do not have a QQmlTypeModule.
*/
void QQmlImports::populateCache(QQmlTypeNameCache *cache) const
{
@@ -420,11 +419,14 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache) const
const QQmlImportNamespace &set = *ns;
+ // positioning is important; we must create the namespace even if there is no module.
+ QQmlTypeNameCache::Import &typeimport = cache->m_namedImports[set.prefix];
+ typeimport.m_qualifier = set.prefix;
+
for (int ii = set.imports.count() - 1; ii >= 0; --ii) {
const QQmlImportInstance *import = set.imports.at(ii);
QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion);
if (module) {
- QQmlTypeNameCache::Import &typeimport = cache->m_namedImports[set.prefix];
typeimport.modules.append(QQmlTypeModuleVersion(module, import->minversion));
}
}
diff --git a/src/qml/qml/qqmltypeloader.cpp b/src/qml/qml/qqmltypeloader.cpp
index a0781ee08b..8dea866c9a 100644
--- a/src/qml/qml/qqmltypeloader.cpp
+++ b/src/qml/qml/qqmltypeloader.cpp
@@ -2602,7 +2602,7 @@ QQmlCompileError QQmlTypeData::buildTypeResolutionCaches(
QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache
) const
{
- typeNameCache->adopt(new QQmlTypeNameCache);
+ typeNameCache->adopt(new QQmlTypeNameCache(m_importCache));
for (const QString &ns: m_namespaces)
(*typeNameCache)->add(ns);
@@ -2946,7 +2946,7 @@ void QQmlScriptBlob::done()
}
}
- m_scriptData->typeNameCache = new QQmlTypeNameCache();
+ m_scriptData->typeNameCache = new QQmlTypeNameCache(m_importCache);
QSet<QString> ns;
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index c2098bc9a1..b5b14d1ae8 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -43,7 +43,8 @@
QT_BEGIN_NAMESPACE
-QQmlTypeNameCache::QQmlTypeNameCache()
+QQmlTypeNameCache::QQmlTypeNameCache(const QQmlImports &importCache)
+ : m_imports(importCache)
{
}
@@ -70,6 +71,7 @@ void QQmlTypeNameCache::add(const QHashedString &name, int importedScriptIndex,
{
Import import;
import.scriptIndex = importedScriptIndex;
+ import.m_qualifier = name;
if (nameSpace.length() != 0) {
Import *i = m_namedImports.value(nameSpace);
@@ -94,6 +96,18 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name)
if (!result.isValid())
result = query(m_anonymousCompositeSingletons, name);
+ if (!result.isValid()) {
+ // Look up anonymous types from the imports of this document
+ QQmlImportNamespace *typeNamespace = 0;
+ QList<QQmlError> errors;
+ QQmlType *t = 0;
+ bool typeFound = m_imports.resolveType(name, &t, 0, 0, &typeNamespace, &errors);
+ if (typeFound) {
+ return Result(t);
+ }
+
+ }
+
return result;
}
@@ -109,6 +123,20 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name,
if (!result.isValid())
result = query(i->compositeSingletons, name);
+ if (!result.isValid()) {
+ // Look up types from the imports of this document
+ // ### it would be nice if QQmlImports allowed us to resolve a namespace
+ // first, and then types on it.
+ QString qualifiedTypeName = i->m_qualifier + "." + name.toString();
+ QQmlImportNamespace *typeNamespace = 0;
+ QList<QQmlError> errors;
+ QQmlType *t = 0;
+ bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, 0, 0, &typeNamespace, &errors);
+ if (typeFound) {
+ return Result(t);
+ }
+ }
+
return result;
}
@@ -122,6 +150,19 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name) cons
if (!result.isValid())
result = query(m_anonymousCompositeSingletons, name);
+ if (!result.isValid()) {
+ // Look up anonymous types from the imports of this document
+ QString typeName = name->toQStringNoThrow();
+ QQmlImportNamespace *typeNamespace = 0;
+ QList<QQmlError> errors;
+ QQmlType *t = 0;
+ bool typeFound = m_imports.resolveType(typeName, &t, 0, 0, &typeNamespace, &errors);
+ if (typeFound) {
+ return Result(t);
+ }
+
+ }
+
return result;
}
@@ -143,6 +184,20 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QV4::String *name, cons
if (!r.isValid())
r = query(i->compositeSingletons, name);
+ if (!r.isValid()) {
+ // Look up types from the imports of this document
+ // ### it would be nice if QQmlImports allowed us to resolve a namespace
+ // first, and then types on it.
+ QString qualifiedTypeName = i->m_qualifier + "." + name->toQStringNoThrow();
+ QQmlImportNamespace *typeNamespace = 0;
+ QList<QQmlError> errors;
+ QQmlType *t = 0;
+ bool typeFound = m_imports.resolveType(qualifiedTypeName, &t, 0, 0, &typeNamespace, &errors);
+ if (typeFound) {
+ return Result(t);
+ }
+ }
+
return r;
}
diff --git a/src/qml/qml/qqmltypenamecache_p.h b/src/qml/qml/qqmltypenamecache_p.h
index 8a387bed5f..7cdcbe91b6 100644
--- a/src/qml/qml/qqmltypenamecache_p.h
+++ b/src/qml/qml/qqmltypenamecache_p.h
@@ -56,6 +56,7 @@
#include "qqmlmetatype_p.h"
#include <private/qhashedstring_p.h>
+#include <private/qqmlimport_p.h>
#include <QtCore/qvector.h>
@@ -66,7 +67,7 @@ class QQmlEngine;
class QQmlTypeNameCache : public QQmlRefCount
{
public:
- QQmlTypeNameCache();
+ QQmlTypeNameCache(const QQmlImports &imports);
virtual ~QQmlTypeNameCache();
inline bool isEmpty() const;
@@ -105,6 +106,9 @@ private:
// Or, imported compositeSingletons
QStringHash<QUrl> compositeSingletons;
+
+ // The qualifier of this import
+ QString m_qualifier;
};
template<typename Key>
@@ -112,6 +116,7 @@ private:
{
Import *i = imports.value(key);
if (i) {
+ Q_ASSERT(!i->m_qualifier.isEmpty());
if (i->scriptIndex != -1) {
return Result(i->scriptIndex);
} else {
@@ -151,6 +156,7 @@ private:
QMap<const Import *, QStringHash<Import> > m_namespacedImports;
QVector<QQmlTypeModuleVersion> m_anonymousImports;
QStringHash<QUrl> m_anonymousCompositeSingletons;
+ QQmlImports m_imports;
};
QQmlTypeNameCache::Result::Result()
diff --git a/tests/auto/qml/qqmllanguage/data/compositeTypeByName_anon_qmldir.qml b/tests/auto/qml/qqmllanguage/data/compositeTypeByName_anon_qmldir.qml
new file mode 100644
index 0000000000..5ffdc26096
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/compositeTypeByName_anon_qmldir.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.6
+import "simpleimportByName"
+
+Item {
+ Component.onCompleted: {
+ console.warn(SimpleType)
+ }
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/compositeTypeByName_named_qmldir.qml b/tests/auto/qml/qqmllanguage/data/compositeTypeByName_named_qmldir.qml
new file mode 100644
index 0000000000..c446eae84c
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/compositeTypeByName_named_qmldir.qml
@@ -0,0 +1,9 @@
+import QtQuick 2.6
+import "simpleimportByName" as ImportName
+
+Item {
+ Component.onCompleted: {
+ console.warn(ImportName.SimpleType)
+ }
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/quickTypeByName_anon.qml b/tests/auto/qml/qqmllanguage/data/quickTypeByName_anon.qml
new file mode 100644
index 0000000000..abe750db33
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/quickTypeByName_anon.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.6
+
+Item {
+ Component.onCompleted: {
+ console.warn(Item)
+ }
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/quickTypeByName_named.qml b/tests/auto/qml/qqmllanguage/data/quickTypeByName_named.qml
new file mode 100644
index 0000000000..397d4f42f0
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/quickTypeByName_named.qml
@@ -0,0 +1,8 @@
+import QtQuick 2.6 as Quick
+
+Quick.Item {
+ Quick.Component.onCompleted: {
+ console.warn(Quick.Item)
+ }
+}
+
diff --git a/tests/auto/qml/qqmllanguage/data/simpleimportByName/SimpleType.qml b/tests/auto/qml/qqmllanguage/data/simpleimportByName/SimpleType.qml
new file mode 100644
index 0000000000..4772dde8f0
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/simpleimportByName/SimpleType.qml
@@ -0,0 +1,4 @@
+import QtQuick 2.6
+
+MouseArea {
+}
diff --git a/tests/auto/qml/qqmllanguage/data/simpleimportByName/qmldir b/tests/auto/qml/qqmllanguage/data/simpleimportByName/qmldir
new file mode 100644
index 0000000000..80df37d0e6
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/simpleimportByName/qmldir
@@ -0,0 +1 @@
+SimpleType 1.0 SimpleType.qml
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index f586f7d429..c0500afddd 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -257,6 +257,9 @@ private slots:
void defaultListProperty();
void namespacedPropertyTypes();
+ void qmlTypeCanBeResolvedByName_data();
+ void qmlTypeCanBeResolvedByName();
+
private:
QQmlEngine engine;
QStringList defaultImportPathList;
@@ -4250,6 +4253,32 @@ void tst_qqmllanguage::namespacedPropertyTypes()
QVERIFY(!o.isNull());
}
+void tst_qqmllanguage::qmlTypeCanBeResolvedByName_data()
+{
+ QTest::addColumn<QUrl>("componentUrl");
+
+ // Built-in C++ types
+ QTest::newRow("C++ - Anonymous") << testFileUrl("quickTypeByName_anon.qml");
+ QTest::newRow("C++ - Named") << testFileUrl("quickTypeByName_named.qml");
+
+ // Composite types with a qmldir
+ QTest::newRow("QML - Anonymous - qmldir") << testFileUrl("compositeTypeByName_anon_qmldir.qml");
+ QTest::newRow("QML - Named - qmldir") << testFileUrl("compositeTypeByName_named_qmldir.qml");
+}
+
+void tst_qqmllanguage::qmlTypeCanBeResolvedByName()
+{
+ QFETCH(QUrl, componentUrl);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine, componentUrl);
+ VERIFY_ERRORS(0);
+ QTest::ignoreMessage(QtMsgType::QtWarningMsg, "[object Object]"); // a bit crude, but it will do
+
+ QScopedPointer<QObject> o(component.create());
+ QVERIFY(!o.isNull());
+}
+
QTEST_MAIN(tst_qqmllanguage)
#include "tst_qqmllanguage.moc"