1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
#![doc = include_str!("README.md")]
#![doc(html_logo_url = "https://slint-ui.com/logo/slint-logo-square-light.svg")]
#![deny(unsafe_code)]
#[cfg(feature = "proc_macro_span")]
extern crate proc_macro;
use core::future::Future;
use core::pin::Pin;
use std::cell::RefCell;
use std::rc::Rc;
pub mod builtin_macros;
pub mod diagnostics;
pub mod embedded_resources;
pub mod expression_tree;
pub mod fileaccess;
pub mod generator;
pub mod langtype;
pub mod layout;
pub mod lexer;
pub mod literals;
pub mod llr;
pub(crate) mod load_builtins;
pub mod lookup;
pub mod namedreference;
pub mod object_tree;
pub mod parser;
pub mod typeloader;
pub mod typeregister;
mod passes;
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum EmbedResourcesKind {
OnlyBuiltinResources,
EmbedAllResources,
EmbedTextures,
}
#[derive(Clone)]
pub struct CompilerConfiguration {
pub embed_resources: EmbedResourcesKind,
pub include_paths: Vec<std::path::PathBuf>,
pub style: Option<String>,
pub open_import_fallback: Option<
Rc<dyn Fn(String) -> Pin<Box<dyn Future<Output = Option<std::io::Result<String>>>>>>,
>,
pub inline_all_elements: bool,
pub scale_factor: f64,
}
impl CompilerConfiguration {
pub fn new(output_format: crate::generator::OutputFormat) -> Self {
let embed_resources = match std::env::var("SLINT_EMBED_RESOURCES") {
Ok(var) => {
let var = var.parse::<bool>().unwrap_or_else(|_|{
panic!("SLINT_EMBED_RESOURCES has incorrect value. Must be either unset, 'true' or 'false'")
});
match var {
true => EmbedResourcesKind::OnlyBuiltinResources,
false => EmbedResourcesKind::EmbedAllResources,
}
}
Err(_) => match output_format {
#[cfg(feature = "rust")]
crate::generator::OutputFormat::Rust => {
match std::env::var_os("SLINT_EMBED_TEXTURES") {
Some(_) => EmbedResourcesKind::EmbedTextures,
None => EmbedResourcesKind::EmbedAllResources,
}
}
_ => EmbedResourcesKind::OnlyBuiltinResources,
},
};
let inline_all_elements = match std::env::var("SLINT_INLINING") {
Ok(var) => var.parse::<bool>().unwrap_or_else(|_| {
panic!(
"SLINT_INLINING has incorrect value. Must be either unset, 'true' or 'false'"
)
}),
Err(_) => output_format == crate::generator::OutputFormat::Interpreter,
};
let scale_factor = std::env::var("SLINT_SCALE_FACTOR")
.ok()
.and_then(|x| x.parse::<f64>().ok())
.filter(|f| *f > 0.)
.unwrap_or(1.);
Self {
embed_resources,
include_paths: Default::default(),
style: Default::default(),
open_import_fallback: Default::default(),
inline_all_elements,
scale_factor,
}
}
}
pub async fn compile_syntax_node(
doc_node: parser::SyntaxNode,
mut diagnostics: diagnostics::BuildDiagnostics,
compiler_config: CompilerConfiguration,
) -> (object_tree::Document, diagnostics::BuildDiagnostics) {
let global_type_registry = typeregister::TypeRegister::builtin();
let type_registry =
Rc::new(RefCell::new(typeregister::TypeRegister::new(&global_type_registry)));
let doc_node: parser::syntax_nodes::Document = doc_node.into();
let mut loader =
typeloader::TypeLoader::new(global_type_registry, &compiler_config, &mut diagnostics);
if diagnostics.has_error() {
return (crate::object_tree::Document::default(), diagnostics);
}
let foreign_imports =
loader.load_dependencies_recursively(&doc_node, &mut diagnostics, &type_registry).await;
let doc = crate::object_tree::Document::from_node(
doc_node,
foreign_imports,
&mut diagnostics,
&type_registry,
);
if let Some((_, node)) = &*doc.root_component.child_insertion_point.borrow() {
diagnostics
.push_error("@children placeholder not allowed in the final component".into(), node)
}
if !diagnostics.has_error() {
passes::run_passes(&doc, &mut diagnostics, &mut loader, &compiler_config).await;
}
diagnostics.all_loaded_files = loader.all_files().cloned().collect();
(doc, diagnostics)
}