mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 10:50:00 +00:00
LLR: used typed index for vectors in the LLR
type-safety+=1 This would avoid for example using a sub-component index in an array of instances or items. It also self-document what the index is for. There are still a couple of cast from repeater-index to u32 because we do some hack with the repeater-index number for component containers We also cast back to numbers in order to convert it to string in the generated code.
This commit is contained in:
parent
1aeeba7d6b
commit
6c7a50bd3d
10 changed files with 307 additions and 298 deletions
|
@ -54,6 +54,7 @@ by_address = { workspace = true }
|
|||
itertools = { workspace = true }
|
||||
url = "2.2.1"
|
||||
linked_hash_set = "0.1.4"
|
||||
typed-index-collections = "3.2"
|
||||
|
||||
# for processing and embedding the rendered image (texture)
|
||||
image = { workspace = true, optional = true, features = ["default"] }
|
||||
|
|
|
@ -95,7 +95,7 @@ fn access_item_rc(pr: &llr::PropertyReference, ctx: &EvaluationContext) -> Strin
|
|||
component_access += &sub_compo_path;
|
||||
}
|
||||
let component_rc = format!("{component_access}self_weak.lock()->into_dyn()");
|
||||
let item_index_in_tree = sub_component.items[*item_index as usize].index_in_tree;
|
||||
let item_index_in_tree = sub_component.items[*item_index].index_in_tree;
|
||||
let item_index = if item_index_in_tree == 0 {
|
||||
format!("{component_access}tree_index")
|
||||
} else {
|
||||
|
@ -794,7 +794,7 @@ pub fn generate(
|
|||
}),
|
||||
));
|
||||
|
||||
for (idx, glob) in llr.globals.iter().enumerate() {
|
||||
for (idx, glob) in llr.globals.iter_enumerated() {
|
||||
let ty = if glob.is_builtin {
|
||||
format_smolstr!("slint::cbindgen_private::{}", glob.name)
|
||||
} else if glob.must_generate() {
|
||||
|
@ -1293,7 +1293,7 @@ fn generate_public_component(
|
|||
fn add_friends(
|
||||
friends: &mut Vec<SmolStr>,
|
||||
unit: &llr::CompilationUnit,
|
||||
c: llr::SubComponentIndex,
|
||||
c: llr::SubComponentIdx,
|
||||
is_root: bool,
|
||||
) {
|
||||
let sc = &unit.sub_components[c];
|
||||
|
@ -1344,49 +1344,55 @@ fn generate_item_tree(
|
|||
sub_tree.tree.visit_in_array(&mut |node, children_offset, parent_index| {
|
||||
let parent_index = parent_index as u32;
|
||||
|
||||
if node.repeated {
|
||||
assert_eq!(node.children.len(), 0);
|
||||
let mut repeater_index = node.item_index;
|
||||
let mut sub_component = &root.sub_components[sub_tree.root];
|
||||
for i in &node.sub_component_path {
|
||||
repeater_index += sub_component.sub_components[*i].repeater_offset;
|
||||
sub_component = &root.sub_components[sub_component.sub_components[*i].ty];
|
||||
match node.item_index {
|
||||
Either::Right(mut repeater_index) => {
|
||||
assert_eq!(node.children.len(), 0);
|
||||
let mut sub_component = &root.sub_components[sub_tree.root];
|
||||
for i in &node.sub_component_path {
|
||||
repeater_index += sub_component.sub_components[*i].repeater_offset;
|
||||
sub_component = &root.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
item_tree_array.push(format!(
|
||||
"slint::private_api::make_dyn_node({}, {})",
|
||||
repeater_index, parent_index
|
||||
));
|
||||
}
|
||||
item_tree_array.push(format!(
|
||||
"slint::private_api::make_dyn_node({}, {})",
|
||||
repeater_index, parent_index
|
||||
));
|
||||
} else {
|
||||
let mut compo_offset = String::new();
|
||||
let mut sub_component = &root.sub_components[sub_tree.root];
|
||||
for i in &node.sub_component_path {
|
||||
let next_sub_component_name = ident(&sub_component.sub_components[*i].name);
|
||||
write!(
|
||||
Either::Left(item_index) => {
|
||||
let mut compo_offset = String::new();
|
||||
let mut sub_component = &root.sub_components[sub_tree.root];
|
||||
for i in &node.sub_component_path {
|
||||
let next_sub_component_name = ident(&sub_component.sub_components[*i].name);
|
||||
write!(
|
||||
compo_offset,
|
||||
"offsetof({}, {}) + ",
|
||||
ident(&sub_component.name),
|
||||
next_sub_component_name
|
||||
)
|
||||
.unwrap();
|
||||
sub_component = &root.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
|
||||
let item = &sub_component.items[item_index];
|
||||
let children_count = node.children.len() as u32;
|
||||
let children_index = children_offset as u32;
|
||||
let item_array_index = item_array.len() as u32;
|
||||
|
||||
item_tree_array.push(format!(
|
||||
"slint::private_api::make_item_node({}, {}, {}, {}, {})",
|
||||
children_count,
|
||||
children_index,
|
||||
parent_index,
|
||||
item_array_index,
|
||||
node.is_accessible
|
||||
));
|
||||
item_array.push(format!(
|
||||
"{{ {}, {} offsetof({}, {}) }}",
|
||||
item.ty.cpp_vtable_getter,
|
||||
compo_offset,
|
||||
"offsetof({}, {}) + ",
|
||||
ident(&sub_component.name),
|
||||
next_sub_component_name
|
||||
)
|
||||
.unwrap();
|
||||
sub_component = &root.sub_components[sub_component.sub_components[*i].ty];
|
||||
&ident(&sub_component.name),
|
||||
ident(&item.name),
|
||||
));
|
||||
}
|
||||
|
||||
let item = &sub_component.items[node.item_index as usize];
|
||||
let children_count = node.children.len() as u32;
|
||||
let children_index = children_offset as u32;
|
||||
let item_array_index = item_array.len() as u32;
|
||||
|
||||
item_tree_array.push(format!(
|
||||
"slint::private_api::make_item_node({}, {}, {}, {}, {})",
|
||||
children_count, children_index, parent_index, item_array_index, node.is_accessible
|
||||
));
|
||||
item_array.push(format!(
|
||||
"{{ {}, {} offsetof({}, {}) }}",
|
||||
item.ty.cpp_vtable_getter,
|
||||
compo_offset,
|
||||
&ident(&sub_component.name),
|
||||
ident(&item.name),
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1482,7 +1488,7 @@ fn generate_item_tree(
|
|||
.and_then(|parent| {
|
||||
parent
|
||||
.repeater_index
|
||||
.map(|idx| parent.ctx.current_sub_component().unwrap().repeated[idx as usize].index_in_tree)
|
||||
.map(|idx| parent.ctx.current_sub_component().unwrap().repeated[idx].index_in_tree)
|
||||
}).map(|parent_index|
|
||||
vec![
|
||||
format!(
|
||||
|
@ -1814,7 +1820,7 @@ fn generate_item_tree(
|
|||
|
||||
fn generate_sub_component(
|
||||
target_struct: &mut Struct,
|
||||
component: llr::SubComponentIndex,
|
||||
component: llr::SubComponentIdx,
|
||||
root: &llr::CompilationUnit,
|
||||
parent_ctx: Option<ParentCtx>,
|
||||
field_access: Access,
|
||||
|
@ -2062,8 +2068,7 @@ fn generate_sub_component(
|
|||
));
|
||||
}
|
||||
|
||||
for (idx, repeated) in component.repeated.iter().enumerate() {
|
||||
let idx = idx as u32;
|
||||
for (idx, repeated) in component.repeated.iter_enumerated() {
|
||||
let sc = &root.sub_components[repeated.sub_tree.root];
|
||||
let data_type = if let Some(data_prop) = repeated.data_prop {
|
||||
sc.properties[data_prop].ty.clone()
|
||||
|
@ -2080,6 +2085,7 @@ fn generate_sub_component(
|
|||
conditional_includes,
|
||||
);
|
||||
|
||||
let idx = usize::from(idx);
|
||||
let repeater_id = format_smolstr!("repeater_{}", idx);
|
||||
|
||||
let mut model = compile_expression(&repeated.model.borrow(), &ctx);
|
||||
|
@ -2200,9 +2206,9 @@ fn generate_sub_component(
|
|||
));
|
||||
}
|
||||
|
||||
target_struct
|
||||
.members
|
||||
.extend(generate_functions(&component.functions, &ctx).map(|x| (Access::Public, x)));
|
||||
target_struct.members.extend(
|
||||
generate_functions(&component.functions.as_ref(), &ctx).map(|x| (Access::Public, x)),
|
||||
);
|
||||
|
||||
target_struct.members.push((
|
||||
field_access,
|
||||
|
@ -2555,7 +2561,7 @@ fn generate_repeated_component(
|
|||
fn generate_global(
|
||||
file: &mut File,
|
||||
conditional_includes: &ConditionalIncludes,
|
||||
global_idx: llr::GlobalIndex,
|
||||
global_idx: llr::GlobalIdx,
|
||||
global: &llr::GlobalComponent,
|
||||
root: &llr::CompilationUnit,
|
||||
) {
|
||||
|
@ -2592,7 +2598,7 @@ fn generate_global(
|
|||
CppGeneratorContext { global_access: "this->globals".into(), conditional_includes },
|
||||
);
|
||||
|
||||
for (property_index, expression) in global.init_values.iter().enumerate() {
|
||||
for (property_index, expression) in global.init_values.iter_enumerated() {
|
||||
if global.properties[property_index].use_count.get() == 0 {
|
||||
continue;
|
||||
}
|
||||
|
@ -2612,7 +2618,7 @@ fn generate_global(
|
|||
Access::Private,
|
||||
Declaration::Var(Var {
|
||||
ty: "slint::private_api::ChangeTracker".into(),
|
||||
name: format_smolstr!("change_tracker{}", i),
|
||||
name: format_smolstr!("change_tracker{}", usize::from(*i)),
|
||||
..Default::default()
|
||||
}),
|
||||
));
|
||||
|
@ -2620,7 +2626,7 @@ fn generate_global(
|
|||
init.extend(global.change_callbacks.iter().map(|(p, e)| {
|
||||
let code = compile_expression(&e.borrow(), &ctx);
|
||||
let prop = access_member(&llr::PropertyReference::Local { sub_component_path: vec![], property_index: *p }, &ctx);
|
||||
format!("this->change_tracker{p}.init(this, [this]([[maybe_unused]] auto self) {{ return {prop}.get(); }}, [this]([[maybe_unused]] auto self, auto) {{ {code}; }});")
|
||||
format!("this->change_tracker{}.init(this, [this]([[maybe_unused]] auto self) {{ return {prop}.get(); }}, [this]([[maybe_unused]] auto self, auto) {{ {code}; }});", usize::from(*p))
|
||||
}));
|
||||
|
||||
global_struct.members.push((
|
||||
|
@ -2651,7 +2657,7 @@ fn generate_global(
|
|||
);
|
||||
global_struct
|
||||
.members
|
||||
.extend(generate_functions(&global.functions, &ctx).map(|x| (Access::Public, x)));
|
||||
.extend(generate_functions(global.functions.as_ref(), &ctx).map(|x| (Access::Public, x)));
|
||||
|
||||
file.definitions.extend(global_struct.extract_definitions().collect::<Vec<_>>());
|
||||
file.declarations.push(Declaration::Struct(global_struct));
|
||||
|
@ -2856,8 +2862,8 @@ fn generate_public_api_for_properties(
|
|||
|
||||
fn follow_sub_component_path<'a>(
|
||||
compilation_unit: &'a llr::CompilationUnit,
|
||||
root: llr::SubComponentIndex,
|
||||
sub_component_path: &[usize],
|
||||
root: llr::SubComponentIdx,
|
||||
sub_component_path: &[llr::SubComponentInstanceIdx],
|
||||
) -> (String, &'a llr::SubComponent) {
|
||||
let mut compo_path = String::new();
|
||||
let mut sub_component = &compilation_unit.sub_components[root];
|
||||
|
@ -2888,8 +2894,8 @@ fn access_window_field(ctx: &EvaluationContext) -> String {
|
|||
fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) -> String {
|
||||
fn in_native_item(
|
||||
ctx: &EvaluationContext,
|
||||
sub_component_path: &[usize],
|
||||
item_index: u32,
|
||||
sub_component_path: &[llr::SubComponentInstanceIdx],
|
||||
item_index: llr::ItemInstanceIdx,
|
||||
prop_name: &str,
|
||||
path: &str,
|
||||
) -> String {
|
||||
|
@ -2898,7 +2904,7 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
ctx.current_sub_component.unwrap(),
|
||||
sub_component_path,
|
||||
);
|
||||
let item_name = ident(&sub_component.items[item_index as usize].name);
|
||||
let item_name = ident(&sub_component.items[item_index].name);
|
||||
if prop_name.is_empty() {
|
||||
// then this is actually a reference to the element itself
|
||||
format!("{}->{}{}", path, compo_path, item_name)
|
||||
|
@ -3018,7 +3024,7 @@ fn native_item<'a>(
|
|||
ctx.current_sub_component.unwrap(),
|
||||
sub_component_path,
|
||||
);
|
||||
&sub_component.items[*item_index as usize].ty
|
||||
&sub_component.items[*item_index].ty
|
||||
}
|
||||
llr::PropertyReference::InParent { level, parent_reference } => {
|
||||
let mut ctx = ctx;
|
||||
|
@ -3224,7 +3230,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
|
|||
let repeater_index = repeater_index.unwrap();
|
||||
let mut index_prop = llr::PropertyReference::Local {
|
||||
sub_component_path: vec![],
|
||||
property_index: ctx2.current_sub_component().unwrap().repeated[repeater_index as usize]
|
||||
property_index: ctx2.current_sub_component().unwrap().repeated[repeater_index]
|
||||
.index_prop
|
||||
.unwrap(),
|
||||
};
|
||||
|
@ -3233,7 +3239,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
|
|||
llr::PropertyReference::InParent { level, parent_reference: index_prop.into() };
|
||||
}
|
||||
let index_access = access_member(&index_prop, ctx);
|
||||
write!(path, "->repeater_{}", repeater_index).unwrap();
|
||||
write!(path, "->repeater_{}", usize::from(repeater_index)).unwrap();
|
||||
format!("{}.model_set_row_data({}.get(), {})", path, index_access, value)
|
||||
}
|
||||
Expression::ArrayIndexAssignment { array, index, value } => {
|
||||
|
@ -3415,7 +3421,7 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
|
|||
} => box_layout_function(
|
||||
cells_variable,
|
||||
repeater_indices.as_ref().map(SmolStr::as_str),
|
||||
elements,
|
||||
elements.as_ref(),
|
||||
*orientation,
|
||||
sub_expression,
|
||||
ctx,
|
||||
|
@ -3890,7 +3896,7 @@ fn compile_builtin_function_call(
|
|||
fn box_layout_function(
|
||||
cells_variable: &str,
|
||||
repeated_indices: Option<&str>,
|
||||
elements: &[Either<llr::Expression, u32>],
|
||||
elements: &[Either<llr::Expression, llr::RepeatedElementIdx>],
|
||||
orientation: Orientation,
|
||||
sub_expression: &llr::Expression,
|
||||
ctx: &llr_EvaluationContext<CppGeneratorContext>,
|
||||
|
@ -3911,6 +3917,7 @@ fn box_layout_function(
|
|||
.unwrap();
|
||||
}
|
||||
Either::Right(repeater) => {
|
||||
let repeater = usize::from(*repeater);
|
||||
write!(push_code, "self->repeater_{}.ensure_updated(self);", repeater).unwrap();
|
||||
|
||||
if let Some(ri) = &repeated_indices {
|
||||
|
|
|
@ -198,8 +198,7 @@ pub fn generate(
|
|||
|
||||
let globals = llr
|
||||
.globals
|
||||
.iter()
|
||||
.enumerate()
|
||||
.iter_enumerated()
|
||||
.filter(|(_, glob)| glob.must_generate())
|
||||
.map(|(idx, glob)| generate_global(idx, glob, &llr));
|
||||
let shared_globals = generate_shared_globals(&llr, &compiler_config);
|
||||
|
@ -669,10 +668,10 @@ fn public_api(
|
|||
|
||||
/// Generate the rust code for the given component.
|
||||
fn generate_sub_component(
|
||||
component_idx: llr::SubComponentIndex,
|
||||
component_idx: llr::SubComponentIdx,
|
||||
root: &llr::CompilationUnit,
|
||||
parent_ctx: Option<ParentCtx>,
|
||||
index_property: Option<llr::PropertyIndex>,
|
||||
index_property: Option<llr::PropertyIdx>,
|
||||
pinned_drop: bool,
|
||||
) -> TokenStream {
|
||||
let component = &root.sub_components[component_idx];
|
||||
|
@ -726,7 +725,7 @@ fn generate_sub_component(
|
|||
.enumerate()
|
||||
.map(|(idx, _)| format_ident!("change_tracker{idx}"));
|
||||
|
||||
let declared_functions = generate_functions(&component.functions, &ctx);
|
||||
let declared_functions = generate_functions(component.functions.as_ref(), &ctx);
|
||||
|
||||
let mut init = vec![];
|
||||
let mut item_names = vec![];
|
||||
|
@ -769,13 +768,13 @@ fn generate_sub_component(
|
|||
let mut repeated_subtree_ranges: Vec<TokenStream> = vec![];
|
||||
let mut repeated_subtree_components: Vec<TokenStream> = vec![];
|
||||
|
||||
for (idx, repeated) in component.repeated.iter().enumerate() {
|
||||
let idx = idx as u32;
|
||||
for (idx, repeated) in component.repeated.iter_enumerated() {
|
||||
extra_components.push(generate_repeated_component(
|
||||
repeated,
|
||||
root,
|
||||
ParentCtx::new(&ctx, Some(idx)),
|
||||
));
|
||||
let idx = usize::from(idx) as u32;
|
||||
let repeater_id = format_ident!("repeater{}", idx);
|
||||
let rep_inner_component_id =
|
||||
self::inner_component_id(&root.sub_components[repeated.sub_tree.root]);
|
||||
|
@ -1329,7 +1328,7 @@ fn generate_functions(functions: &[llr::Function], ctx: &EvaluationContext) -> V
|
|||
}
|
||||
|
||||
fn generate_global(
|
||||
global_idx: llr::GlobalIndex,
|
||||
global_idx: llr::GlobalIdx,
|
||||
global: &llr::GlobalComponent,
|
||||
root: &llr::CompilationUnit,
|
||||
) -> TokenStream {
|
||||
|
@ -1372,9 +1371,9 @@ fn generate_global(
|
|||
},
|
||||
);
|
||||
|
||||
let declared_functions = generate_functions(&global.functions, &ctx);
|
||||
let declared_functions = generate_functions(global.functions.as_ref(), &ctx);
|
||||
|
||||
for (property_index, expression) in global.init_values.iter().enumerate() {
|
||||
for (property_index, expression) in global.init_values.iter_enumerated() {
|
||||
if global.properties[property_index].use_count.get() == 0 {
|
||||
continue;
|
||||
}
|
||||
|
@ -1387,7 +1386,7 @@ fn generate_global(
|
|||
)
|
||||
}
|
||||
}
|
||||
for (property_index, cst) in global.const_properties.iter().enumerate() {
|
||||
for (property_index, cst) in global.const_properties.iter_enumerated() {
|
||||
if global.properties[property_index].use_count.get() == 0 {
|
||||
continue;
|
||||
}
|
||||
|
@ -1404,8 +1403,10 @@ fn generate_global(
|
|||
let public_component_id = ident(&global.name);
|
||||
let global_id = format_ident!("global_{}", public_component_id);
|
||||
|
||||
let change_tracker_names =
|
||||
global.change_callbacks.iter().map(|(idx, _)| format_ident!("change_tracker{idx}"));
|
||||
let change_tracker_names = global
|
||||
.change_callbacks
|
||||
.iter()
|
||||
.map(|(idx, _)| format_ident!("change_tracker{}", usize::from(*idx)));
|
||||
init.extend(global.change_callbacks.iter().map(|(p, e)| {
|
||||
let code = compile_expression(&e.borrow(), &ctx);
|
||||
let prop = access_member(
|
||||
|
@ -1413,7 +1414,7 @@ fn generate_global(
|
|||
&ctx,
|
||||
)
|
||||
.unwrap();
|
||||
let change_tracker = format_ident!("change_tracker{p}");
|
||||
let change_tracker = format_ident!("change_tracker{}", usize::from(*p));
|
||||
quote! {
|
||||
#[allow(dead_code, unused)]
|
||||
_self.#change_tracker.init(
|
||||
|
@ -1498,7 +1499,7 @@ fn generate_item_tree(
|
|||
sub_tree: &llr::ItemTree,
|
||||
root: &llr::CompilationUnit,
|
||||
parent_ctx: Option<ParentCtx>,
|
||||
index_property: Option<llr::PropertyIndex>,
|
||||
index_property: Option<llr::PropertyIdx>,
|
||||
is_popup_menu: bool,
|
||||
) -> TokenStream {
|
||||
let sub_comp = generate_sub_component(sub_tree.root, root, parent_ctx, index_property, true);
|
||||
|
@ -1529,7 +1530,7 @@ fn generate_item_tree(
|
|||
|
||||
let parent_item_expression = parent_ctx.and_then(|parent| {
|
||||
parent.repeater_index.map(|idx| {
|
||||
let sub_component_offset = parent.ctx.current_sub_component().unwrap().repeated[idx as usize].index_in_tree;
|
||||
let sub_component_offset = parent.ctx.current_sub_component().unwrap().repeated[idx].index_in_tree;
|
||||
|
||||
quote!(if let Some((parent_component, parent_index)) = self
|
||||
.parent
|
||||
|
@ -1548,41 +1549,43 @@ fn generate_item_tree(
|
|||
let parent_index = parent_index as u32;
|
||||
let (path, component) =
|
||||
follow_sub_component_path(root, sub_tree.root, &node.sub_component_path);
|
||||
if node.repeated || node.component_container {
|
||||
assert_eq!(node.children.len(), 0);
|
||||
let mut repeater_index = node.item_index;
|
||||
let mut sub_component = &root.sub_components[sub_tree.root];
|
||||
for i in &node.sub_component_path {
|
||||
repeater_index += sub_component.sub_components[*i].repeater_offset;
|
||||
sub_component = &root.sub_components[sub_component.sub_components[*i].ty];
|
||||
match node.item_index {
|
||||
Either::Right(mut repeater_index) => {
|
||||
assert_eq!(node.children.len(), 0);
|
||||
let mut sub_component = &root.sub_components[sub_tree.root];
|
||||
for i in &node.sub_component_path {
|
||||
repeater_index += sub_component.sub_components[*i].repeater_offset;
|
||||
sub_component = &root.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
item_tree_array.push(quote!(
|
||||
sp::ItemTreeNode::DynamicTree {
|
||||
index: #repeater_index,
|
||||
parent_index: #parent_index,
|
||||
}
|
||||
));
|
||||
}
|
||||
item_tree_array.push(quote!(
|
||||
sp::ItemTreeNode::DynamicTree {
|
||||
index: #repeater_index,
|
||||
parent_index: #parent_index,
|
||||
}
|
||||
));
|
||||
} else {
|
||||
let item = &component.items[node.item_index as usize];
|
||||
let field = access_component_field_offset(
|
||||
&self::inner_component_id(component),
|
||||
&ident(&item.name),
|
||||
);
|
||||
Either::Left(item_index) => {
|
||||
let item = &component.items[item_index];
|
||||
let field = access_component_field_offset(
|
||||
&self::inner_component_id(component),
|
||||
&ident(&item.name),
|
||||
);
|
||||
|
||||
let children_count = node.children.len() as u32;
|
||||
let children_index = children_offset as u32;
|
||||
let item_array_len = item_array.len() as u32;
|
||||
let is_accessible = node.is_accessible;
|
||||
item_tree_array.push(quote!(
|
||||
sp::ItemTreeNode::Item {
|
||||
is_accessible: #is_accessible,
|
||||
children_count: #children_count,
|
||||
children_index: #children_index,
|
||||
parent_index: #parent_index,
|
||||
item_array_index: #item_array_len,
|
||||
}
|
||||
));
|
||||
item_array.push(quote!(sp::VOffset::new(#path #field)));
|
||||
let children_count = node.children.len() as u32;
|
||||
let children_index = children_offset as u32;
|
||||
let item_array_len = item_array.len() as u32;
|
||||
let is_accessible = node.is_accessible;
|
||||
item_tree_array.push(quote!(
|
||||
sp::ItemTreeNode::Item {
|
||||
is_accessible: #is_accessible,
|
||||
children_count: #children_count,
|
||||
children_index: #children_index,
|
||||
parent_index: #parent_index,
|
||||
item_array_index: #item_array_len,
|
||||
}
|
||||
));
|
||||
item_array.push(quote!(sp::VOffset::new(#path #field)));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1889,8 +1892,8 @@ fn property_set_value_tokens(
|
|||
fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) -> MemberAccess {
|
||||
fn in_native_item(
|
||||
ctx: &EvaluationContext,
|
||||
sub_component_path: &[usize],
|
||||
item_index: u32,
|
||||
sub_component_path: &[llr::SubComponentInstanceIdx],
|
||||
item_index: llr::ItemInstanceIdx,
|
||||
prop_name: &str,
|
||||
path: TokenStream,
|
||||
) -> TokenStream {
|
||||
|
@ -1900,14 +1903,14 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
sub_component_path,
|
||||
);
|
||||
let component_id = inner_component_id(sub_component);
|
||||
let item_name = ident(&sub_component.items[item_index as usize].name);
|
||||
let item_name = ident(&sub_component.items[item_index].name);
|
||||
let item_field = access_component_field_offset(&component_id, &item_name);
|
||||
if prop_name.is_empty() {
|
||||
// then this is actually a reference to the element itself
|
||||
quote!((#compo_path #item_field).apply_pin(#path))
|
||||
} else {
|
||||
let property_name = ident(prop_name);
|
||||
let item_ty = ident(&sub_component.items[item_index as usize].ty.class_name);
|
||||
let item_ty = ident(&sub_component.items[item_index].ty.class_name);
|
||||
quote!((#compo_path #item_field + sp::#item_ty::FIELD_OFFSETS.#property_name).apply_pin(#path))
|
||||
}
|
||||
}
|
||||
|
@ -2109,8 +2112,8 @@ impl MemberAccess {
|
|||
|
||||
fn follow_sub_component_path<'a>(
|
||||
compilation_unit: &'a llr::CompilationUnit,
|
||||
root: llr::SubComponentIndex,
|
||||
sub_component_path: &[usize],
|
||||
root: llr::SubComponentIdx,
|
||||
sub_component_path: &[llr::SubComponentInstanceIdx],
|
||||
) -> (TokenStream, &'a llr::SubComponent) {
|
||||
let mut compo_path = quote!();
|
||||
let mut sub_component = &compilation_unit.sub_components[root];
|
||||
|
@ -2159,7 +2162,7 @@ fn access_item_rc(pr: &llr::PropertyReference, ctx: &EvaluationContext) -> Token
|
|||
&ctx.compilation_unit.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
let component_rc_tokens = quote!(sp::VRcMapped::origin(&#component_access_tokens.self_weak.get().unwrap().upgrade().unwrap()));
|
||||
let item_index_in_tree = sub_component.items[*item_index as usize].index_in_tree;
|
||||
let item_index_in_tree = sub_component.items[*item_index].index_in_tree;
|
||||
let item_index_tokens = if item_index_in_tree == 0 {
|
||||
quote!(#component_access_tokens.tree_index.get())
|
||||
} else {
|
||||
|
@ -2348,10 +2351,7 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream
|
|||
let repeater_index = repeater_index.unwrap();
|
||||
let mut index_prop = llr::PropertyReference::Local {
|
||||
sub_component_path: vec![],
|
||||
property_index: ctx2.current_sub_component().unwrap().repeated
|
||||
[repeater_index as usize]
|
||||
.index_prop
|
||||
.unwrap(),
|
||||
property_index: ctx2.current_sub_component().unwrap().repeated[repeater_index].index_prop.unwrap(),
|
||||
};
|
||||
if let Some(level) = NonZeroUsize::new(*level) {
|
||||
index_prop =
|
||||
|
@ -2360,7 +2360,7 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream
|
|||
let index_access = access_member(&index_prop, ctx).get_property();
|
||||
let repeater = access_component_field_offset(
|
||||
&inner_component_id(ctx2.current_sub_component().unwrap()),
|
||||
&format_ident!("repeater{}", repeater_index),
|
||||
&format_ident!("repeater{}", usize::from(repeater_index)),
|
||||
);
|
||||
quote!(#repeater.apply_pin(#path.as_pin_ref()).model_set_row_data(#index_access as _, #value as _))
|
||||
}
|
||||
|
@ -2598,7 +2598,7 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream
|
|||
} => box_layout_function(
|
||||
cells_variable,
|
||||
repeater_indices.as_ref().map(SmolStr::as_str),
|
||||
elements,
|
||||
elements.as_ref(),
|
||||
*orientation,
|
||||
sub_expression,
|
||||
ctx,
|
||||
|
@ -3126,7 +3126,7 @@ fn struct_name_to_tokens(name: &str) -> TokenStream {
|
|||
fn box_layout_function(
|
||||
cells_variable: &str,
|
||||
repeated_indices: Option<&str>,
|
||||
elements: &[Either<Expression, u32>],
|
||||
elements: &[Either<Expression, llr::RepeatedElementIdx>],
|
||||
orientation: Orientation,
|
||||
sub_expression: &Expression,
|
||||
ctx: &EvaluationContext,
|
||||
|
@ -3145,14 +3145,10 @@ fn box_layout_function(
|
|||
push_code.push(quote!(items_vec.push(#value);))
|
||||
}
|
||||
Either::Right(repeater) => {
|
||||
let repeater_id = format_ident!("repeater{}", repeater);
|
||||
let repeater_id = format_ident!("repeater{}", usize::from(*repeater));
|
||||
let rep_inner_component_id = self::inner_component_id(
|
||||
&ctx.compilation_unit.sub_components[ctx
|
||||
.current_sub_component()
|
||||
.unwrap()
|
||||
.repeated[*repeater as usize]
|
||||
.sub_tree
|
||||
.root],
|
||||
&ctx.compilation_unit.sub_components
|
||||
[ctx.current_sub_component().unwrap().repeated[*repeater].sub_tree.root],
|
||||
);
|
||||
repeated_count = quote!(#repeated_count + _self.#repeater_id.len());
|
||||
let ri = repeated_indices.as_ref().map(|ri| {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
|
||||
|
||||
use super::{GlobalIndex, PropertyReference, SubComponentIndex};
|
||||
use super::{
|
||||
GlobalIdx, PropertyReference, RepeatedElementIdx, SubComponentIdx, SubComponentInstanceIdx,
|
||||
};
|
||||
use crate::expression_tree::{BuiltinFunction, MinMaxOp, OperatorClass};
|
||||
use crate::langtype::Type;
|
||||
use crate::layout::Orientation;
|
||||
|
@ -169,7 +171,7 @@ pub enum Expression {
|
|||
/// The name for the local variable that contains the repeater indices
|
||||
repeater_indices: Option<SmolStr>,
|
||||
/// Either an expression of type BoxLayoutCellData, or an index to the repeater
|
||||
elements: Vec<Either<Expression, u32>>,
|
||||
elements: Vec<Either<Expression, RepeatedElementIdx>>,
|
||||
orientation: Orientation,
|
||||
sub_expression: Box<Expression>,
|
||||
},
|
||||
|
@ -462,7 +464,7 @@ pub trait TypeResolutionContext {
|
|||
pub struct ParentCtx<'a, T = ()> {
|
||||
pub ctx: &'a EvaluationContext<'a, T>,
|
||||
// Index of the repeater within the ctx.current_sub_component
|
||||
pub repeater_index: Option<u32>,
|
||||
pub repeater_index: Option<RepeatedElementIdx>,
|
||||
}
|
||||
|
||||
impl<'a, T> Clone for ParentCtx<'a, T> {
|
||||
|
@ -473,7 +475,10 @@ impl<'a, T> Clone for ParentCtx<'a, T> {
|
|||
impl<'a, T> Copy for ParentCtx<'a, T> {}
|
||||
|
||||
impl<'a, T> ParentCtx<'a, T> {
|
||||
pub fn new(ctx: &'a EvaluationContext<'a, T>, repeater_index: Option<u32>) -> Self {
|
||||
pub fn new(
|
||||
ctx: &'a EvaluationContext<'a, T>,
|
||||
repeater_index: Option<RepeatedElementIdx>,
|
||||
) -> Self {
|
||||
Self { ctx, repeater_index }
|
||||
}
|
||||
}
|
||||
|
@ -481,8 +486,8 @@ impl<'a, T> ParentCtx<'a, T> {
|
|||
#[derive(Clone)]
|
||||
pub struct EvaluationContext<'a, T = ()> {
|
||||
pub compilation_unit: &'a super::CompilationUnit,
|
||||
pub current_sub_component: Option<SubComponentIndex>,
|
||||
pub current_global: Option<GlobalIndex>,
|
||||
pub current_sub_component: Option<SubComponentIdx>,
|
||||
pub current_global: Option<GlobalIdx>,
|
||||
pub generator_state: T,
|
||||
/// The repeater parent
|
||||
pub parent: Option<ParentCtx<'a, T>>,
|
||||
|
@ -494,7 +499,7 @@ pub struct EvaluationContext<'a, T = ()> {
|
|||
impl<'a, T> EvaluationContext<'a, T> {
|
||||
pub fn new_sub_component(
|
||||
compilation_unit: &'a super::CompilationUnit,
|
||||
sub_component: SubComponentIndex,
|
||||
sub_component: SubComponentIdx,
|
||||
generator_state: T,
|
||||
parent: Option<ParentCtx<'a, T>>,
|
||||
) -> Self {
|
||||
|
@ -510,7 +515,7 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
|
||||
pub fn new_global(
|
||||
compilation_unit: &'a super::CompilationUnit,
|
||||
global: GlobalIndex,
|
||||
global: GlobalIdx,
|
||||
generator_state: T,
|
||||
) -> Self {
|
||||
Self {
|
||||
|
@ -708,7 +713,7 @@ impl<'a, T> TypeResolutionContext for EvaluationContext<'a, T> {
|
|||
&self.compilation_unit.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
|
||||
sub_component.items[*item_index as usize].ty.lookup_property(prop_name).unwrap()
|
||||
sub_component.items[*item_index].ty.lookup_property(prop_name).unwrap()
|
||||
}
|
||||
PropertyReference::InParent { level, parent_reference } => {
|
||||
let mut ctx = self;
|
||||
|
@ -758,12 +763,12 @@ pub(crate) struct PropertyInfoResult<'a> {
|
|||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum ContextMap {
|
||||
Identity,
|
||||
InSubElement { path: Vec<usize>, parent: usize },
|
||||
InGlobal(GlobalIndex),
|
||||
InSubElement { path: Vec<SubComponentInstanceIdx>, parent: usize },
|
||||
InGlobal(GlobalIdx),
|
||||
}
|
||||
|
||||
impl ContextMap {
|
||||
fn deeper_in_sub_component(self, sub: usize) -> Self {
|
||||
fn deeper_in_sub_component(self, sub: SubComponentInstanceIdx) -> Self {
|
||||
match self {
|
||||
ContextMap::Identity => ContextMap::InSubElement { parent: 0, path: vec![sub] },
|
||||
ContextMap::InSubElement { mut path, parent } => {
|
||||
|
@ -778,7 +783,7 @@ impl ContextMap {
|
|||
match self {
|
||||
ContextMap::Identity => p.clone(),
|
||||
ContextMap::InSubElement { path, parent } => {
|
||||
let map_sub_path = |sub_component_path: &[usize]| -> Vec<usize> {
|
||||
let map_sub_path = |sub_component_path: &[SubComponentInstanceIdx]| -> Vec<SubComponentInstanceIdx> {
|
||||
path.iter().chain(sub_component_path.iter()).copied().collect()
|
||||
};
|
||||
|
||||
|
|
|
@ -8,13 +8,24 @@ use std::cell::{Cell, RefCell};
|
|||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::num::NonZeroUsize;
|
||||
use std::rc::Rc;
|
||||
use typed_index_collections::TiVec;
|
||||
|
||||
// Index in the `SubComponent::properties`
|
||||
pub type PropertyIndex = usize;
|
||||
// Index in CompilationUint::sub_components
|
||||
pub type SubComponentIndex = usize;
|
||||
// Index in CompilationUnit::globas
|
||||
pub type GlobalIndex = usize;
|
||||
#[derive(
|
||||
Debug, Clone, Copy, derive_more::Into, derive_more::From, Hash, PartialEq, Eq, PartialOrd, Ord,
|
||||
)]
|
||||
pub struct PropertyIdx(usize);
|
||||
#[derive(Debug, Clone, Copy, derive_more::Into, derive_more::From, Hash, PartialEq, Eq)]
|
||||
pub struct FunctionIdx(usize);
|
||||
#[derive(Debug, Clone, Copy, derive_more::Into, derive_more::From)]
|
||||
pub struct SubComponentIdx(usize);
|
||||
#[derive(Debug, Clone, Copy, derive_more::Into, derive_more::From, Hash, PartialEq, Eq)]
|
||||
pub struct GlobalIdx(usize);
|
||||
#[derive(Debug, Clone, Copy, derive_more::Into, derive_more::From, Hash, PartialEq, Eq)]
|
||||
pub struct SubComponentInstanceIdx(usize);
|
||||
#[derive(Debug, Clone, Copy, derive_more::Into, derive_more::From, Hash, PartialEq, Eq)]
|
||||
pub struct ItemInstanceIdx(usize);
|
||||
#[derive(Debug, Clone, Copy, derive_more::Into, derive_more::From, Hash, PartialEq, Eq)]
|
||||
pub struct RepeatedElementIdx(usize);
|
||||
|
||||
#[derive(Debug, Clone, derive_more::Deref)]
|
||||
pub struct MutExpression(RefCell<Expression>);
|
||||
|
@ -56,13 +67,13 @@ pub struct BindingExpression {
|
|||
#[derive(Debug)]
|
||||
pub struct GlobalComponent {
|
||||
pub name: SmolStr,
|
||||
pub properties: Vec<Property>,
|
||||
pub functions: Vec<Function>,
|
||||
pub properties: TiVec<PropertyIdx, Property>,
|
||||
pub functions: TiVec<FunctionIdx, Function>,
|
||||
/// One entry per property
|
||||
pub init_values: Vec<Option<BindingExpression>>,
|
||||
pub init_values: TiVec<PropertyIdx, Option<BindingExpression>>,
|
||||
// maps property to its changed callback
|
||||
pub change_callbacks: BTreeMap<usize, MutExpression>,
|
||||
pub const_properties: Vec<bool>,
|
||||
pub change_callbacks: BTreeMap<PropertyIdx, MutExpression>,
|
||||
pub const_properties: TiVec<PropertyIdx, bool>,
|
||||
pub public_properties: PublicProperties,
|
||||
pub private_properties: PrivateProperties,
|
||||
/// true if we should expose the global in the generated API
|
||||
|
@ -74,7 +85,7 @@ pub struct GlobalComponent {
|
|||
pub is_builtin: bool,
|
||||
|
||||
/// Analysis for each properties
|
||||
pub prop_analysis: Vec<crate::object_tree::PropertyAnalysis>,
|
||||
pub prop_analysis: TiVec<PropertyIdx, crate::object_tree::PropertyAnalysis>,
|
||||
}
|
||||
|
||||
impl GlobalComponent {
|
||||
|
@ -90,18 +101,22 @@ impl GlobalComponent {
|
|||
#[derive(Clone, Debug, Hash, PartialEq, Eq)]
|
||||
pub enum PropertyReference {
|
||||
/// A property relative to this SubComponent
|
||||
Local { sub_component_path: Vec<usize>, property_index: PropertyIndex },
|
||||
Local { sub_component_path: Vec<SubComponentInstanceIdx>, property_index: PropertyIdx },
|
||||
/// A property in a Native item
|
||||
InNativeItem { sub_component_path: Vec<usize>, item_index: u32, prop_name: String },
|
||||
InNativeItem {
|
||||
sub_component_path: Vec<SubComponentInstanceIdx>,
|
||||
item_index: ItemInstanceIdx,
|
||||
prop_name: String,
|
||||
},
|
||||
/// The properties is a property relative to a parent ItemTree (`level` level deep)
|
||||
InParent { level: NonZeroUsize, parent_reference: Box<PropertyReference> },
|
||||
/// The property within a GlobalComponent
|
||||
Global { global_index: GlobalIndex, property_index: usize },
|
||||
Global { global_index: GlobalIdx, property_index: PropertyIdx },
|
||||
|
||||
/// A function in a sub component.
|
||||
Function { sub_component_path: Vec<usize>, function_index: usize },
|
||||
Function { sub_component_path: Vec<SubComponentInstanceIdx>, function_index: FunctionIdx },
|
||||
/// A function in a global.
|
||||
GlobalFunction { global_index: GlobalIndex, function_index: usize },
|
||||
GlobalFunction { global_index: GlobalIdx, function_index: FunctionIdx },
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
|
@ -143,9 +158,9 @@ pub struct ListViewInfo {
|
|||
pub struct RepeatedElement {
|
||||
pub model: MutExpression,
|
||||
/// Within the sub_tree's root component
|
||||
pub index_prop: Option<PropertyIndex>,
|
||||
pub index_prop: Option<PropertyIdx>,
|
||||
/// Within the sub_tree's root component
|
||||
pub data_prop: Option<PropertyIndex>,
|
||||
pub data_prop: Option<PropertyIdx>,
|
||||
pub sub_tree: ItemTree,
|
||||
/// The index of the item node in the parent tree
|
||||
pub index_in_tree: u32,
|
||||
|
@ -158,7 +173,7 @@ pub struct ComponentContainerElement {
|
|||
/// The index of the `ComponentContainer` in the enclosing components `item_tree` array
|
||||
pub component_container_item_tree_index: u32,
|
||||
/// The index of the `ComponentContainer` item in the enclosing components `items` array
|
||||
pub component_container_items_index: u32,
|
||||
pub component_container_items_index: ItemInstanceIdx,
|
||||
/// The index to a dynamic tree node where the component is supposed to be embedded at
|
||||
pub component_placeholder_item_tree_index: u32,
|
||||
}
|
||||
|
@ -182,11 +197,9 @@ impl std::fmt::Debug for Item {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct TreeNode {
|
||||
pub sub_component_path: Vec<usize>,
|
||||
/// Either an index in the items or repeater, depending on (repeated || component_container)
|
||||
pub item_index: u32,
|
||||
pub repeated: bool,
|
||||
pub component_container: bool,
|
||||
pub sub_component_path: Vec<SubComponentInstanceIdx>,
|
||||
/// Either an index in the items, or the local dynamic index for repeater or component container
|
||||
pub item_index: itertools::Either<ItemInstanceIdx, u32>,
|
||||
pub children: Vec<TreeNode>,
|
||||
pub is_accessible: bool,
|
||||
}
|
||||
|
@ -237,14 +250,14 @@ impl TreeNode {
|
|||
#[derive(Debug)]
|
||||
pub struct SubComponent {
|
||||
pub name: SmolStr,
|
||||
pub properties: Vec<Property>,
|
||||
pub functions: Vec<Function>,
|
||||
pub items: Vec<Item>,
|
||||
pub repeated: Vec<RepeatedElement>,
|
||||
pub properties: TiVec<PropertyIdx, Property>,
|
||||
pub functions: TiVec<FunctionIdx, Function>,
|
||||
pub items: TiVec<ItemInstanceIdx, Item>,
|
||||
pub repeated: TiVec<RepeatedElementIdx, RepeatedElement>,
|
||||
pub component_containers: Vec<ComponentContainerElement>,
|
||||
pub popup_windows: Vec<PopupWindow>,
|
||||
pub timers: Vec<Timer>,
|
||||
pub sub_components: Vec<SubComponentInstance>,
|
||||
pub sub_components: TiVec<SubComponentInstanceIdx, SubComponentInstance>,
|
||||
/// The initial value or binding for properties.
|
||||
/// This is ordered in the order they must be set.
|
||||
pub property_init: Vec<(PropertyReference, BindingExpression)>,
|
||||
|
@ -335,7 +348,7 @@ impl SubComponent {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct SubComponentInstance {
|
||||
pub ty: SubComponentIndex,
|
||||
pub ty: SubComponentIdx,
|
||||
pub name: SmolStr,
|
||||
pub index_in_tree: u32,
|
||||
pub index_of_first_child_in_tree: u32,
|
||||
|
@ -344,7 +357,7 @@ pub struct SubComponentInstance {
|
|||
|
||||
#[derive(Debug)]
|
||||
pub struct ItemTree {
|
||||
pub root: SubComponentIndex,
|
||||
pub root: SubComponentIdx,
|
||||
pub tree: TreeNode,
|
||||
/// This tree has a parent. e.g: it is a Repeater or a PopupWindow whose property can access
|
||||
/// the parent ItemTree.
|
||||
|
@ -364,10 +377,10 @@ pub struct PublicComponent {
|
|||
pub struct CompilationUnit {
|
||||
pub public_components: Vec<PublicComponent>,
|
||||
/// Storage for all sub-components
|
||||
pub sub_components: Vec<SubComponent>,
|
||||
pub sub_components: TiVec<SubComponentIdx, SubComponent>,
|
||||
/// The sub-components that are not item-tree root
|
||||
pub used_sub_components: Vec<SubComponentIndex>,
|
||||
pub globals: Vec<GlobalComponent>,
|
||||
pub used_sub_components: Vec<SubComponentIdx>,
|
||||
pub globals: TiVec<GlobalIdx, GlobalComponent>,
|
||||
pub popup_menu: Option<PopupMenu>,
|
||||
pub has_debug_info: bool,
|
||||
#[cfg(feature = "bundle-translations")]
|
||||
|
@ -381,19 +394,19 @@ impl CompilationUnit {
|
|||
) {
|
||||
fn visit_component<'a>(
|
||||
root: &'a CompilationUnit,
|
||||
c: SubComponentIndex,
|
||||
c: SubComponentIdx,
|
||||
visitor: &mut dyn FnMut(&'a SubComponent, &EvaluationContext<'_>),
|
||||
parent: Option<ParentCtx<'_>>,
|
||||
) {
|
||||
let ctx = EvaluationContext::new_sub_component(root, c, (), parent);
|
||||
let sc = &root.sub_components[c];
|
||||
visitor(sc, &ctx);
|
||||
for (idx, r) in sc.repeated.iter().enumerate() {
|
||||
for (idx, r) in sc.repeated.iter_enumerated() {
|
||||
visit_component(
|
||||
root,
|
||||
r.sub_tree.root,
|
||||
visitor,
|
||||
Some(ParentCtx::new(&ctx, Some(idx as u32))),
|
||||
Some(ParentCtx::new(&ctx, Some(idx))),
|
||||
);
|
||||
}
|
||||
for popup in &sc.popup_windows {
|
||||
|
@ -439,7 +452,7 @@ impl CompilationUnit {
|
|||
visitor(e, ctx);
|
||||
}
|
||||
});
|
||||
for (idx, g) in self.globals.iter().enumerate() {
|
||||
for (idx, g) in self.globals.iter_enumerated() {
|
||||
let ctx = EvaluationContext::new_global(self, idx, ());
|
||||
for e in g.init_values.iter().filter_map(|x| x.as_ref()) {
|
||||
visitor(&e.expression, &ctx)
|
||||
|
|
|
@ -11,7 +11,7 @@ use itertools::Either;
|
|||
use smol_str::{format_smolstr, SmolStr};
|
||||
|
||||
use super::lower_to_item_tree::{LoweredElement, LoweredSubComponentMapping, LoweringState};
|
||||
use super::{Animation, PropertyReference};
|
||||
use super::{Animation, PropertyIdx, PropertyReference, RepeatedElementIdx};
|
||||
use crate::expression_tree::{BuiltinFunction, Callable, Expression as tree_Expression};
|
||||
use crate::langtype::{EnumerationValue, Struct, Type};
|
||||
use crate::layout::Orientation;
|
||||
|
@ -88,10 +88,10 @@ pub fn lower_expression(
|
|||
)))
|
||||
}
|
||||
tree_Expression::RepeaterIndexReference { element } => {
|
||||
repeater_special_property(element, ctx.component, 1)
|
||||
repeater_special_property(element, ctx.component, 1usize.into())
|
||||
}
|
||||
tree_Expression::RepeaterModelReference { element } => {
|
||||
repeater_special_property(element, ctx.component, 0)
|
||||
repeater_special_property(element, ctx.component, 0usize.into())
|
||||
}
|
||||
tree_Expression::FunctionParameterReference { index, .. } => {
|
||||
llr_Expression::FunctionParameterReference { index: *index }
|
||||
|
@ -288,7 +288,7 @@ fn lower_assignment(
|
|||
}
|
||||
tree_Expression::RepeaterModelReference { element } => {
|
||||
let rhs = lower_expression(rhs, ctx);
|
||||
let prop = repeater_special_property(element, ctx.component, 0);
|
||||
let prop = repeater_special_property(element, ctx.component, 0usize.into());
|
||||
|
||||
let level = match &prop {
|
||||
llr_Expression::PropertyReference(PropertyReference::InParent {
|
||||
|
@ -331,7 +331,7 @@ fn lower_assignment(
|
|||
fn repeater_special_property(
|
||||
element: &Weak<RefCell<Element>>,
|
||||
component: &Rc<crate::object_tree::Component>,
|
||||
property_index: usize,
|
||||
property_index: PropertyIdx,
|
||||
) -> llr_Expression {
|
||||
let mut r = PropertyReference::Local { sub_component_path: vec![], property_index };
|
||||
let enclosing = element.upgrade().unwrap().borrow().enclosing_component.upgrade().unwrap();
|
||||
|
@ -695,7 +695,7 @@ struct BoxLayoutDataResult {
|
|||
cells: llr_Expression,
|
||||
/// When there are repeater involved, we need to do a BoxLayoutFunction with the
|
||||
/// given cell variable and elements
|
||||
compute_cells: Option<(String, Vec<Either<llr_Expression, u32>>)>,
|
||||
compute_cells: Option<(String, Vec<Either<llr_Expression, RepeatedElementIdx>>)>,
|
||||
}
|
||||
|
||||
fn box_layout_data(
|
||||
|
|
|
@ -13,6 +13,7 @@ use crate::CompilerConfiguration;
|
|||
use smol_str::{format_smolstr, SmolStr};
|
||||
use std::collections::{BTreeMap, HashMap};
|
||||
use std::rc::Rc;
|
||||
use typed_index_collections::TiVec;
|
||||
|
||||
pub fn lower_to_item_tree(
|
||||
document: &crate::object_tree::Document,
|
||||
|
@ -31,9 +32,9 @@ pub fn lower_to_item_tree(
|
|||
);
|
||||
}
|
||||
|
||||
let mut globals = Vec::new();
|
||||
let mut globals = TiVec::new();
|
||||
for g in &document.used_types.borrow().globals {
|
||||
let count = globals.len();
|
||||
let count = globals.next_key();
|
||||
globals.push(lower_global(g, count, &mut state));
|
||||
}
|
||||
for (g, l) in document.used_types.borrow().globals.iter().zip(&mut globals) {
|
||||
|
@ -42,8 +43,8 @@ pub fn lower_to_item_tree(
|
|||
|
||||
for c in &document.used_types.borrow().sub_components {
|
||||
let sc = lower_sub_component(c, &mut state, None, compiler_config);
|
||||
state.sub_component_mapping.insert(ByAddress(c.clone()), state.sub_components.len());
|
||||
state.sub_components.push(sc);
|
||||
let idx = state.sub_components.push_and_get_key(sc);
|
||||
state.sub_component_mapping.insert(ByAddress(c.clone()), idx);
|
||||
}
|
||||
|
||||
let public_components = document
|
||||
|
@ -51,13 +52,12 @@ pub fn lower_to_item_tree(
|
|||
.map(|component| {
|
||||
let mut sc = lower_sub_component(&component, &mut state, None, compiler_config);
|
||||
let public_properties = public_properties(&component, &sc.mapping, &state);
|
||||
sc.sub_component.name = component.id.clone();
|
||||
let item_tree = ItemTree {
|
||||
tree: make_tree(&state, &component.root_element, &sc, &[]),
|
||||
root: state.sub_components.len(),
|
||||
root: state.sub_components.push_and_get_key(sc),
|
||||
parent_context: None,
|
||||
};
|
||||
sc.sub_component.name = component.id.clone();
|
||||
state.sub_components.push(sc);
|
||||
// For C++ codegen, the root component must have the same name as the public component
|
||||
PublicComponent {
|
||||
item_tree,
|
||||
|
@ -70,11 +70,6 @@ pub fn lower_to_item_tree(
|
|||
|
||||
let popup_menu = document.popup_menu_impl.as_ref().map(|c| {
|
||||
let sc = lower_sub_component(&c, &mut state, None, compiler_config);
|
||||
let item_tree = ItemTree {
|
||||
tree: make_tree(&state, &c.root_element, &sc, &[]),
|
||||
root: state.sub_components.len(),
|
||||
parent_context: None,
|
||||
};
|
||||
let sub_menu = sc.mapping.map_property_reference(
|
||||
&NamedReference::new(&c.root_element, SmolStr::new_static("sub-menu")),
|
||||
&state,
|
||||
|
@ -87,7 +82,11 @@ pub fn lower_to_item_tree(
|
|||
&NamedReference::new(&c.root_element, SmolStr::new_static("entries")),
|
||||
&state,
|
||||
);
|
||||
state.sub_components.push(sc);
|
||||
let item_tree = ItemTree {
|
||||
tree: make_tree(&state, &c.root_element, &sc, &[]),
|
||||
root: state.sub_components.push_and_get_key(sc),
|
||||
parent_context: None,
|
||||
};
|
||||
PopupMenu { item_tree, sub_menu, activated, entries }
|
||||
});
|
||||
|
||||
|
@ -113,9 +112,9 @@ pub fn lower_to_item_tree(
|
|||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum LoweredElement {
|
||||
SubComponent { sub_component_index: usize },
|
||||
NativeItem { item_index: u32 },
|
||||
Repeated { repeated_index: u32 },
|
||||
SubComponent { sub_component_index: SubComponentInstanceIdx },
|
||||
NativeItem { item_index: ItemInstanceIdx },
|
||||
Repeated { repeated_index: RepeatedElementIdx },
|
||||
ComponentPlaceholder { repeated_index: u32 },
|
||||
}
|
||||
|
||||
|
@ -182,8 +181,8 @@ pub struct LoweredSubComponent {
|
|||
#[derive(Default)]
|
||||
pub struct LoweringState {
|
||||
global_properties: HashMap<NamedReference, PropertyReference>,
|
||||
sub_components: Vec<LoweredSubComponent>,
|
||||
sub_component_mapping: HashMap<ByAddress<Rc<Component>>, SubComponentIndex>,
|
||||
sub_components: TiVec<SubComponentIdx, LoweredSubComponent>,
|
||||
sub_component_mapping: HashMap<ByAddress<Rc<Component>>, SubComponentIdx>,
|
||||
#[cfg(feature = "bundle-translations")]
|
||||
pub translation_builder: Option<super::translations::TranslationsBuilder>,
|
||||
}
|
||||
|
@ -203,20 +202,19 @@ impl LoweringState {
|
|||
&self.sub_components[self.sub_component_idx(component)]
|
||||
}
|
||||
|
||||
fn sub_component_idx(&self, component: &Rc<Component>) -> usize {
|
||||
fn sub_component_idx(&self, component: &Rc<Component>) -> SubComponentIdx {
|
||||
self.sub_component_mapping[&ByAddress(component.clone())]
|
||||
}
|
||||
|
||||
fn push_sub_component(&mut self, sc: LoweredSubComponent) -> SubComponentIndex {
|
||||
self.sub_components.push(sc);
|
||||
self.sub_components.len() - 1
|
||||
fn push_sub_component(&mut self, sc: LoweredSubComponent) -> SubComponentIdx {
|
||||
self.sub_components.push_and_get_key(sc)
|
||||
}
|
||||
}
|
||||
|
||||
// Map a PropertyReference within a `sub_component` to a PropertyReference to the component containing it
|
||||
fn property_reference_within_sub_component(
|
||||
mut prop_ref: PropertyReference,
|
||||
sub_component: usize,
|
||||
sub_component: SubComponentInstanceIdx,
|
||||
) -> PropertyReference {
|
||||
match &mut prop_ref {
|
||||
PropertyReference::Local { sub_component_path, .. }
|
||||
|
@ -271,7 +269,7 @@ fn lower_sub_component(
|
|||
prop_analysis: Default::default(),
|
||||
};
|
||||
let mut mapping = LoweredSubComponentMapping::default();
|
||||
let mut repeated = vec![];
|
||||
let mut repeated = TiVec::new();
|
||||
let mut component_container_data = vec![];
|
||||
let mut accessible_prop = Vec::new();
|
||||
let mut change_callbacks = Vec::new();
|
||||
|
@ -304,32 +302,30 @@ fn lower_sub_component(
|
|||
continue;
|
||||
}
|
||||
if let Type::Function(function) = &x.property_type {
|
||||
let function_index = sub_component.functions.len();
|
||||
mapping.property_mapping.insert(
|
||||
NamedReference::new(element, p.clone()),
|
||||
PropertyReference::Function { sub_component_path: vec![], function_index },
|
||||
);
|
||||
// TODO: Function could wrap the Rc<langtype::Function>
|
||||
// instead of cloning the return type and args?
|
||||
sub_component.functions.push(Function {
|
||||
let function_index = sub_component.functions.push_and_get_key(Function {
|
||||
name: p.clone(),
|
||||
ret_ty: function.return_type.clone(),
|
||||
args: function.args.clone(),
|
||||
// will be replaced later
|
||||
code: super::Expression::CodeBlock(vec![]),
|
||||
});
|
||||
mapping.property_mapping.insert(
|
||||
NamedReference::new(element, p.clone()),
|
||||
PropertyReference::Function { sub_component_path: vec![], function_index },
|
||||
);
|
||||
continue;
|
||||
}
|
||||
let property_index = sub_component.properties.len();
|
||||
mapping.property_mapping.insert(
|
||||
NamedReference::new(element, p.clone()),
|
||||
PropertyReference::Local { sub_component_path: vec![], property_index },
|
||||
);
|
||||
sub_component.properties.push(Property {
|
||||
let property_index = sub_component.properties.push_and_get_key(Property {
|
||||
name: format_smolstr!("{}_{}", elem.id, p),
|
||||
ty: x.property_type.clone(),
|
||||
..Property::default()
|
||||
});
|
||||
mapping.property_mapping.insert(
|
||||
NamedReference::new(element, p.clone()),
|
||||
PropertyReference::Local { sub_component_path: vec![], property_index },
|
||||
);
|
||||
}
|
||||
if elem.is_component_placeholder {
|
||||
mapping.element_mapping.insert(
|
||||
|
@ -345,40 +341,43 @@ fn lower_sub_component(
|
|||
if elem.repeated.is_some() {
|
||||
mapping.element_mapping.insert(
|
||||
element.clone().into(),
|
||||
LoweredElement::Repeated { repeated_index: repeated.len() as u32 },
|
||||
LoweredElement::Repeated {
|
||||
repeated_index: repeated.push_and_get_key(element.clone()),
|
||||
},
|
||||
);
|
||||
repeated.push(element.clone());
|
||||
mapping.repeater_count += 1;
|
||||
return None;
|
||||
}
|
||||
match &elem.base_type {
|
||||
ElementType::Component(comp) => {
|
||||
let ty = state.sub_component_idx(comp);
|
||||
let sub_component_index = sub_component.sub_components.len();
|
||||
let sub_component_index =
|
||||
sub_component.sub_components.push_and_get_key(SubComponentInstance {
|
||||
ty: ty.clone(),
|
||||
name: elem.id.clone(),
|
||||
index_in_tree: *elem.item_index.get().unwrap(),
|
||||
index_of_first_child_in_tree: *elem
|
||||
.item_index_of_first_children
|
||||
.get()
|
||||
.unwrap(),
|
||||
repeater_offset,
|
||||
});
|
||||
mapping.element_mapping.insert(
|
||||
element.clone().into(),
|
||||
LoweredElement::SubComponent { sub_component_index },
|
||||
);
|
||||
sub_component.sub_components.push(SubComponentInstance {
|
||||
ty: ty.clone(),
|
||||
name: elem.id.clone(),
|
||||
index_in_tree: *elem.item_index.get().unwrap(),
|
||||
index_of_first_child_in_tree: *elem.item_index_of_first_children.get().unwrap(),
|
||||
repeater_offset,
|
||||
});
|
||||
repeater_offset += comp.repeater_count();
|
||||
}
|
||||
|
||||
ElementType::Native(n) => {
|
||||
let item_index = sub_component.items.len() as u32;
|
||||
mapping
|
||||
.element_mapping
|
||||
.insert(element.clone().into(), LoweredElement::NativeItem { item_index });
|
||||
sub_component.items.push(Item {
|
||||
let item_index = sub_component.items.push_and_get_key(Item {
|
||||
ty: n.clone(),
|
||||
name: elem.id.clone(),
|
||||
index_in_tree: *elem.item_index.get().unwrap(),
|
||||
})
|
||||
});
|
||||
mapping
|
||||
.element_mapping
|
||||
.insert(element.clone().into(), LoweredElement::NativeItem { item_index });
|
||||
}
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
@ -671,8 +670,8 @@ fn lower_repeated_component(
|
|||
root: ctx.state.push_sub_component(sc),
|
||||
parent_context: Some(e.enclosing_component.upgrade().unwrap().id.clone()),
|
||||
},
|
||||
index_prop: (!repeated.is_conditional_element).then_some(1),
|
||||
data_prop: (!repeated.is_conditional_element).then_some(0),
|
||||
index_prop: (!repeated.is_conditional_element).then_some(1usize.into()),
|
||||
data_prop: (!repeated.is_conditional_element).then_some(0usize.into()),
|
||||
index_in_tree: *e.item_index.get().unwrap(),
|
||||
listview,
|
||||
}
|
||||
|
@ -686,11 +685,8 @@ fn lower_component_container(
|
|||
let c = container.borrow();
|
||||
|
||||
let component_container_index = *c.item_index.get().unwrap();
|
||||
let component_container_items_index = sub_component
|
||||
.items
|
||||
.iter()
|
||||
.position(|i| i.index_in_tree == component_container_index)
|
||||
.unwrap() as u32;
|
||||
let component_container_items_index =
|
||||
sub_component.items.position(|i| i.index_in_tree == component_container_index).unwrap();
|
||||
|
||||
ComponentContainerElement {
|
||||
component_container_item_tree_index: component_container_index,
|
||||
|
@ -752,39 +748,37 @@ fn lower_timer(timer: &object_tree::Timer, ctx: &ExpressionLoweringCtx) -> Timer
|
|||
/// Lower the globals (but not their expressions as we first need to lower all the global to get proper mapping in the state)
|
||||
fn lower_global(
|
||||
global: &Rc<Component>,
|
||||
global_index: usize,
|
||||
global_index: GlobalIdx,
|
||||
state: &mut LoweringState,
|
||||
) -> GlobalComponent {
|
||||
let mut properties = vec![];
|
||||
let mut const_properties = vec![];
|
||||
let mut prop_analysis = vec![];
|
||||
let mut functions = vec![];
|
||||
let mut properties = TiVec::new();
|
||||
let mut const_properties = TiVec::new();
|
||||
let mut prop_analysis = TiVec::new();
|
||||
let mut functions = TiVec::new();
|
||||
|
||||
for (p, x) in &global.root_element.borrow().property_declarations {
|
||||
if x.is_alias.is_some() {
|
||||
continue;
|
||||
}
|
||||
let property_index = properties.len();
|
||||
let nr = NamedReference::new(&global.root_element, p.clone());
|
||||
|
||||
if let Type::Function(function) = &x.property_type {
|
||||
let function_index = functions.len();
|
||||
state.global_properties.insert(
|
||||
nr.clone(),
|
||||
PropertyReference::GlobalFunction { global_index, function_index },
|
||||
);
|
||||
// TODO: wrap the Rc<langtype::Function> instead of cloning
|
||||
functions.push(Function {
|
||||
let function_index = functions.push_and_get_key(Function {
|
||||
name: p.clone(),
|
||||
ret_ty: function.return_type.clone(),
|
||||
args: function.args.clone(),
|
||||
// will be replaced later
|
||||
code: super::Expression::CodeBlock(vec![]),
|
||||
});
|
||||
state.global_properties.insert(
|
||||
nr.clone(),
|
||||
PropertyReference::GlobalFunction { global_index, function_index },
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
properties.push(Property {
|
||||
let property_index = properties.push_and_get_key(Property {
|
||||
name: p.clone(),
|
||||
ty: x.property_type.clone(),
|
||||
..Property::default()
|
||||
|
@ -812,8 +806,11 @@ fn lower_global(
|
|||
let is_builtin = if let Some(builtin) = global.root_element.borrow().native_class() {
|
||||
// We just generate the property so we know how to address them
|
||||
for (p, x) in &builtin.properties {
|
||||
let property_index = properties.len();
|
||||
properties.push(Property { name: p.clone(), ty: x.ty.clone(), ..Property::default() });
|
||||
let property_index = properties.push_and_get_key(Property {
|
||||
name: p.clone(),
|
||||
ty: x.ty.clone(),
|
||||
..Property::default()
|
||||
});
|
||||
let nr = NamedReference::new(&global.root_element, p.clone());
|
||||
state
|
||||
.global_properties
|
||||
|
@ -838,7 +835,7 @@ fn lower_global(
|
|||
|
||||
GlobalComponent {
|
||||
name: global.root_element.borrow().id.clone(),
|
||||
init_values: vec![None; properties.len()],
|
||||
init_values: typed_index_collections::ti_vec![None; properties.len()],
|
||||
properties,
|
||||
functions,
|
||||
change_callbacks: BTreeMap::new(),
|
||||
|
@ -907,7 +904,7 @@ fn make_tree(
|
|||
state: &LoweringState,
|
||||
element: &ElementRc,
|
||||
component: &LoweredSubComponent,
|
||||
sub_component_path: &[usize],
|
||||
sub_component_path: &[SubComponentInstanceIdx],
|
||||
) -> TreeNode {
|
||||
let e = element.borrow();
|
||||
let children = e.children.iter().map(|c| make_tree(state, c, component, sub_component_path));
|
||||
|
@ -933,26 +930,20 @@ fn make_tree(
|
|||
LoweredElement::NativeItem { item_index } => TreeNode {
|
||||
is_accessible: !e.accessibility_props.0.is_empty(),
|
||||
sub_component_path: sub_component_path.into(),
|
||||
item_index: *item_index,
|
||||
item_index: itertools::Either::Left(*item_index),
|
||||
children: children.collect(),
|
||||
repeated: false,
|
||||
component_container: false,
|
||||
},
|
||||
LoweredElement::Repeated { repeated_index } => TreeNode {
|
||||
is_accessible: false,
|
||||
sub_component_path: sub_component_path.into(),
|
||||
item_index: *repeated_index,
|
||||
item_index: itertools::Either::Right(usize::from(*repeated_index) as u32),
|
||||
children: vec![],
|
||||
repeated: true,
|
||||
component_container: false,
|
||||
},
|
||||
LoweredElement::ComponentPlaceholder { repeated_index } => TreeNode {
|
||||
is_accessible: false,
|
||||
sub_component_path: sub_component_path.into(),
|
||||
item_index: *repeated_index + repeater_count,
|
||||
item_index: itertools::Either::Right(*repeated_index + repeater_count),
|
||||
children: vec![],
|
||||
repeated: false,
|
||||
component_container: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
visit_property(&p.prop, &root_ctx);
|
||||
}
|
||||
}
|
||||
for (idx, g) in root.globals.iter().enumerate().filter(|(_, g)| g.exported) {
|
||||
for (idx, g) in root.globals.iter_enumerated().filter(|(_, g)| g.exported) {
|
||||
let ctx = EvaluationContext::new_global(root, idx, ());
|
||||
for p in g.public_properties.iter().filter(|p| {
|
||||
!matches!(
|
||||
|
@ -63,7 +63,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
expr.borrow().visit_property_references(ctx, &mut visit_property);
|
||||
}
|
||||
// 4. the models
|
||||
for (idx, r) in sc.repeated.iter().enumerate() {
|
||||
for (idx, r) in sc.repeated.iter_enumerated() {
|
||||
r.model.borrow().visit_property_references(ctx, &mut visit_property);
|
||||
if let Some(lv) = &r.listview {
|
||||
visit_property(&lv.viewport_y, ctx);
|
||||
|
@ -76,7 +76,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
root,
|
||||
r.sub_tree.root,
|
||||
(),
|
||||
Some(ParentCtx::new(ctx, Some(idx as u32))),
|
||||
Some(ParentCtx::new(ctx, Some(idx))),
|
||||
);
|
||||
visit_property(&lv.prop_y, &rep_ctx);
|
||||
visit_property(&lv.prop_height, &rep_ctx);
|
||||
|
@ -136,7 +136,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
});
|
||||
|
||||
// TODO: only visit used function
|
||||
for (idx, g) in root.globals.iter().enumerate() {
|
||||
for (idx, g) in root.globals.iter_enumerated() {
|
||||
let ctx = EvaluationContext::new_global(root, idx, ());
|
||||
for f in &g.functions {
|
||||
f.code.visit_property_references(&ctx, &mut visit_property);
|
||||
|
|
|
@ -8,7 +8,7 @@ use itertools::Itertools;
|
|||
use crate::expression_tree::MinMaxOp;
|
||||
|
||||
use super::{
|
||||
CompilationUnit, EvaluationContext, Expression, ParentCtx, PropertyReference, SubComponentIndex,
|
||||
CompilationUnit, EvaluationContext, Expression, ParentCtx, PropertyReference, SubComponentIdx,
|
||||
};
|
||||
|
||||
pub fn pretty_print(root: &CompilationUnit, writer: &mut dyn Write) -> Result {
|
||||
|
@ -22,12 +22,12 @@ struct PrettyPrinter<'a> {
|
|||
|
||||
impl<'a> PrettyPrinter<'a> {
|
||||
fn print_root(&mut self, root: &CompilationUnit) -> Result {
|
||||
for (idx, g) in root.globals.iter().enumerate() {
|
||||
for (idx, g) in root.globals.iter_enumerated() {
|
||||
if !g.is_builtin {
|
||||
self.print_global(root, idx, g)?;
|
||||
}
|
||||
}
|
||||
for c in 0..root.sub_components.len() {
|
||||
for c in root.sub_components.keys() {
|
||||
self.print_component(root, c, None)?
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ impl<'a> PrettyPrinter<'a> {
|
|||
fn print_component(
|
||||
&mut self,
|
||||
root: &CompilationUnit,
|
||||
sc_idx: SubComponentIndex,
|
||||
sc_idx: SubComponentIdx,
|
||||
parent: Option<ParentCtx<'_>>,
|
||||
) -> Result {
|
||||
let ctx = EvaluationContext::new_sub_component(root, sc_idx, (), parent);
|
||||
|
@ -98,14 +98,10 @@ impl<'a> PrettyPrinter<'a> {
|
|||
});
|
||||
writeln!(self.writer, "{} := {} {{ {geometry} }};", item.name, item.ty.class_name)?;
|
||||
}
|
||||
for (idx, r) in sc.repeated.iter().enumerate() {
|
||||
for (idx, r) in sc.repeated.iter_enumerated() {
|
||||
self.indent()?;
|
||||
write!(self.writer, "for in {} : ", DisplayExpression(&r.model.borrow(), &ctx))?;
|
||||
self.print_component(
|
||||
root,
|
||||
r.sub_tree.root,
|
||||
Some(ParentCtx::new(&ctx, Some(idx as u32))),
|
||||
)?
|
||||
self.print_component(root, r.sub_tree.root, Some(ParentCtx::new(&ctx, Some(idx))))?
|
||||
}
|
||||
for w in &sc.popup_windows {
|
||||
self.indent()?;
|
||||
|
@ -119,7 +115,7 @@ impl<'a> PrettyPrinter<'a> {
|
|||
fn print_global(
|
||||
&mut self,
|
||||
root: &CompilationUnit,
|
||||
idx: super::GlobalIndex,
|
||||
idx: super::GlobalIdx,
|
||||
global: &super::GlobalComponent,
|
||||
) -> Result {
|
||||
let ctx = EvaluationContext::new_global(root, idx, ());
|
||||
|
@ -206,7 +202,7 @@ impl<T> Display for DisplayPropertyRef<'_, T> {
|
|||
write!(f, "{}.", sc.sub_components[*i].name)?;
|
||||
sc = &ctx.compilation_unit.sub_components[sc.sub_components[*i].ty];
|
||||
}
|
||||
let i = &sc.items[*item_index as usize];
|
||||
let i = &sc.items[*item_index];
|
||||
write!(f, "{}.{}", i.name, prop_name)
|
||||
}
|
||||
PropertyReference::InParent { level, parent_reference } => {
|
||||
|
|
|
@ -385,10 +385,10 @@ mod plural_rule_parser {
|
|||
fn p(string: &str) -> String {
|
||||
let ctx = crate::llr::EvaluationContext {
|
||||
compilation_unit: &crate::llr::CompilationUnit {
|
||||
public_components: Vec::new(),
|
||||
sub_components: Vec::new(),
|
||||
used_sub_components: Vec::new(),
|
||||
globals: Vec::new(),
|
||||
public_components: Default::default(),
|
||||
sub_components: Default::default(),
|
||||
used_sub_components: Default::default(),
|
||||
globals: Default::default(),
|
||||
has_debug_info: false,
|
||||
translations: None,
|
||||
popup_menu: None,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue