Compiler: Fix changed callback on private global properties

The code would fail to compile because the property would not be seen as
used and would be removed, but not the change callback.

Fixes #8269

Also fix a segfault in the added test because it will initialize the
change callback (and therefore query the properties) because the
SharedGlobal structure is fully initialized.
So we must only initialize the change callback on global after the
SharedGlobal is fully initialized
This commit is contained in:
Olivier Goffart 2025-04-25 16:10:12 +02:00 committed by GitHub
parent a50b8f8793
commit ff2e2e6731
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 43 additions and 6 deletions

View file

@ -789,10 +789,14 @@ pub fn generate(
}),
));
let mut init_global = vec![];
for (idx, glob) in llr.globals.iter_enumerated() {
let name = format_smolstr!("global_{}", concatenate_ident(&glob.name));
let ty = if glob.is_builtin {
format_smolstr!("slint::cbindgen_private::{}", glob.name)
} else if glob.must_generate() {
init_global.push(format!("{name}->init();"));
generate_global(&mut file, &conditional_includes, idx, glob, &llr);
file.definitions.extend(glob.aliases.iter().map(|name| {
Declaration::TypeAlias(TypeAlias {
@ -809,12 +813,24 @@ pub fn generate(
Access::Public,
Declaration::Var(Var {
ty: format_smolstr!("std::shared_ptr<{}>", ty),
name: format_smolstr!("global_{}", concatenate_ident(&glob.name)),
name,
init: Some(format!("std::make_shared<{ty}>(this)")),
..Default::default()
}),
));
}
globals_struct.members.push((
Access::Public,
Declaration::Function(Function {
name: globals_struct.name.clone(),
is_constructor_or_destructor: true,
signature: "()".into(),
statements: Some(init_global),
..Default::default()
}),
));
file.declarations.push(Declaration::Struct(globals_struct));
if let Some(popup_menu) = &llr.popup_menu {
@ -2625,11 +2641,20 @@ fn generate_global(
name: ident(&global.name),
signature: "(const class SharedGlobals *globals)".into(),
is_constructor_or_destructor: true,
statements: Some(init),
statements: Some(vec![]),
constructor_member_initializers: vec!["globals(globals)".into()],
..Default::default()
}),
));
global_struct.members.push((
Access::Private,
Declaration::Function(Function {
name: ident("init"),
signature: "() -> void".into(),
statements: Some(init),
..Default::default()
}),
));
global_struct.members.push((
Access::Private,
Declaration::Var(Var {
@ -2638,6 +2663,7 @@ fn generate_global(
..Default::default()
}),
));
global_struct.friends.push(SmolStr::new_static("SharedGlobals"));
generate_public_api_for_properties(
&mut global_struct.members,