Skip to content

Commit 74beaa7

Browse files
LeonMatthesKDABahayzen-kdab
authored andcommitted
Remove the full qualification prefix ::
This is conflicting with Qt5s Meta Object system. E.g.: In Qt5 only `QPoint` is a valid type for a Q_PROPERTY, `::QPoint` is not!
1 parent a825c29 commit 74beaa7

20 files changed

+391
-375
lines changed

crates/cxx-qt-gen/src/generator/cpp/method.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -411,15 +411,12 @@ mod tests {
411411
} else {
412412
panic!("Expected pair")
413413
};
414-
assert_str_eq!(
415-
header,
416-
"Q_INVOKABLE ::B2 trivialInvokable(::A1 param) const;"
417-
);
414+
assert_str_eq!(header, "Q_INVOKABLE B2 trivialInvokable(A1 param) const;");
418415
assert_str_eq!(
419416
source,
420417
indoc! {r#"
421-
::B2
422-
MyObject::trivialInvokable(::A1 param) const
418+
B2
419+
MyObject::trivialInvokable(A1 param) const
423420
{
424421
const ::rust::cxxqt1::MaybeLockGuard<MyObject> guard(*this);
425422
return trivialInvokableWrapper(param);
@@ -437,7 +434,7 @@ mod tests {
437434
};
438435
assert_str_eq!(
439436
header,
440-
"::B2 trivialInvokableWrapper(::A1 param) const noexcept;"
437+
"B2 trivialInvokableWrapper(A1 param) const noexcept;"
441438
);
442439
}
443440
}

crates/cxx-qt-gen/src/generator/cpp/signal.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -639,10 +639,10 @@ mod tests {
639639
header,
640640
indoc! {
641641
r#"
642-
namespace rust::cxxqtgen1::mynamespace {
642+
namespace mynamespace::rust::cxxqtgen1 {
643643
::QMetaObject::Connection
644-
ObjRust_signalCxxNameConnect(::mynamespace::ObjCpp& self, ::rust::cxxqtgen1::mynamespace::ObjRustCxxQtSignalHandlersignalCxxName closure, ::Qt::ConnectionType type);
645-
} // namespace rust::cxxqtgen1::mynamespace
644+
ObjRust_signalCxxNameConnect(mynamespace::ObjCpp& self, ::mynamespace::rust::cxxqtgen1::ObjRustCxxQtSignalHandlersignalCxxName closure, ::Qt::ConnectionType type);
645+
} // namespace mynamespace::rust::cxxqtgen1
646646
"#}
647647
);
648648
assert_str_eq!(
@@ -652,7 +652,7 @@ mod tests {
652652
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56480
653653
namespace rust::cxxqt1 {
654654
template <>
655-
SignalHandler<::rust::cxxqtgen1::mynamespace::ObjRustCxxQtSignalParamssignalCxxName *>::~SignalHandler() noexcept
655+
SignalHandler<::mynamespace::rust::cxxqtgen1::ObjRustCxxQtSignalParamssignalCxxName *>::~SignalHandler() noexcept
656656
{
657657
if (data[0] == nullptr && data[1] == nullptr)
658658
{
@@ -664,30 +664,30 @@ mod tests {
664664
665665
template <>
666666
template <>
667-
void SignalHandler<::rust::cxxqtgen1::mynamespace::ObjRustCxxQtSignalParamssignalCxxName *>::operator()<::mynamespace::ObjCpp&>(::mynamespace::ObjCpp& self)
667+
void SignalHandler<::mynamespace::rust::cxxqtgen1::ObjRustCxxQtSignalParamssignalCxxName *>::operator()<mynamespace::ObjCpp&>(mynamespace::ObjCpp& self)
668668
{
669669
call_ObjRust_signal_handler_signalCxxName(*this, self);
670670
}
671671
672-
static_assert(alignof(SignalHandler<::rust::cxxqtgen1::mynamespace::ObjRustCxxQtSignalParamssignalCxxName *>) <= alignof(::std::size_t), "unexpected aligment");
673-
static_assert(sizeof(SignalHandler<::rust::cxxqtgen1::mynamespace::ObjRustCxxQtSignalParamssignalCxxName *>) == sizeof(::std::size_t[2]), "unexpected size");
672+
static_assert(alignof(SignalHandler<::mynamespace::rust::cxxqtgen1::ObjRustCxxQtSignalParamssignalCxxName *>) <= alignof(::std::size_t), "unexpected aligment");
673+
static_assert(sizeof(SignalHandler<::mynamespace::rust::cxxqtgen1::ObjRustCxxQtSignalParamssignalCxxName *>) == sizeof(::std::size_t[2]), "unexpected size");
674674
} // namespace rust::cxxqt1
675675
676-
namespace rust::cxxqtgen1::mynamespace {
676+
namespace mynamespace::rust::cxxqtgen1 {
677677
::QMetaObject::Connection
678-
ObjRust_signalCxxNameConnect(::mynamespace::ObjCpp& self, ::rust::cxxqtgen1::mynamespace::ObjRustCxxQtSignalHandlersignalCxxName closure, ::Qt::ConnectionType type)
678+
ObjRust_signalCxxNameConnect(mynamespace::ObjCpp& self, ::mynamespace::rust::cxxqtgen1::ObjRustCxxQtSignalHandlersignalCxxName closure, ::Qt::ConnectionType type)
679679
{
680680
return ::QObject::connect(
681681
&self,
682-
&::mynamespace::ObjCpp::signalCxxName,
682+
&mynamespace::ObjCpp::signalCxxName,
683683
&self,
684684
[&, closure = ::std::move(closure)]() mutable {
685-
const ::rust::cxxqt1::MaybeLockGuard<::mynamespace::ObjCpp> guard(self);
686-
closure.template operator()<::mynamespace::ObjCpp&>(self);
685+
const ::rust::cxxqt1::MaybeLockGuard<mynamespace::ObjCpp> guard(self);
686+
closure.template operator()<mynamespace::ObjCpp&>(self);
687687
},
688688
type);
689689
}
690-
} // namespace rust::cxxqtgen1::mynamespace
690+
} // namespace mynamespace::rust::cxxqtgen1
691691
"#}
692692
);
693693
}

crates/cxx-qt-gen/src/generator/naming/signals.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,22 @@ impl QSignalHelperName {
5656
let signal_ident = &idents.name.cpp;
5757
let handler_alias = format_ident!("{qobject_ident}CxxQtSignalHandler{signal_ident}");
5858
let namespace = {
59-
let mut namespace = vec!["rust::cxxqtgen1".to_owned()];
60-
if let Some(qobject_namespace) = type_names.namespace(qobject_ident) {
61-
namespace.push(qobject_namespace);
62-
}
59+
// This namespace will take the form of:
60+
// qobject_namespace::rust::cxxqtgen1
61+
//
62+
// We experimented with using rust::cxxqtgen1::qobject_namespace.
63+
// However, this currently doesn't work, as we can't fully-qualify all C++ access.
64+
// Therefore when refering to the QObject type (e.g. qobject_namespace::QObject),
65+
// It would fail, as it would look up in this helper namespace, instead of the actual
66+
// qobject_namespace.
67+
//
68+
// See the comment on TypeNames::cxx_qualified for why fully qualifying is
69+
// unfortunately not possible.
70+
let qobject_namespace = type_names.namespace(qobject_ident);
71+
let namespace: Vec<_> = qobject_namespace
72+
.into_iter()
73+
.chain(vec!["rust::cxxqtgen1".to_owned()])
74+
.collect();
6375

6476
namespace.join("::")
6577
};

crates/cxx-qt-gen/src/naming/cpp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,15 +373,15 @@ mod tests {
373373
let ty = parse_quote! { A };
374374
let mut type_names = TypeNames::default();
375375
type_names.insert("A", None, Some("A1"), None);
376-
assert_eq!(syn_type_to_cpp_type(&ty, &type_names).unwrap(), "::A1");
376+
assert_eq!(syn_type_to_cpp_type(&ty, &type_names).unwrap(), "A1");
377377
}
378378

379379
#[test]
380380
fn test_syn_type_to_cpp_type_mapped_with_namespace() {
381381
let ty = parse_quote! { A };
382382
let mut type_names = TypeNames::default();
383383
type_names.insert("A", None, Some("A1"), Some("N1"));
384-
assert_eq!(syn_type_to_cpp_type(&ty, &type_names).unwrap(), "::N1::A1");
384+
assert_eq!(syn_type_to_cpp_type(&ty, &type_names).unwrap(), "N1::A1");
385385
}
386386

387387
#[test]

crates/cxx-qt-gen/src/naming/type_names.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,15 @@ impl TypeNames {
178178
}
179179

180180
/// For a given rust ident return the CXX name with its namespace
181+
///
182+
/// Ideally we'd want this type name to always be **fully** qualified, staring with `::`.
183+
/// Unfortunately, this isn't always possible, as the Qt5 meta object system doesn't register
184+
/// types with the fully qualified path :(
185+
/// E.g. it will recognize `QString`, but not `::QString` from QML.
186+
///
187+
/// This needs to be considered in many places (properties, signals, invokables, etc.)
188+
/// Therefore, for now we'll use the qualified, but not fully qualified version of `namespace::type`.
189+
/// This should work in most cases, but it's not perfect.
181190
pub fn cxx_qualified(&self, ident: &Ident) -> String {
182191
// Check if there is a cxx_name or namespace to handle
183192
let name = self.names.get(ident);
@@ -190,9 +199,9 @@ impl TypeNames {
190199
let cxx_name = name.cxx.clone().unwrap_or_else(|| name.rust.to_string());
191200

192201
if let Some(namespace) = &name.namespace {
193-
format!("::{namespace}::{cxx_name}")
202+
format!("{namespace}::{cxx_name}")
194203
} else {
195-
format!("::{cxx_name}")
204+
cxx_name
196205
}
197206
}
198207

@@ -284,7 +293,7 @@ mod tests {
284293

285294
assert_eq!(types.num_types(), 1);
286295
assert_eq!(types.rust_qualified(&ident), parse_quote! { ffi::A });
287-
assert_eq!(types.cxx_qualified(&ident), "::A");
296+
assert_eq!(types.cxx_qualified(&ident), "A");
288297
assert!(types.namespace(&ident).is_none());
289298
}
290299

@@ -302,7 +311,7 @@ mod tests {
302311
.is_ok());
303312

304313
assert_eq!(types.num_types(), 1);
305-
assert_eq!(types.cxx_qualified(&ident), "::B");
314+
assert_eq!(types.cxx_qualified(&ident), "B");
306315
assert!(types.namespace(&ident).is_none());
307316
assert_eq!(types.rust_qualified(&ident), parse_quote! { ffi::A });
308317
}
@@ -354,7 +363,7 @@ mod tests {
354363
.populate(&ident, &[], Some("bridge_namespace"), &format_ident!("ffi"))
355364
.is_ok());
356365

357-
assert_eq!(types.cxx_qualified(&ident), "::bridge_namespace::A");
366+
assert_eq!(types.cxx_qualified(&ident), "bridge_namespace::A");
358367
assert_eq!(types.namespace(&ident).unwrap(), "bridge_namespace");
359368
assert_eq!(types.num_types(), 1);
360369
assert_eq!(
@@ -397,7 +406,7 @@ mod tests {
397406
let type_names = parse_cxx_item(item);
398407
let ident = format_ident!("A");
399408
assert_eq!(type_names.num_types(), 1);
400-
assert_eq!(type_names.cxx_qualified(&ident), "::B");
409+
assert_eq!(type_names.cxx_qualified(&ident), "B");
401410

402411
assert_eq!(type_names.rust_qualified(&ident), parse_quote! { ffi::A });
403412
}
@@ -431,15 +440,15 @@ mod tests {
431440

432441
assert_eq!(
433442
&types.cxx_qualified(&format_ident!("A")),
434-
"::type_namespace::B"
443+
"type_namespace::B"
435444
);
436445
assert_eq!(
437446
&types.cxx_qualified(&format_ident!("C")),
438-
"::extern_namespace::D"
447+
"extern_namespace::D"
439448
);
440449
assert_eq!(
441450
&types.cxx_qualified(&format_ident!("E")),
442-
"::bridge_namespace::E"
451+
"bridge_namespace::E"
443452
);
444453

445454
assert_eq!(
@@ -485,7 +494,7 @@ mod tests {
485494
assert_eq!(type_names.num_types(), 1);
486495
assert_eq!(type_names.cxx_unqualified(&ident).unwrap(), "EnumB");
487496
assert_eq!(type_names.namespace(&ident).unwrap(), "enum_namespace");
488-
assert_eq!(type_names.cxx_qualified(&ident), "::enum_namespace::EnumB");
497+
assert_eq!(type_names.cxx_qualified(&ident), "enum_namespace::EnumB");
489498
assert_eq!(
490499
type_names.rust_qualified(&ident),
491500
parse_quote! { ffi::EnumA }
@@ -507,7 +516,7 @@ mod tests {
507516

508517
assert_eq!(types.num_types(), 1);
509518
assert_eq!(types.cxx_unqualified(&ident).unwrap(), "StructB");
510-
assert_eq!(types.cxx_qualified(&ident), "::struct_namespace::StructB");
519+
assert_eq!(types.cxx_qualified(&ident), "struct_namespace::StructB");
511520
assert_eq!(types.namespace(&ident).unwrap(), "struct_namespace");
512521
assert_eq!(types.rust_qualified(&ident), parse_quote! { ffi::StructA });
513522
}

crates/cxx-qt-gen/test_outputs/inheritance.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#include "cxx-qt-gen/inheritance.cxxqt.h"
22

3-
::QVariant
4-
MyObject::data(::QModelIndex const& _index, ::std::int32_t _role) const
3+
QVariant
4+
MyObject::data(QModelIndex const& _index, ::std::int32_t _role) const
55
{
66
const ::rust::cxxqt1::MaybeLockGuard<MyObject> guard(*this);
77
return dataWrapper(_index, _role);
88
}
99

1010
bool
11-
MyObject::hasChildren(::QModelIndex const& _parent) const
11+
MyObject::hasChildren(QModelIndex const& _parent) const
1212
{
1313
const ::rust::cxxqt1::MaybeLockGuard<MyObject> guard(*this);
1414
return hasChildrenWrapper(_parent);

crates/cxx-qt-gen/test_outputs/inheritance.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class MyObject
1818
virtual ~MyObject() = default;
1919

2020
public:
21-
Q_INVOKABLE ::QVariant data(::QModelIndex const& _index,
22-
::std::int32_t _role) const override;
23-
Q_INVOKABLE bool hasChildren(::QModelIndex const& _parent) const override;
21+
Q_INVOKABLE QVariant data(QModelIndex const& _index,
22+
::std::int32_t _role) const override;
23+
Q_INVOKABLE bool hasChildren(QModelIndex const& _parent) const override;
2424
template<class... Args>
2525
bool hasChildrenCxxQtInherit(Args... args) const
2626
{
@@ -34,9 +34,9 @@ class MyObject
3434
explicit MyObject(QObject* parent = nullptr);
3535

3636
private:
37-
::QVariant dataWrapper(::QModelIndex const& _index,
38-
::std::int32_t _role) const noexcept;
39-
bool hasChildrenWrapper(::QModelIndex const& _parent) const noexcept;
37+
QVariant dataWrapper(QModelIndex const& _index,
38+
::std::int32_t _role) const noexcept;
39+
bool hasChildrenWrapper(QModelIndex const& _parent) const noexcept;
4040
};
4141

4242
static_assert(::std::is_base_of<QObject, MyObject>::value,

crates/cxx-qt-gen/test_outputs/invokables.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@ MyObject::invokableMutable()
2323
}
2424

2525
void
26-
MyObject::invokableParameters(::QColor const& opaque,
27-
::QPoint const& trivial,
26+
MyObject::invokableParameters(QColor const& opaque,
27+
QPoint const& trivial,
2828
::std::int32_t primitive) const
2929
{
3030
const ::rust::cxxqt1::MaybeLockGuard<MyObject> guard(*this);
@@ -38,7 +38,7 @@ MyObject::invokableReturnOpaque()
3838
return invokableReturnOpaqueWrapper();
3939
}
4040

41-
::QPoint
41+
QPoint
4242
MyObject::invokableReturnTrivial()
4343
{
4444
const ::rust::cxxqt1::MaybeLockGuard<MyObject> guard(*this);

crates/cxx-qt-gen/test_outputs/invokables.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ class MyObject
2626
void cppMethod() const;
2727
Q_INVOKABLE void invokable() const;
2828
Q_INVOKABLE void invokableMutable();
29-
Q_INVOKABLE void invokableParameters(::QColor const& opaque,
30-
::QPoint const& trivial,
29+
Q_INVOKABLE void invokableParameters(QColor const& opaque,
30+
QPoint const& trivial,
3131
::std::int32_t primitive) const;
3232
Q_INVOKABLE ::std::unique_ptr<Opaque> invokableReturnOpaque();
33-
Q_INVOKABLE ::QPoint invokableReturnTrivial();
33+
Q_INVOKABLE QPoint invokableReturnTrivial();
3434
Q_INVOKABLE void invokableFinal() const final;
3535
Q_INVOKABLE void invokableOverride() const override;
3636
Q_INVOKABLE virtual void invokableVirtual() const;
@@ -43,11 +43,11 @@ class MyObject
4343
void cppMethodWrapper() const noexcept;
4444
void invokableWrapper() const noexcept;
4545
void invokableMutableWrapper() noexcept;
46-
void invokableParametersWrapper(::QColor const& opaque,
47-
::QPoint const& trivial,
46+
void invokableParametersWrapper(QColor const& opaque,
47+
QPoint const& trivial,
4848
::std::int32_t primitive) const noexcept;
4949
::std::unique_ptr<Opaque> invokableReturnOpaqueWrapper() noexcept;
50-
::QPoint invokableReturnTrivialWrapper() noexcept;
50+
QPoint invokableReturnTrivialWrapper() noexcept;
5151
void invokableFinalWrapper() const noexcept;
5252
void invokableOverrideWrapper() const noexcept;
5353
void invokableVirtualWrapper() const noexcept;

0 commit comments

Comments
 (0)