From 13269cebc49208bde17799beea22c64fca4e9bb6 Mon Sep 17 00:00:00 2001 From: Colin Rofls Date: Tue, 30 Jul 2024 11:08:57 -0400 Subject: [PATCH] [fea-rs] Add CompilerError::display_verbose fea-rs collects extensive diagnostic information during parsing and compilation, and is able to report errors associated to specific locations in the input FEA. This wasn't very fine-grained, though, and was causing problems with crater (because sometimes the stderr text for a given error would be extremely long, and include a bunch of ANSI escape codes) and so I turned off this finer-grained reporting. It would be nice to have it available as an option, though, especially now that I'm trying to add support for new syntax, and would like to see what the actual errors are. This adds a new method to the CompilerError that will print the error in the old verbose style, and makes it so that when you call the fea-rs binary directly (which is really not useful for debugging) it uses this method when printing the returned error. --- fea-rs/src/bin/compile.rs | 6 +++--- fea-rs/src/compile/error.rs | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/fea-rs/src/bin/compile.rs b/fea-rs/src/bin/compile.rs index a970ad02..f5c1db87 100644 --- a/fea-rs/src/bin/compile.rs +++ b/fea-rs/src/bin/compile.rs @@ -6,7 +6,7 @@ use clap::Parser; use fea_rs::{ compile::{ self, - error::{FontGlyphOrderError, GlyphOrderError, UfoGlyphOrderError}, + error::{CompilerError, FontGlyphOrderError, GlyphOrderError, UfoGlyphOrderError}, Compiler, MockVariationInfo, NopFeatureProvider, Opts, }, GlyphMap, @@ -80,8 +80,8 @@ enum Error { MissingGlyphOrder, #[error("Error parsing axis info: L{line}, '{message}'")] BadAxisInfo { line: usize, message: String }, - #[error("{0}")] - CompileFail(#[from] compile::error::CompilerError), + #[error("{}", .0.display_verbose())] + CompileFail(#[from] CompilerError), } /// Compile FEA files diff --git a/fea-rs/src/compile/error.rs b/fea-rs/src/compile/error.rs index 57761eac..e445248a 100644 --- a/fea-rs/src/compile/error.rs +++ b/fea-rs/src/compile/error.rs @@ -1,5 +1,7 @@ //! Error types related to compilation +use std::fmt::Display; + use write_fonts::{read::ReadError, BuilderError}; use crate::{parse::SourceLoadError, DiagnosticSet}; @@ -58,6 +60,26 @@ pub enum CompilerError { WriteFail(#[from] BuilderError), } +impl CompilerError { + /// Return a `Display` type that reports the location and nature of syntax errors + pub fn display_verbose(&self) -> impl Display + '_ { + struct Verbose<'a>(&'a CompilerError); + impl std::fmt::Display for Verbose<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{}", self.0)?; + let diagnostic = match self.0 { + CompilerError::ParseFail(x) + | CompilerError::ValidationFail(x) + | CompilerError::CompilationFail(x) => x, + _ => return Ok(()), + }; + write!(f, "\n{}", diagnostic.display()) + } + } + Verbose(self) + } +} + #[cfg(test)] mod tests { use super::*;