git.delta.rocks / jrsonnet / refs/commits / 759175b8af18

difftreelog

feat add tracing format based on hi-doc

Yaroslav Bolyukin2024-02-20parent: #9ae683a.patch.diff
in: master

7 files changed

modifiedCargo.lockdiffbeforeafterboth
108source = "registry+https://github.com/rust-lang/crates.io-index"108source = "registry+https://github.com/rust-lang/crates.io-index"
109checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"109checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
110
111[[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]
122110
123[[package]]111[[package]]
124name = "autocfg"112name = "autocfg"
420 "version_check",408 "version_check",
421]409]
422
423[[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]
433410
434[[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]
444421
445[[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"
449
450[[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]
472462
473[[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]
1063
1064[[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]
10771054
1078[[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]
1088
1089[[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]
10981065
1099[[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]
1108
1109[[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]
11171075
1118[[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]
1126
1127[[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]
1135
1136[[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]
11441084
1145[[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]
11531093
1154[[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"
1584
1585[[package]]
1586name = "wasi"
1587version = "0.9.0+wasi-snapshot-preview1"
1588source = "registry+https://github.com/rust-lang/crates.io-index"
1589checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
15901524
1591[[package]]1525[[package]]
1592name = "wasi"1526name = "wasi"
modifiedCargo.tomldiffbeforeafterboth
16jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre95" }16jrsonnet-types = { path = "./crates/jrsonnet-types", version = "0.5.0-pre95" }
1717
18jrsonnet-gcmodule = "0.3.6"18jrsonnet-gcmodule = "0.3.6"
19ass-stroke = { git = "https://github.com/CertainLach/ass-stroke", version = "0.1.0" }19hi-doc = "0.1.0"
2020
21serde = "1.0.197"21serde = "1.0.197"
22serde_json = "1.0.114"22serde_json = "1.0.114"
modifiedcmds/jrsonnet-fmt/Cargo.tomldiffbeforeafterboth
8jrsonnet-rowan-parser.workspace = true8jrsonnet-rowan-parser.workspace = true
9insta.workspace = true9insta.workspace = true
10indoc.workspace = true10indoc.workspace = true
11ass-stroke.workspace = true11hi-doc.workspace = true
12clap = { workspace = true, features = ["derive"] }12clap = { workspace = true, features = ["derive"] }
13tempfile.workspace = true13tempfile.workspace = true
14thiserror.workspace = true14thiserror.workspace = true
modifiedcmds/jrsonnet/Cargo.tomldiffbeforeafterboth
58clap_complete.workspace = true58clap_complete.workspace = true
59serde_json.workspace = true59serde_json.workspace = true
60serde = { workspace = true, features = ["derive"] }60serde = { workspace = true, features = ["derive"] }
61ass-stroke.workspace = true61hi-doc.workspace = true
6262
modifiedcrates/jrsonnet-cli/src/trace.rsdiffbeforeafterboth
1use clap::{Parser, ValueEnum};1use clap::{Parser, ValueEnum};
2use jrsonnet_evaluator::trace::{CompactFormat, ExplainingFormat, PathResolver, TraceFormat};2use jrsonnet_evaluator::trace::{
3 AssStrokeFormat, CompactFormat, ExplainingFormat, PathResolver, TraceFormat,
4};
35
4#[derive(PartialEq, Eq, ValueEnum, Clone)]6#[derive(PartialEq, Eq, ValueEnum, Clone)]
5pub enum TraceFormatName {7pub enum TraceFormatName {
6 /// Only show `filename:line:column`8 /// Only show `filename:line:column`
7 Compact,9 Compact,
8 /// Display source code with attached trace annotations10 /// Display source code with attached trace annotations
9 Explaining,11 Explaining,
12 /// Experimental trace formatting based on hi-doc library
13 HiDoc,
10}14}
1115
12#[derive(Parser)]16#[derive(Parser)]
38 resolver,42 resolver,
39 max_trace,43 max_trace,
40 }),44 }),
45 TraceFormatName::HiDoc => Box::new(AssStrokeFormat {
46 resolver,
47 max_trace,
48 }),
41 };49 };
42 format50 format
43 }51 }
modifiedcrates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth
10[features]10[features]
11default = ["explaining-traces"]11default = ["explaining-traces"]
12# Rustc-like trace visualization12# Rustc-like trace visualization
13explaining-traces = ["annotate-snippets"]13explaining-traces = ["annotate-snippets", "hi-doc"]
14# Allows library authors to throw custom errors14# Allows library authors to throw custom errors
15anyhow-error = ["anyhow"]15anyhow-error = ["anyhow"]
16# Adds ability to build import closure in async16# Adds ability to build import closure in async
54bincode = { workspace = true, optional = true }54bincode = { workspace = true, optional = true }
55# Explaining traces55# Explaining traces
56annotate-snippets = { workspace = true, optional = true }56annotate-snippets = { workspace = true, optional = true }
57# Better explaining traces
58hi-doc = { workspace = true, optional = true }
57# Bigint59# Bigint
58num-bigint = { workspace = true, features = ["serde"], optional = true }60num-bigint = { workspace = true, features = ["serde"], optional = true }
59derivative.workspace = true61derivative.workspace = true
modifiedcrates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth
1use std::{1use std::{
2 any::Any,2 any::Any,
3 cell::RefCell,
3 path::{Path, PathBuf},4 path::{Path, PathBuf},
4};5};
56
6use jrsonnet_gcmodule::Trace;7use jrsonnet_gcmodule::Trace;
7use jrsonnet_parser::{CodeLocation, Source};8use jrsonnet_parser::{CodeLocation, ExprLocation, Source};
89
9use crate::{error::ErrorKind, Error};10use crate::{error::ErrorKind, Error};
1011
303 }304 }
304}305}
305306
307#[cfg(feature = "explaining-traces")]
306impl ExplainingFormat {308impl ExplainingFormat {
307 fn print_snippet(309 fn print_snippet(
308 &self,310 &self,
364 }366 }
365}367}
368
369#[cfg(feature = "explaining-traces")]
370#[derive(Trace)]
371pub struct AssStrokeFormat {
372 pub resolver: PathResolver,
373 pub max_trace: usize,
374}
375#[cfg(feature = "explaining-traces")]
376impl TraceFormat for AssStrokeFormat {
377 fn write_trace(
378 &self,
379 out: &mut dyn std::fmt::Write,
380 error: &Error,
381 ) -> Result<(), std::fmt::Error> {
382 struct ResetData {
383 loc: ExprLocation,
384 }
385 use hi_doc::{source_to_ansi, Formatting, SnippetBuilder, Text};
386
387 write!(out, "{}", error.error())?;
388 if let ErrorKind::ImportSyntaxError { path, error } = error.error() {
389 writeln!(out)?;
390 let offset = error.location.offset;
391 let mut builder = SnippetBuilder::new(path.code());
392 builder
393 .error(Text::single("syntax error".chars(), Formatting::default()))
394 .range(offset..=offset)
395 .build();
396 let source = builder.build();
397 let ansi = source_to_ansi(&source);
398 write!(out, "{ansi}")?;
399 }
400 let trace = &error.trace();
401 let snippet_builder: RefCell<Option<SnippetBuilder>> = RefCell::new(None);
402 let mut last_location: Option<ExprLocation> = None;
403 let mut flush_builder = |data: Option<ResetData>| {
404 use std::fmt::Write;
405 let mut out = String::new();
406 let location_changed = if let Some(ResetData { loc }) = &data {
407 if last_location.as_ref().map(|l| l.0.code()) != Some(loc.0.code()) {
408 true
409 } else if let (Some(last), new) = (&last_location, loc) {
410 // Reverse condition if traceback
411 last.1 > new.1 || last.2 > new.2
412 } else {
413 false
414 }
415 } else {
416 true
417 };
418 if location_changed {
419 if let Some(builder) = snippet_builder.borrow_mut().take() {
420 let rendered = builder.build();
421 let ansi = source_to_ansi(&rendered);
422 if let Some(loc) = &last_location {
423 let _ = writeln!(out, "...because of {}", loc.0.source_path());
424 }
425 let _ = write!(out, "{}", ansi.trim_end());
426 }
427 last_location = None;
428
429 if let Some(ResetData { loc }) = data {
430 *snippet_builder.borrow_mut() = Some(SnippetBuilder::new(loc.0.code()));
431 last_location = Some(loc);
432 }
433 }
434 if out.is_empty() {
435 return None;
436 }
437 Some(out)
438 };
439 for item in &trace.0 {
440 let desc = &item.desc;
441 if let Some(source) = &item.location {
442 if let Some(flushed) = flush_builder(Some(ResetData {
443 loc: source.clone(),
444 })) {
445 writeln!(out)?;
446 write!(out, "{flushed}")?;
447 }
448 let mut builder = snippet_builder.borrow_mut();
449 let builder = builder.as_mut().unwrap();
450 builder
451 .note(Text::single(desc.chars(), Formatting::default()))
452 .range(source.1 as usize..=(source.2 as usize - 1).max(source.1 as usize))
453 .build();
454 } else {
455 if let Some(flushed) = flush_builder(None) {
456 writeln!(out)?;
457 write!(out, "{flushed}")?;
458 }
459 write!(out, "{desc}")?;
460 }
461 }
462
463 if let Some(flushed) = flush_builder(None) {
464 writeln!(out)?;
465 write!(out, "{flushed}")?;
466 }
467 Ok(())
468 }
469
470 fn as_any(&self) -> &dyn Any {
471 self
472 }
473
474 fn as_any_mut(&mut self) -> &mut dyn Any {
475 self
476 }
477}
366478