difftreelog
feat locationless stack frames
in: master
4 files changed
crates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -132,7 +132,7 @@
#[derive(Clone, Debug)]
pub struct StackTraceElement {
- pub location: ExprLocation,
+ pub location: Option<ExprLocation>,
pub desc: String,
}
#[derive(Debug, Clone)]
crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -132,11 +132,15 @@
frame_desc: impl FnOnce() -> String,
f: impl FnOnce() -> Result<T>,
) -> Result<T> {
- if let Some(v) = e {
- with_state(|s| s.push(v, frame_desc, f))
- } else {
- f()
- }
+ with_state(|s| s.push(e, frame_desc, f))
+}
+
+pub fn push_stack_frame<T>(
+ e: Option<&ExprLocation>,
+ frame_desc: impl FnOnce() -> String,
+ f: impl FnOnce() -> Result<T>,
+ ) -> Result<T> {
+ push(e, frame_desc, f)
}
/// Maintains stack trace and import resolution
@@ -271,7 +275,7 @@
/// Executes code creating a new stack frame
pub fn push<T>(
&self,
- e: &ExprLocation,
+ e: Option<&ExprLocation>,
frame_desc: impl FnOnce() -> String,
f: impl FnOnce() -> Result<T>,
) -> Result<T> {
@@ -290,7 +294,7 @@
self.data_mut().stack_depth -= 1;
if let Err(mut err) = result {
err.trace_mut().0.push(StackTraceElement {
- location: e.clone(),
+ location: e.cloned(),
desc: frame_desc(),
});
return Err(err);
@@ -336,11 +340,11 @@
pub fn with_tla(&self, val: Val) -> Result<Val> {
self.run_in_state(|| {
Ok(match val {
- Val::Func(func) => func.evaluate_map(
+ Val::Func(func) => push(None, || "during TLA call".to_owned(), || Ok(func.evaluate_map(
self.create_default_context()?,
&self.settings().tla_vars,
true,
- )?,
+ )?))?,
v => v,
})
})
crates/jrsonnet-evaluator/src/trace/location.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/trace/location.rs
+++ b/crates/jrsonnet-evaluator/src/trace/location.rs
@@ -37,7 +37,7 @@
];
let mut with_no_known_line_ending = vec![];
let mut this_line_offset = 0;
- for (pos, ch) in file.chars().enumerate() {
+ for (pos, ch) in file.chars().enumerate().chain(std::iter::once((file.len(), ' '))) {
column += 1;
match offset_map.last() {
Some(x) if x.0 == pos => {
crates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth118 .trace()118 .trace()119 .0119 .0120 .iter()120 .iter()121 .map(|el| {121 .map(|el| el.location.as_ref().map(|l| {122 let resolved_path = self.resolver.resolve(&el.location.0);123 // TODO: Process all trace elements first124 let location = evaluation_state125 .map_source_locations(&el.location.0, &[el.location.1, el.location.2]);126 (resolved_path, location)127 })128 .map(|(mut n, location)| {129 use std::fmt::Write;122 use std::fmt::Write;123 let mut resolved_path = self.resolver.resolve(&l.0);124 // TODO: Process all trace elements first125 let location = evaluation_state126 .map_source_locations(&l.0, &[l.1, l.2]);130 write!(n, ":").unwrap();127 write!(resolved_path, ":").unwrap();131 print_code_location(&mut n, &location[0], &location[1]).unwrap();128 print_code_location(&mut resolved_path, &location[0], &location[1]).unwrap();132 n129 resolved_path133 })130 }))134 .collect::<Vec<_>>();131 .collect::<Vec<_>>();135 let align = file_names.iter().map(|e| e.len()).max().unwrap_or(0);132 let align = file_names.iter().flatten().map(|e| e.len()).max().unwrap_or(0);136 for (i, (el, file)) in error.trace().0.iter().zip(file_names).enumerate() {133 for (i, (el, file)) in error.trace().0.iter().zip(file_names).enumerate() {137 if i != 0 {134 if i != 0 {138 writeln!(out)?;135 writeln!(out)?;141 out,138 out,142 "{:<p$}{:<w$}: {}",139 "{:<p$}{:<w$}: {}",143 "",140 "",144 file,141 file.unwrap_or_else(|| "".to_owned()),145 el.desc,142 el.desc,146 p = self.padding,143 p = self.padding,147 w = align144 w = align165 writeln!(out)?;162 writeln!(out)?;166 }163 }167 let desc = &item.desc;164 let desc = &item.desc;168 let source = item.location.clone();165 if let Some (source) = &item.location {169 let start_end = evaluation_state.map_source_locations(&source.0, &[source.1, source.2]);166 let start_end = evaluation_state.map_source_locations(&source.0, &[source.1, source.2]);170167171 write!(168 write!(176 start_end[0].line,173 start_end[0].line,177 start_end[0].column,174 start_end[0].column,178 )?;175 )?;176 } else {177 write!(178 out,179 " at {}",180 desc,181 )?;182 }179 }183 }180 Ok(())184 Ok(())181 }185 }225 let trace = &error.trace();229 let trace = &error.trace();226 for item in trace.0.iter() {230 for item in trace.0.iter() {227 let desc = &item.desc;231 let desc = &item.desc;228 let source = item.location.clone();232 if let Some(source) = &item.location {229 let start_end = evaluation_state.map_source_locations(&source.0, &[source.1, source.2]);233 let start_end = evaluation_state.map_source_locations(&source.0, &[source.1, source.2]);230231 self.print_snippet(234 self.print_snippet(236 &start_end[1],239 &start_end[1],237 desc,240 desc,238 )?;241 )?;242 } else {243 write!(out, "{}", desc)?;244 }239 }245 }240 Ok(())246 Ok(())241 }247 }