i_slint_compiler/passes/
inject_debug_hooks.rs1use crate::{expression_tree, object_tree, typeloader};
7
8pub fn inject_debug_hooks(doc: &object_tree::Document, type_loader: &typeloader::TypeLoader) {
9 let Some(random_state) = &type_loader.compiler_config.debug_hooks else {
10 return;
11 };
12
13 doc.visit_all_used_components(|component| {
14 object_tree::recurse_elem_including_sub_components(component, &(), &mut |e, &()| {
15 process_element(e, random_state);
16 })
17 });
18}
19
20fn property_id(element_id: u64, name: &smol_str::SmolStr) -> smol_str::SmolStr {
21 smol_str::format_smolstr!("?{element_id}-{name}")
22}
23
24fn calculate_element_hash(
25 elem: &object_tree::Element,
26 random_state: &std::hash::RandomState,
27) -> u64 {
28 let node = &elem.debug.first().expect("There was one element a moment ago").node;
29
30 let elem_path = node.source_file.path();
31 let elem_offset = node
32 .child_token(crate::parser::SyntaxKind::LBrace)
33 .expect("All elements have a opening Brace")
34 .text_range()
35 .start();
36
37 use std::hash::{BuildHasher, Hasher};
38 let mut hasher = random_state.build_hasher();
39 hasher.write(elem_path.as_os_str().as_encoded_bytes());
40 hasher.write_u32(elem_offset.into());
41 hasher.finish()
42}
43
44fn process_element(element: &object_tree::ElementRc, random_state: &std::hash::RandomState) {
45 let mut elem = element.borrow_mut();
46 assert_eq!(elem.debug.len(), 1);
48
49 if elem.debug.first().expect("There was one element a moment ago").element_hash != 0 {
51 return;
52 }
53
54 let element_hash = calculate_element_hash(&elem, random_state);
55
56 elem.bindings.iter().for_each(|(name, be)| {
57 let expr = std::mem::take(&mut be.borrow_mut().expression);
58 be.borrow_mut().expression = {
59 let stripped = super::ignore_debug_hooks(&expr);
60 if matches!(stripped, expression_tree::Expression::Invalid) {
61 stripped.clone()
62 } else {
63 expression_tree::Expression::DebugHook {
64 expression: Box::new(expr),
65 id: property_id(element_hash, name),
66 }
67 }
68 };
69 });
70
71 elem.debug.first_mut().expect("There was one element a moment ago").element_hash = element_hash;
72}