mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 18:58:36 +00:00
llr: don't store Rc<SubComponent>
but an index instead
The goal eventually is to serialize the LLR and we can't do it if it uses Rc inside.
This commit is contained in:
parent
c739f1e9ba
commit
55bafbb51b
9 changed files with 328 additions and 261 deletions
|
@ -86,8 +86,11 @@ fn access_item_rc(pr: &llr::PropertyReference, ctx: &EvaluationContext) -> Strin
|
|||
match pr {
|
||||
llr::PropertyReference::InNativeItem { sub_component_path, item_index, prop_name } => {
|
||||
assert!(prop_name.is_empty());
|
||||
let (sub_compo_path, sub_component) =
|
||||
follow_sub_component_path(ctx.current_sub_component.unwrap(), sub_component_path);
|
||||
let (sub_compo_path, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
ctx.current_sub_component.unwrap(),
|
||||
sub_component_path,
|
||||
);
|
||||
if !sub_component_path.is_empty() {
|
||||
component_access += &sub_compo_path;
|
||||
}
|
||||
|
@ -724,12 +727,12 @@ pub fn generate(
|
|||
|
||||
let conditional_includes = ConditionalIncludes::default();
|
||||
|
||||
for sub_compo in &llr.sub_components {
|
||||
let sub_compo_id = ident(&sub_compo.name);
|
||||
for sub_compo in &llr.used_sub_components {
|
||||
let sub_compo_id = ident(&llr.sub_components[*sub_compo].name);
|
||||
let mut sub_compo_struct = Struct { name: sub_compo_id.clone(), ..Default::default() };
|
||||
generate_sub_component(
|
||||
&mut sub_compo_struct,
|
||||
sub_compo,
|
||||
*sub_compo,
|
||||
&llr,
|
||||
None,
|
||||
Access::Public,
|
||||
|
@ -820,7 +823,7 @@ pub fn generate(
|
|||
file.declarations.push(Declaration::Struct(globals_struct));
|
||||
|
||||
if let Some(popup_menu) = &llr.popup_menu {
|
||||
let component_id = ident(&popup_menu.item_tree.root.name);
|
||||
let component_id = ident(&llr.sub_components[popup_menu.item_tree.root].name);
|
||||
let mut popup_struct = Struct { name: component_id.clone(), ..Default::default() };
|
||||
generate_item_tree(
|
||||
&mut popup_struct,
|
||||
|
@ -1200,7 +1203,7 @@ fn generate_public_component(
|
|||
|
||||
let ctx = EvaluationContext {
|
||||
compilation_unit: unit,
|
||||
current_sub_component: Some(&component.item_tree.root),
|
||||
current_sub_component: Some(component.item_tree.root),
|
||||
current_global: None,
|
||||
generator_state: CppGeneratorContext {
|
||||
global_access: "(&this->m_globals)".to_string(),
|
||||
|
@ -1285,17 +1288,23 @@ fn generate_public_component(
|
|||
|
||||
component_struct.friends.push("slint::private_api::WindowAdapterRc".into());
|
||||
|
||||
add_friends(&mut component_struct.friends, &component.item_tree.root, true);
|
||||
add_friends(&mut component_struct.friends, unit, component.item_tree.root, true);
|
||||
|
||||
fn add_friends(friends: &mut Vec<SmolStr>, sc: &llr::SubComponent, is_root: bool) {
|
||||
fn add_friends(
|
||||
friends: &mut Vec<SmolStr>,
|
||||
unit: &llr::CompilationUnit,
|
||||
c: llr::SubComponentIndex,
|
||||
is_root: bool,
|
||||
) {
|
||||
let sc = &unit.sub_components[c];
|
||||
if !is_root {
|
||||
friends.push(ident(&sc.name));
|
||||
}
|
||||
for repeater in &sc.repeated {
|
||||
add_friends(friends, &repeater.sub_tree.root, false)
|
||||
add_friends(friends, unit, repeater.sub_tree.root, false)
|
||||
}
|
||||
for popup in &sc.popup_windows {
|
||||
add_friends(friends, &popup.item_tree.root, false)
|
||||
add_friends(friends, unit, popup.item_tree.root, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1321,7 +1330,7 @@ fn generate_item_tree(
|
|||
|
||||
generate_sub_component(
|
||||
target_struct,
|
||||
&sub_tree.root,
|
||||
sub_tree.root,
|
||||
root,
|
||||
parent_ctx,
|
||||
field_access,
|
||||
|
@ -1338,10 +1347,10 @@ fn generate_item_tree(
|
|||
if node.repeated {
|
||||
assert_eq!(node.children.len(), 0);
|
||||
let mut repeater_index = node.item_index;
|
||||
let mut sub_component = &sub_tree.root;
|
||||
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 = &sub_component.sub_components[*i].ty;
|
||||
sub_component = &root.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
item_tree_array.push(format!(
|
||||
"slint::private_api::make_dyn_node({}, {})",
|
||||
|
@ -1349,7 +1358,7 @@ fn generate_item_tree(
|
|||
));
|
||||
} else {
|
||||
let mut compo_offset = String::new();
|
||||
let mut sub_component = &sub_tree.root;
|
||||
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!(
|
||||
|
@ -1359,7 +1368,7 @@ fn generate_item_tree(
|
|||
next_sub_component_name
|
||||
)
|
||||
.unwrap();
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
sub_component = &root.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
|
||||
let item = &sub_component.items[node.item_index as usize];
|
||||
|
@ -1473,7 +1482,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 as usize].index_in_tree)
|
||||
}).map(|parent_index|
|
||||
vec![
|
||||
format!(
|
||||
|
@ -1713,7 +1722,7 @@ fn generate_item_tree(
|
|||
|
||||
if let Some(parent) = &parent_ctx {
|
||||
let parent_type =
|
||||
format!("class {} const *", ident(&parent.ctx.current_sub_component.unwrap().name));
|
||||
format!("class {} const *", ident(&parent.ctx.current_sub_component().unwrap().name));
|
||||
create_parameters.push(format!("{} parent", parent_type));
|
||||
|
||||
init_parent_parameters = ", parent";
|
||||
|
@ -1805,7 +1814,7 @@ fn generate_item_tree(
|
|||
|
||||
fn generate_sub_component(
|
||||
target_struct: &mut Struct,
|
||||
component: &llr::SubComponent,
|
||||
component: llr::SubComponentIndex,
|
||||
root: &llr::CompilationUnit,
|
||||
parent_ctx: Option<ParentCtx>,
|
||||
field_access: Access,
|
||||
|
@ -1866,7 +1875,7 @@ fn generate_sub_component(
|
|||
if let Some(parent_ctx) = &parent_ctx {
|
||||
let parent_type = format_smolstr!(
|
||||
"class {} const *",
|
||||
ident(&parent_ctx.ctx.current_sub_component.unwrap().name)
|
||||
ident(&parent_ctx.ctx.current_sub_component().unwrap().name)
|
||||
);
|
||||
init_parameters.push(format!("{} parent", parent_type));
|
||||
|
||||
|
@ -1884,8 +1893,10 @@ fn generate_sub_component(
|
|||
parent_ctx,
|
||||
);
|
||||
|
||||
let component = &root.sub_components[component];
|
||||
|
||||
component.popup_windows.iter().for_each(|popup| {
|
||||
let component_id = ident(&popup.item_tree.root.name);
|
||||
let component_id = ident(&root.sub_components[popup.item_tree.root].name);
|
||||
let mut popup_struct = Struct { name: component_id.clone(), ..Default::default() };
|
||||
generate_item_tree(
|
||||
&mut popup_struct,
|
||||
|
@ -1943,6 +1954,7 @@ fn generate_sub_component(
|
|||
|
||||
for sub in &component.sub_components {
|
||||
let field_name = ident(&sub.name);
|
||||
let sub_sc = &root.sub_components[sub.ty];
|
||||
let local_tree_index: u32 = sub.index_in_tree as _;
|
||||
let local_index_of_first_child: u32 = sub.index_of_first_child_in_tree as _;
|
||||
|
||||
|
@ -1965,7 +1977,7 @@ fn generate_sub_component(
|
|||
));
|
||||
user_init.push(format!("this->{}.user_init();", field_name));
|
||||
|
||||
let sub_component_repeater_count = sub.ty.repeater_count();
|
||||
let sub_component_repeater_count = sub_sc.repeater_count(root);
|
||||
if sub_component_repeater_count > 0 {
|
||||
let mut case_code = String::new();
|
||||
let repeater_offset = sub.repeater_offset;
|
||||
|
@ -2004,7 +2016,7 @@ fn generate_sub_component(
|
|||
target_struct.members.push((
|
||||
field_access,
|
||||
Declaration::Var(Var {
|
||||
ty: ident(&sub.ty.name),
|
||||
ty: ident(&sub_sc.name),
|
||||
name: field_name,
|
||||
..Default::default()
|
||||
}),
|
||||
|
@ -2033,7 +2045,7 @@ fn generate_sub_component(
|
|||
|
||||
let mut properties_init_code = Vec::new();
|
||||
for (prop, expression) in &component.property_init {
|
||||
if expression.use_count.get() > 0 && component.prop_used(prop) {
|
||||
if expression.use_count.get() > 0 && component.prop_used(prop, root) {
|
||||
handle_property_init(prop, expression, &mut properties_init_code, &ctx)
|
||||
}
|
||||
}
|
||||
|
@ -2052,8 +2064,9 @@ fn generate_sub_component(
|
|||
|
||||
for (idx, repeated) in component.repeated.iter().enumerate() {
|
||||
let idx = idx as u32;
|
||||
let sc = &root.sub_components[repeated.sub_tree.root];
|
||||
let data_type = if let Some(data_prop) = repeated.data_prop {
|
||||
repeated.sub_tree.root.properties[data_prop].ty.clone()
|
||||
sc.properties[data_prop].ty.clone()
|
||||
} else {
|
||||
Type::Int32
|
||||
};
|
||||
|
@ -2132,7 +2145,7 @@ fn generate_sub_component(
|
|||
Declaration::Var(Var {
|
||||
ty: format_smolstr!(
|
||||
"slint::private_api::Repeater<class {}, {}>",
|
||||
ident(&repeated.sub_tree.root.name),
|
||||
ident(&sc.name),
|
||||
data_type.cpp_type().unwrap(),
|
||||
),
|
||||
name: repeater_id,
|
||||
|
@ -2240,7 +2253,8 @@ fn generate_sub_component(
|
|||
|
||||
let mut else_ = "";
|
||||
for sub in &component.sub_components {
|
||||
let sub_items_count = sub.ty.child_item_count();
|
||||
let sub_sc = &ctx.compilation_unit.sub_components[sub.ty];
|
||||
let sub_items_count = sub_sc.child_item_count(ctx.compilation_unit);
|
||||
code.push(format!("{else_}if (index == {}) {{", sub.index_in_tree,));
|
||||
code.push(format!(" return self->{}.{name}(0{forward_args});", ident(&sub.name)));
|
||||
if sub_items_count > 1 {
|
||||
|
@ -2248,7 +2262,7 @@ fn generate_sub_component(
|
|||
"}} else if (index >= {} && index < {}) {{",
|
||||
sub.index_of_first_child_in_tree,
|
||||
sub.index_of_first_child_in_tree + sub_items_count - 1
|
||||
+ sub.ty.repeater_count()
|
||||
+ sub_sc.repeater_count(ctx.compilation_unit)
|
||||
));
|
||||
code.push(format!(
|
||||
" return self->{}.{name}(index - {}{forward_args});",
|
||||
|
@ -2425,7 +2439,7 @@ fn generate_repeated_component(
|
|||
file: &mut File,
|
||||
conditional_includes: &ConditionalIncludes,
|
||||
) {
|
||||
let repeater_id = ident(&repeated.sub_tree.root.name);
|
||||
let repeater_id = ident(&root.sub_components[repeated.sub_tree.root].name);
|
||||
let mut repeater_struct = Struct { name: repeater_id.clone(), ..Default::default() };
|
||||
generate_item_tree(
|
||||
&mut repeater_struct,
|
||||
|
@ -2441,7 +2455,7 @@ fn generate_repeated_component(
|
|||
|
||||
let ctx = EvaluationContext {
|
||||
compilation_unit: root,
|
||||
current_sub_component: Some(&repeated.sub_tree.root),
|
||||
current_sub_component: Some(repeated.sub_tree.root),
|
||||
current_global: None,
|
||||
generator_state: CppGeneratorContext { global_access: "self".into(), conditional_includes },
|
||||
parent: Some(parent_ctx),
|
||||
|
@ -2840,15 +2854,16 @@ fn generate_public_api_for_properties(
|
|||
}
|
||||
|
||||
fn follow_sub_component_path<'a>(
|
||||
root: &'a llr::SubComponent,
|
||||
compilation_unit: &'a llr::CompilationUnit,
|
||||
root: llr::SubComponentIndex,
|
||||
sub_component_path: &[usize],
|
||||
) -> (String, &'a llr::SubComponent) {
|
||||
let mut compo_path = String::new();
|
||||
let mut sub_component = root;
|
||||
let mut sub_component = &compilation_unit.sub_components[root];
|
||||
for i in sub_component_path {
|
||||
let sub_component_name = ident(&sub_component.sub_components[*i].name);
|
||||
write!(compo_path, "{}.", sub_component_name).unwrap();
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
sub_component = &compilation_unit.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
(compo_path, sub_component)
|
||||
}
|
||||
|
@ -2877,8 +2892,11 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
prop_name: &str,
|
||||
path: &str,
|
||||
) -> String {
|
||||
let (compo_path, sub_component) =
|
||||
follow_sub_component_path(ctx.current_sub_component.unwrap(), sub_component_path);
|
||||
let (compo_path, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
ctx.current_sub_component.unwrap(),
|
||||
sub_component_path,
|
||||
);
|
||||
let item_name = ident(&sub_component.items[item_index as usize].name);
|
||||
if prop_name.is_empty() {
|
||||
// then this is actually a reference to the element itself
|
||||
|
@ -2893,8 +2911,11 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
match reference {
|
||||
llr::PropertyReference::Local { sub_component_path, property_index } => {
|
||||
if let Some(sub_component) = ctx.current_sub_component {
|
||||
let (compo_path, sub_component) =
|
||||
follow_sub_component_path(sub_component, sub_component_path);
|
||||
let (compo_path, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
sub_component,
|
||||
sub_component_path,
|
||||
);
|
||||
let property_name = ident(&sub_component.properties[*property_index].name);
|
||||
format!("self->{}{}", compo_path, property_name)
|
||||
} else if let Some(current_global) = ctx.current_global {
|
||||
|
@ -2905,8 +2926,11 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
}
|
||||
llr::PropertyReference::Function { sub_component_path, function_index } => {
|
||||
if let Some(sub_component) = ctx.current_sub_component {
|
||||
let (compo_path, sub_component) =
|
||||
follow_sub_component_path(sub_component, sub_component_path);
|
||||
let (compo_path, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
sub_component,
|
||||
sub_component_path,
|
||||
);
|
||||
let name = ident(&sub_component.functions[*function_index].name);
|
||||
format!("self->{compo_path}fn_{name}")
|
||||
} else if let Some(current_global) = ctx.current_global {
|
||||
|
@ -2929,15 +2953,21 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
match &**parent_reference {
|
||||
llr::PropertyReference::Local { sub_component_path, property_index } => {
|
||||
let sub_component = ctx.current_sub_component.unwrap();
|
||||
let (compo_path, sub_component) =
|
||||
follow_sub_component_path(sub_component, sub_component_path);
|
||||
let (compo_path, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
sub_component,
|
||||
sub_component_path,
|
||||
);
|
||||
let property_name = ident(&sub_component.properties[*property_index].name);
|
||||
format!("{}->{}{}", path, compo_path, property_name)
|
||||
}
|
||||
llr::PropertyReference::Function { sub_component_path, function_index } => {
|
||||
let sub_component = ctx.current_sub_component.unwrap();
|
||||
let (compo_path, sub_component) =
|
||||
follow_sub_component_path(sub_component, sub_component_path);
|
||||
let (compo_path, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
sub_component,
|
||||
sub_component_path,
|
||||
);
|
||||
let name = ident(&sub_component.functions[*function_index].name);
|
||||
format!("{path}->{compo_path}fn_{name}")
|
||||
}
|
||||
|
@ -2982,10 +3012,11 @@ fn native_item<'a>(
|
|||
) -> &'a NativeClass {
|
||||
match item_ref {
|
||||
llr::PropertyReference::InNativeItem { sub_component_path, item_index, prop_name: _ } => {
|
||||
let mut sub_component = ctx.current_sub_component.unwrap();
|
||||
for i in sub_component_path {
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
}
|
||||
let (_, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
ctx.current_sub_component.unwrap(),
|
||||
sub_component_path,
|
||||
);
|
||||
&sub_component.items[*item_index as usize].ty
|
||||
}
|
||||
llr::PropertyReference::InParent { level, parent_reference } => {
|
||||
|
@ -3192,7 +3223,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 as usize]
|
||||
.index_prop
|
||||
.unwrap(),
|
||||
};
|
||||
|
@ -3669,14 +3700,14 @@ fn compile_builtin_function_call(
|
|||
};
|
||||
|
||||
let window = access_window_field(ctx);
|
||||
let current_sub_component = parent_ctx.current_sub_component.unwrap();
|
||||
let current_sub_component = parent_ctx.current_sub_component().unwrap();
|
||||
let popup = ¤t_sub_component.popup_windows[*popup_index as usize];
|
||||
let popup_window_id =
|
||||
ident(&popup.item_tree.root.name);
|
||||
ident(&ctx.compilation_unit.sub_components[popup.item_tree.root].name);
|
||||
let parent_component = access_item_rc(parent_ref, ctx);
|
||||
let popup_ctx = EvaluationContext::new_sub_component(
|
||||
ctx.compilation_unit,
|
||||
&popup.item_tree.root,
|
||||
popup.item_tree.root,
|
||||
CppGeneratorContext { global_access: "self->globals".into(), conditional_includes: ctx.generator_state.conditional_includes },
|
||||
Some(ParentCtx::new(&ctx, None)),
|
||||
);
|
||||
|
@ -3722,12 +3753,12 @@ fn compile_builtin_function_call(
|
|||
.popup_menu
|
||||
.as_ref()
|
||||
.expect("there should be a popup menu if we want to show it");
|
||||
let popup_id = ident(&popup.item_tree.root.name);
|
||||
let popup_id = ident(&ctx.compilation_unit.sub_components[popup.item_tree.root].name);
|
||||
let window = access_window_field(ctx);
|
||||
|
||||
let popup_ctx = EvaluationContext::new_sub_component(
|
||||
ctx.compilation_unit,
|
||||
&popup.item_tree.root,
|
||||
popup.item_tree.root,
|
||||
CppGeneratorContext { global_access: "self->globals".into(), conditional_includes: ctx.generator_state.conditional_includes },
|
||||
None,
|
||||
);
|
||||
|
|
|
@ -179,9 +179,9 @@ pub fn generate(
|
|||
}
|
||||
|
||||
let sub_compos = llr
|
||||
.sub_components
|
||||
.used_sub_components
|
||||
.iter()
|
||||
.map(|sub_compo| generate_sub_component(sub_compo, &llr, None, None, false))
|
||||
.map(|sub_compo| generate_sub_component(*sub_compo, &llr, None, None, false))
|
||||
.collect::<Vec<_>>();
|
||||
let public_components =
|
||||
llr.public_components.iter().map(|p| generate_public_component(p, &llr));
|
||||
|
@ -251,13 +251,13 @@ fn generate_public_component(
|
|||
unit: &llr::CompilationUnit,
|
||||
) -> TokenStream {
|
||||
let public_component_id = ident(&llr.name);
|
||||
let inner_component_id = inner_component_id(&llr.item_tree.root);
|
||||
let inner_component_id = inner_component_id(&unit.sub_components[llr.item_tree.root]);
|
||||
|
||||
let component = generate_item_tree(&llr.item_tree, unit, None, None, false);
|
||||
|
||||
let ctx = EvaluationContext {
|
||||
compilation_unit: unit,
|
||||
current_sub_component: Some(&llr.item_tree.root),
|
||||
current_sub_component: Some(llr.item_tree.root),
|
||||
current_global: None,
|
||||
generator_state: RustGeneratorContext {
|
||||
global_access: quote!(_self.globals.get().unwrap()),
|
||||
|
@ -668,17 +668,18 @@ fn public_api(
|
|||
|
||||
/// Generate the rust code for the given component.
|
||||
fn generate_sub_component(
|
||||
component: &llr::SubComponent,
|
||||
component_idx: llr::SubComponentIndex,
|
||||
root: &llr::CompilationUnit,
|
||||
parent_ctx: Option<ParentCtx>,
|
||||
index_property: Option<llr::PropertyIndex>,
|
||||
pinned_drop: bool,
|
||||
) -> TokenStream {
|
||||
let component = &root.sub_components[component_idx];
|
||||
let inner_component_id = inner_component_id(component);
|
||||
|
||||
let ctx = EvaluationContext::new_sub_component(
|
||||
root,
|
||||
component,
|
||||
component_idx,
|
||||
RustGeneratorContext { global_access: quote!(_self.globals.get().unwrap()) },
|
||||
parent_ctx,
|
||||
);
|
||||
|
@ -775,7 +776,8 @@ fn generate_sub_component(
|
|||
ParentCtx::new(&ctx, Some(idx)),
|
||||
));
|
||||
let repeater_id = format_ident!("repeater{}", idx);
|
||||
let rep_inner_component_id = self::inner_component_id(&repeated.sub_tree.root);
|
||||
let rep_inner_component_id =
|
||||
self::inner_component_id(&root.sub_components[repeated.sub_tree.root]);
|
||||
|
||||
let mut model = compile_expression(&repeated.model.borrow(), &ctx);
|
||||
if repeated.model.ty(&ctx) == Type::Bool {
|
||||
|
@ -932,7 +934,8 @@ fn generate_sub_component(
|
|||
|
||||
for sub in &component.sub_components {
|
||||
let field_name = ident(&sub.name);
|
||||
let sub_component_id = self::inner_component_id(&sub.ty);
|
||||
let sc = &root.sub_components[sub.ty];
|
||||
let sub_component_id = self::inner_component_id(sc);
|
||||
let local_tree_index: u32 = sub.index_in_tree as _;
|
||||
let local_index_of_first_child: u32 = sub.index_of_first_child_in_tree as _;
|
||||
let global_access = &ctx.generator_state.global_access;
|
||||
|
@ -960,7 +963,7 @@ fn generate_sub_component(
|
|||
sp::VRcMapped::map(self_rc.clone(), |x| #sub_compo_field.apply_pin(x)),
|
||||
);));
|
||||
|
||||
let sub_component_repeater_count = sub.ty.repeater_count();
|
||||
let sub_component_repeater_count = sc.repeater_count(root);
|
||||
if sub_component_repeater_count > 0 {
|
||||
let repeater_offset = sub.repeater_offset;
|
||||
let last_repeater = repeater_offset + sub_component_repeater_count - 1;
|
||||
|
@ -981,7 +984,7 @@ fn generate_sub_component(
|
|||
));
|
||||
}
|
||||
|
||||
let sub_items_count = sub.ty.child_item_count();
|
||||
let sub_items_count = sc.child_item_count(root);
|
||||
accessible_role_branch.push(quote!(
|
||||
#local_tree_index => #sub_compo_field.apply_pin(_self).accessible_role(0),
|
||||
));
|
||||
|
@ -996,7 +999,7 @@ fn generate_sub_component(
|
|||
));
|
||||
if sub_items_count > 1 {
|
||||
let range_begin = local_index_of_first_child;
|
||||
let range_end = range_begin + sub_items_count - 2 + sub.ty.repeater_count();
|
||||
let range_end = range_begin + sub_items_count - 2 + sc.repeater_count(root);
|
||||
accessible_role_branch.push(quote!(
|
||||
#range_begin..=#range_end => #sub_compo_field.apply_pin(_self).accessible_role(index - #range_begin + 1),
|
||||
));
|
||||
|
@ -1032,12 +1035,12 @@ fn generate_sub_component(
|
|||
}
|
||||
|
||||
for (prop, expression) in &component.property_init {
|
||||
if expression.use_count.get() > 0 && component.prop_used(prop) {
|
||||
if expression.use_count.get() > 0 && component.prop_used(prop, root) {
|
||||
handle_property_init(prop, expression, &mut init, &ctx)
|
||||
}
|
||||
}
|
||||
for prop in &component.const_properties {
|
||||
if component.prop_used(prop) {
|
||||
if component.prop_used(prop, root) {
|
||||
let rust_property = access_member(prop, &ctx).unwrap();
|
||||
init.push(quote!(#rust_property.set_constant();))
|
||||
}
|
||||
|
@ -1045,7 +1048,7 @@ fn generate_sub_component(
|
|||
|
||||
let parent_component_type = parent_ctx.iter().map(|parent| {
|
||||
let parent_component_id =
|
||||
self::inner_component_id(parent.ctx.current_sub_component.unwrap());
|
||||
self::inner_component_id(parent.ctx.current_sub_component().unwrap());
|
||||
quote!(sp::VWeakMapped::<sp::ItemTreeVTable, #parent_component_id>)
|
||||
});
|
||||
|
||||
|
@ -1493,13 +1496,13 @@ fn generate_item_tree(
|
|||
index_property: Option<llr::PropertyIndex>,
|
||||
is_popup_menu: bool,
|
||||
) -> TokenStream {
|
||||
let sub_comp = generate_sub_component(&sub_tree.root, root, parent_ctx, index_property, true);
|
||||
let inner_component_id = self::inner_component_id(&sub_tree.root);
|
||||
let sub_comp = generate_sub_component(sub_tree.root, root, parent_ctx, index_property, true);
|
||||
let inner_component_id = self::inner_component_id(&root.sub_components[sub_tree.root]);
|
||||
let parent_component_type = parent_ctx
|
||||
.iter()
|
||||
.map(|parent| {
|
||||
let parent_component_id =
|
||||
self::inner_component_id(parent.ctx.current_sub_component.unwrap());
|
||||
self::inner_component_id(parent.ctx.current_sub_component().unwrap());
|
||||
quote!(sp::VWeakMapped::<sp::ItemTreeVTable, #parent_component_id>)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
@ -1521,7 +1524,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 as usize].index_in_tree;
|
||||
|
||||
quote!(if let Some((parent_component, parent_index)) = self
|
||||
.parent
|
||||
|
@ -1538,14 +1541,15 @@ fn generate_item_tree(
|
|||
let mut item_array = vec![];
|
||||
sub_tree.tree.visit_in_array(&mut |node, children_offset, parent_index| {
|
||||
let parent_index = parent_index as u32;
|
||||
let (path, component) = follow_sub_component_path(&sub_tree.root, &node.sub_component_path);
|
||||
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 = &sub_tree.root;
|
||||
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 = &sub_component.sub_components[*i].ty;
|
||||
sub_component = &root.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
item_tree_array.push(quote!(
|
||||
sp::ItemTreeNode::DynamicTree {
|
||||
|
@ -1756,14 +1760,15 @@ fn generate_repeated_component(
|
|||
|
||||
let ctx = EvaluationContext {
|
||||
compilation_unit: unit,
|
||||
current_sub_component: Some(&repeated.sub_tree.root),
|
||||
current_sub_component: Some(repeated.sub_tree.root),
|
||||
current_global: None,
|
||||
generator_state: RustGeneratorContext { global_access: quote!(_self) },
|
||||
parent: Some(parent_ctx),
|
||||
argument_types: &[],
|
||||
};
|
||||
|
||||
let inner_component_id = self::inner_component_id(&repeated.sub_tree.root);
|
||||
let root_sc = &unit.sub_components[repeated.sub_tree.root];
|
||||
let inner_component_id = self::inner_component_id(&root_sc);
|
||||
|
||||
let extra_fn = if let Some(listview) = &repeated.listview {
|
||||
let p_y = access_member(&listview.prop_y, &ctx).unwrap();
|
||||
|
@ -1791,7 +1796,7 @@ fn generate_repeated_component(
|
|||
};
|
||||
|
||||
let data_type = if let Some(data_prop) = repeated.data_prop {
|
||||
rust_primitive_type(&repeated.sub_tree.root.properties[data_prop].ty).unwrap()
|
||||
rust_primitive_type(&root_sc.properties[data_prop].ty).unwrap()
|
||||
} else {
|
||||
quote!(())
|
||||
};
|
||||
|
@ -1884,8 +1889,11 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
prop_name: &str,
|
||||
path: TokenStream,
|
||||
) -> TokenStream {
|
||||
let (compo_path, sub_component) =
|
||||
follow_sub_component_path(ctx.current_sub_component.unwrap(), sub_component_path);
|
||||
let (compo_path, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
ctx.current_sub_component.unwrap(),
|
||||
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_field = access_component_field_offset(&component_id, &item_name);
|
||||
|
@ -1901,8 +1909,11 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
match reference {
|
||||
llr::PropertyReference::Local { sub_component_path, property_index } => {
|
||||
if let Some(sub_component) = ctx.current_sub_component {
|
||||
let (compo_path, sub_component) =
|
||||
follow_sub_component_path(sub_component, sub_component_path);
|
||||
let (compo_path, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
sub_component,
|
||||
sub_component_path,
|
||||
);
|
||||
let component_id = inner_component_id(sub_component);
|
||||
let property_name = ident(&sub_component.properties[*property_index].name);
|
||||
let property_field = access_component_field_offset(&component_id, &property_name);
|
||||
|
@ -1936,8 +1947,11 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
match &**parent_reference {
|
||||
llr::PropertyReference::Local { sub_component_path, property_index } => {
|
||||
let sub_component = ctx.current_sub_component.unwrap();
|
||||
let (compo_path, sub_component) =
|
||||
follow_sub_component_path(sub_component, sub_component_path);
|
||||
let (compo_path, sub_component) = follow_sub_component_path(
|
||||
ctx.compilation_unit,
|
||||
sub_component,
|
||||
sub_component_path,
|
||||
);
|
||||
let component_id = inner_component_id(sub_component);
|
||||
let property_name = ident(&sub_component.properties[*property_index].name);
|
||||
MemberAccess::Option(
|
||||
|
@ -1959,14 +1973,15 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
MemberAccess::Option(quote!(#path.as_ref().map(|x| #in_native)))
|
||||
}
|
||||
llr::PropertyReference::Function { sub_component_path, function_index } => {
|
||||
let mut sub_component = ctx.current_sub_component.unwrap();
|
||||
let mut sub_component = ctx.current_sub_component().unwrap();
|
||||
|
||||
let mut compo_path = quote!(x.as_pin_ref());
|
||||
for i in sub_component_path {
|
||||
let component_id = inner_component_id(sub_component);
|
||||
let sub_component_name = ident(&sub_component.sub_components[*i].name);
|
||||
compo_path = quote!( #component_id::FIELD_OFFSETS.#sub_component_name.apply_pin(#compo_path));
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
sub_component = &ctx.compilation_unit.sub_components
|
||||
[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
let fn_id =
|
||||
ident(&format!("fn_{}", sub_component.functions[*function_index].name));
|
||||
|
@ -1992,13 +2007,14 @@ fn access_member(reference: &llr::PropertyReference, ctx: &EvaluationContext) ->
|
|||
)
|
||||
}
|
||||
llr::PropertyReference::Function { sub_component_path, function_index } => {
|
||||
if let Some(mut sub_component) = ctx.current_sub_component {
|
||||
if let Some(mut sub_component) = ctx.current_sub_component() {
|
||||
let mut compo_path = quote!(_self);
|
||||
for i in sub_component_path {
|
||||
let component_id = inner_component_id(sub_component);
|
||||
let sub_component_name = ident(&sub_component.sub_components[*i].name);
|
||||
compo_path = quote!( #component_id::FIELD_OFFSETS.#sub_component_name.apply_pin(#compo_path));
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
sub_component =
|
||||
&ctx.compilation_unit.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
let fn_id = ident(&format!("fn_{}", sub_component.functions[*function_index].name));
|
||||
MemberAccess::Direct(quote!(#compo_path.#fn_id))
|
||||
|
@ -2087,16 +2103,17 @@ impl MemberAccess {
|
|||
}
|
||||
|
||||
fn follow_sub_component_path<'a>(
|
||||
root: &'a llr::SubComponent,
|
||||
compilation_unit: &'a llr::CompilationUnit,
|
||||
root: llr::SubComponentIndex,
|
||||
sub_component_path: &[usize],
|
||||
) -> (TokenStream, &'a llr::SubComponent) {
|
||||
let mut compo_path = quote!();
|
||||
let mut sub_component = root;
|
||||
let mut sub_component = &compilation_unit.sub_components[root];
|
||||
for i in sub_component_path {
|
||||
let component_id = inner_component_id(sub_component);
|
||||
let sub_component_name = ident(&sub_component.sub_components[*i].name);
|
||||
compo_path = quote!(#compo_path {#component_id::FIELD_OFFSETS.#sub_component_name} +);
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
sub_component = &compilation_unit.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
(compo_path, sub_component)
|
||||
}
|
||||
|
@ -2128,12 +2145,13 @@ fn access_item_rc(pr: &llr::PropertyReference, ctx: &EvaluationContext) -> Token
|
|||
llr::PropertyReference::InNativeItem { sub_component_path, item_index, prop_name } => {
|
||||
assert!(prop_name.is_empty());
|
||||
|
||||
let root = ctx.current_sub_component.unwrap();
|
||||
let root = ctx.current_sub_component().unwrap();
|
||||
let mut sub_component = root;
|
||||
for i in sub_component_path {
|
||||
let sub_component_name = ident(&sub_component.sub_components[*i].name);
|
||||
component_access_tokens = quote!(#component_access_tokens . #sub_component_name);
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
sub_component =
|
||||
&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;
|
||||
|
@ -2325,7 +2343,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
|
||||
property_index: ctx2.current_sub_component().unwrap().repeated
|
||||
[repeater_index as usize]
|
||||
.index_prop
|
||||
.unwrap(),
|
||||
|
@ -2336,7 +2354,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()),
|
||||
&inner_component_id(ctx2.current_sub_component().unwrap()),
|
||||
&format_ident!("repeater{}", repeater_index),
|
||||
);
|
||||
quote!(#repeater.apply_pin(#path.as_pin_ref()).model_set_row_data(#index_access as _, #value as _))
|
||||
|
@ -2674,14 +2692,15 @@ fn compile_builtin_function_call(
|
|||
parent_ctx = parent_ctx.parent.as_ref().unwrap().ctx;
|
||||
}
|
||||
}
|
||||
let current_sub_component = parent_ctx.current_sub_component.unwrap();
|
||||
let current_sub_component = parent_ctx.current_sub_component().unwrap();
|
||||
let popup = ¤t_sub_component.popup_windows[*popup_index as usize];
|
||||
let popup_window_id = inner_component_id(&popup.item_tree.root);
|
||||
let popup_window_id =
|
||||
inner_component_id(&ctx.compilation_unit.sub_components[popup.item_tree.root]);
|
||||
let parent_component = access_item_rc(parent_ref, ctx);
|
||||
|
||||
let popup_ctx = EvaluationContext::new_sub_component(
|
||||
ctx.compilation_unit,
|
||||
&popup.item_tree.root,
|
||||
popup.item_tree.root,
|
||||
RustGeneratorContext { global_access: quote!(_self.globals.get().unwrap()) },
|
||||
Some(ParentCtx::new(&ctx, None)),
|
||||
);
|
||||
|
@ -2750,12 +2769,13 @@ fn compile_builtin_function_call(
|
|||
.popup_menu
|
||||
.as_ref()
|
||||
.expect("there should be a popup menu if we want to show it");
|
||||
let popup_id = inner_component_id(&popup.item_tree.root);
|
||||
let popup_id =
|
||||
inner_component_id(&ctx.compilation_unit.sub_components[popup.item_tree.root]);
|
||||
let window_adapter_tokens = access_window_adapter_field(ctx);
|
||||
|
||||
let popup_ctx = EvaluationContext::new_sub_component(
|
||||
ctx.compilation_unit,
|
||||
&popup.item_tree.root,
|
||||
popup.item_tree.root,
|
||||
RustGeneratorContext { global_access: quote!(_self.globals.get().unwrap()) },
|
||||
None,
|
||||
);
|
||||
|
@ -3005,7 +3025,7 @@ fn compile_builtin_function_call(
|
|||
let entries = compile_expression(entries, ctx);
|
||||
let sub_menu = access_member(sub_menu, ctx).unwrap();
|
||||
let activated = access_member(activated, ctx).unwrap();
|
||||
let inner_component_id = self::inner_component_id(ctx.current_sub_component.unwrap());
|
||||
let inner_component_id = self::inner_component_id(ctx.current_sub_component().unwrap());
|
||||
quote! {
|
||||
if sp::WindowInner::from_pub(#window_adapter_tokens.window()).supports_native_menu_bar() {
|
||||
// May seem overkill to have an instance of the struct for each call, but there should only be one call per component anyway
|
||||
|
@ -3107,7 +3127,7 @@ fn box_layout_function(
|
|||
ctx: &EvaluationContext,
|
||||
) -> TokenStream {
|
||||
let repeated_indices = repeated_indices.map(ident);
|
||||
let inner_component_id = self::inner_component_id(ctx.current_sub_component.unwrap());
|
||||
let inner_component_id = self::inner_component_id(ctx.current_sub_component().unwrap());
|
||||
let mut fixed_count = 0usize;
|
||||
let mut repeated_count = quote!();
|
||||
let mut push_code = vec![];
|
||||
|
@ -3122,7 +3142,12 @@ fn box_layout_function(
|
|||
Either::Right(repeater) => {
|
||||
let repeater_id = format_ident!("repeater{}", repeater);
|
||||
let rep_inner_component_id = self::inner_component_id(
|
||||
&ctx.current_sub_component.unwrap().repeated[*repeater as usize].sub_tree.root,
|
||||
&ctx.compilation_unit.sub_components[ctx
|
||||
.current_sub_component()
|
||||
.unwrap()
|
||||
.repeated[*repeater as usize]
|
||||
.sub_tree
|
||||
.root],
|
||||
);
|
||||
repeated_count = quote!(#repeated_count + _self.#repeater_id.len());
|
||||
let ri = repeated_indices.as_ref().map(|ri| {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// 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::PropertyReference;
|
||||
use super::{PropertyReference, SubComponentIndex};
|
||||
use crate::expression_tree::{BuiltinFunction, MinMaxOp, OperatorClass};
|
||||
use crate::langtype::Type;
|
||||
use crate::layout::Orientation;
|
||||
|
@ -481,7 +481,7 @@ impl<'a, T> ParentCtx<'a, T> {
|
|||
#[derive(Clone)]
|
||||
pub struct EvaluationContext<'a, T = ()> {
|
||||
pub compilation_unit: &'a super::CompilationUnit,
|
||||
pub current_sub_component: Option<&'a super::SubComponent>,
|
||||
pub current_sub_component: Option<SubComponentIndex>,
|
||||
pub current_global: Option<&'a super::GlobalComponent>,
|
||||
pub generator_state: T,
|
||||
/// The repeater parent
|
||||
|
@ -494,7 +494,7 @@ pub struct EvaluationContext<'a, T = ()> {
|
|||
impl<'a, T> EvaluationContext<'a, T> {
|
||||
pub fn new_sub_component(
|
||||
compilation_unit: &'a super::CompilationUnit,
|
||||
sub_component: &'a super::SubComponent,
|
||||
sub_component: SubComponentIndex,
|
||||
generator_state: T,
|
||||
parent: Option<ParentCtx<'a, T>>,
|
||||
) -> Self {
|
||||
|
@ -525,6 +525,7 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
|
||||
pub(crate) fn property_info<'b>(&'b self, prop: &PropertyReference) -> PropertyInfoResult<'b> {
|
||||
fn match_in_sub_component<'b>(
|
||||
cu: &'b super::CompilationUnit,
|
||||
sc: &'b super::SubComponent,
|
||||
prop: &PropertyReference,
|
||||
map: ContextMap,
|
||||
|
@ -533,7 +534,7 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
if let PropertyReference::Local { property_index, sub_component_path } = &prop {
|
||||
let mut sc = sc;
|
||||
for i in sub_component_path {
|
||||
sc = &sc.sub_components[*i].ty;
|
||||
sc = &cu.sub_components[sc.sub_components[*i].ty];
|
||||
}
|
||||
Some(&sc.properties[*property_index])
|
||||
} else {
|
||||
|
@ -570,7 +571,8 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
};
|
||||
let idx = sub_component_path[0];
|
||||
return apply_analysis(match_in_sub_component(
|
||||
&sc.sub_components[idx].ty,
|
||||
cu,
|
||||
&cu.sub_components[sc.sub_components[idx].ty],
|
||||
&prop2,
|
||||
map.deeper_in_sub_component(idx),
|
||||
));
|
||||
|
@ -585,7 +587,8 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
};
|
||||
let idx = sub_component_path[0];
|
||||
return apply_analysis(match_in_sub_component(
|
||||
&sc.sub_components[idx].ty,
|
||||
cu,
|
||||
&cu.sub_components[sc.sub_components[idx].ty],
|
||||
&prop2,
|
||||
map.deeper_in_sub_component(idx),
|
||||
));
|
||||
|
@ -610,15 +613,21 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
animation: None,
|
||||
property_decl: Some(&g.properties[*property_index]),
|
||||
};
|
||||
} else if let Some(sc) = self.current_sub_component.as_ref() {
|
||||
return match_in_sub_component(sc, prop, ContextMap::Identity);
|
||||
} else if let Some(sc) = self.current_sub_component() {
|
||||
return match_in_sub_component(
|
||||
self.compilation_unit,
|
||||
sc,
|
||||
prop,
|
||||
ContextMap::Identity,
|
||||
);
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
PropertyReference::InNativeItem { .. } => {
|
||||
return match_in_sub_component(
|
||||
self.current_sub_component.as_ref().unwrap(),
|
||||
self.compilation_unit,
|
||||
self.current_sub_component().unwrap(),
|
||||
prop,
|
||||
ContextMap::Identity,
|
||||
);
|
||||
|
@ -661,15 +670,20 @@ impl<'a, T> EvaluationContext<'a, T> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn current_sub_component(&self) -> Option<&super::SubComponent> {
|
||||
self.current_sub_component.and_then(|i| self.compilation_unit.sub_components.get(i))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> TypeResolutionContext for EvaluationContext<'a, T> {
|
||||
fn property_ty(&self, prop: &PropertyReference) -> &Type {
|
||||
match prop {
|
||||
PropertyReference::Local { sub_component_path, property_index } => {
|
||||
if let Some(mut sub_component) = self.current_sub_component {
|
||||
if let Some(mut sub_component) = self.current_sub_component() {
|
||||
for i in sub_component_path {
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
sub_component = &self.compilation_unit.sub_components
|
||||
[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
&sub_component.properties[*property_index].ty
|
||||
} else if let Some(current_global) = self.current_global {
|
||||
|
@ -684,9 +698,10 @@ impl<'a, T> TypeResolutionContext for EvaluationContext<'a, T> {
|
|||
return &Type::PathData;
|
||||
}
|
||||
|
||||
let mut sub_component = self.current_sub_component.unwrap();
|
||||
let mut sub_component = self.current_sub_component().unwrap();
|
||||
for i in sub_component_path {
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
sub_component =
|
||||
&self.compilation_unit.sub_components[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
|
||||
sub_component.items[*item_index as usize].ty.lookup_property(prop_name).unwrap()
|
||||
|
@ -702,9 +717,10 @@ impl<'a, T> TypeResolutionContext for EvaluationContext<'a, T> {
|
|||
&self.compilation_unit.globals[*global_index].properties[*property_index].ty
|
||||
}
|
||||
PropertyReference::Function { sub_component_path, function_index } => {
|
||||
if let Some(mut sub_component) = self.current_sub_component {
|
||||
if let Some(mut sub_component) = self.current_sub_component() {
|
||||
for i in sub_component_path {
|
||||
sub_component = &sub_component.sub_components[*i].ty;
|
||||
sub_component = &self.compilation_unit.sub_components
|
||||
[sub_component.sub_components[*i].ty];
|
||||
}
|
||||
&sub_component.functions[*function_index].ret_ty
|
||||
} else if let Some(current_global) = self.current_global {
|
||||
|
@ -840,7 +856,7 @@ impl ContextMap {
|
|||
} else {
|
||||
let mut e = ctx.current_sub_component.unwrap();
|
||||
for i in path {
|
||||
e = &e.sub_components[*i].ty;
|
||||
e = ctx.compilation_unit.sub_components[e].sub_components[*i].ty;
|
||||
}
|
||||
EvaluationContext::new_sub_component(ctx.compilation_unit, e, (), None)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ use std::rc::Rc;
|
|||
|
||||
// Index in the `SubComponent::properties`
|
||||
pub type PropertyIndex = usize;
|
||||
// Index in CompilationUint::sub_components
|
||||
pub type SubComponentIndex = usize;
|
||||
|
||||
#[derive(Debug, Clone, derive_more::Deref)]
|
||||
pub struct MutExpression(RefCell<Expression>);
|
||||
|
@ -297,29 +299,29 @@ pub struct PropAnalysis {
|
|||
|
||||
impl SubComponent {
|
||||
/// total count of repeater, including in sub components
|
||||
pub fn repeater_count(&self) -> u32 {
|
||||
pub fn repeater_count(&self, cu: &CompilationUnit) -> u32 {
|
||||
let mut count = (self.repeated.len() + self.component_containers.len()) as u32;
|
||||
for x in self.sub_components.iter() {
|
||||
count += x.ty.repeater_count();
|
||||
count += cu.sub_components[x.ty].repeater_count(cu);
|
||||
}
|
||||
count
|
||||
}
|
||||
|
||||
/// total count of items, including in sub components
|
||||
pub fn child_item_count(&self) -> u32 {
|
||||
pub fn child_item_count(&self, cu: &CompilationUnit) -> u32 {
|
||||
let mut count = self.items.len() as u32;
|
||||
for x in self.sub_components.iter() {
|
||||
count += x.ty.child_item_count();
|
||||
count += cu.sub_components[x.ty].child_item_count(cu);
|
||||
}
|
||||
count
|
||||
}
|
||||
|
||||
/// Return if a local property is used. (unused property shouldn't be generated)
|
||||
pub fn prop_used(&self, prop: &PropertyReference) -> bool {
|
||||
pub fn prop_used(&self, prop: &PropertyReference, cu: &CompilationUnit) -> bool {
|
||||
if let PropertyReference::Local { property_index, sub_component_path } = prop {
|
||||
let mut sc = self;
|
||||
for i in sub_component_path {
|
||||
sc = &sc.sub_components[*i].ty;
|
||||
sc = &cu.sub_components[sc.sub_components[*i].ty];
|
||||
}
|
||||
if sc.properties[*property_index].use_count.get() == 0 {
|
||||
return false;
|
||||
|
@ -329,30 +331,18 @@ impl SubComponent {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct SubComponentInstance {
|
||||
pub ty: Rc<SubComponent>,
|
||||
pub ty: SubComponentIndex,
|
||||
pub name: SmolStr,
|
||||
pub index_in_tree: u32,
|
||||
pub index_of_first_child_in_tree: u32,
|
||||
pub repeater_offset: u32,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for SubComponentInstance {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("SubComponentInstance")
|
||||
// only dump ty.name, not the whole structure
|
||||
.field("ty", &self.ty.name)
|
||||
.field("name", &self.name)
|
||||
.field("index_in_tree", &self.index_in_tree)
|
||||
.field("index_of_first_child_in_tree", &self.index_of_first_child_in_tree)
|
||||
.field("repeater_offset", &self.repeater_offset)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ItemTree {
|
||||
pub root: SubComponent,
|
||||
pub root: SubComponentIndex,
|
||||
pub tree: TreeNode,
|
||||
/// This tree has a parent. e.g: it is a Repeater or a PopupWindow whose property can access
|
||||
/// the parent ItemTree.
|
||||
|
@ -371,7 +361,10 @@ pub struct PublicComponent {
|
|||
#[derive(Debug)]
|
||||
pub struct CompilationUnit {
|
||||
pub public_components: Vec<PublicComponent>,
|
||||
pub sub_components: Vec<Rc<SubComponent>>,
|
||||
/// Storage for all sub-components
|
||||
pub sub_components: Vec<SubComponent>,
|
||||
/// The sub-components that are not item-tree root
|
||||
pub used_sub_components: Vec<SubComponentIndex>,
|
||||
pub globals: Vec<GlobalComponent>,
|
||||
pub popup_menu: Option<PopupMenu>,
|
||||
pub has_debug_info: bool,
|
||||
|
@ -386,37 +379,38 @@ impl CompilationUnit {
|
|||
) {
|
||||
fn visit_component<'a>(
|
||||
root: &'a CompilationUnit,
|
||||
c: &'a SubComponent,
|
||||
c: SubComponentIndex,
|
||||
visitor: &mut dyn FnMut(&'a SubComponent, &EvaluationContext<'_>),
|
||||
parent: Option<ParentCtx<'_>>,
|
||||
) {
|
||||
let ctx = EvaluationContext::new_sub_component(root, c, (), parent);
|
||||
visitor(c, &ctx);
|
||||
for (idx, r) in c.repeated.iter().enumerate() {
|
||||
let sc = &root.sub_components[c];
|
||||
visitor(sc, &ctx);
|
||||
for (idx, r) in sc.repeated.iter().enumerate() {
|
||||
visit_component(
|
||||
root,
|
||||
&r.sub_tree.root,
|
||||
r.sub_tree.root,
|
||||
visitor,
|
||||
Some(ParentCtx::new(&ctx, Some(idx as u32))),
|
||||
);
|
||||
}
|
||||
for popup in &c.popup_windows {
|
||||
for popup in &sc.popup_windows {
|
||||
visit_component(
|
||||
root,
|
||||
&popup.item_tree.root,
|
||||
popup.item_tree.root,
|
||||
visitor,
|
||||
Some(ParentCtx::new(&ctx, None)),
|
||||
);
|
||||
}
|
||||
}
|
||||
for c in &self.sub_components {
|
||||
visit_component(self, c, visitor, None);
|
||||
for c in &self.used_sub_components {
|
||||
visit_component(self, *c, visitor, None);
|
||||
}
|
||||
for p in &self.public_components {
|
||||
visit_component(self, &p.item_tree.root, visitor, None);
|
||||
visit_component(self, p.item_tree.root, visitor, None);
|
||||
}
|
||||
if let Some(p) = &self.popup_menu {
|
||||
visit_component(self, &p.item_tree.root, visitor, None);
|
||||
visit_component(self, p.item_tree.root, visitor, None);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,11 +20,17 @@ use crate::namedreference::NamedReference;
|
|||
use crate::object_tree::{Element, ElementRc, PropertyAnimation};
|
||||
use crate::typeregister::BUILTIN;
|
||||
|
||||
pub struct ExpressionContext<'a> {
|
||||
pub struct ExpressionContextInner<'a> {
|
||||
pub component: &'a Rc<crate::object_tree::Component>,
|
||||
/// The mapping for the current component
|
||||
pub mapping: &'a LoweredSubComponentMapping,
|
||||
pub state: &'a LoweringState,
|
||||
pub parent: Option<&'a ExpressionContext<'a>>,
|
||||
pub parent: Option<&'a ExpressionContextInner<'a>>,
|
||||
}
|
||||
#[derive(derive_more::Deref)]
|
||||
pub struct ExpressionContext<'a> {
|
||||
pub state: &'a mut LoweringState,
|
||||
#[deref]
|
||||
pub inner: ExpressionContextInner<'a>,
|
||||
}
|
||||
|
||||
impl ExpressionContext<'_> {
|
||||
|
@ -32,7 +38,7 @@ impl ExpressionContext<'_> {
|
|||
let element = from.element();
|
||||
let enclosing = &element.borrow().enclosing_component.upgrade().unwrap();
|
||||
if !enclosing.is_global() {
|
||||
let mut map = self;
|
||||
let mut map = &self.inner;
|
||||
let mut level = 0;
|
||||
while !Rc::ptr_eq(enclosing, map.component) {
|
||||
map = map.parent.unwrap();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use by_address::ByAddress;
|
||||
|
||||
use super::lower_expression::ExpressionContext;
|
||||
use super::lower_expression::{ExpressionContext, ExpressionContextInner};
|
||||
use crate::expression_tree::Expression as tree_Expression;
|
||||
use crate::langtype::{ElementType, Struct, Type};
|
||||
use crate::llr::item_tree::*;
|
||||
|
@ -41,22 +41,24 @@ pub fn lower_to_item_tree(
|
|||
}
|
||||
|
||||
for c in &document.used_types.borrow().sub_components {
|
||||
let sc = lower_sub_component(c, &state, None, compiler_config);
|
||||
state.sub_components.insert(ByAddress(c.clone()), sc);
|
||||
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 public_components = document
|
||||
.exported_roots()
|
||||
.map(|component| {
|
||||
let sc = lower_sub_component(&component, &state, None, compiler_config);
|
||||
let mut sc = lower_sub_component(&component, &mut state, None, compiler_config);
|
||||
let public_properties = public_properties(&component, &sc.mapping, &state);
|
||||
let mut item_tree = ItemTree {
|
||||
let item_tree = ItemTree {
|
||||
tree: make_tree(&state, &component.root_element, &sc, &[]),
|
||||
root: Rc::try_unwrap(sc.sub_component).unwrap(),
|
||||
root: state.sub_components.len(),
|
||||
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
|
||||
item_tree.root.name = component.id.clone();
|
||||
PublicComponent {
|
||||
item_tree,
|
||||
public_properties,
|
||||
|
@ -67,40 +69,38 @@ pub fn lower_to_item_tree(
|
|||
.collect();
|
||||
|
||||
let popup_menu = document.popup_menu_impl.as_ref().map(|c| {
|
||||
let sc = lower_sub_component(&c, &state, None, compiler_config);
|
||||
let sc = lower_sub_component(&c, &mut state, None, compiler_config);
|
||||
let item_tree = ItemTree {
|
||||
tree: make_tree(&state, &c.root_element, &sc, &[]),
|
||||
root: Rc::try_unwrap(sc.sub_component).unwrap(),
|
||||
root: state.sub_components.len(),
|
||||
parent_context: None,
|
||||
};
|
||||
PopupMenu {
|
||||
item_tree,
|
||||
sub_menu: sc.mapping.map_property_reference(
|
||||
&NamedReference::new(&c.root_element, SmolStr::new_static("sub-menu")),
|
||||
&state,
|
||||
),
|
||||
activated: sc.mapping.map_property_reference(
|
||||
&NamedReference::new(&c.root_element, SmolStr::new_static("activated")),
|
||||
&state,
|
||||
),
|
||||
entries: sc.mapping.map_property_reference(
|
||||
&NamedReference::new(&c.root_element, SmolStr::new_static("entries")),
|
||||
&state,
|
||||
),
|
||||
}
|
||||
let sub_menu = sc.mapping.map_property_reference(
|
||||
&NamedReference::new(&c.root_element, SmolStr::new_static("sub-menu")),
|
||||
&state,
|
||||
);
|
||||
let activated = sc.mapping.map_property_reference(
|
||||
&NamedReference::new(&c.root_element, SmolStr::new_static("activated")),
|
||||
&state,
|
||||
);
|
||||
let entries = sc.mapping.map_property_reference(
|
||||
&NamedReference::new(&c.root_element, SmolStr::new_static("entries")),
|
||||
&state,
|
||||
);
|
||||
state.sub_components.push(sc);
|
||||
PopupMenu { item_tree, sub_menu, activated, entries }
|
||||
});
|
||||
|
||||
let root = CompilationUnit {
|
||||
public_components,
|
||||
globals,
|
||||
sub_components: document
|
||||
sub_components: state.sub_components.into_iter().map(|sc| sc.sub_component).collect(),
|
||||
used_sub_components: document
|
||||
.used_types
|
||||
.borrow()
|
||||
.sub_components
|
||||
.iter()
|
||||
.map(|tree_sub_compo| {
|
||||
state.sub_components[&ByAddress(tree_sub_compo.clone())].sub_component.clone()
|
||||
})
|
||||
.map(|tree_sub_compo| state.sub_component_mapping[&ByAddress(tree_sub_compo.clone())])
|
||||
.collect(),
|
||||
has_debug_info: compiler_config.debug_info,
|
||||
popup_menu,
|
||||
|
@ -111,14 +111,6 @@ pub fn lower_to_item_tree(
|
|||
Ok(root)
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct LoweringState {
|
||||
global_properties: HashMap<NamedReference, PropertyReference>,
|
||||
sub_components: HashMap<ByAddress<Rc<Component>>, LoweredSubComponent>,
|
||||
#[cfg(feature = "bundle-translations")]
|
||||
pub translation_builder: Option<std::cell::RefCell<super::translations::TranslationsBuilder>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum LoweredElement {
|
||||
SubComponent { sub_component_index: usize },
|
||||
|
@ -183,10 +175,19 @@ impl LoweredSubComponentMapping {
|
|||
}
|
||||
|
||||
pub struct LoweredSubComponent {
|
||||
sub_component: Rc<SubComponent>,
|
||||
sub_component: SubComponent,
|
||||
mapping: LoweredSubComponentMapping,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct LoweringState {
|
||||
global_properties: HashMap<NamedReference, PropertyReference>,
|
||||
sub_components: Vec<LoweredSubComponent>,
|
||||
sub_component_mapping: HashMap<ByAddress<Rc<Component>>, SubComponentIndex>,
|
||||
#[cfg(feature = "bundle-translations")]
|
||||
pub translation_builder: Option<std::cell::RefCell<super::translations::TranslationsBuilder>>,
|
||||
}
|
||||
|
||||
impl LoweringState {
|
||||
pub fn map_property_reference(&self, from: &NamedReference) -> PropertyReference {
|
||||
if let Some(x) = self.global_properties.get(from) {
|
||||
|
@ -194,12 +195,21 @@ impl LoweringState {
|
|||
}
|
||||
|
||||
let element = from.element();
|
||||
let enclosing = self
|
||||
.sub_components
|
||||
.get(&element.borrow().enclosing_component.upgrade().unwrap().into())
|
||||
.unwrap();
|
||||
let sc = self.sub_component(&element.borrow().enclosing_component.upgrade().unwrap());
|
||||
sc.mapping.map_property_reference(from, self)
|
||||
}
|
||||
|
||||
enclosing.mapping.map_property_reference(from, self)
|
||||
fn sub_component<'a>(&'a self, component: &Rc<Component>) -> &'a LoweredSubComponent {
|
||||
&self.sub_components[self.sub_component_idx(component)]
|
||||
}
|
||||
|
||||
fn sub_component_idx(&self, component: &Rc<Component>) -> usize {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,12 +230,6 @@ fn property_reference_within_sub_component(
|
|||
prop_ref
|
||||
}
|
||||
|
||||
impl LoweringState {
|
||||
fn sub_component(&self, component: &Rc<Component>) -> &LoweredSubComponent {
|
||||
&self.sub_components[&ByAddress(component.clone())]
|
||||
}
|
||||
}
|
||||
|
||||
fn component_id(component: &Rc<Component>) -> SmolStr {
|
||||
if component.is_global() {
|
||||
component.root_element.borrow().id.clone()
|
||||
|
@ -238,8 +242,8 @@ fn component_id(component: &Rc<Component>) -> SmolStr {
|
|||
|
||||
fn lower_sub_component(
|
||||
component: &Rc<Component>,
|
||||
state: &LoweringState,
|
||||
parent_context: Option<&ExpressionContext>,
|
||||
state: &mut LoweringState,
|
||||
parent_context: Option<&ExpressionContextInner>,
|
||||
compiler_config: &CompilerConfiguration,
|
||||
) -> LoweredSubComponent {
|
||||
let mut sub_component = SubComponent {
|
||||
|
@ -349,8 +353,7 @@ fn lower_sub_component(
|
|||
}
|
||||
match &elem.base_type {
|
||||
ElementType::Component(comp) => {
|
||||
let lc = state.sub_component(comp);
|
||||
let ty = lc.sub_component.clone();
|
||||
let ty = state.sub_component_idx(comp);
|
||||
let sub_component_index = sub_component.sub_components.len();
|
||||
mapping.element_mapping.insert(
|
||||
element.clone().into(),
|
||||
|
@ -363,7 +366,7 @@ fn lower_sub_component(
|
|||
index_of_first_child_in_tree: *elem.item_index_of_first_children.get().unwrap(),
|
||||
repeater_offset,
|
||||
});
|
||||
repeater_offset += ty.repeater_count();
|
||||
repeater_offset += comp.repeater_count();
|
||||
}
|
||||
|
||||
ElementType::Native(n) => {
|
||||
|
@ -400,7 +403,8 @@ fn lower_sub_component(
|
|||
|
||||
Some(element.clone())
|
||||
});
|
||||
let ctx = ExpressionContext { mapping: &mapping, state, parent: parent_context, component };
|
||||
let inner = ExpressionContextInner { mapping: &mapping, parent: parent_context, component };
|
||||
let mut ctx = ExpressionContext { inner, state };
|
||||
crate::generator::handle_property_bindings_init(component, |e, p, binding| {
|
||||
let nr = NamedReference::new(e, p.clone());
|
||||
let prop = ctx.map_property_reference(&nr);
|
||||
|
@ -481,7 +485,7 @@ fn lower_sub_component(
|
|||
.collect();
|
||||
sub_component.repeated = repeated
|
||||
.into_iter()
|
||||
.map(|elem| lower_repeated_component(&elem, &ctx, compiler_config))
|
||||
.map(|elem| lower_repeated_component(&elem, &mut ctx, compiler_config))
|
||||
.collect();
|
||||
for s in &mut sub_component.sub_components {
|
||||
s.repeater_offset +=
|
||||
|
@ -492,7 +496,7 @@ fn lower_sub_component(
|
|||
.popup_windows
|
||||
.borrow()
|
||||
.iter()
|
||||
.map(|popup| lower_popup_component(popup, &ctx, compiler_config))
|
||||
.map(|popup| lower_popup_component(popup, &mut ctx, compiler_config))
|
||||
.collect();
|
||||
|
||||
sub_component.timers = component.timers.borrow().iter().map(|t| lower_timer(t, &ctx)).collect();
|
||||
|
@ -583,7 +587,7 @@ fn lower_sub_component(
|
|||
sub_component.geometries[item_index] = Some(lower_geometry(geom, &ctx).into());
|
||||
});
|
||||
|
||||
LoweredSubComponent { sub_component: Rc::new(sub_component), mapping }
|
||||
LoweredSubComponent { sub_component, mapping }
|
||||
}
|
||||
|
||||
fn lower_geometry(
|
||||
|
@ -636,15 +640,14 @@ fn get_property_analysis(elem: &ElementRc, p: &str) -> crate::object_tree::Prope
|
|||
|
||||
fn lower_repeated_component(
|
||||
elem: &ElementRc,
|
||||
ctx: &ExpressionContext,
|
||||
ctx: &mut ExpressionContext,
|
||||
compiler_config: &CompilerConfiguration,
|
||||
) -> RepeatedElement {
|
||||
let e = elem.borrow();
|
||||
let component = e.base_type.as_component().clone();
|
||||
let repeated = e.repeated.as_ref().unwrap();
|
||||
|
||||
let sc: LoweredSubComponent =
|
||||
lower_sub_component(&component, ctx.state, Some(ctx), compiler_config);
|
||||
let sc = lower_sub_component(&component, ctx.state, Some(&ctx.inner), compiler_config);
|
||||
|
||||
let geom = component.root_element.borrow().geometry_props.clone().unwrap();
|
||||
|
||||
|
@ -662,7 +665,7 @@ fn lower_repeated_component(
|
|||
model: super::lower_expression::lower_expression(&repeated.model, ctx).into(),
|
||||
sub_tree: ItemTree {
|
||||
tree: make_tree(ctx.state, &component.root_element, &sc, &[]),
|
||||
root: Rc::try_unwrap(sc.sub_component).unwrap(),
|
||||
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),
|
||||
|
@ -695,13 +698,22 @@ fn lower_component_container(
|
|||
|
||||
fn lower_popup_component(
|
||||
popup: &object_tree::PopupWindow,
|
||||
ctx: &ExpressionContext,
|
||||
ctx: &mut ExpressionContext,
|
||||
compiler_config: &CompilerConfiguration,
|
||||
) -> PopupWindow {
|
||||
let sc = lower_sub_component(&popup.component, ctx.state, Some(ctx), compiler_config);
|
||||
let sc = lower_sub_component(&popup.component, ctx.state, Some(&ctx.inner), compiler_config);
|
||||
use super::Expression::PropertyReference as PR;
|
||||
let position = super::lower_expression::make_struct(
|
||||
"LogicalPosition",
|
||||
[
|
||||
("x", Type::LogicalLength, PR(sc.mapping.map_property_reference(&popup.x, ctx.state))),
|
||||
("y", Type::LogicalLength, PR(sc.mapping.map_property_reference(&popup.y, ctx.state))),
|
||||
],
|
||||
);
|
||||
|
||||
let item_tree = ItemTree {
|
||||
tree: make_tree(ctx.state, &popup.component.root_element, &sc, &[]),
|
||||
root: Rc::try_unwrap(sc.sub_component).unwrap(),
|
||||
root: ctx.state.push_sub_component(sc),
|
||||
parent_context: Some(
|
||||
popup
|
||||
.component
|
||||
|
@ -716,16 +728,6 @@ fn lower_popup_component(
|
|||
.clone(),
|
||||
),
|
||||
};
|
||||
|
||||
use super::Expression::PropertyReference as PR;
|
||||
let position = super::lower_expression::make_struct(
|
||||
"LogicalPosition",
|
||||
[
|
||||
("x", Type::LogicalLength, PR(sc.mapping.map_property_reference(&popup.x, ctx.state))),
|
||||
("y", Type::LogicalLength, PR(sc.mapping.map_property_reference(&popup.y, ctx.state))),
|
||||
],
|
||||
);
|
||||
|
||||
PopupWindow { item_tree, position: position.into() }
|
||||
}
|
||||
|
||||
|
@ -854,7 +856,8 @@ fn lower_global_expressions(
|
|||
) {
|
||||
// Note that this mapping doesn't contain anything useful, everything is in the state
|
||||
let mapping = LoweredSubComponentMapping::default();
|
||||
let ctx = ExpressionContext { mapping: &mapping, state, parent: None, component: global };
|
||||
let inner = ExpressionContextInner { mapping: &mapping, parent: None, component: global };
|
||||
let ctx = ExpressionContext { inner, state };
|
||||
|
||||
for (prop, binding) in &global.root_element.borrow().bindings {
|
||||
assert!(binding.borrow().two_way_bindings.is_empty());
|
||||
|
@ -863,7 +866,7 @@ fn lower_global_expressions(
|
|||
super::lower_expression::lower_expression(&binding.borrow().expression, &ctx);
|
||||
|
||||
let nr = NamedReference::new(&global.root_element, prop.clone());
|
||||
let property_index = match state.global_properties[&nr] {
|
||||
let property_index = match ctx.state.global_properties[&nr] {
|
||||
PropertyReference::Global { property_index, .. } => property_index,
|
||||
PropertyReference::GlobalFunction { function_index, .. } => {
|
||||
lowered.functions[function_index].code = expression;
|
||||
|
@ -883,7 +886,7 @@ fn lower_global_expressions(
|
|||
|
||||
for (prop, expr) in &global.root_element.borrow().change_callbacks {
|
||||
let nr = NamedReference::new(&global.root_element, prop.clone());
|
||||
let property_index = match state.global_properties[&nr] {
|
||||
let property_index = match ctx.state.global_properties[&nr] {
|
||||
PropertyReference::Global { property_index, .. } => property_index,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
|
|
@ -14,7 +14,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
// Visit the root properties that are used.
|
||||
// 1. the public properties
|
||||
for c in &root.public_components {
|
||||
let root_ctx = EvaluationContext::new_sub_component(root, &c.item_tree.root, (), None);
|
||||
let root_ctx = EvaluationContext::new_sub_component(root, c.item_tree.root, (), None);
|
||||
for p in c.public_properties.iter().filter(|p| {
|
||||
!matches!(
|
||||
p.prop,
|
||||
|
@ -43,7 +43,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
PropertyReference::Local { sub_component_path, property_index } => {
|
||||
let mut sc = sc;
|
||||
for i in sub_component_path {
|
||||
sc = &sc.sub_components[*i].ty;
|
||||
sc = &ctx.compilation_unit.sub_components[sc.sub_components[*i].ty];
|
||||
}
|
||||
if sc.properties[*property_index].use_count.get() == 0 {
|
||||
continue;
|
||||
|
@ -74,7 +74,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
|
||||
let rep_ctx = EvaluationContext::new_sub_component(
|
||||
root,
|
||||
&r.sub_tree.root,
|
||||
r.sub_tree.root,
|
||||
(),
|
||||
Some(ParentCtx::new(ctx, Some(idx as u32))),
|
||||
);
|
||||
|
@ -83,7 +83,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
}
|
||||
for idx in r.data_prop.iter().chain(r.index_prop.iter()) {
|
||||
// prevent optimizing model properties
|
||||
let p = &r.sub_tree.root.properties[*idx];
|
||||
let p = &root.sub_components[r.sub_tree.root].properties[*idx];
|
||||
p.use_count.set(2);
|
||||
}
|
||||
}
|
||||
|
@ -121,7 +121,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
for popup in &sc.popup_windows {
|
||||
let popup_ctx = EvaluationContext::new_sub_component(
|
||||
root,
|
||||
&popup.item_tree.root,
|
||||
popup.item_tree.root,
|
||||
(),
|
||||
Some(ParentCtx::new(&ctx, None)),
|
||||
);
|
||||
|
@ -144,7 +144,7 @@ pub fn count_property_use(root: &CompilationUnit) {
|
|||
}
|
||||
|
||||
if let Some(p) = &root.popup_menu {
|
||||
let ctx = EvaluationContext::new_sub_component(&root, &p.item_tree.root, (), None);
|
||||
let ctx = EvaluationContext::new_sub_component(&root, p.item_tree.root, (), None);
|
||||
visit_property(&p.entries, &ctx);
|
||||
visit_property(&p.sub_menu, &ctx);
|
||||
visit_property(&p.activated, &ctx);
|
||||
|
|
|
@ -8,21 +8,13 @@ use itertools::Itertools;
|
|||
use crate::expression_tree::MinMaxOp;
|
||||
|
||||
use super::{
|
||||
CompilationUnit, EvaluationContext, Expression, ParentCtx, PropertyReference, SubComponent,
|
||||
CompilationUnit, EvaluationContext, Expression, ParentCtx, PropertyReference, SubComponentIndex,
|
||||
};
|
||||
|
||||
pub fn pretty_print(root: &CompilationUnit, writer: &mut dyn Write) -> Result {
|
||||
PrettyPrinter { writer, indentation: 0 }.print_root(root)
|
||||
}
|
||||
|
||||
pub fn pretty_print_component(
|
||||
root: &CompilationUnit,
|
||||
component: &SubComponent,
|
||||
writer: &mut dyn Write,
|
||||
) -> Result {
|
||||
PrettyPrinter { writer, indentation: 0 }.print_component(root, component, None)
|
||||
}
|
||||
|
||||
struct PrettyPrinter<'a> {
|
||||
writer: &'a mut dyn Write,
|
||||
indentation: usize,
|
||||
|
@ -35,22 +27,21 @@ impl<'a> PrettyPrinter<'a> {
|
|||
self.print_global(root, g)?;
|
||||
}
|
||||
}
|
||||
for c in &root.sub_components {
|
||||
for c in 0..root.sub_components.len() {
|
||||
self.print_component(root, c, None)?
|
||||
}
|
||||
for p in &root.public_components {
|
||||
self.print_component(root, &p.item_tree.root, None)?
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_component(
|
||||
&mut self,
|
||||
root: &CompilationUnit,
|
||||
sc: &SubComponent,
|
||||
sc_idx: SubComponentIndex,
|
||||
parent: Option<ParentCtx<'_>>,
|
||||
) -> Result {
|
||||
let ctx = EvaluationContext::new_sub_component(root, sc, (), parent);
|
||||
let ctx = EvaluationContext::new_sub_component(root, sc_idx, (), parent);
|
||||
let sc = &root.sub_components[sc_idx];
|
||||
writeln!(self.writer, "component {} {{", sc.name)?;
|
||||
self.indentation += 1;
|
||||
for p in &sc.properties {
|
||||
|
@ -98,7 +89,7 @@ impl<'a> PrettyPrinter<'a> {
|
|||
}
|
||||
for ssc in &sc.sub_components {
|
||||
self.indent()?;
|
||||
writeln!(self.writer, "{} := {} {{}};", ssc.name, ssc.ty.name)?;
|
||||
writeln!(self.writer, "{} := {} {{}};", ssc.name, root.sub_components[ssc.ty].name)?;
|
||||
}
|
||||
for (item, geom) in std::iter::zip(&sc.items, &sc.geometries) {
|
||||
self.indent()?;
|
||||
|
@ -112,13 +103,13 @@ impl<'a> PrettyPrinter<'a> {
|
|||
write!(self.writer, "for in {} : ", DisplayExpression(&r.model.borrow(), &ctx))?;
|
||||
self.print_component(
|
||||
root,
|
||||
&r.sub_tree.root,
|
||||
r.sub_tree.root,
|
||||
Some(ParentCtx::new(&ctx, Some(idx as u32))),
|
||||
)?
|
||||
}
|
||||
for w in &sc.popup_windows {
|
||||
self.indent()?;
|
||||
self.print_component(root, &w.item_tree.root, Some(ParentCtx::new(&ctx, None)))?
|
||||
self.print_component(root, w.item_tree.root, Some(ParentCtx::new(&ctx, None)))?
|
||||
}
|
||||
self.indentation -= 1;
|
||||
self.indent()?;
|
||||
|
@ -196,19 +187,19 @@ impl<T> Display for DisplayPropertyRef<'_, T> {
|
|||
if let Some(g) = ctx.current_global {
|
||||
write!(f, "{}.{}", g.name, g.properties[*property_index].name)
|
||||
} else {
|
||||
let mut sc = ctx.current_sub_component.unwrap();
|
||||
let mut sc = ctx.current_sub_component().unwrap();
|
||||
for i in sub_component_path {
|
||||
write!(f, "{}.", sc.sub_components[*i].name)?;
|
||||
sc = &sc.sub_components[*i].ty;
|
||||
sc = &ctx.compilation_unit.sub_components[sc.sub_components[*i].ty];
|
||||
}
|
||||
write!(f, "{}", sc.properties[*property_index].name)
|
||||
}
|
||||
}
|
||||
PropertyReference::InNativeItem { sub_component_path, item_index, prop_name } => {
|
||||
let mut sc = ctx.current_sub_component.unwrap();
|
||||
let mut sc = ctx.current_sub_component().unwrap();
|
||||
for i in sub_component_path {
|
||||
write!(f, "{}.", sc.sub_components[*i].name)?;
|
||||
sc = &sc.sub_components[*i].ty;
|
||||
sc = &ctx.compilation_unit.sub_components[sc.sub_components[*i].ty];
|
||||
}
|
||||
let i = &sc.items[*item_index as usize];
|
||||
write!(f, "{}.{}", i.name, prop_name)
|
||||
|
@ -227,10 +218,10 @@ impl<T> Display for DisplayPropertyRef<'_, T> {
|
|||
if let Some(g) = ctx.current_global {
|
||||
write!(f, "{}.{}", g.name, g.functions[*function_index].name)
|
||||
} else {
|
||||
let mut sc = ctx.current_sub_component.unwrap();
|
||||
let mut sc = ctx.current_sub_component().unwrap();
|
||||
for i in sub_component_path {
|
||||
write!(f, "{}.", sc.sub_components[*i].name)?;
|
||||
sc = &sc.sub_components[*i].ty;
|
||||
sc = &ctx.compilation_unit.sub_components[sc.sub_components[*i].ty];
|
||||
}
|
||||
write!(f, "{}", sc.functions[*function_index].name)
|
||||
}
|
||||
|
|
|
@ -387,6 +387,7 @@ mod plural_rule_parser {
|
|||
compilation_unit: &crate::llr::CompilationUnit {
|
||||
public_components: Vec::new(),
|
||||
sub_components: Vec::new(),
|
||||
used_sub_components: Vec::new(),
|
||||
globals: Vec::new(),
|
||||
has_debug_info: false,
|
||||
translations: None,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue