1mod apply_default_properties_from_style;
5mod binding_analysis;
6mod border_radius;
7mod check_expressions;
8mod check_public_api;
9mod clip;
10mod collect_custom_fonts;
11mod collect_globals;
12mod collect_init_code;
13mod collect_libraries;
14mod collect_structs_and_enums;
15mod collect_subcomponents;
16mod compile_paths;
17mod const_propagation;
18mod deduplicate_property_read;
19mod default_geometry;
20mod deprecated_rotation_origin;
21#[cfg(feature = "software-renderer")]
22mod embed_glyphs;
23mod embed_images;
24mod flickable;
25mod focus_handling;
26pub mod generate_item_indices;
27pub mod infer_aliases_types;
28mod inject_debug_hooks;
29mod inlining;
30mod key_bindings;
31mod lower_absolute_coordinates;
32mod lower_accessibility;
33mod lower_component_container;
34mod lower_layout;
35mod lower_menus;
36mod lower_platform;
37mod lower_popups;
38mod lower_property_to_element;
39mod lower_repeated_rows;
40mod lower_shadows;
41mod lower_states;
42mod lower_tabwidget;
43mod lower_text_input_interface;
44mod lower_timers;
45pub mod materialize_fake_properties;
46pub mod move_declarations;
47mod optimize_useless_rectangles;
48mod purity_check;
49mod remove_aliases;
50mod remove_return;
51mod remove_unused_properties;
52mod repeater_component;
53pub mod resolve_native_classes;
54pub mod resolving;
55mod unique_id;
56mod visible;
57mod windows;
58mod z_order;
59
60use crate::expression_tree::Expression;
61use smol_str::SmolStr;
62
63pub use binding_analysis::GlobalAnalysis;
64
65pub fn ignore_debug_hooks(expr: &Expression) -> &Expression {
66 let mut expr = expr;
67 loop {
68 match expr {
69 Expression::DebugHook { expression, .. } => expr = expression.as_ref(),
70 _ => return expr,
71 }
72 }
73}
74
75pub async fn run_passes(
76 doc: &mut crate::object_tree::Document,
77 type_loader: &mut crate::typeloader::TypeLoader,
78 keep_raw: bool,
79 diag: &mut crate::diagnostics::BuildDiagnostics,
80) -> Option<crate::typeloader::TypeLoader> {
81 let style_metrics = {
82 let mut build_diags_to_ignore = crate::diagnostics::BuildDiagnostics::default();
84 type_loader
87 .import_component("style-base.slint", "StyleMetrics", &mut build_diags_to_ignore)
88 .await
89 .unwrap_or_else(|| panic!("can't load style metrics"))
90 };
91
92 let palette = {
93 let mut build_diags_to_ignore = crate::diagnostics::BuildDiagnostics::default();
95 type_loader
98 .import_component("style-base.slint", "Palette", &mut build_diags_to_ignore)
99 .await
100 .unwrap_or_else(|| panic!("can't load palette"))
101 };
102
103 let global_type_registry = type_loader.global_type_registry.clone();
104
105 run_import_passes(doc, type_loader, diag);
106 check_public_api::check_public_api(doc, &type_loader.compiler_config, diag);
107
108 let raw_type_loader =
109 keep_raw.then(|| crate::typeloader::snapshot_with_extra_doc(type_loader, doc).unwrap());
110
111 collect_libraries::collect_libraries(doc);
112 collect_subcomponents::collect_subcomponents(doc);
113 lower_tabwidget::lower_tabwidget(doc, type_loader, diag).await;
114 lower_menus::lower_menus(doc, type_loader, diag).await;
115 lower_component_container::lower_component_container(doc, type_loader, diag);
116 collect_subcomponents::collect_subcomponents(doc);
117
118 doc.visit_all_used_components(|component| {
119 apply_default_properties_from_style::apply_default_properties_from_style(
120 component,
121 &style_metrics,
122 &palette,
123 diag,
124 );
125 lower_states::lower_states(component, diag);
126 lower_text_input_interface::lower_text_input_interface(component);
127 compile_paths::compile_paths(
128 component,
129 &doc.local_registry,
130 type_loader.compiler_config.embed_resources,
131 diag,
132 );
133 repeater_component::process_repeater_components(component);
134 lower_popups::lower_popups(component, &doc.local_registry, diag);
135 collect_init_code::collect_init_code(component);
136 lower_timers::lower_timers(component, diag);
137 });
138
139 inlining::inline(doc, inlining::InlineSelection::InlineOnlyRequiredComponents, diag);
140 collect_subcomponents::collect_subcomponents(doc);
141
142 for root_component in doc.exported_roots() {
143 focus_handling::call_focus_on_init(&root_component);
144 windows::ensure_window(&root_component, &doc.local_registry, &style_metrics, diag);
145 }
146 if let Some(popup_menu_impl) = &doc.popup_menu_impl {
147 focus_handling::call_focus_on_init(popup_menu_impl);
148 }
149
150 doc.visit_all_used_components(|component| {
151 border_radius::handle_border_radius(component, diag);
152 deprecated_rotation_origin::handle_rotation_origin(component, diag);
153 flickable::handle_flickable(component, &global_type_registry.borrow());
154 lower_layout::lower_layouts(component, type_loader, &style_metrics, diag);
155 default_geometry::default_geometry(component, diag);
156 lower_absolute_coordinates::lower_absolute_coordinates(component);
157 z_order::reorder_by_z_order(component, diag);
158 lower_property_to_element::lower_property_to_element(
159 component,
160 core::iter::once("opacity"),
161 core::iter::empty(),
162 None,
163 &SmolStr::new_static("Opacity"),
164 &global_type_registry.borrow(),
165 diag,
166 );
167 lower_property_to_element::lower_property_to_element(
168 component,
169 core::iter::once("cache-rendering-hint"),
170 core::iter::empty(),
171 None,
172 &SmolStr::new_static("Layer"),
173 &global_type_registry.borrow(),
174 diag,
175 );
176 visible::handle_visible(component, &global_type_registry.borrow(), diag);
177 lower_shadows::lower_shadow_properties(component, &doc.local_registry, diag);
178 lower_property_to_element::lower_transform_properties(
179 component,
180 &global_type_registry.borrow(),
181 diag,
182 );
183 clip::handle_clip(component, &global_type_registry.borrow(), diag);
184 if type_loader.compiler_config.accessibility {
185 lower_accessibility::lower_accessibility_properties(component, diag);
186 }
187 lower_repeated_rows::lower_repeated_rows(component, &global_type_registry.borrow());
188 materialize_fake_properties::materialize_fake_properties(component);
189 });
190 for root_component in doc.exported_roots() {
191 lower_layout::check_window_layout(&root_component);
192 }
193 collect_globals::collect_globals(doc, diag);
194
195 if type_loader.compiler_config.inline_all_elements {
196 inlining::inline(doc, inlining::InlineSelection::InlineAllComponents, diag);
197 doc.used_types.borrow_mut().sub_components.clear();
198 }
199
200 let global_analysis =
201 binding_analysis::binding_analysis(doc, &type_loader.compiler_config, diag);
202 collect_globals::mark_library_globals(doc);
203 unique_id::assign_unique_id(doc);
204
205 doc.visit_all_used_components(|component| {
206 key_bindings::warn_duplicates(component, diag);
207 lower_platform::lower_platform(component, type_loader);
208
209 if !type_loader.compiler_config.debug_info {
214 optimize_useless_rectangles::optimize_useless_rectangles(component);
215 }
216 move_declarations::move_declarations(component);
217 });
218
219 remove_aliases::remove_aliases(doc, diag);
220 remove_return::remove_return(doc);
221
222 doc.visit_all_used_components(|component| {
223 if !diag.has_errors() {
224 const_propagation::const_propagation(component, &global_analysis);
226 }
227 deduplicate_property_read::deduplicate_property_read(component);
228 if !component.is_global() && !component.is_interface() {
229 resolve_native_classes::resolve_native_classes(component);
230 }
231 });
232
233 remove_unused_properties::remove_unused_properties(doc);
234 collect_globals::collect_globals(doc, diag);
236 collect_structs_and_enums::collect_structs_and_enums(doc);
237
238 doc.visit_all_used_components(|component| {
239 if !component.is_global() {
240 generate_item_indices::generate_item_indices(component);
241 }
242 });
243
244 embed_images::embed_images(
245 doc,
246 type_loader.compiler_config.embed_resources,
247 type_loader.compiler_config.const_scale_factor.unwrap_or(1.),
248 &type_loader.compiler_config.resource_url_mapper,
249 diag,
250 )
251 .await;
252
253 #[cfg(feature = "bundle-translations")]
254 if let Some(path) = &type_loader.compiler_config.translation_path_bundle {
255 match crate::translations::TranslationsBuilder::load_translations(
256 path,
257 type_loader.compiler_config.translation_domain.as_deref().unwrap_or(""),
258 ) {
259 Ok(builder) => {
260 doc.translation_builder = Some(builder);
261 }
262 Err(err) => {
263 diag.push_error(
264 format!("Cannot load bundled translation: {err}"),
265 doc.node.as_ref().expect("Unexpected empty document"),
266 );
267 }
268 }
269 }
270
271 match type_loader.compiler_config.embed_resources {
272 #[cfg(feature = "software-renderer")]
273 crate::EmbedResourcesKind::EmbedTextures => {
274 let mut characters_seen = std::collections::HashSet::new();
275
276 let sf = type_loader.compiler_config.const_scale_factor.unwrap_or(1.) as f64;
277
278 let mut font_pixel_sizes = vec![(12. * sf) as i16];
280 use i_slint_common::sharedfontique::fontique;
281 let mut font_weights = vec![fontique::FontWeight::NORMAL.value() as u16];
282 doc.visit_all_used_components(|component| {
283 embed_glyphs::collect_font_sizes_used(component, sf, &mut font_pixel_sizes);
284 embed_glyphs::collect_font_weights_used(component, &mut font_weights);
285 embed_glyphs::scan_string_literals(component, &mut characters_seen);
286 });
287
288 #[cfg(feature = "bundle-translations")]
290 if let Some(translation_builder) = doc.translation_builder.as_ref() {
291 translation_builder.collect_characters_seen(&mut characters_seen);
292 }
293
294 embed_glyphs::embed_glyphs(
295 doc,
296 &type_loader.compiler_config,
297 font_pixel_sizes,
298 font_weights,
299 characters_seen,
300 std::iter::once(&*doc).chain(type_loader.all_documents()),
301 diag,
302 );
303 }
304 _ => {
305 collect_custom_fonts::collect_custom_fonts(
307 doc,
308 std::iter::once(&*doc).chain(type_loader.all_documents()),
309 type_loader.compiler_config.embed_resources
310 == crate::EmbedResourcesKind::EmbedAllResources,
311 );
312 }
313 };
314
315 raw_type_loader
316}
317
318pub fn run_import_passes(
320 doc: &crate::object_tree::Document,
321 type_loader: &crate::typeloader::TypeLoader,
322 diag: &mut crate::diagnostics::BuildDiagnostics,
323) {
324 inject_debug_hooks::inject_debug_hooks(doc, type_loader);
325 infer_aliases_types::resolve_aliases(doc, diag);
326 resolving::resolve_expressions(doc, type_loader, diag);
327 purity_check::purity_check(doc, diag);
328 focus_handling::replace_forward_focus_bindings_with_focus_functions(doc, diag);
329 check_expressions::check_expressions(doc, diag);
330 windows::warn_about_child_windows(doc, diag);
331 unique_id::check_unique_id(doc, diag);
332}