From d1b89671de70ac9ffca52337058e976d86a367c1 Mon Sep 17 00:00:00 2001 From: Volker Hilsheimer Date: Fri, 21 Jun 2024 21:51:00 +0200 Subject: [PATCH] JNI: don't declare namespaces nested into QtJniTypes as inline Sadly, inline namespaces are resulting in ambiguities. With two declarations QtJniTypes::android::io::File and QtJniTypes::org::qtproject::qt::android::QtWindow referring to QtJniTypes::android already is ambiguous if `org`, `qtproject`, and `qt` namespaces are all inline. This breaks the idea behind Q_DECLARE_JNI_CLASS as a variadic macro that generates types that we can transparently use as QtJniTypes. So remove the inline keyword from the namespace declarations. The macro might still be the way to go, but user code will to either fully qualify the types, or use `using namespace QtJniTypes::java::lang` to use e.g. the `String` type without ambiguities. Types declared with the two-argument overload continue to live directly in the QtJniTypes namespace anyway. As a drive-by, break the excessively long lines. Pick-to: 6.8 Change-Id: Ie9303e6c9117fb96b3cff31c7df4df92237b5520 Reviewed-by: Assam Boudjelthia --- src/corelib/kernel/qjnitypes.h | 39 +++++++++++-------- .../kernel/qjnitypes/tst_qjnitypes.cpp | 13 +++---- 2 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/corelib/kernel/qjnitypes.h b/src/corelib/kernel/qjnitypes.h index 682a91534cc..4556dfa0a9a 100644 --- a/src/corelib/kernel/qjnitypes.h +++ b/src/corelib/kernel/qjnitypes.h @@ -53,62 +53,69 @@ struct QtJniTypes::Traits { \ }; \ #define Q_DECLARE_JNI_CLASS_3(NS0, NS1, Type) \ -inline namespace NS0 { \ -inline namespace NS1 { \ +namespace NS0 { \ +namespace NS1 { \ Q_DECLARE_JNI_CLASS_2(Type, Q_UNUSED(0)) \ } \ } \ -#define Q_DECLARE_JNI_CLASS_SPECIALIZATION_3(NS0, NS1, Type) \ - Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::Type, #NS0 "/" #NS1 "/" #Type) +#define Q_DECLARE_JNI_CLASS_SPECIALIZATION_3(NS0, NS1, Type) \ + Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::Type, \ + #NS0 "/" #NS1 "/" #Type) #define Q_DECLARE_JNI_CLASS_4(NS0, NS1, NS2, Type) \ -inline namespace NS0 { \ +namespace NS0 { \ Q_DECLARE_JNI_CLASS_3(NS1, NS2, Type) \ } \ #define Q_DECLARE_JNI_CLASS_SPECIALIZATION_4(NS0, NS1, NS2, Type) \ - Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::Type, #NS0 "/" #NS1 "/" #NS2 "/" #Type) + Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::Type, \ + #NS0 "/" #NS1 "/" #NS2 "/" #Type) #define Q_DECLARE_JNI_CLASS_5(NS0, NS1, NS2, NS3, Type) \ -inline namespace NS0 { \ +namespace NS0 { \ Q_DECLARE_JNI_CLASS_4(NS1, NS2, NS3, Type) \ } \ #define Q_DECLARE_JNI_CLASS_SPECIALIZATION_5(NS0, NS1, NS2, NS3, Type) \ - Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::Type, #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #Type) + Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::Type, \ + #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #Type) #define Q_DECLARE_JNI_CLASS_6(NS0, NS1, NS2, NS3, NS4, Type) \ -inline namespace NS0 { \ +namespace NS0 { \ Q_DECLARE_JNI_CLASS_5(NS1, NS2, NS3, NS4, Type) \ } \ #define Q_DECLARE_JNI_CLASS_SPECIALIZATION_6(NS0, NS1, NS2, NS3, NS4, Type) \ - Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::NS4::Type, #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #NS4 "/" #Type) + Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::NS4::Type, \ + #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #NS4 "/" #Type) #define Q_DECLARE_JNI_CLASS_7(NS0, NS1, NS2, NS3, NS4, NS5, Type) \ -inline namespace NS0 { \ +namespace NS0 { \ Q_DECLARE_JNI_CLASS_6(NS1, NS2, NS3, NS4, NS5, Type) \ } \ #define Q_DECLARE_JNI_CLASS_SPECIALIZATION_7(NS0, NS1, NS2, NS3, NS4, NS5, Type) \ - Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::NS4::NS5::Type, #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #NS4 "/" #NS5 "/" #Type) + Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::NS4::NS5::Type, \ + #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #NS4 "/" #NS5 "/" #Type) #define Q_DECLARE_JNI_CLASS_8(NS0, NS1, NS2, NS3, NS4, NS5, NS6, Type) \ -inline namespace NS0 { \ +namespace NS0 { \ Q_DECLARE_JNI_CLASS_7(NS1, NS2, NS3, NS4, NS5, NS6, Type) \ } \ #define Q_DECLARE_JNI_CLASS_SPECIALIZATION_8(NS0, NS1, NS2, NS3, NS4, NS5, NS6, Type) \ - Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::NS4::NS5::NS6::Type, #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #NS4 "/" #NS5 "/" #NS6 "/" #Type) + Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::NS4::NS5::NS6::Type, \ + #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #NS4 "/" #NS5 "/" #NS6 "/" #Type) #define Q_DECLARE_JNI_CLASS_9(NS0, NS1, NS2, NS3, NS4, NS5, NS6, NS7, Type) \ -inline namespace NS0 { \ +namespace NS0 { \ Q_DECLARE_JNI_CLASS_8(NS1, NS2, NS3, NS4, NS5, NS6, NS7, Type) \ } \ #define Q_DECLARE_JNI_CLASS_SPECIALIZATION_9(NS0, NS1, NS2, NS3, NS4, NS5, NS6, NS7, Type) \ - Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::NS4::NS5::NS6::NS7::Type, #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #NS4 "/" #NS5 "/" #NS6 "/" #NS7 "/" #Type) + Q_DECLARE_JNI_CLASS_SPECIALIZATION_2(NS0::NS1::NS2::NS3::NS4::NS5::NS6::NS7::Type, \ + #NS0 "/" #NS1 "/" #NS2 "/" #NS3 "/" #NS4 "/" #NS5 "/" #NS6 "/" #NS7 "/" #Type) #define Q_DECLARE_JNI_CLASS(...) \ namespace QtJniTypes { \ diff --git a/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp index cb9c7022b1d..db0700ef2fb 100644 --- a/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp +++ b/tests/auto/corelib/kernel/qjnitypes/tst_qjnitypes.cpp @@ -73,16 +73,13 @@ static_assert(QtJniTypes::Traits::className() == "or // declaring two types Size in different packages Q_DECLARE_JNI_CLASS(android, util, Size) -// inline namespaces, so this works -static_assert(QtJniTypes::Traits::className() == "android/util/Size"); +Q_DECLARE_JNI_CLASS(org, qtproject, android, Size) -Q_DECLARE_JNI_CLASS(org, qtproject, Size) -// this would now be ambiguous -// static_assert(QtJniTypes::Traits::className() == "android/util/Size"); - -// but client code can be explicit static_assert(QtJniTypes::Traits::className() == "android/util/Size"); -static_assert(QtJniTypes::Traits::className() == "org/qtproject/Size"); +static_assert(QtJniTypes::Traits::className() == "org/qtproject/android/Size"); + +using namespace QtJniTypes::org::qtproject; +static_assert(QtJniTypes::Traits::className() == "org/qtproject/android/Size"); static_assert(QtJniTypes::fieldSignature() == "I"); static_assert(QtJniTypes::fieldSignature() == "[I");