Library/Fn/OXC/
Compile.rs1use std::{
11 io::Write,
12 sync::atomic::{AtomicUsize, Ordering},
13};
14
15use tracing::{debug, error, info, trace};
16
17static FILE_PROCESS_COUNT:AtomicUsize = AtomicUsize::new(0);
18
19fn get_nesting_depth(path:&str) -> usize {
21 path.chars().filter(|&c| c == std::path::MAIN_SEPARATOR || c == '/').count()
22}
23
24#[tracing::instrument(skip(options))]
25pub async fn Fn(options:crate::Struct::SWC::Option, _parallel:bool) -> anyhow::Result<()> {
34 info!("=== OXC Compilation START ===");
35
36 tracing_subscriber::fmt::init();
37
38 let compiler = std::sync::Arc::new(crate::Fn::OXC::Compiler::Compiler::new(options.config.clone()));
39
40 let input_base = options.entry[0][0].clone();
42
43 let output_base = options.output.clone();
44
45 let pattern = options.pattern.clone();
46
47 info!("Compilation from {} to {}", input_base, output_base);
48
49 debug!("Pattern: {}, Parallel: {}", pattern, _parallel);
50
51 let walk_start = std::time::Instant::now();
53
54 let ts_files:Vec<String> = walkdir::WalkDir::new(&input_base)
55 .follow_links(true)
56 .into_iter()
57 .filter_map(|e| {
58 let entry = e.ok()?;
59
60 let path = entry.path();
61
62 if path.is_file() && path.to_string_lossy().ends_with(&pattern) {
63 Some(path.to_string_lossy().to_string())
64 } else {
65 None
66 }
67 })
68 .collect();
69
70 info!(
71 "File discovery completed in {:?}, found {} TypeScript files",
72 walk_start.elapsed(),
73 ts_files.len()
74 );
75
76 let mut depth_dist = std::collections::HashMap::new();
78
79 for f in &ts_files {
80 let depth = get_nesting_depth(f);
81
82 *depth_dist.entry(depth).or_insert(0) += 1;
83 }
84
85 debug!("File distribution by depth: {:?}", depth_dist);
86
87 let mut sorted_files = ts_files.clone();
89
90 sorted_files.sort_by_key(|f| get_nesting_depth(f));
91
92 trace!("File list (sorted by depth):");
93
94 for (i, f) in sorted_files.iter().enumerate() {
95 trace!(" [{}] {} (depth={})", i, f, get_nesting_depth(f));
96 }
97
98 let mut count = 0;
100
101 let mut error = 0;
102
103 let mut current_file = 0;
104
105 let total_files = sorted_files.len();
106
107 info!("Starting sequential file processing ({} files)...", total_files);
108
109 for file_path in sorted_files {
110 current_file += 1;
111
112 let file_id = FILE_PROCESS_COUNT.fetch_add(1, Ordering::SeqCst);
113
114 let depth = get_nesting_depth(&file_path);
115
116 print!(".");
117
118 std::io::stdout().flush().unwrap();
119
120 info!(
121 "[File #{file_id}] Processing [{}/{}]: {} (depth={})",
122 current_file, total_files, file_path, depth
123 );
124
125 match tokio::fs::read_to_string(&file_path).await {
126 Ok(input) => {
127 trace!("[File #{file_id}] Read {} bytes", input.len());
128
129 let input_path = std::path::Path::new(&file_path);
131
132 let base_path = std::path::Path::new(&input_base);
133
134 let relative_path = input_path.strip_prefix(base_path).unwrap_or(input_path);
135
136 let output_path = std::path::Path::new(&output_base).join(relative_path).with_extension("js");
138
139 debug!("[File #{file_id}] Output path: {}", output_path.display());
140
141 let compile_start = std::time::Instant::now();
142
143 match compiler.compile_file_to(&file_path, input, &output_path, options.use_define_for_class_fields) {
144 Ok(output) => {
145 info!(
146 "[File #{file_id}] SUCCESS in {:?}: {} -> {}",
147 compile_start.elapsed(),
148 file_path,
149 output
150 );
151
152 count += 1;
153 },
154
155 Err(e) => {
156 error!(
157 "[File #{file_id}] FAILED in {:?}: {} - Error: {}",
158 compile_start.elapsed(),
159 file_path,
160 e
161 );
162
163 error += 1;
164 },
165 }
166 },
167
168 Err(e) => {
169 error!("[File #{file_id}] READ FAILED: {} - Error: {}", file_path, e);
170
171 error += 1;
172 },
173 }
174 }
175
176 println!();
177
178 let outlook = compiler.outlook.lock().unwrap();
179
180 info!("=== OXC Compilation COMPLETE ===");
181
182 info!(
183 "Total: {} files, Successful: {}, Failed: {}, Time: {:?}",
184 outlook.count, count, error, outlook.elapsed
185 );
186
187 println!("\n=== Compilation Summary ===");
189
190 println!("Total files processed: {}", outlook.count);
191
192 println!("Successful: {}", count);
193
194 println!("Failed: {}", error);
195
196 println!("Time elapsed: {:?}\n", outlook.elapsed);
197
198 Ok(())
199}