sixtyfps_compilerlib/
lib.rs1#![doc(html_logo_url = "https://sixtyfps.io/resources/logo.drawio.svg")]
17#![deny(unsafe_code)]
19
20#[cfg(feature = "proc_macro_span")]
21extern crate proc_macro;
22
23use core::future::Future;
24use core::pin::Pin;
25use std::cell::RefCell;
26use std::rc::Rc;
27
28pub mod builtin_macros;
29pub mod diagnostics;
30pub mod embedded_resources;
31pub mod expression_tree;
32pub mod fileaccess;
33pub mod generator;
34pub mod langtype;
35pub mod layout;
36pub mod lexer;
37pub mod literals;
38pub mod llr;
39pub(crate) mod load_builtins;
40pub mod lookup;
41pub mod namedreference;
42pub mod object_tree;
43pub mod parser;
44pub mod typeloader;
45pub mod typeregister;
46
47mod passes;
48
49#[derive(Clone)]
51pub struct CompilerConfiguration {
52 pub embed_resources: bool,
55 pub include_paths: Vec<std::path::PathBuf>,
57 pub style: Option<String>,
59
60 pub open_import_fallback: Option<
65 Rc<dyn Fn(String) -> Pin<Box<dyn Future<Output = Option<std::io::Result<String>>>>>>,
66 >,
67
68 pub inline_all_elements: bool,
73}
74
75impl CompilerConfiguration {
76 pub fn new(output_format: crate::generator::OutputFormat) -> Self {
77 let embed_resources = match std::env::var("SIXTYFPS_EMBED_RESOURCES") {
78 Ok(var) => {
79 var.parse().unwrap_or_else(|_|{
80 panic!("SIXTYFPS_EMBED_RESOURCES has incorrect value. Must be either unset, 'true' or 'false'")
81 })
82 }
83 Err(_) => {
84 match output_format {
85 #[cfg(feature = "rust")]
86 crate::generator::OutputFormat::Rust => true,
87 _ => false,
88 }
89 }
90 };
91
92 let inline_all_elements = match std::env::var("SIXTYFPS_INLINING") {
93 Ok(var) => {
94 var.parse::<bool>().unwrap_or_else(|_|{
95 panic!("SIXTYFPS_INLINING has incorrect value. Must be either unset, 'true' or 'false'")
96 })
97 }
98 Err(_) => output_format == crate::generator::OutputFormat::Interpreter,
100 };
101
102 Self {
103 embed_resources,
104 include_paths: Default::default(),
105 style: Default::default(),
106 open_import_fallback: Default::default(),
107 inline_all_elements,
108 }
109 }
110}
111
112pub async fn compile_syntax_node(
113 doc_node: parser::SyntaxNode,
114 mut diagnostics: diagnostics::BuildDiagnostics,
115 compiler_config: CompilerConfiguration,
116) -> (object_tree::Document, diagnostics::BuildDiagnostics) {
117 let global_type_registry = typeregister::TypeRegister::builtin();
118 let type_registry =
119 Rc::new(RefCell::new(typeregister::TypeRegister::new(&global_type_registry)));
120
121 let doc_node: parser::syntax_nodes::Document = doc_node.into();
122
123 let mut loader =
124 typeloader::TypeLoader::new(global_type_registry, &compiler_config, &mut diagnostics);
125 let foreign_imports =
126 loader.load_dependencies_recursively(&doc_node, &mut diagnostics, &type_registry).await;
127
128 let doc = crate::object_tree::Document::from_node(
129 doc_node,
130 foreign_imports,
131 &mut diagnostics,
132 &type_registry,
133 );
134
135 if let Some((_, node)) = &*doc.root_component.child_insertion_point.borrow() {
136 diagnostics
137 .push_error("@children placeholder not allowed in the final component".into(), node)
138 }
139
140 if !diagnostics.has_error() {
141 passes::run_passes(&doc, &mut diagnostics, &mut loader, &compiler_config).await;
143 }
144
145 diagnostics.all_loaded_files = loader.all_files().cloned().collect();
146
147 (doc, diagnostics)
148}