From 280e11a95eaf5268da762247208160573f093518 Mon Sep 17 00:00:00 2001 From: Klesti Selimaj Date: Tue, 2 Jun 2026 23:24:11 +0200 Subject: [PATCH] Bootstrapped builder --- crates/mist-api/src/builder.mist | 188 +++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 crates/mist-api/src/builder.mist diff --git a/crates/mist-api/src/builder.mist b/crates/mist-api/src/builder.mist new file mode 100644 index 0000000..90a9bd9 --- /dev/null +++ b/crates/mist-api/src/builder.mist @@ -0,0 +1,188 @@ +use ; +use ; +use ; +use ; +use ; +use ; +use ; +use ; +use ; +use ; + +#[derive(Debug, Clone)] +pub struct MistDiagnosticMessage { + pub String message, + pub PathBuf file_path, + pub String file_name, + pub usize line, + pub usize column, +} + +#[derive(Debug, Clone)] +pub enum MistDiagnostic { + Error[MistDiagnosticMessage], + Warning[MistDiagnosticMessage], + Rust[CompilerMessage], +} + +pub bool build(Vec mut args, PathBuf root) { + args.remove(0); + args.insert(1, "--message-format=json".to_string()); + + var is_root = root == env::current_dir().expect("Failed getting env"); + + var mut command = Command::new("cargo") + .args(args) + .stdout(Stdio::piped()) + .stderr(Stdio::inherit()) + .stdin(Stdio::inherit()) + .spawn() + .expect("Failed to run cargo"); + + var mut reader = std::io::BufReader::new(command.stdout.take().expect("Failed to get reader")); + + var mut diagnostics = Vec::new(); + + var mut mapping = HashMap::new(); + + var mist_src = format!(".mist{MAIN_SEPARATOR}src"); + + for (message : cargo_metadata::Message::parse_stream(&mut reader)) { + match (message) { + Ok[Message::CompilerMessage[msg]] => { + for (span : &msg.message.spans) { + if (span.is_primary) { + var rust_path = root.join(&span.file_name); + + var mist_file = span + .file_name + .replacen(&mist_src, "src", 1) + .trim_end_matches(".rs") + .to_string() + + ".mist"; + + var mist_path = root.join(&mist_file); + + if (!fs::exists(&mist_path).expect("Unable to check if mist file exists")) { + diagnostics.push(MistDiagnostic::Rust(msg)); + break; + } + + var map = mapping.entry(rust_path.clone()).or_insert_with(|| { + rev_mapper::get_mapping( + &fs::read_to_string(rust_path) + .expect("Failed to read file for mapping") + ) + }); + + var [_, rev_mapper::MistMap[line, column]] = + rev_mapper::find_mapping(&map, &rev_mapper::RustMap(span.line_end, span.column_start)) + .expect("Unable to find mapping"); + + var mist_msg = MistDiagnosticMessage { + message: format!( + "{}: {}", + msg.message.message, + span.label.clone().unwrap_or_default() + ), + file_name: if (is_root) { + mist_file + } else { + mist_path.to_string_lossy().to_string() + }, + file_path: mist_path, + line: line, + column: column + }; + + match (msg.message.level) { + cargo_metadata::diagnostic::DiagnosticLevel::Error => { + diagnostics.push(MistDiagnostic::Error(mist_msg)) + } + + cargo_metadata::diagnostic::DiagnosticLevel::Warning => { + diagnostics.push(MistDiagnostic::Warning(mist_msg)) + } + + _ => {} + } + } + } + } + + Ok[Message::BuildFinished[finish]] => { + print_diagnostics(&diagnostics); + + var mut raw_reader = reader.into_inner(); + var mut stdout = std::io::stdout(); + + std::io::copy(&mut raw_reader, &mut stdout) + .map_err(|var v| v.to_string()) + .expect("(Mist) Failed to copy IO"); + + command.wait().unwrap(); + + return finish.success; + } + + Ok[Message::TextLine[text]] => println!("{text}"); + _ => {} + } + } + + false +} + +pub void print_diagnostics(Vec* diagnostics) { + var mut files = HashMap::new(); + + for (diag : diagnostics) { + match (diag) { + MistDiagnostic::Error[msg] => { + var line = get_line(&mut files, &msg); + + println!( + "\n{}:{}:{}\n \x1b[31mError\x1b[0m: {}\n\t{}", + msg.file_name, + msg.line, + msg.column, + msg.message, + line.unwrap_or_default(), + ) + } + + MistDiagnostic::Warning[msg] => { + var line = get_line(&mut files, &msg); + + println!( + "\n{}:{}:{}\n \x1b[33mWarning\x1b[0m: {}\n\t{}", + msg.file_name, + msg.line, + msg.column, + msg.message, + line.unwrap_or_default(), + ) + } + + MistDiagnostic::Rust[rs] => println!("{rs}"); + } + } +} + +pub Option get_line( + HashMap> mut* files, + MistDiagnosticMessage* msg, +) { + var src_path = msg.file_path.clone(); + + var lines = files.entry(src_path.clone()).or_insert_with(|| { + fs::read_to_string(src_path) + .expect("Unable to read mist file") + .lines() + .into_iter() + .map(String::from) + .collect() + }); + + lines.get(msg.line - 1).map(|var v| v.trim().to_string()) +}