diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2017-09-25 13:31:11 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2017-09-26 05:57:22 +0000 |
commit | 930aea8b9ca59a24838cf7f279653e3b2ee40cee (patch) | |
tree | e76557a11ee9ed31e09005924dfa9ff6a9adc423 | |
parent | 112d668c0fded8c6ab7bf40fd3800cf43e005f95 (diff) |
Fix implicit loading of internal types when using explicit imports
The QQC Android style has a type that is intended to be internal only
and it's loaded implictly (see bug report for details). However the qml
file also has to import the module explicitly in order to get access to
the singleton the module provides.
The documentation says that types of a module are to be specified in the
qmldir file, otherwise they are derived from the file name. With commit
22a2cc43387ec3b9f74a6c01f8665378a4541147 that become an exclusive
relationship with regards to types from implicit imports.
The proposed solution for the JIRA task is to mark the types that are
needed internally as "internal" in the qmldir file and fix support for
loading internal types through implicit imports (which is what this
commit fixes).
Task-number: QTBUG-63309
Change-Id: Id696a691f1af1d335c7c8d72f2627064c3d7b9ac
Reviewed-by: Michael Brasser <michael.brasser@live.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
7 files changed, 45 insertions, 2 deletions
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp index bc8be04f24..345b88b007 100644 --- a/src/qml/qml/qqmlimport.cpp +++ b/src/qml/qml/qqmlimport.cpp @@ -753,6 +753,7 @@ bool QQmlImportInstance::resolveType(QQmlTypeLoader *typeLoader, // importing version -1 means import ALL versions if ((majversion == -1) || + (implicitlyImported && c.internal) || // allow the implicit import of internal types (c.majorVersion == majversion && c.minorVersion <= minversion)) { // Is this better than the previous candidate? if ((candidate == end) || @@ -1510,12 +1511,15 @@ bool QQmlImportsPrivate::addFileImport(const QString& uri, const QString &prefix // ### For enum support, we are now adding the implicit import always (and earlier). Bail early // if the implicit import has already been explicitly added, otherwise we can run into issues - // with duplicate imports + // with duplicate imports. However remember that we attempted to add this as implicit import, to + // allow for the loading of internal types. if (isImplicitImport) { for (QList<QQmlImportInstance *>::const_iterator it = nameSpace->imports.constBegin(); it != nameSpace->imports.constEnd(); ++it) { - if ((*it)->uri == importUri) + if ((*it)->uri == importUri) { + (*it)->implicitlyImported = true; return true; + } } } diff --git a/src/qml/qml/qqmlimport_p.h b/src/qml/qml/qqmlimport_p.h index 0b4a0e6f80..a1911515d0 100644 --- a/src/qml/qml/qqmlimport_p.h +++ b/src/qml/qml/qqmlimport_p.h @@ -81,6 +81,7 @@ struct QQmlImportInstance int majversion; // the major version imported int minversion; // the minor version imported bool isLibrary; // true means that this is not a file import + bool implicitlyImported = false; QQmlDirComponents qmlDirComponents; // a copy of the components listed in the qmldir QQmlDirScripts qmlDirScripts; // a copy of the scripts in the qmldir diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml new file mode 100644 index 0000000000..0e69012662 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyInternalType.qml @@ -0,0 +1,2 @@ +import QtQml 2.0 +QtObject {} diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml new file mode 100644 index 0000000000..c6b38d51a9 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicType.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + property InternalType myInternalType: InternalType {} +} diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml new file mode 100644 index 0000000000..9b488f92da --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/MyPublicTypeWithExplicitImport.qml @@ -0,0 +1,5 @@ +import QtQml 2.0 +import modulewithinternaltypes 1.0 +QtObject { + property InternalType myInternalType: InternalType {} +} diff --git a/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir new file mode 100644 index 0000000000..3593845329 --- /dev/null +++ b/tests/auto/qml/qqmllanguage/data/modulewithinternaltypes/qmldir @@ -0,0 +1,3 @@ +PublicType 1.0 MyPublicType.qml +PublicTypeWithExplicitImport 1.0 MyPublicTypeWithExplicitImport.qml +internal InternalType MyInternalType.qml diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp index e5366b5c48..eb462979ed 100644 --- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp +++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp @@ -179,6 +179,7 @@ private slots: void importJs_data(); void importJs(); void explicitSelfImport(); + void importInternalType(); void qmlAttachedPropertiesObjectMethod(); void customOnProperty(); @@ -3086,6 +3087,29 @@ void tst_qqmllanguage::explicitSelfImport() engine.setImportPathList(defaultImportPathList); } +void tst_qqmllanguage::importInternalType() +{ + QQmlEngine engine; + engine.addImportPath(dataDirectory()); + + { + QQmlComponent component(&engine); + component.setData("import modulewithinternaltypes 1.0\nPublicType{}", QUrl()); + VERIFY_ERRORS(0); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + QVERIFY(obj->property("myInternalType").value<QObject*>() != 0); + } + { + QQmlComponent component(&engine); + component.setData("import modulewithinternaltypes 1.0\nPublicTypeWithExplicitImport{}", QUrl()); + VERIFY_ERRORS(0); + QScopedPointer<QObject> obj(component.create()); + QVERIFY(!obj.isNull()); + QVERIFY(obj->property("myInternalType").value<QObject*>() != 0); + } +} + void tst_qqmllanguage::qmlAttachedPropertiesObjectMethod() { QObject object; |