diff options
-rw-r--r-- | src/qml/Qt6QmlMacros.cmake | 7 | ||||
-rw-r--r-- | src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp | 2 | ||||
-rw-r--r-- | src/qml/doc/src/cmake/qt_add_qml_module.qdoc | 11 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/CMakeLists.txt | 2 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/NamespaceTest/Subfolder/CMakeLists.txt | 41 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/NamespaceTest/Subfolder/Type.qml | 5 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/tst_qmltc.cpp | 59 | ||||
-rw-r--r-- | tests/auto/qml/qmltc/tst_qmltc.h | 1 | ||||
-rw-r--r-- | tools/qmltc/qmltccodewriter.cpp | 24 |
10 files changed, 118 insertions, 35 deletions
diff --git a/src/qml/Qt6QmlMacros.cmake b/src/qml/Qt6QmlMacros.cmake index 2f7659c2a0..c0df7a92f0 100644 --- a/src/qml/Qt6QmlMacros.cmake +++ b/src/qml/Qt6QmlMacros.cmake @@ -664,10 +664,15 @@ function(qt6_add_qml_module target) endif() if (arg_ENABLE_TYPE_COMPILER) + if (DEFINED arg_TYPE_COMPILER_NAMESPACE AND NOT $<STREQUAL:"${arg_TYPE_COMPILER_NAMESPACE}","">) + set(qmltc_namespace ${arg_TYPE_COMPILER_NAMESPACE}) + else() + string(REPLACE "." "::" qmltc_namespace "${arg_URI}") + endif() _qt_internal_target_enable_qmltc(${target} QML_FILES ${arg_QML_FILES} IMPORT_PATHS ${arg_IMPORT_PATH} - NAMESPACE ${arg_TYPE_COMPILER_NAMESPACE} + NAMESPACE ${qmltc_namespace} ) endif() diff --git a/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp b/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp index a78da416e2..7bda70f985 100644 --- a/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp +++ b/src/qml/doc/snippets/qmltc/tst_qmltc_examples.cpp @@ -53,7 +53,7 @@ void tst_qmltc_examples::app() QQmlEngine e; QQuickWindow window; - QScopedPointer<myApp> documentRoot(new myApp(&e)); + QScopedPointer<QmltcExample::myApp> documentRoot(new QmltcExample::myApp(&e)); documentRoot->setParentItem(window.contentItem()); window.setHeight(documentRoot->height()); diff --git a/src/qml/doc/src/cmake/qt_add_qml_module.qdoc b/src/qml/doc/src/cmake/qt_add_qml_module.qdoc index 9bef299970..7617d19033 100644 --- a/src/qml/doc/src/cmake/qt_add_qml_module.qdoc +++ b/src/qml/doc/src/cmake/qt_add_qml_module.qdoc @@ -655,4 +655,15 @@ with \l{QML Type Compiler}{qmltc}. Files with the source property C++ code resides. By default, no namespace is specified for user projects. The code generated from Qt's own sources is put under a QT_NAMESPACE namespace. +\c TYPE_COMPILER_NAMESPACE argument allows to override the namespace in which +\l{QML Type Compiler}{qmltc} generates code. +By default, the namespace of the generated code follows the module +hierarchy as depicted in the URI, +e.g., \c MyModule for a module with URI \c MyModule or +\c com::example::Module for URI \c com.example.MyModule. +By specifying the \c TYPE_COMPILER_NAMESPACE option, the generated code +can be put instead in a custom namespace, where different subnamespaces are to +be separated by a "::", e.g. "MyNamespace::MySubnamespace" for the namespace MySubnamespace that +is inside the MyNamespace. Apart from the "::", C++ namespace naming rules +apply. */ diff --git a/tests/auto/qml/qmltc/CMakeLists.txt b/tests/auto/qml/qmltc/CMakeLists.txt index d71d1ac557..4b86a6c018 100644 --- a/tests/auto/qml/qmltc/CMakeLists.txt +++ b/tests/auto/qml/qmltc/CMakeLists.txt @@ -2,6 +2,7 @@ # SPDX-License-Identifier: BSD-3-Clause add_subdirectory(QmltcTests) +add_subdirectory(NamespaceTest/Subfolder) set(test_sources nameconflict.h nameconflict.cpp @@ -16,6 +17,7 @@ set(qmltc_module_libs # - Properly see C++ types exposed to QML in the engine (we need C++ # automatic type registration that comes from the plugin) qmltc_test_moduleplugin + qmltc_namespace_test_module ) qt_internal_add_test(tst_qmltc_diskcache SOURCES ${test_sources} diff --git a/tests/auto/qml/qmltc/NamespaceTest/Subfolder/CMakeLists.txt b/tests/auto/qml/qmltc/NamespaceTest/Subfolder/CMakeLists.txt new file mode 100644 index 0000000000..a93698655c --- /dev/null +++ b/tests/auto/qml/qmltc/NamespaceTest/Subfolder/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +set(cpp_sources +) + +set(qml_sources + Type.qml +) + +set(js_sources +) + +set(common_libraries + Qt::Core + Qt::QmlPrivate + Qt::QuickPrivate + Qt::TestPrivate + Qt::Gui # QColor, QMatrix4x4, ... +) + +qt_add_library(qmltc_namespace_test_module STATIC) +qt_autogen_tools_initial_setup(qmltc_namespace_test_module) + +target_link_libraries(qmltc_namespace_test_module PUBLIC ${common_libraries}) + +qt6_add_qml_module(qmltc_namespace_test_module + VERSION 1.0 + URI NamespaceTest.Subfolder + AUTO_RESOURCE_PREFIX + SOURCES + ${cpp_sources} + QML_FILES + ${qml_sources} + ${js_sources} + DEPENDENCIES + QtQuick + ENABLE_TYPE_COMPILER +) + +qt_autogen_tools_initial_setup(qmltc_namespace_test_moduleplugin) diff --git a/tests/auto/qml/qmltc/NamespaceTest/Subfolder/Type.qml b/tests/auto/qml/qmltc/NamespaceTest/Subfolder/Type.qml new file mode 100644 index 0000000000..101e9f69a1 --- /dev/null +++ b/tests/auto/qml/qmltc/NamespaceTest/Subfolder/Type.qml @@ -0,0 +1,5 @@ +import QtQuick + +Item { + property string data +} diff --git a/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt b/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt index cfb1469a38..870d21f61d 100644 --- a/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt +++ b/tests/auto/qml/qmltc/QmltcTests/CMakeLists.txt @@ -180,7 +180,6 @@ qt6_add_qml_module(qmltc_test_module LIBRARIES qmltc_test_module_translation_by_id ENABLE_TYPE_COMPILER - TYPE_COMPILER_NAMESPACE QmltcTest ) qt_autogen_tools_initial_setup(qmltc_test_moduleplugin) diff --git a/tests/auto/qml/qmltc/tst_qmltc.cpp b/tests/auto/qml/qmltc/tst_qmltc.cpp index 4e65554e45..1fa4030642 100644 --- a/tests/auto/qml/qmltc/tst_qmltc.cpp +++ b/tests/auto/qml/qmltc/tst_qmltc.cpp @@ -82,6 +82,7 @@ #include "singletons.h" #include "mysignals.h" #include "namespacedtypes.h" +#include "type.h" // Qt: #include <QtCore/qstring.h> @@ -103,7 +104,7 @@ # error "QMLTC_TESTS_DISABLE_CACHE is supposed to be defined and be equal to either 0 or 1" #endif -#define PREPEND_NAMESPACE(name) ::QmltcTest::name // silent contract that the namespace is QmltcTest +#define PREPEND_NAMESPACE(name) QmltcTests::name // silent contract that the namespace is QmltcTest using namespace Qt::StringLiterals; @@ -1647,7 +1648,7 @@ void tst_qmltc::defaultAlias() QScopedPointer<QObject> fromEngine(c.create()); QVERIFY2(fromEngine, qPrintable(c.errorString())); - auto *child = static_cast<QmltcTest::defaultAlias_QtObject *>(created.child()); + auto *child = static_cast<PREPEND_NAMESPACE(defaultAlias_QtObject) *>(created.child()); QVERIFY(fromEngine->property("child").canConvert<QObject *>()); QObject *childFromEngine = fromEngine->property("child").value<QObject *>(); QVERIFY(childFromEngine); @@ -2653,23 +2654,23 @@ void tst_qmltc::appendToQQmlListProperty() } // test classes to access protected member typecount -class myInlineComponentA : public QmltcTest::inlineComponents_A +class myInlineComponentA : public PREPEND_NAMESPACE(inlineComponents_A) { friend class tst_qmltc; }; -class myInlineComponentB : public QmltcTest::inlineComponents_B +class myInlineComponentB : public PREPEND_NAMESPACE(inlineComponents_B) { friend class tst_qmltc; }; -class myInlineComponentMyComponent : public QmltcTest::inlineComponents_MyComponent +class myInlineComponentMyComponent : public PREPEND_NAMESPACE(inlineComponents_MyComponent) { friend class tst_qmltc; }; -class myInlineComponentAPlus : public QmltcTest::inlineComponents_APlus +class myInlineComponentAPlus : public PREPEND_NAMESPACE(inlineComponents_APlus) { friend class tst_qmltc; }; -class myInlineComponentAPlusPlus : public QmltcTest::inlineComponents_APlusPlus +class myInlineComponentAPlusPlus : public PREPEND_NAMESPACE(inlineComponents_APlusPlus) { friend class tst_qmltc; }; @@ -2730,10 +2731,10 @@ void tst_qmltc::inlineComponents() // test if nonrecursive components behave well { - auto *myMyComponentFromQmltc = (QmltcTest::inlineComponents_MyComponent_3 *) - createdByQmltc.myMyComponentComponent(); - auto *myMyComponentFromQmltc2 = (QmltcTest::inlineComponents_MyComponent_4 *) - createdByQmltc.myMyComponentComponent2(); + auto *myMyComponentFromQmltc = (PREPEND_NAMESPACE( + inlineComponents_MyComponent_3) *)createdByQmltc.myMyComponentComponent(); + auto *myMyComponentFromQmltc2 = (PREPEND_NAMESPACE( + inlineComponents_MyComponent_4) *)createdByQmltc.myMyComponentComponent2(); QVERIFY(myMyComponentFromQmltc); QVERIFY(myMyComponentFromQmltc2); auto *myMyComponentFromComponent = @@ -2795,10 +2796,12 @@ void tst_qmltc::inlineComponents() QCOMPARE(myMyComponentFromQmltc->children().size(), 1); QCOMPARE(myMyComponentFromQmltc2->children().size(), 1); auto *childFromQmltc = - (QmltcTest::inlineComponents_MyComponent_Item *)myMyComponentFromQmltc->children() + (PREPEND_NAMESPACE(inlineComponents_MyComponent_Item) *)myMyComponentFromQmltc + ->children() .front(); auto *childFromQmltc2 = - (QmltcTest::inlineComponents_MyComponent_Item *)myMyComponentFromQmltc2->children() + (PREPEND_NAMESPACE(inlineComponents_MyComponent_Item) *)myMyComponentFromQmltc2 + ->children() .front(); QVERIFY(childFromQmltc); @@ -2855,15 +2858,18 @@ void tst_qmltc::inlineComponents() // test if recursive components are behaving well { - auto *myAFromQmltc = (QmltcTest::inlineComponents_A_1 *)createdByQmltc.myAComponent(); - auto *innerBFromQmltc = (QmltcTest::inlineComponents_A_B *)myAFromQmltc->b(); + auto *myAFromQmltc = + (PREPEND_NAMESPACE(inlineComponents_A_1) *)createdByQmltc.myAComponent(); + auto *innerBFromQmltc = (PREPEND_NAMESPACE(inlineComponents_A_B) *)myAFromQmltc->b(); QVERIFY(innerBFromQmltc); - auto *innerAFromQmltc = (QmltcTest::inlineComponents_A_B_A *)innerBFromQmltc->a(); + auto *innerAFromQmltc = (PREPEND_NAMESPACE(inlineComponents_A_B_A) *)innerBFromQmltc->a(); QVERIFY(innerAFromQmltc); constexpr bool typeNotCompiledAsQQmlComponent = - std::is_same_v<decltype(myAFromQmltc->b()), QmltcTest::inlineComponents_B *>; + std::is_same_v<decltype(myAFromQmltc->b()), + PREPEND_NAMESPACE(inlineComponents_B) *>; constexpr bool typeNotCompiledAsQQmlComponent2 = - std::is_same_v<decltype(innerBFromQmltc->a()), QmltcTest::inlineComponents_A *>; + std::is_same_v<decltype(innerBFromQmltc->a()), + PREPEND_NAMESPACE(inlineComponents_A) *>; QVERIFY(typeNotCompiledAsQQmlComponent); QVERIFY(typeNotCompiledAsQQmlComponent2); @@ -2880,10 +2886,11 @@ void tst_qmltc::inlineComponents() // test if ids in inlineComponents are not getting mixed up with those from the root component { auto *conflictingComponentTomFromQmltc = - createdByQmltc.tom().value<QmltcTest::inlineComponents_ConflictingComponent_1 *>(); + createdByQmltc.tom() + .value<PREPEND_NAMESPACE(inlineComponents_ConflictingComponent_1) *>(); auto *conflictingComponentJerryFromQmltc = createdByQmltc.jerry() - .value<QmltcTest::inlineComponents_ConflictingComponent_2 *>(); + .value<PREPEND_NAMESPACE(inlineComponents_ConflictingComponent_2) *>(); auto *conflictingComponentTomFromComponent = createdByComponent->property("tom").value<QObject *>(); @@ -2941,8 +2948,8 @@ void tst_qmltc::inlineComponents() // check that inline components are resolved in the correct order { - auto componentFromQmltc = - createdByQmltc.inlineComponentOrder().value<QmltcTest::inlineComponents_IC2_1 *>(); + auto componentFromQmltc = createdByQmltc.inlineComponentOrder() + .value<PREPEND_NAMESPACE(inlineComponents_IC2_1) *>(); auto componentFromComponent = createdByComponent->property("inlineComponentOrder").value<QObject *>(); @@ -3193,4 +3200,12 @@ void tst_qmltc::cppNamespaces() QCOMPARE(createdByQmltc.myObject()->property("value"), 55); } +void tst_qmltc::namespacedName() +{ + // cmake script should be able to auto-fill the namespace of the generated modules, and to + // replace . with :: + NamespaceTest::Subfolder::Type *t; + Q_UNUSED(t); +} + QTEST_MAIN(tst_qmltc) diff --git a/tests/auto/qml/qmltc/tst_qmltc.h b/tests/auto/qml/qmltc/tst_qmltc.h index a2d656bae7..af084dcc01 100644 --- a/tests/auto/qml/qmltc/tst_qmltc.h +++ b/tests/auto/qml/qmltc/tst_qmltc.h @@ -92,4 +92,5 @@ private slots: void singletons(); void constSignalParameters(); void cppNamespaces(); + void namespacedName(); }; diff --git a/tools/qmltc/qmltccodewriter.cpp b/tools/qmltc/qmltccodewriter.cpp index c4c5c30f83..8010f1066c 100644 --- a/tools/qmltc/qmltccodewriter.cpp +++ b/tools/qmltc/qmltccodewriter.cpp @@ -149,24 +149,28 @@ void QmltcCodeWriter::writeGlobalHeader(QmltcOutputWrapper &code, const QString code.rawAppendToCpp(u""); // blank line code.rawAppendToCpp(u"QT_USE_NAMESPACE // avoid issues with QT_NAMESPACE"); - if (!outNamespace.isEmpty()) { - code.rawAppendToHeader(u""); // blank line - code.rawAppendToHeader(u"namespace %1 {"_s.arg(outNamespace)); - code.rawAppendToCpp(u""); // blank line - code.rawAppendToCpp(u"namespace %1 {"_s.arg(outNamespace)); + + code.rawAppendToHeader(u""); // blank line + + const QStringList namespaces = outNamespace.split(u"::"_s); + + for (const QString ¤tNamespace : namespaces) { + code.rawAppendToHeader(u"namespace %1 {"_s.arg(currentNamespace)); + code.rawAppendToCpp(u"namespace %1 {"_s.arg(currentNamespace)); } } void QmltcCodeWriter::writeGlobalFooter(QmltcOutputWrapper &code, const QString &sourcePath, const QString &outNamespace) { - if (!outNamespace.isEmpty()) { - code.rawAppendToCpp(u"} // namespace %1"_s.arg(outNamespace)); - code.rawAppendToCpp(u""); // blank line - code.rawAppendToHeader(u"} // namespace %1"_s.arg(outNamespace)); - code.rawAppendToHeader(u""); // blank line + const QStringList namespaces = outNamespace.split(u"::"_s); + + for (auto it = namespaces.crbegin(), end = namespaces.crend(); it != end; it++) { + code.rawAppendToCpp(u"} // namespace %1"_s.arg(*it)); + code.rawAppendToHeader(u"} // namespace %1"_s.arg(*it)); } + code.rawAppendToHeader(u""); // blank line code.rawAppendToHeader(u"#endif // %1_H"_s.arg(urlToMacro(sourcePath))); code.rawAppendToHeader(u""); // blank line } |