Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

leo error reporting after build #28327

Open
wants to merge 3 commits into
base: mainnet
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
77 changes: 72 additions & 5 deletions compiler/compiler/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,28 @@ impl<'a, N: Network> Compiler<'a, N> {

/// Runs the type checker pass.
pub fn type_checker_pass(&'a self, symbol_table: SymbolTable) -> Result<(SymbolTable, StructGraph, CallGraph)> {
let (symbol_table, struct_graph, call_graph) = TypeChecker::<N>::do_pass((
let type_check_result = TypeChecker::<N>::do_pass((
&self.ast,
self.handler,
symbol_table,
&self.type_table,
self.compiler_options.build.conditional_block_max_depth,
self.compiler_options.build.disable_conditional_branch_type_checking,
))?;
if self.compiler_options.output.type_checked_symbol_table {
self.write_symbol_table_to_json("type_checked_symbol_table.json", &symbol_table)?;
));

// Always report errors and warnings, regardless of the result,
// because even in the Ok case, there might still be warnings.
self.report_errors_and_warnings();

match type_check_result {
Ok((symbol_table, struct_graph, call_graph)) => {
if self.compiler_options.output.type_checked_symbol_table {
self.write_symbol_table_to_json("type_checked_symbol_table.json", &symbol_table)?;
}
Ok((symbol_table, struct_graph, call_graph))
}
Err(e) => Err(e),
}
Ok((symbol_table, struct_graph, call_graph))
}

/// Runs the loop unrolling pass.
Expand Down Expand Up @@ -316,6 +326,63 @@ impl<'a, N: Network> Compiler<'a, N> {
Ok(bytecode)
}

/// Reports any errors and warnings found during type checking.
fn report_errors_and_warnings(&self) {
// Retrieve error and warning counts.
let inner = self.handler.inner.borrow();
let err_count = inner.err_count;
let warn_count = inner.warn_count;

// Color codes for terminal.
const RED: &str = "\x1b[31m";
const YELLOW: &str = "\x1b[33m";
const RESET: &str = "\x1b[0m";

// Get program name.
let program_name = &self
.ast
.ast
.program_scopes
.keys()
.next()
.map(|s| s.to_string())
.unwrap_or_else(|| "Unknown program".to_string());

// Adds two empty lines before the report if there are any errors or warnings.
if err_count + warn_count > 0 {
println!("\n");
}

// Show warning counts.
if warn_count > 0 {
println!(
"{}warning{}: {}.leo generated {} warning{}",
YELLOW,
RESET,
program_name,
warn_count,
if warn_count > 1 { "s" } else { "" }
);
}

// Show error counts, if warnings emitted include them as well.
if err_count > 0 {
let error_message = format!(
"{}error{}: could not compile {}.leo due to {} previous error{}",
RED,
RESET,
program_name,
err_count,
if err_count > 1 { "s" } else { "" }
);
if warn_count > 0 {
println!("{}; {} warning{} emitted", error_message, warn_count, if warn_count > 1 { "s" } else { "" });
} else {
println!("{}", error_message);
}
}
}

/// Writes the AST to a JSON file.
fn write_ast_to_json(&self, file_suffix: &str) -> Result<()> {
// Remove `Span`s if they are not enabled.
Expand Down
8 changes: 4 additions & 4 deletions errors/src/emitter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,11 @@ impl Emitter for BufferEmitter {

/// Contains the actual data for `Handler`.
/// Modelled this way to afford an API using interior mutability.
struct HandlerInner {
pub struct HandlerInner {
/// Number of errors emitted thus far.
err_count: usize,
pub err_count: usize,
/// Number of warnings emitted thus far.
warn_count: usize,
pub warn_count: usize,
/// The sink through which errors will be emitted.
emitter: Box<dyn Emitter>,
}
Expand Down Expand Up @@ -168,7 +168,7 @@ impl HandlerInner {
pub struct Handler {
/// The inner handler.
/// `RefCell` is used here to avoid `&mut` all over the compiler.
inner: RefCell<HandlerInner>,
pub inner: RefCell<HandlerInner>,
}

impl Default for Handler {
Expand Down