From 7a6e8cbd4a25f39a7e3f56f876a65f7bf5fb8455 Mon Sep 17 00:00:00 2001 From: Лач Date: Mon, 29 Jun 2020 13:47:13 +0000 Subject: [PATCH] feat: move trace mapping api to evaluator --- --- a/cmds/jrsonnet/src/location.rs +++ /dev/null @@ -1,99 +0,0 @@ -#[derive(Clone, PartialEq, Debug)] -pub struct CodeLocation { - pub line: usize, - pub column: usize, - - pub line_start_offset: usize, - pub line_end_offset: usize, -} - -pub fn offset_to_location(file: &str, offsets: &[usize]) -> Vec { - if offsets.is_empty() { - return vec![]; - } - let mut line = 1; - let mut column = 0; - let max_offset = *offsets.iter().max().unwrap(); - - let mut offset_map = offsets - .iter() - .enumerate() - .map(|(pos, offset)| (*offset, pos)) - .collect::>(); - offset_map.sort_by_key(|v| v.0); - offset_map.reverse(); - - let mut out = vec![ - CodeLocation { - column: 0, - line: 0, - line_start_offset: 0, - line_end_offset: 0 - }; - offsets.len() - ]; - let mut with_no_known_line_ending = vec![]; - let mut this_line_offset = 0; - for (pos, ch) in file.chars().enumerate() { - column += 1; - match offset_map.last() { - Some(x) if x.0 == pos => { - let out_idx = x.1; - with_no_known_line_ending.push(out_idx); - out[out_idx].line = line; - out[out_idx].column = column; - out[out_idx].line_start_offset = this_line_offset + 1; - offset_map.pop(); - } - _ => {} - } - if ch == '\n' { - line += 1; - column = 0; - - for idx in with_no_known_line_ending.drain(..) { - out[idx].line_end_offset = pos; - } - this_line_offset = pos; - - if pos == max_offset + 1 { - break; - } - } - } - let file_end = file.chars().count(); - for idx in with_no_known_line_ending { - out[idx].line_end_offset = file_end; - } - - out -} - -#[cfg(test)] -pub mod tests { - use super::{offset_to_location, CodeLocation}; - - #[test] - fn test() { - assert_eq!( - offset_to_location( - "hello world\n_______________________________________________________", - &[0, 14] - ), - vec![ - CodeLocation { - line: 1, - column: 1, - line_start_offset: 1, - line_end_offset: 11 - }, - CodeLocation { - line: 2, - column: 3, - line_start_offset: 12, - line_end_offset: 67 - } - ] - ) - } -} --- a/cmds/jrsonnet/src/main.rs +++ b/cmds/jrsonnet/src/main.rs @@ -1,9 +1,6 @@ -pub mod location; - use clap::Clap; -use jrsonnet_evaluator::{EvaluationState, LocError, StackTrace, Val}; +use jrsonnet_evaluator::{trace::CodeLocation, EvaluationState, LocError, StackTrace, Val}; use jrsonnet_parser::{el, Arg, ArgsDesc, Expr, LocExpr, ParserSettings}; -use location::{offset_to_location, CodeLocation}; use std::env::current_dir; use std::{collections::HashMap, path::PathBuf, rc::Rc, str::FromStr}; @@ -252,14 +249,11 @@ for item in trace.0.iter() { let desc = &item.1; let source = item.0.clone(); - let code = evaluator.get_source(&source.0); - if code.is_none() { - continue; - } - let code = code.unwrap(); - let start_end = offset_to_location(&code, &[source.1, source.2]); + let start_end = evaluator.map_source_locations(&source.0, &[source.1, source.2]); if opts.trace_format == TraceFormat::Custom { - let source_fragment: String = code + let source_fragment: String = evaluator + .get_source(&source.0) + .unwrap() .chars() .skip(start_end[0].line_start_offset) .take(start_end[1].line_end_offset - start_end[0].line_start_offset) --- a/crates/jrsonnet-evaluator/src/lib.rs +++ b/crates/jrsonnet-evaluator/src/lib.rs @@ -16,6 +16,7 @@ mod map; mod obj; mod val; +pub mod trace; pub use ctx::*; pub use dynamic::*; @@ -27,6 +28,7 @@ pub use obj::*; use std::{cell::{Ref, RefCell, RefMut}, collections::HashMap, fmt::Debug, path::PathBuf, rc::Rc}; pub use val::*; +use trace::{offset_to_location, CodeLocation}; type BindableFn = dyn Fn(Option, Option) -> Result; #[derive(Clone)] @@ -187,6 +189,10 @@ let ro_map = &self.data().files; ro_map.get(name).map(|value| value.0.clone()) } + pub fn map_source_locations(&self, file: &PathBuf, locs: &[usize]) -> Vec { + offset_to_location(&self.get_source(file).unwrap(), locs) + } + pub fn evaluate_file(&self, name: &PathBuf) -> Result { self.run_in_state(|| { let expr: LocExpr = { --- /dev/null +++ b/crates/jrsonnet-evaluator/src/trace.rs @@ -0,0 +1,99 @@ +#[derive(Clone, PartialEq, Debug)] +pub struct CodeLocation { + pub line: usize, + pub column: usize, + + pub line_start_offset: usize, + pub line_end_offset: usize, +} + +pub fn offset_to_location(file: &str, offsets: &[usize]) -> Vec { + if offsets.is_empty() { + return vec![]; + } + let mut line = 1; + let mut column = 0; + let max_offset = *offsets.iter().max().unwrap(); + + let mut offset_map = offsets + .iter() + .enumerate() + .map(|(pos, offset)| (*offset, pos)) + .collect::>(); + offset_map.sort_by_key(|v| v.0); + offset_map.reverse(); + + let mut out = vec![ + CodeLocation { + column: 0, + line: 0, + line_start_offset: 0, + line_end_offset: 0 + }; + offsets.len() + ]; + let mut with_no_known_line_ending = vec![]; + let mut this_line_offset = 0; + for (pos, ch) in file.chars().enumerate() { + column += 1; + match offset_map.last() { + Some(x) if x.0 == pos => { + let out_idx = x.1; + with_no_known_line_ending.push(out_idx); + out[out_idx].line = line; + out[out_idx].column = column; + out[out_idx].line_start_offset = this_line_offset + 1; + offset_map.pop(); + } + _ => {} + } + if ch == '\n' { + line += 1; + column = 0; + + for idx in with_no_known_line_ending.drain(..) { + out[idx].line_end_offset = pos; + } + this_line_offset = pos; + + if pos == max_offset + 1 { + break; + } + } + } + let file_end = file.chars().count(); + for idx in with_no_known_line_ending { + out[idx].line_end_offset = file_end; + } + + out +} + +#[cfg(test)] +pub mod tests { + use super::{offset_to_location, CodeLocation}; + + #[test] + fn test() { + assert_eq!( + offset_to_location( + "hello world\n_______________________________________________________", + &[0, 14] + ), + vec![ + CodeLocation { + line: 1, + column: 1, + line_start_offset: 1, + line_end_offset: 11 + }, + CodeLocation { + line: 2, + column: 3, + line_start_offset: 12, + line_end_offset: 67 + } + ] + ) + } +} -- gitstuff