difftreelog
feat add tracing format based on hi-doc
in: master
7 files changed
Cargo.lockdiffbeforeafterboth108source = "registry+https://github.com/rust-lang/crates.io-index"108source = "registry+https://github.com/rust-lang/crates.io-index"109checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"109checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"110111[[package]]112name = "ass-stroke"113version = "0.1.0"114source = "git+https://github.com/CertainLach/ass-stroke#e649d7ffb2beb4800143b7a5acfdae0ad3fb6d94"115dependencies = [116 "num-traits",117 "rand 0.8.5",118 "random_color",119 "range-map",120 "smallvec",121]122110123[[package]]111[[package]]124name = "autocfg"112name = "autocfg"420 "version_check",408 "version_check",421]409]422423[[package]]424name = "getrandom"425version = "0.1.16"426source = "registry+https://github.com/rust-lang/crates.io-index"427checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"428dependencies = [429 "cfg-if",430 "libc",431 "wasi 0.9.0+wasi-snapshot-preview1",432]433410434[[package]]411[[package]]435name = "getrandom"412name = "getrandom"439dependencies = [416dependencies = [440 "cfg-if",417 "cfg-if",441 "libc",418 "libc",442 "wasi 0.11.0+wasi-snapshot-preview1",419 "wasi",443]420]444421445[[package]]422[[package]]470source = "registry+https://github.com/rust-lang/crates.io-index"447source = "registry+https://github.com/rust-lang/crates.io-index"471checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"448checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"449450[[package]]451name = "hi-doc"452version = "0.1.0"453source = "registry+https://github.com/rust-lang/crates.io-index"454checksum = "748c617f3021ee027bf6f94d54f9c28877467cb79c5847d0dd70c3a6db4da0fc"455dependencies = [456 "num-traits",457 "rand",458 "random_color",459 "range-map",460 "smallvec",461]472462473[[package]]463[[package]]474name = "idna"464name = "idna"545name = "jrsonnet"535name = "jrsonnet"546version = "0.5.0-pre95"536version = "0.5.0-pre95"547dependencies = [537dependencies = [548 "ass-stroke",549 "clap",538 "clap",550 "clap_complete",539 "clap_complete",540 "hi-doc",551 "jrsonnet-cli",541 "jrsonnet-cli",552 "jrsonnet-evaluator",542 "jrsonnet-evaluator",553 "jrsonnet-gcmodule",543 "jrsonnet-gcmodule",578 "bincode",568 "bincode",579 "derivative",569 "derivative",580 "hashbrown 0.14.3",570 "hashbrown 0.14.3",571 "hi-doc",581 "jrsonnet-gcmodule",572 "jrsonnet-gcmodule",582 "jrsonnet-interner",573 "jrsonnet-interner",583 "jrsonnet-macros",574 "jrsonnet-macros",596name = "jrsonnet-fmt"587name = "jrsonnet-fmt"597version = "0.5.0-pre95"588version = "0.5.0-pre95"598dependencies = [589dependencies = [599 "ass-stroke",600 "clap",590 "clap",601 "dprint-core",591 "dprint-core",592 "hi-doc",602 "indoc",593 "indoc",603 "insta",594 "insta",604 "jrsonnet-rowan-parser",595 "jrsonnet-rowan-parser",1061 "proc-macro2",1052 "proc-macro2",1062]1053]10631064[[package]]1065name = "rand"1066version = "0.7.3"1067source = "registry+https://github.com/rust-lang/crates.io-index"1068checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"1069dependencies = [1070 "getrandom 0.1.16",1071 "libc",1072 "rand_chacha 0.2.2",1073 "rand_core 0.5.1",1074 "rand_hc",1075 "rand_pcg",1076]107710541078[[package]]1055[[package]]1079name = "rand"1056name = "rand"1082checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"1059checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"1083dependencies = [1060dependencies = [1084 "libc",1061 "libc",1085 "rand_chacha 0.3.1",1062 "rand_chacha",1086 "rand_core 0.6.4",1063 "rand_core",1087]1064]10881089[[package]]1090name = "rand_chacha"1091version = "0.2.2"1092source = "registry+https://github.com/rust-lang/crates.io-index"1093checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"1094dependencies = [1095 "ppv-lite86",1096 "rand_core 0.5.1",1097]109810651099[[package]]1066[[package]]1100name = "rand_chacha"1067name = "rand_chacha"1103checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"1070checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"1104dependencies = [1071dependencies = [1105 "ppv-lite86",1072 "ppv-lite86",1106 "rand_core 0.6.4",1073 "rand_core",1107]1074]11081109[[package]]1110name = "rand_core"1111version = "0.5.1"1112source = "registry+https://github.com/rust-lang/crates.io-index"1113checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"1114dependencies = [1115 "getrandom 0.1.16",1116]111710751118[[package]]1076[[package]]1119name = "rand_core"1077name = "rand_core"1120version = "0.6.4"1078version = "0.6.4"1121source = "registry+https://github.com/rust-lang/crates.io-index"1079source = "registry+https://github.com/rust-lang/crates.io-index"1122checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"1080checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"1123dependencies = [1081dependencies = [1124 "getrandom 0.2.12",1082 "getrandom",1125]1083]11261127[[package]]1128name = "rand_hc"1129version = "0.2.0"1130source = "registry+https://github.com/rust-lang/crates.io-index"1131checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"1132dependencies = [1133 "rand_core 0.5.1",1134]11351136[[package]]1137name = "rand_pcg"1138version = "0.2.1"1139source = "registry+https://github.com/rust-lang/crates.io-index"1140checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"1141dependencies = [1142 "rand_core 0.5.1",1143]114410841145[[package]]1085[[package]]1146name = "random_color"1086name = "random_color"1147version = "0.6.1"1087version = "0.8.0"1148source = "registry+https://github.com/rust-lang/crates.io-index"1088source = "registry+https://github.com/rust-lang/crates.io-index"1149checksum = "f5f34bd6526786b2ce5141fd37a4084b5da1ebae74595b5b0d05482a7cef7181"1089checksum = "0085421bc527effa7ed6d46bac0a28734663c47abe03d80a5e78e441fad85196"1150dependencies = [1090dependencies = [1151 "rand 0.7.3",1091 "rand",1152]1092]115310931154[[package]]1094[[package]]1582source = "registry+https://github.com/rust-lang/crates.io-index"1522source = "registry+https://github.com/rust-lang/crates.io-index"1583checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"1523checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"15841585[[package]]1586name = "wasi"1587version = "0.9.0+wasi-snapshot-preview1"1588source = "registry+https://github.com/rust-lang/crates.io-index"1589checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"159015241591[[package]]1525[[package]]1592name = "wasi"1526name = "wasi"Cargo.tomldiffbeforeafterboth--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,7 +16,7 @@
jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre95" }
jrsonnet-gcmodule = "0.3.6"
-ass-stroke = { git = "https://github.com/CertainLach/ass-stroke", version = "0.1.0" }
+hi-doc = "0.1.0"
serde = "1.0.197"
serde_json = "1.0.114"
cmds/jrsonnet-fmt/Cargo.tomldiffbeforeafterboth--- a/cmds/jrsonnet-fmt/Cargo.toml
+++ b/cmds/jrsonnet-fmt/Cargo.toml
@@ -8,7 +8,7 @@
jrsonnet-rowan-parser.workspace = true
insta.workspace = true
indoc.workspace = true
-ass-stroke.workspace = true
+hi-doc.workspace = true
clap = { workspace = true, features = ["derive"] }
tempfile.workspace = true
thiserror.workspace = true
cmds/jrsonnet/Cargo.tomldiffbeforeafterboth--- a/cmds/jrsonnet/Cargo.toml
+++ b/cmds/jrsonnet/Cargo.toml
@@ -58,4 +58,4 @@
clap_complete.workspace = true
serde_json.workspace = true
serde = { workspace = true, features = ["derive"] }
-ass-stroke.workspace = true
+hi-doc.workspace = true
crates/jrsonnet-cli/src/trace.rsdiffbeforeafterboth--- a/crates/jrsonnet-cli/src/trace.rs
+++ b/crates/jrsonnet-cli/src/trace.rs
@@ -1,5 +1,7 @@
use clap::{Parser, ValueEnum};
-use jrsonnet_evaluator::trace::{CompactFormat, ExplainingFormat, PathResolver, TraceFormat};
+use jrsonnet_evaluator::trace::{
+ AssStrokeFormat, CompactFormat, ExplainingFormat, PathResolver, TraceFormat,
+};
#[derive(PartialEq, Eq, ValueEnum, Clone)]
pub enum TraceFormatName {
@@ -7,6 +9,8 @@
Compact,
/// Display source code with attached trace annotations
Explaining,
+ /// Experimental trace formatting based on hi-doc library
+ HiDoc,
}
#[derive(Parser)]
@@ -38,6 +42,10 @@
resolver,
max_trace,
}),
+ TraceFormatName::HiDoc => Box::new(AssStrokeFormat {
+ resolver,
+ max_trace,
+ }),
};
format
}
crates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth--- a/crates/jrsonnet-evaluator/Cargo.toml
+++ b/crates/jrsonnet-evaluator/Cargo.toml
@@ -10,7 +10,7 @@
[features]
default = ["explaining-traces"]
# Rustc-like trace visualization
-explaining-traces = ["annotate-snippets"]
+explaining-traces = ["annotate-snippets", "hi-doc"]
# Allows library authors to throw custom errors
anyhow-error = ["anyhow"]
# Adds ability to build import closure in async
@@ -54,6 +54,8 @@
bincode = { workspace = true, optional = true }
# Explaining traces
annotate-snippets = { workspace = true, optional = true }
+# Better explaining traces
+hi-doc = { workspace = true, optional = true }
# Bigint
num-bigint = { workspace = true, features = ["serde"], optional = true }
derivative.workspace = true
crates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/trace/mod.rs
+++ b/crates/jrsonnet-evaluator/src/trace/mod.rs
@@ -1,10 +1,11 @@
use std::{
any::Any,
+ cell::RefCell,
path::{Path, PathBuf},
};
use jrsonnet_gcmodule::Trace;
-use jrsonnet_parser::{CodeLocation, Source};
+use jrsonnet_parser::{CodeLocation, ExprLocation, Source};
use crate::{error::ErrorKind, Error};
@@ -303,6 +304,7 @@
}
}
+#[cfg(feature = "explaining-traces")]
impl ExplainingFormat {
fn print_snippet(
&self,
@@ -363,3 +365,113 @@
Ok(())
}
}
+
+#[cfg(feature = "explaining-traces")]
+#[derive(Trace)]
+pub struct AssStrokeFormat {
+ pub resolver: PathResolver,
+ pub max_trace: usize,
+}
+#[cfg(feature = "explaining-traces")]
+impl TraceFormat for AssStrokeFormat {
+ fn write_trace(
+ &self,
+ out: &mut dyn std::fmt::Write,
+ error: &Error,
+ ) -> Result<(), std::fmt::Error> {
+ struct ResetData {
+ loc: ExprLocation,
+ }
+ use hi_doc::{source_to_ansi, Formatting, SnippetBuilder, Text};
+
+ write!(out, "{}", error.error())?;
+ if let ErrorKind::ImportSyntaxError { path, error } = error.error() {
+ writeln!(out)?;
+ let offset = error.location.offset;
+ let mut builder = SnippetBuilder::new(path.code());
+ builder
+ .error(Text::single("syntax error".chars(), Formatting::default()))
+ .range(offset..=offset)
+ .build();
+ let source = builder.build();
+ let ansi = source_to_ansi(&source);
+ write!(out, "{ansi}")?;
+ }
+ let trace = &error.trace();
+ let snippet_builder: RefCell<Option<SnippetBuilder>> = RefCell::new(None);
+ let mut last_location: Option<ExprLocation> = None;
+ let mut flush_builder = |data: Option<ResetData>| {
+ use std::fmt::Write;
+ let mut out = String::new();
+ let location_changed = if let Some(ResetData { loc }) = &data {
+ if last_location.as_ref().map(|l| l.0.code()) != Some(loc.0.code()) {
+ true
+ } else if let (Some(last), new) = (&last_location, loc) {
+ // Reverse condition if traceback
+ last.1 > new.1 || last.2 > new.2
+ } else {
+ false
+ }
+ } else {
+ true
+ };
+ if location_changed {
+ if let Some(builder) = snippet_builder.borrow_mut().take() {
+ let rendered = builder.build();
+ let ansi = source_to_ansi(&rendered);
+ if let Some(loc) = &last_location {
+ let _ = writeln!(out, "...because of {}", loc.0.source_path());
+ }
+ let _ = write!(out, "{}", ansi.trim_end());
+ }
+ last_location = None;
+
+ if let Some(ResetData { loc }) = data {
+ *snippet_builder.borrow_mut() = Some(SnippetBuilder::new(loc.0.code()));
+ last_location = Some(loc);
+ }
+ }
+ if out.is_empty() {
+ return None;
+ }
+ Some(out)
+ };
+ for item in &trace.0 {
+ let desc = &item.desc;
+ if let Some(source) = &item.location {
+ if let Some(flushed) = flush_builder(Some(ResetData {
+ loc: source.clone(),
+ })) {
+ writeln!(out)?;
+ write!(out, "{flushed}")?;
+ }
+ let mut builder = snippet_builder.borrow_mut();
+ let builder = builder.as_mut().unwrap();
+ builder
+ .note(Text::single(desc.chars(), Formatting::default()))
+ .range(source.1 as usize..=(source.2 as usize - 1).max(source.1 as usize))
+ .build();
+ } else {
+ if let Some(flushed) = flush_builder(None) {
+ writeln!(out)?;
+ write!(out, "{flushed}")?;
+ }
+ write!(out, "{desc}")?;
+ }
+ }
+
+ if let Some(flushed) = flush_builder(None) {
+ writeln!(out)?;
+ write!(out, "{flushed}")?;
+ }
+ Ok(())
+ }
+
+ fn as_any(&self) -> &dyn Any {
+ self
+ }
+
+ fn as_any_mut(&mut self) -> &mut dyn Any {
+ self
+ }
+}