add support for errfmt friendly output

This commit is contained in:
Akshay 2021-10-23 22:14:56 +05:30
parent 2e7b95f224
commit c79799c0e4
2 changed files with 96 additions and 41 deletions

View File

@ -49,7 +49,7 @@ fn _main() -> Result<(), StatixErr> {
let mut stderr = io::stderr();
lint_results.for_each(|r| {
stderr.write(&r, &vfs).unwrap();
stderr.write(&r, &vfs, lint_config.format).unwrap();
});
errors.for_each(|e| {
eprintln!("{}", e);

View File

@ -3,7 +3,7 @@ use std::{
str,
};
use crate::lint::LintResult;
use crate::{config::OutFormat, lint::LintResult};
use ariadne::{
CharSet, Color, Config as CliConfig, Fmt, Label, LabelAttach, Report as CliReport,
@ -13,14 +13,37 @@ use rnix::TextRange;
use vfs::ReadOnlyVfs;
pub trait WriteDiagnostic {
fn write(&mut self, report: &LintResult, vfs: &ReadOnlyVfs) -> io::Result<()>;
fn write(
&mut self,
report: &LintResult,
vfs: &ReadOnlyVfs,
format: OutFormat,
) -> io::Result<()>;
}
impl<T> WriteDiagnostic for T
where
T: Write,
{
fn write(&mut self, lint_result: &LintResult, vfs: &ReadOnlyVfs) -> io::Result<()> {
fn write(
&mut self,
lint_result: &LintResult,
vfs: &ReadOnlyVfs,
format: OutFormat,
) -> io::Result<()> {
match format {
OutFormat::StdErr => write_stderr(self, lint_result, vfs),
OutFormat::Errfmt => write_errfmt(self, lint_result, vfs),
_ => Ok(()),
}
}
}
fn write_stderr<T: Write>(
writer: &mut T,
lint_result: &LintResult,
vfs: &ReadOnlyVfs,
) -> io::Result<()> {
let file_id = lint_result.file_id;
let src = str::from_utf8(vfs.get(file_id)).unwrap();
let path = vfs.file_path(file_id);
@ -56,10 +79,42 @@ where
},
)
.finish()
.write((src_id, Source::from(src)), &mut *self)?;
.write((src_id, Source::from(src)), &mut *writer)?;
}
Ok(())
}
fn write_errfmt<T: Write>(writer: &mut T, lint_result: &LintResult, vfs: &ReadOnlyVfs) -> io::Result<()> {
let file_id = lint_result.file_id;
let src = str::from_utf8(vfs.get(file_id)).unwrap();
let path = vfs.file_path(file_id);
for report in lint_result.reports.iter() {
for diagnostic in report.diagnostics.iter() {
let line = line(diagnostic.at, &src);
let col = column(diagnostic.at, &src);
writeln!(
writer,
"{filename}>{linenumber}:{columnnumber}:{errortype}:{errornumber}:{errormessage}",
filename = path.to_str().unwrap_or("<unknown>"),
linenumber = line,
columnnumber = col,
errortype = "W",
errornumber = report.code,
errormessage = diagnostic.message
)?;
}
}
Ok(())
}
fn line(at: TextRange, src: &str) -> usize {
let at = at.start().into();
src[..at].chars().filter(|&c| c == '\n').count() + 1
}
fn column(at: TextRange, src: &str) -> usize {
let at = at.start().into();
src[..at].rfind('\n').map(|c| at - c).unwrap_or(at + 1)
}
// everything within backticks is colorized, backticks are removed