git.delta.rocks / jrsonnet / refs/commits / 0d591aa205cc

difftreelog

feat locationless stack frames

Yaroslav Bolyukin2021-01-25parent: #a682d0e.patch.diff
in: master

4 files changed

modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
132132
133#[derive(Clone, Debug)]133#[derive(Clone, Debug)]
134pub struct StackTraceElement {134pub struct StackTraceElement {
135 pub location: ExprLocation,135 pub location: Option<ExprLocation>,
136 pub desc: String,136 pub desc: String,
137}137}
138#[derive(Debug, Clone)]138#[derive(Debug, Clone)]
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
132 frame_desc: impl FnOnce() -> String,132 frame_desc: impl FnOnce() -> String,
133 f: impl FnOnce() -> Result<T>,133 f: impl FnOnce() -> Result<T>,
134) -> Result<T> {134) -> Result<T> {
135 if let Some(v) = e {
136 with_state(|s| s.push(v, frame_desc, f))135 with_state(|s| s.push(e, frame_desc, f))
137 } else {
138 f()
139 }
140}136}
137
138pub fn push_stack_frame<T>(
139 e: Option<&ExprLocation>,
140 frame_desc: impl FnOnce() -> String,
141 f: impl FnOnce() -> Result<T>,
142 ) -> Result<T> {
143 push(e, frame_desc, f)
144}
141145
142/// Maintains stack trace and import resolution146/// Maintains stack trace and import resolution
143#[derive(Default, Clone)]147#[derive(Default, Clone)]
271 /// Executes code creating a new stack frame275 /// Executes code creating a new stack frame
272 pub fn push<T>(276 pub fn push<T>(
273 &self,277 &self,
274 e: &ExprLocation,278 e: Option<&ExprLocation>,
275 frame_desc: impl FnOnce() -> String,279 frame_desc: impl FnOnce() -> String,
276 f: impl FnOnce() -> Result<T>,280 f: impl FnOnce() -> Result<T>,
277 ) -> Result<T> {281 ) -> Result<T> {
290 self.data_mut().stack_depth -= 1;294 self.data_mut().stack_depth -= 1;
291 if let Err(mut err) = result {295 if let Err(mut err) = result {
292 err.trace_mut().0.push(StackTraceElement {296 err.trace_mut().0.push(StackTraceElement {
293 location: e.clone(),297 location: e.cloned(),
294 desc: frame_desc(),298 desc: frame_desc(),
295 });299 });
296 return Err(err);300 return Err(err);
336 pub fn with_tla(&self, val: Val) -> Result<Val> {340 pub fn with_tla(&self, val: Val) -> Result<Val> {
337 self.run_in_state(|| {341 self.run_in_state(|| {
338 Ok(match val {342 Ok(match val {
339 Val::Func(func) => func.evaluate_map(343 Val::Func(func) => push(None, || "during TLA call".to_owned(), || Ok(func.evaluate_map(
340 self.create_default_context()?,344 self.create_default_context()?,
341 &self.settings().tla_vars,345 &self.settings().tla_vars,
342 true,346 true,
343 )?,347 )?))?,
344 v => v,348 v => v,
345 })349 })
346 })350 })
modifiedcrates/jrsonnet-evaluator/src/trace/location.rsdiffbeforeafterboth
37 ];37 ];
38 let mut with_no_known_line_ending = vec![];38 let mut with_no_known_line_ending = vec![];
39 let mut this_line_offset = 0;39 let mut this_line_offset = 0;
40 for (pos, ch) in file.chars().enumerate() {40 for (pos, ch) in file.chars().enumerate().chain(std::iter::once((file.len(), ' '))) {
41 column += 1;41 column += 1;
42 match offset_map.last() {42 match offset_map.last() {
43 Some(x) if x.0 == pos => {43 Some(x) if x.0 == pos => {
modifiedcrates/jrsonnet-evaluator/src/trace/mod.rsdiffbeforeafterboth
118 .trace()118 .trace()
119 .0119 .0
120 .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 first
124 let location = evaluation_state
125 .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 first
125 let location = evaluation_state
126 .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_path
133 })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 = align
165 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]);
170167
171 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]);
230
231 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 }