Add better error reporting for repl.

This commit is contained in:
Jesse Brault 2026-08-20 20:02:23 -05:00
parent 05a1f5d091
commit 56196551b8
4 changed files with 59 additions and 41 deletions

43
dm/src/common.rs Normal file
View File

@ -0,0 +1,43 @@
use codespan_reporting::diagnostic::Label;
use dmc_lib::diagnostic::Diagnostic;
pub fn to_csr_diagnostic(
file_id: usize,
diagnostic: &Diagnostic,
) -> codespan_reporting::diagnostic::Diagnostic<usize> {
let mut primary_label = Label::primary(file_id, diagnostic.start()..diagnostic.end());
if let Some(primary_label_message) = diagnostic.primary_label_message() {
primary_label = primary_label.with_message(primary_label_message);
}
let secondary_labels: Vec<Label<usize>> = diagnostic
.secondary_labels()
.iter()
.map(|secondary_label| {
let mut label =
Label::secondary(file_id, secondary_label.start()..secondary_label.end());
if let Some(message) = secondary_label.message() {
label = label.with_message(message);
}
label
})
.collect();
let mut csr_diagnostic = codespan_reporting::diagnostic::Diagnostic::error()
.with_message(diagnostic.message())
.with_label(primary_label)
.with_labels(secondary_labels);
if let Some(error_code) = diagnostic.error_code() {
csr_diagnostic = csr_diagnostic.with_code(format!("E{:04}", error_code));
}
if let Some((reporter_file, reporter_line)) = diagnostic.reporter() {
csr_diagnostic = csr_diagnostic.with_note(format!(
"Reported by (Rust) source: {}, line {}",
reporter_file, reporter_line
));
}
csr_diagnostic
}

View File

@ -1,9 +1,11 @@
mod common;
mod repl; mod repl;
mod run; mod run;
use crate::repl::repl; use crate::repl::repl;
use crate::run::compile_and_run_script; use crate::run::compile_and_run_script;
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
use std::io; use std::io;
use std::path::PathBuf; use std::path::PathBuf;
@ -47,7 +49,7 @@ fn main() {
repl( repl(
&mut io::stdin().lock(), &mut io::stdin().lock(),
&mut io::stdout().lock(), &mut io::stdout().lock(),
&mut io::stderr().lock(), &mut StandardStream::stderr(ColorChoice::Always),
register_count, register_count,
); );
} }

View File

@ -1,3 +1,6 @@
use crate::common::to_csr_diagnostic;
use codespan_reporting::files::SimpleFiles;
use codespan_reporting::term::{Config, WriteStyle, emit_to_write_style};
use dmc_lib::SyntheticFunctionSession; use dmc_lib::SyntheticFunctionSession;
use dmc_lib::constants_table::ConstantsTable; use dmc_lib::constants_table::ConstantsTable;
use dmc_lib::diagnostic::Diagnostics; use dmc_lib::diagnostic::Diagnostics;
@ -11,9 +14,13 @@ use std::io::{BufRead, Write};
pub fn repl( pub fn repl(
read: &mut impl BufRead, read: &mut impl BufRead,
out: &mut impl Write, out: &mut impl Write,
err: &mut impl Write, err: &mut impl WriteStyle,
register_count: usize, register_count: usize,
) { ) {
let diagnostics_config = Config::default();
let mut files: SimpleFiles<&str, String> = SimpleFiles::new();
let mut current_file_id;
let mut buffer = String::new(); let mut buffer = String::new();
let mut session = SyntheticFunctionSession::new("__repl"); let mut session = SyntheticFunctionSession::new("__repl");
@ -48,8 +55,10 @@ pub fn repl(
.insert(function.name_owned(), function); .insert(function.name_owned(), function);
} }
Err(diagnostics) => { Err(diagnostics) => {
current_file_id = files.add("input", String::from(input));
for diagnostic in diagnostics { for diagnostic in diagnostics {
writeln!(err, "{}", diagnostic.message()).unwrap(); let csr_diagnostic = to_csr_diagnostic(current_file_id, &diagnostic);
emit_to_write_style(err, &diagnostics_config, &files, &csr_diagnostic).unwrap();
} }
buffer.clear(); buffer.clear();
continue 'repl; continue 'repl;

View File

@ -1,4 +1,4 @@
use codespan_reporting::diagnostic::Label; use crate::common::to_csr_diagnostic;
use codespan_reporting::files::SimpleFiles; use codespan_reporting::files::SimpleFiles;
use codespan_reporting::term; use codespan_reporting::term;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream}; use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
@ -88,43 +88,7 @@ fn report_and_exit(
let writer = StandardStream::stderr(ColorChoice::Always); let writer = StandardStream::stderr(ColorChoice::Always);
let config = term::Config::default(); let config = term::Config::default();
for diagnostic in diagnostics { for diagnostic in diagnostics {
let mut primary_label = let csr_diagnostic = to_csr_diagnostic(script_file_id, diagnostic);
Label::primary(script_file_id, diagnostic.start()..diagnostic.end());
if let Some(primary_label_message) = diagnostic.primary_label_message() {
primary_label = primary_label.with_message(primary_label_message);
}
let secondary_labels: Vec<Label<usize>> = diagnostic
.secondary_labels()
.iter()
.map(|secondary_label| {
let mut label = Label::secondary(
script_file_id,
secondary_label.start()..secondary_label.end(),
);
if let Some(message) = secondary_label.message() {
label = label.with_message(message);
}
label
})
.collect();
let mut csr_diagnostic = codespan_reporting::diagnostic::Diagnostic::error()
.with_message(diagnostic.message())
.with_label(primary_label)
.with_labels(secondary_labels);
if let Some(error_code) = diagnostic.error_code() {
csr_diagnostic = csr_diagnostic.with_code(format!("E{:04}", error_code));
}
if let Some((reporter_file, reporter_line)) = diagnostic.reporter() {
csr_diagnostic = csr_diagnostic.with_note(format!(
"Reported by (Rust) source: {}, line {}",
reporter_file, reporter_line
));
}
term::emit_to_write_style(&mut writer.lock(), &config, files, &csr_diagnostic).unwrap(); term::emit_to_write_style(&mut writer.lock(), &config, files, &csr_diagnostic).unwrap();
} }
if diagnostics.len() == 1 { if diagnostics.len() == 1 {