1use super::{EvaluationContext, EvaluationScope, Expression, ParentScope};
5use crate::langtype::{NativeClass, Type};
6use derive_more::{From, Into};
7use smol_str::SmolStr;
8use std::cell::{Cell, RefCell};
9use std::collections::{BTreeMap, HashMap};
10use std::sync::Arc;
11use typed_index_collections::TiVec;
12
13#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
14pub struct PropertyIdx(usize);
15#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
16pub struct FunctionIdx(usize);
17#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
18pub struct CallbackIdx(usize);
19#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq)]
20pub struct SubComponentIdx(usize);
21#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq)]
22pub struct GlobalIdx(usize);
23#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
24pub struct SubComponentInstanceIdx(usize);
25#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
26pub struct ItemInstanceIdx(usize);
27#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq)]
28pub struct RepeatedElementIdx(usize);
29#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq, PartialOrd, Ord)]
30pub struct TimerIdx(usize);
31#[derive(Debug, Clone, Copy, Into, From, Hash, PartialEq, Eq)]
32pub struct GridLayoutChildIdx(usize);
33
34#[derive(Debug, Clone)]
38pub enum RowChildTemplateInfo {
39 Static { child_index: GridLayoutChildIdx },
41 Repeated {
43 repeater_index: RepeatedElementIdx,
44 measure_at_cross_width: bool,
50 },
51}
52
53pub fn has_inner_repeaters(templates: &Option<Vec<RowChildTemplateInfo>>) -> bool {
55 templates
56 .as_ref()
57 .is_some_and(|t| t.iter().any(|e| matches!(e, RowChildTemplateInfo::Repeated { .. })))
58}
59
60pub fn static_child_count(templates: &[RowChildTemplateInfo]) -> usize {
62 templates.iter().filter(|e| matches!(e, RowChildTemplateInfo::Static { .. })).count()
63}
64
65#[derive(Debug, Clone)]
66pub struct LayoutRepeatedElement {
67 pub repeater_index: RepeatedElementIdx,
68 pub row_child_templates: Option<Vec<RowChildTemplateInfo>>,
71 pub cross_width: Option<Expression>,
78}
79
80#[derive(Debug, Clone)]
81pub struct GridLayoutRepeatedElement {
82 pub new_row: bool,
83 pub repeater_index: RepeatedElementIdx,
84 pub row_child_templates: Option<Vec<RowChildTemplateInfo>>,
87}
88
89impl PropertyIdx {
90 pub const REPEATER_DATA: Self = Self(0);
91 pub const REPEATER_INDEX: Self = Self(1);
92}
93
94#[derive(Debug, Clone)]
97pub struct GridLayoutChildLayoutInfo {
98 pub layout_info_h: MutExpression,
99 pub layout_info_v: MutExpression,
100}
101
102#[derive(Debug, Clone, derive_more::Deref, derive_more::DerefMut)]
103pub struct MutExpression(RefCell<Expression>);
104
105impl From<Expression> for MutExpression {
106 fn from(e: Expression) -> Self {
107 Self(e.into())
108 }
109}
110
111impl MutExpression {
112 pub fn ty(&self, ctx: &dyn super::TypeResolutionContext) -> Type {
113 self.0.borrow().ty(ctx)
114 }
115}
116
117#[derive(Debug, Clone)]
118pub enum Animation {
119 Static(Expression),
121 Transition(Expression),
122}
123
124#[derive(Debug, Clone, Copy, PartialEq, Eq)]
126pub enum BindingKind {
127 Constant,
129 Normal,
131 State,
135}
136
137#[derive(Debug, Clone)]
138pub struct BindingExpression {
139 pub expression: MutExpression,
140 pub animation: Option<Animation>,
141 pub kind: BindingKind,
142
143 pub use_count: Cell<usize>,
146}
147
148#[derive(Debug)]
149pub struct GlobalComponent {
150 pub name: SmolStr,
151 pub properties: TiVec<PropertyIdx, Property>,
152 pub callbacks: TiVec<CallbackIdx, Callback>,
153 pub functions: TiVec<FunctionIdx, Function>,
154 pub init_values: BTreeMap<LocalMemberIndex, BindingExpression>,
156 pub change_callbacks: BTreeMap<PropertyIdx, MutExpression>,
158 pub const_properties: TiVec<PropertyIdx, bool>,
159 pub public_properties: PublicProperties,
160 pub private_properties: PrivateProperties,
161 pub exported: bool,
163 pub aliases: Vec<SmolStr>,
166 pub is_builtin: bool,
168 pub from_library: bool,
170 pub prop_analysis: TiVec<PropertyIdx, crate::object_tree::PropertyAnalysis>,
172}
173
174impl GlobalComponent {
175 pub fn must_generate(&self) -> bool {
176 !self.from_library
177 && (self.exported
178 || !self.functions.is_empty()
179 || self.properties.iter().any(|p| p.use_count.get() > 0)
180 || self.callbacks.iter().any(|c| c.use_count.get() > 0))
181 }
182}
183
184#[derive(Clone, Debug, Hash, PartialEq, Eq, From, PartialOrd, Ord)]
185pub enum LocalMemberIndex {
186 #[from]
187 Property(PropertyIdx),
188 #[from]
189 Function(FunctionIdx),
190 #[from]
191 Callback(CallbackIdx),
192 #[from]
195 Timer(TimerIdx),
196 Native {
197 item_index: ItemInstanceIdx,
198 prop_name: SmolStr,
199 kind: NativeMemberKind,
206 },
207}
208
209#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
210pub enum NativeMemberKind {
211 Property,
214 Callback,
217 Function,
221}
222impl LocalMemberIndex {
223 pub fn property(&self) -> Option<PropertyIdx> {
224 if let LocalMemberIndex::Property(p) = self { Some(*p) } else { None }
225 }
226}
227
228#[derive(Clone, Debug, Hash, PartialEq, Eq)]
230pub enum MemberReference {
231 Global { global_index: GlobalIdx, member: LocalMemberIndex },
233
234 Relative {
236 parent_level: usize,
238 local_reference: LocalMemberReference,
239 },
240}
241impl MemberReference {
242 #[track_caller]
244 pub fn local(&self) -> LocalMemberReference {
245 match self {
246 MemberReference::Relative { parent_level: 0, local_reference, .. } => {
247 local_reference.clone()
248 }
249 _ => panic!("not a local reference"),
250 }
251 }
252
253 pub fn is_function(&self) -> bool {
254 matches!(
255 self,
256 MemberReference::Global { member: LocalMemberIndex::Function(..), .. }
257 | MemberReference::Relative {
258 local_reference: LocalMemberReference {
259 reference: LocalMemberIndex::Function(..),
260 ..
261 },
262 ..
263 }
264 )
265 }
266}
267
268impl From<LocalMemberReference> for MemberReference {
269 fn from(local_reference: LocalMemberReference) -> Self {
270 MemberReference::Relative { parent_level: 0, local_reference }
271 }
272}
273
274#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
276pub struct LocalMemberReference {
277 pub sub_component_path: Vec<SubComponentInstanceIdx>,
278 pub reference: LocalMemberIndex,
279}
280
281impl<T: Into<LocalMemberIndex>> From<T> for LocalMemberReference {
282 fn from(reference: T) -> Self {
283 Self { sub_component_path: Vec::new(), reference: reference.into() }
284 }
285}
286
287#[derive(Debug, Clone)]
288pub struct TwoWayBinding {
289 pub prop1: LocalMemberReference,
290 pub prop2: MemberReference,
291 pub is_model: Option<PropertyIdx>,
295 pub field_access: Vec<SmolStr>,
297}
298
299pub struct ResolvedModelTwoWayBinding<'a> {
302 pub parent_level: usize,
304 pub body_sub_component: SubComponentIdx,
305 pub data_prop: PropertyIdx,
306 pub data_prop_ty: &'a Type,
308 pub index_prop: PropertyIdx,
309 pub parent_sub_component: SubComponentIdx,
310 pub repeater_index: RepeatedElementIdx,
311}
312
313impl TwoWayBinding {
314 pub fn resolve_model<'a, T>(
317 &self,
318 ctx: &EvaluationContext<'a, T>,
319 ) -> Option<ResolvedModelTwoWayBinding<'a>> {
320 let index_prop = self.is_model?;
321 let MemberReference::Relative { parent_level, local_reference } = &self.prop2 else {
322 unreachable!("model two-way binding's prop2 is always a Relative reference")
323 };
324 debug_assert!(local_reference.sub_component_path.is_empty());
325 let LocalMemberIndex::Property(data_prop) = local_reference.reference else {
326 unreachable!("model two-way binding's prop2 always references a property")
327 };
328 let super::EvaluationScope::SubComponent(mut sc, mut par) = ctx.current_scope else {
329 unreachable!("model two-way binding cannot be in a global")
330 };
331 for _ in 0..*parent_level {
332 let x = par.expect("parent_level should be valid");
333 par = x.parent;
334 sc = x.sub_component;
335 }
336 let par = par.expect("repeated item_tree must have a parent");
337 let data_prop_ty = &ctx.compilation_unit.sub_components[sc].properties[data_prop].ty;
338 Some(ResolvedModelTwoWayBinding {
339 parent_level: *parent_level,
340 body_sub_component: sc,
341 data_prop,
342 data_prop_ty,
343 index_prop,
344 parent_sub_component: par.sub_component,
345 repeater_index: par.repeater_index.expect("repeated parent has a repeater_index"),
346 })
347 }
348}
349
350#[derive(Debug, Default)]
351pub struct Property {
352 pub name: SmolStr,
353 pub ty: Type,
354 pub use_count: Cell<usize>,
357}
358
359#[derive(Debug, Default)]
360pub struct Callback {
361 pub name: SmolStr,
362 pub ret_ty: Type,
363 pub args: Vec<Type>,
364
365 pub ty: Type,
368
369 pub use_count: Cell<usize>,
371
372 pub needs_tracker: bool,
376}
377
378#[derive(Debug)]
379pub struct Function {
380 pub name: SmolStr,
381 pub ret_ty: Type,
382 pub args: Vec<Type>,
383 pub code: MutExpression,
384 pub use_count: Cell<usize>,
387}
388
389#[derive(Debug, Clone)]
390pub struct ListViewInfo {
393 pub content_y: MemberReference,
394 pub content_height: Option<MemberReference>,
397 pub content_width: Option<MemberReference>,
400 pub listview_height: MemberReference,
402 pub listview_width: MemberReference,
404
405 pub prop_y: MemberReference,
407 pub prop_height: MemberReference,
409}
410
411#[derive(Debug)]
412pub struct RepeatedElement {
413 pub model: MutExpression,
414 pub index_prop: Option<PropertyIdx>,
416 pub data_prop: Option<PropertyIdx>,
418 pub dynamic_z: Option<MemberReference>,
422 pub sub_tree: ItemTree,
423 pub index_in_tree: u32,
425
426 pub listview: Option<ListViewInfo>,
427
428 pub container_item_index: Option<ItemInstanceIdx>,
430}
431
432#[derive(Debug)]
433pub struct ComponentContainerElement {
434 pub component_container_item_tree_index: u32,
436 pub component_container_items_index: ItemInstanceIdx,
438 pub component_placeholder_item_tree_index: u32,
440}
441
442pub struct Item {
443 pub ty: Arc<NativeClass>,
444 pub name: SmolStr,
445 pub index_in_tree: u32,
447}
448
449impl std::fmt::Debug for Item {
450 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
451 f.debug_struct("Item")
452 .field("ty", &self.ty.class_name)
453 .field("name", &self.name)
454 .field("index_in_tree", &self.index_in_tree)
455 .finish()
456 }
457}
458
459#[derive(Debug)]
460pub struct TreeNode {
461 pub sub_component_path: Vec<SubComponentInstanceIdx>,
462 pub item_index: itertools::Either<ItemInstanceIdx, u32>,
464 pub children: Vec<TreeNode>,
465 pub is_accessible: bool,
466 pub z_sort_order_property: Option<Vec<ZSource>>,
471}
472
473#[derive(Debug, Clone)]
475pub enum ZSource {
476 Expression(MutExpression),
480 RepeaterInstances,
484}
485
486impl TreeNode {
487 fn children_count(&self) -> usize {
488 let mut count = self.children.len();
489 for c in &self.children {
490 count += c.children_count();
491 }
492 count
493 }
494
495 pub fn visit_in_array<'a>(
498 &'a self,
499 visitor: &mut dyn FnMut(
500 &'a TreeNode,
501 usize,
502 usize,
503 ),
504 ) {
505 visitor(self, 1, 0);
506 visit_in_array_recursive(self, 1, 0, visitor);
507
508 fn visit_in_array_recursive<'a>(
509 node: &'a TreeNode,
510 children_offset: usize,
511 current_index: usize,
512 visitor: &mut dyn FnMut(&'a TreeNode, usize, usize),
513 ) {
514 let mut offset = children_offset + node.children.len();
515 for c in &node.children {
516 visitor(c, offset, current_index);
517 offset += c.children_count();
518 }
519
520 let mut offset = children_offset + node.children.len();
521 for (i, c) in node.children.iter().enumerate() {
522 visit_in_array_recursive(c, offset, children_offset + i, visitor);
523 offset += c.children_count();
524 }
525 }
526 }
527}
528
529#[derive(Debug)]
530pub struct SubComponent {
531 pub name: SmolStr,
532 pub properties: TiVec<PropertyIdx, Property>,
533 pub callbacks: TiVec<CallbackIdx, Callback>,
534 pub functions: TiVec<FunctionIdx, Function>,
535 pub items: TiVec<ItemInstanceIdx, Item>,
536 pub repeated: TiVec<RepeatedElementIdx, RepeatedElement>,
537 pub component_containers: Vec<ComponentContainerElement>,
538 pub popup_windows: Vec<PopupWindow>,
539 pub menu_item_trees: Vec<ItemTree>,
541 pub timers: TiVec<TimerIdx, Timer>,
542 pub sub_components: TiVec<SubComponentInstanceIdx, SubComponentInstance>,
543 pub property_init: Vec<(MemberReference, BindingExpression)>,
546 pub change_callbacks: Vec<(MemberReference, MutExpression)>,
547 pub animations: BTreeMap<LocalMemberReference, Expression>,
549 pub two_way_bindings: Vec<TwoWayBinding>,
551 pub const_properties: Vec<LocalMemberReference>,
552 pub pre_init_code: Vec<MutExpression>,
555 pub init_code: Vec<MutExpression>,
557
558 pub geometries: Vec<Option<MutExpression>>,
560
561 pub layout_info_h: MutExpression,
562 pub layout_info_v: MutExpression,
563 pub child_of_layout: bool,
564 pub grid_layout_input_for_repeated: Option<MutExpression>,
565 pub flexbox_layout_item_info_for_repeated: Option<MutExpression>,
568 pub cross_axis_self_alignment_for_repeated: Option<(crate::layout::Orientation, MutExpression)>,
574 pub layout_order_for_repeated: Option<(crate::layout::Orientation, MutExpression)>,
580 pub layout_info_v_constrained_for_repeated: Option<MutExpression>,
586 pub layout_info_v_at_cross_width_for_repeated: Option<MutExpression>,
592 pub grid_row_child_cross_width: Option<MutExpression>,
601 pub is_repeated_row: bool,
604 pub grid_layout_children: TiVec<GridLayoutChildIdx, GridLayoutChildLayoutInfo>,
607 pub row_child_templates: Option<Vec<RowChildTemplateInfo>>,
611
612 pub accessible_prop: BTreeMap<(u32, String), MutExpression>,
614
615 pub element_infos: BTreeMap<u32, String>,
617
618 pub prop_analysis: HashMap<MemberReference, PropAnalysis>,
619
620 pub debug_info: Option<super::debug_info::SubComponentDebugInfo>,
623}
624
625#[derive(Debug)]
626pub struct PopupWindow {
627 pub item_tree: ItemTree,
628 pub position: MutExpression,
629 pub is_tooltip: bool,
630}
631
632#[derive(Debug)]
633pub struct PopupMenu {
634 pub item_tree: ItemTree,
635 pub sub_menu: MemberReference,
636 pub activated: MemberReference,
637 pub close: MemberReference,
638 pub entries: MemberReference,
639}
640
641#[derive(Debug)]
642pub struct Timer {
643 pub interval: MutExpression,
644 pub running: MutExpression,
645 pub triggered: MutExpression,
646}
647
648#[derive(Debug, Clone)]
649pub struct PropAnalysis {
650 pub property_init: Option<usize>,
652 pub analysis: crate::object_tree::PropertyAnalysis,
653}
654
655impl SubComponent {
656 pub fn repeater_count(&self, cu: &CompilationUnit) -> u32 {
658 let mut count = (self.repeated.len() + self.component_containers.len()) as u32;
659 for x in self.sub_components.iter() {
660 count += cu.sub_components[x.ty].repeater_count(cu);
661 }
662 count
663 }
664
665 pub fn child_item_count(&self, cu: &CompilationUnit) -> u32 {
667 let mut count = self.items.len() as u32;
668 for x in self.sub_components.iter() {
669 count += cu.sub_components[x.ty].child_item_count(cu);
670 }
671 count
672 }
673}
674
675#[derive(Debug)]
676pub struct SubComponentInstance {
677 pub ty: SubComponentIdx,
678 pub name: SmolStr,
679 pub index_in_tree: u32,
680 pub index_of_first_child_in_tree: u32,
681 pub repeater_offset: u32,
682}
683
684#[derive(Debug)]
685pub struct ItemTree {
686 pub root: SubComponentIdx,
687 pub tree: TreeNode,
688}
689
690#[derive(Debug, Clone, Copy, PartialEq, Eq)]
694pub enum TopLevelComponentType {
695 Window,
696 SystemTrayIcon,
697}
698
699#[derive(Debug)]
700pub struct PublicComponent {
701 pub public_properties: PublicProperties,
702 pub private_properties: PrivateProperties,
703 pub item_tree: ItemTree,
704 pub name: SmolStr,
705 pub top_level_type: TopLevelComponentType,
706}
707
708#[derive(Debug)]
711pub struct TypeExport {
712 pub exported_name: SmolStr,
714 pub internal_name: SmolStr,
717 pub deprecated: bool,
720}
721
722impl TypeExport {
723 pub fn is_alias(&self) -> bool {
727 self.exported_name != self.internal_name
728 }
729
730 pub fn deprecation_note(&self) -> Option<String> {
733 self.deprecated.then(|| {
734 if self.is_alias() {
735 format!(
736 "`{0}` was renamed to `{1}` on export. Use `{1}`.",
737 self.exported_name, self.internal_name
738 )
739 } else {
740 format!(
741 "`{}` is not part of the public API. Re-export it from your main .slint file to make it public.",
742 self.exported_name
743 )
744 }
745 })
746 }
747}
748
749#[derive(Debug)]
750pub struct CompilationUnit {
751 pub public_components: Vec<PublicComponent>,
752 pub sub_components: TiVec<SubComponentIdx, SubComponent>,
754 pub used_sub_components: Vec<SubComponentIdx>,
756 pub globals: TiVec<GlobalIdx, GlobalComponent>,
757 pub popup_menu: Option<PopupMenu>,
758 pub has_debug_info: bool,
759 pub type_exports: Vec<TypeExport>,
764 #[cfg(feature = "bundle-translations")]
765 pub translations: Option<crate::translations::Translations>,
766}
767
768const _: () = {
770 const fn assert_send<T: Send>() {}
771 assert_send::<CompilationUnit>();
772};
773
774impl CompilationUnit {
775 pub fn needs_window_adapter(&self) -> bool {
776 self.public_components.iter().any(|p| p.top_level_type == TopLevelComponentType::Window)
777 || self.popup_menu.is_some()
778 }
779
780 pub fn for_each_sub_components<'a>(
781 &'a self,
782 visitor: &mut dyn FnMut(SubComponentIdx, &'a SubComponent, &EvaluationContext<'_>),
783 ) {
784 fn visit_component<'a>(
785 root: &'a CompilationUnit,
786 c: SubComponentIdx,
787 visitor: &mut dyn FnMut(SubComponentIdx, &'a SubComponent, &EvaluationContext<'_>),
788 parent: Option<&ParentScope<'_>>,
789 ) {
790 let ctx = EvaluationContext::new_sub_component(root, c, (), parent);
791 let sc = &root.sub_components[c];
792 visitor(c, sc, &ctx);
793 for (idx, r) in sc.repeated.iter_enumerated() {
794 visit_component(
795 root,
796 r.sub_tree.root,
797 visitor,
798 Some(&ParentScope::new(&ctx, Some(idx))),
799 );
800 }
801 for popup in &sc.popup_windows {
802 visit_component(
803 root,
804 popup.item_tree.root,
805 visitor,
806 Some(&ParentScope::new(&ctx, None)),
807 );
808 }
809 for menu_tree in &sc.menu_item_trees {
810 visit_component(root, menu_tree.root, visitor, Some(&ParentScope::new(&ctx, None)));
811 }
812 }
813 for c in &self.used_sub_components {
814 visit_component(self, *c, visitor, None);
815 }
816 for p in &self.public_components {
817 visit_component(self, p.item_tree.root, visitor, None);
818 }
819 if let Some(p) = &self.popup_menu {
820 visit_component(self, p.item_tree.root, visitor, None);
821 }
822 }
823
824 pub fn for_each_expression<'a>(
825 &'a self,
826 visitor: &mut dyn FnMut(&'a super::MutExpression, &EvaluationContext<'_>),
827 ) {
828 self.for_each_sub_components(&mut |_, sc, ctx| {
829 for e in &sc.pre_init_code {
830 visitor(e, ctx);
831 }
832 for e in &sc.init_code {
833 visitor(e, ctx);
834 }
835 for (_, e) in &sc.property_init {
836 visitor(&e.expression, ctx);
837 }
838 visitor(&sc.layout_info_h, ctx);
839 visitor(&sc.layout_info_v, ctx);
840 if let Some(e) = &sc.grid_layout_input_for_repeated {
841 visitor(e, ctx);
842 }
843 if let Some(e) = &sc.flexbox_layout_item_info_for_repeated {
844 visitor(e, ctx);
845 }
846 if let Some((_, e)) = &sc.cross_axis_self_alignment_for_repeated {
847 visitor(e, ctx);
848 }
849 if let Some((_, e)) = &sc.layout_order_for_repeated {
850 visitor(e, ctx);
851 }
852 if let Some(e) = &sc.layout_info_v_constrained_for_repeated {
853 visitor(e, ctx);
854 }
855 if let Some(e) = &sc.layout_info_v_at_cross_width_for_repeated {
856 visitor(e, ctx);
857 }
858 if let Some(e) = &sc.grid_row_child_cross_width {
859 visitor(e, ctx);
860 }
861 for e in sc.accessible_prop.values() {
862 visitor(e, ctx);
863 }
864 for i in sc.geometries.iter().flatten() {
865 visitor(i, ctx);
866 }
867 for (_, e) in sc.change_callbacks.iter() {
868 visitor(e, ctx);
869 }
870 for child in &sc.grid_layout_children {
871 visitor(&child.layout_info_h, ctx);
872 visitor(&child.layout_info_v, ctx);
873 }
874 for r in sc.repeated.iter() {
875 visitor(&r.model, ctx);
876 }
877 for t in sc.timers.iter() {
878 visitor(&t.interval, ctx);
879 visitor(&t.running, ctx);
880 visitor(&t.triggered, ctx);
881 }
882 if let EvaluationScope::SubComponent(idx, _) = ctx.current_scope {
883 let fn_ctx = EvaluationContext::new_sub_component(self, idx, (), None);
886 visit_function_bodies(&sc.functions, &fn_ctx, visitor);
887 }
888 });
892 for (idx, g) in self.globals.iter_enumerated() {
893 let ctx = EvaluationContext::new_global(self, idx, ());
894 for e in g.init_values.values() {
895 visitor(&e.expression, &ctx)
896 }
897 for e in g.change_callbacks.values() {
898 visitor(e, &ctx)
899 }
900 visit_function_bodies(&g.functions, &ctx, visitor);
901 }
902 self.for_each_z_order_expression(visitor);
903 }
904
905 pub fn for_each_z_order_expression<'a>(
909 &'a self,
910 visitor: &mut dyn FnMut(&'a MutExpression, &EvaluationContext<'_>),
911 ) {
912 fn visit_tree<'a>(
913 node: &'a TreeNode,
914 ctx: &EvaluationContext<'_>,
915 visitor: &mut dyn FnMut(&'a MutExpression, &EvaluationContext<'_>),
916 ) {
917 for e in node.z_sort_order_property.iter().flatten() {
918 if let ZSource::Expression(e) = e {
919 visitor(e, ctx);
920 }
921 }
922 for child in &node.children {
923 visit_tree(child, ctx, visitor);
924 }
925 }
926 let mut trees: HashMap<SubComponentIdx, &TreeNode> = HashMap::new();
928 for c in &self.public_components {
929 trees.insert(c.item_tree.root, &c.item_tree.tree);
930 }
931 if let Some(p) = &self.popup_menu {
932 trees.insert(p.item_tree.root, &p.item_tree.tree);
933 }
934 for sc in self.sub_components.iter() {
935 for r in &sc.repeated {
936 trees.insert(r.sub_tree.root, &r.sub_tree.tree);
937 }
938 for p in &sc.popup_windows {
939 trees.insert(p.item_tree.root, &p.item_tree.tree);
940 }
941 }
942 self.for_each_sub_components(&mut |idx, _, ctx| {
946 if let Some(tree) = trees.get(&idx) {
947 visit_tree(tree, ctx, visitor);
948 }
949 });
950 }
951}
952
953fn visit_function_bodies<'a>(
960 functions: &'a TiVec<FunctionIdx, Function>,
961 ctx: &EvaluationContext<'a>,
962 visitor: &mut dyn FnMut(&'a super::MutExpression, &EvaluationContext<'_>),
963) {
964 for f in functions {
965 if f.use_count.get() > 0 {
966 let mut fn_ctx = ctx.clone();
967 fn_ctx.argument_types = &f.args;
968 visitor(&f.code, &fn_ctx);
969 }
970 }
971}
972
973#[derive(Debug, Clone)]
975pub struct PublicProperty {
976 pub display_name: SmolStr,
981 pub ty: Type,
982 pub prop: MemberReference,
983 pub visibility: crate::object_tree::PropertyVisibility,
984}
985
986impl PublicProperty {
987 pub fn read_only(&self) -> bool {
988 self.visibility == crate::object_tree::PropertyVisibility::Output
989 }
990}
991pub type PublicProperties = BTreeMap<SmolStr, PublicProperty>;
994pub type PrivateProperties = Vec<(SmolStr, Type)>;