Skip to content

Commit 9942afd

Browse files
committed
SQUASH: Rework the element id to be a hash based on filename
and position iof the LBrace token.
1 parent aaeb4a0 commit 9942afd

File tree

7 files changed

+63
-46
lines changed

7 files changed

+63
-46
lines changed

internal/compiler/expression_tree.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1423,7 +1423,7 @@ impl Expression {
14231423
pub fn ignore_debug_hooks(&self) -> &Expression {
14241424
match self {
14251425
Expression::DebugHook { expression, .. } => expression.as_ref(),
1426-
_ => return self,
1426+
_ => self,
14271427
}
14281428
}
14291429
}

internal/compiler/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ pub struct CompilerConfiguration {
149149
pub debug_info: bool,
150150

151151
/// Generate debug hooks to inspect/override properties.
152-
pub debug_hooks: bool,
152+
pub debug_hooks: Option<std::hash::RandomState>,
153153

154154
pub components_to_generate: ComponentSelection,
155155

@@ -229,7 +229,7 @@ impl CompilerConfiguration {
229229
translation_domain: None,
230230
cpp_namespace,
231231
debug_info,
232-
debug_hooks: false,
232+
debug_hooks: None,
233233
components_to_generate: ComponentSelection::ExportedWindows,
234234
#[cfg(feature = "software-renderer")]
235235
font_cache: Default::default(),

internal/compiler/object_tree.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -641,9 +641,11 @@ pub struct ElementDebugInfo {
641641
// The id qualified with the enclosing component name. Given `foo := Bar {}` this is `EnclosingComponent::foo`
642642
pub qualified_id: Option<SmolStr>,
643643
pub type_name: String,
644-
// Hold an id for each element that is unique during this build.
645-
// It helps to cross-reference the element in the different build stages the LSP has to deal with.
646-
pub element_id: u64,
644+
// Hold an id for each element that is unique during this build, based on the source file and
645+
// the offset of the `LBrace` token.
646+
//
647+
// This helps to cross-reference the element in the different build stages the LSP has to deal with.
648+
pub element_hash: u64,
647649
pub node: syntax_nodes::Element,
648650
// Field to indicate whether this element was a layout that had
649651
// been lowered into a rectangle in the lower_layouts pass.
@@ -1000,7 +1002,7 @@ impl Element {
10001002
base_type,
10011003
debug: vec![ElementDebugInfo {
10021004
qualified_id,
1003-
element_id: 0,
1005+
element_hash: 0,
10041006
type_name,
10051007
node: node.clone(),
10061008
layout: None,

internal/compiler/passes.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,6 @@ pub async fn run_passes(
9393

9494
let global_type_registry = type_loader.global_type_registry.clone();
9595

96-
inject_debug_hooks::inject_debug_hooks(doc, type_loader);
97-
9896
run_import_passes(doc, type_loader, diag);
9997
check_public_api::check_public_api(doc, &type_loader.compiler_config, diag);
10098

@@ -327,6 +325,7 @@ pub fn run_import_passes(
327325
type_loader: &crate::typeloader::TypeLoader,
328326
diag: &mut crate::diagnostics::BuildDiagnostics,
329327
) {
328+
inject_debug_hooks::inject_debug_hooks(doc, type_loader);
330329
infer_aliases_types::resolve_aliases(doc, diag);
331330
resolving::resolve_expressions(doc, type_loader, diag);
332331
purity_check::purity_check(doc, diag);

internal/compiler/passes/const_propagation.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,6 @@ fn simplify_expression(expr: &mut Expression) -> bool {
207207
Expression::LayoutCacheAccess { .. } => false,
208208
Expression::SolveLayout { .. } => false,
209209
Expression::ComputeLayoutInfo { .. } => false,
210-
Expression::DebugHook { .. } => false, // This is not const by design
211210
_ => {
212211
let mut result = true;
213212
expr.visit_mut(|expr| result &= simplify_expression(expr));

internal/compiler/passes/inject_debug_hooks.rs

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -5,51 +5,68 @@
55
66
use crate::{expression_tree, object_tree, typeloader};
77

8-
pub fn inject_debug_hooks(
9-
doc: &mut object_tree::Document,
10-
type_loader: &mut typeloader::TypeLoader,
11-
) {
12-
if !type_loader.compiler_config.debug_info {
8+
pub fn inject_debug_hooks(doc: &object_tree::Document, type_loader: &typeloader::TypeLoader) {
9+
let Some(random_state) = &type_loader.compiler_config.debug_hooks else {
1310
return;
14-
}
15-
16-
let mut counter = 1_u64;
11+
};
1712

1813
doc.visit_all_used_components(|component| {
1914
object_tree::recurse_elem_including_sub_components(component, &(), &mut |e, &()| {
20-
process_element(e, counter, &type_loader.compiler_config);
21-
counter += 1;
15+
process_element(e, random_state);
2216
})
2317
});
2418
}
2519

26-
fn property_id(counter: u64, name: &smol_str::SmolStr) -> smol_str::SmolStr {
27-
smol_str::format_smolstr!("?{counter}-{name}")
20+
fn property_id(element_id: u64, name: &smol_str::SmolStr) -> smol_str::SmolStr {
21+
smol_str::format_smolstr!("?{element_id}-{name}")
2822
}
2923

30-
fn process_element(
31-
element: &object_tree::ElementRc,
32-
counter: u64,
33-
config: &crate::CompilerConfiguration,
34-
) {
24+
fn 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+
44+
fn process_element(element: &object_tree::ElementRc, random_state: &std::hash::RandomState) {
3545
let mut elem = element.borrow_mut();
36-
assert_eq!(elem.debug.len(), 1); // We did not merge Elements yet and we have debug info!
37-
38-
if config.debug_hooks {
39-
elem.bindings.iter().for_each(|(name, be)| {
40-
let expr = std::mem::take(&mut be.borrow_mut().expression);
41-
be.borrow_mut().expression = {
42-
let stripped = super::ignore_debug_hooks(&expr);
43-
if matches!(stripped, expression_tree::Expression::Invalid) {
44-
stripped.clone()
45-
} else {
46-
expression_tree::Expression::DebugHook {
47-
expression: Box::new(expr),
48-
id: property_id(counter, name),
49-
}
50-
}
51-
};
52-
});
46+
// We did not merge Elements yet and we have debug info!
47+
assert_eq!(elem.debug.len(), 1);
48+
49+
// Ignore nodes previously set up
50+
if elem.debug.first().expect("There was one element a moment ago").element_hash != 0 {
51+
return;
5352
}
54-
elem.debug.first_mut().expect("There was one element a moment ago").element_id = counter;
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;
5572
}

internal/compiler/passes/lower_layout.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ pub fn lower_layouts(
6060
fn check_preferred_size_100(elem: &ElementRc, prop: &str, diag: &mut BuildDiagnostics) -> bool {
6161
let ret = if let Some(p) = elem.borrow().bindings.get(prop) {
6262
if p.borrow().expression.ty() == Type::Percent {
63-
if !matches!(p.borrow().expression.ignore_debug_hook(), Expression::NumberLiteral(val, _) if val == 100.)
63+
if !matches!(p.borrow().expression.ignore_debug_hooks(), Expression::NumberLiteral(val, _) if *val == 100.)
6464
{
6565
diag.push_error(
6666
format!("{prop} must either be a length, or the literal '100%'"),

0 commit comments

Comments
 (0)