difftreelog
refactor(evaluator) use PathBuf for file paths
in: master
4 files changed
crates/jsonnet-evaluator/build.rsdiffbeforeafterboth5 env,6 fs::File,7 io::Write,8 path::{Path, PathBuf},9};5106fn main() {11fn main() {7 let parsed = parse(12 let parsed = parse(8 STDLIB_STR,13 STDLIB_STR,9 &ParserSettings {14 &ParserSettings {10 file_name: "std.jsonnet".to_owned(),15 file_name: PathBuf::from("std.jsonnet"),11 loc_data: true,16 loc_data: true,12 },17 },13 )18 )crates/jsonnet-evaluator/src/error.rsdiffbeforeafterboth8 NoSuchField(String),8 NoSuchField(String),9910 RuntimeError(String),10 RuntimeError(String),11 StackOverflow,11}12}121313#[derive(Clone, Debug)]14#[derive(Clone, Debug)]crates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth32 b.name.clone(),32 b.name.clone(),33 lazy_binding!(move |this, super_obj| {33 lazy_binding!(move |this, super_obj| {34 Ok(lazy_val!(34 Ok(lazy_val!(closure!(clone context_creator, clone b, ||35 push(b.value.clone(), "thunk".to_owned(), ||{35 closure!(clone context_creator, clone b, || evaluate(36 evaluate(36 context_creator.0(this.clone(), super_obj.clone())?,37 context_creator.0(this.clone(), super_obj.clone())?,37 &b.value38 &b.value38 ))39 )40 })39 ))41 )))40 }),42 }),41 )43 )326 Num(v) => Val::Num(*v),328 Num(v) => Val::Num(*v),327 BinaryOp(v1, o, v2) => evaluate_binary_op_special(context, &v1, *o, &v2)?,329 BinaryOp(v1, o, v2) => evaluate_binary_op_special(context, &v1, *o, &v2)?,328 UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(context, v)?)?,330 UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(context, v)?)?,329 Var(name) => Val::Lazy(context.binding(&name)).unwrap_if_lazy()?,331 Var(name) => push(locexpr, "var".to_owned(), || {332 Val::Lazy(context.binding(&name)).unwrap_if_lazy()333 })?,330 Index(LocExpr(v, _), index) if matches!(&**v, Expr::Literal(LiteralType::Super)) => {334 Index(LocExpr(v, _), index) if matches!(&**v, Expr::Literal(LiteralType::Super)) => {331 let name = evaluate(context.clone(), index)?.try_cast_str("object index")?;335 let name = evaluate(context.clone(), index)?.try_cast_str("object index")?;332 context336 context412 match evaluate(context, expr)? {416 match evaluate(context, expr)? {413 Val::Str(n) => Val::Num(n.chars().count() as f64),417 Val::Str(n) => Val::Num(n.chars().count() as f64),414 Val::Arr(i) => Val::Num(i.len() as f64),418 Val::Arr(i) => Val::Num(i.len() as f64),419 Val::Obj(o) => Val::Num(o.fields().len() as f64),415 v => panic!("can't get length of {:?}", v),420 v => panic!("can't get length of {:?}", v),416 }421 }417 }422 }crates/jsonnet-evaluator/src/lib.rsdiffbeforeafterboth16pub use evaluate::*;16pub use evaluate::*;17use jsonnet_parser::*;17use jsonnet_parser::*;18pub use obj::*;18pub use obj::*;19use std::{cell::RefCell, collections::HashMap, rc::Rc};19use std::{cell::RefCell, collections::HashMap, path::PathBuf, rc::Rc};20pub use val::*;20pub use val::*;212122rc_fn_helper!(22rc_fn_helper!(43 stack: RefCell<Vec<StackTraceElement>>,43 stack: RefCell<Vec<StackTraceElement>>,44 /// Contains file source codes and evaluated results for imports and pretty44 /// Contains file source codes and evaluated results for imports and pretty45 /// printing stacktraces45 /// printing stacktraces46 files: RefCell<HashMap<String, FileData>>,46 files: RefCell<HashMap<PathBuf, FileData>>,47 globals: RefCell<HashMap<String, Val>>,47 globals: RefCell<HashMap<String, Val>>,48}48}494956pub(crate) fn create_error<T>(err: Error) -> Result<T> {56pub(crate) fn create_error<T>(err: Error) -> Result<T> {57 with_state(|s| s.error(err))57 with_state(|s| s.error(err))58}58}59pub(crate) fn push<T>(e: LocExpr, comment: String, f: impl FnOnce() -> T) -> T {59pub(crate) fn push<T>(e: LocExpr, comment: String, f: impl FnOnce() -> Result<T>) -> Result<T> {60 with_state(|s| s.push(e, comment, f))60 with_state(|s| s.push(e, comment, f))61}61}626265impl EvaluationState {65impl EvaluationState {66 pub fn add_file(66 pub fn add_file(67 &self,67 &self,68 name: String,68 name: PathBuf,69 code: String,69 code: String,70 ) -> std::result::Result<(), Box<dyn std::error::Error>> {70 ) -> std::result::Result<(), Box<dyn std::error::Error>> {71 self.0.files.borrow_mut().insert(71 self.0.files.borrow_mut().insert(87 }87 }88 pub fn add_parsed_file(88 pub fn add_parsed_file(89 &self,89 &self,90 name: String,90 name: PathBuf,91 code: String,91 code: String,92 parsed: LocExpr,92 parsed: LocExpr,93 ) -> std::result::Result<(), Box<dyn std::error::Error>> {93 ) -> std::result::Result<(), Box<dyn std::error::Error>> {989899 Ok(())99 Ok(())100 }100 }101 pub fn get_source(&self, name: &str) -> String {101 pub fn get_source(&self, name: &PathBuf) -> Option<String> {102 let ro_map = self.0.files.borrow();102 let ro_map = self.0.files.borrow();103 let value = ro_map103 ro_map104 .get(name)104 .get(name)105 .unwrap_or_else(|| panic!("file not added: {:?}", name));105 .map(|value|value.0.clone())106 value.0.clone()107 }106 }108 pub fn evaluate_file(&self, name: &str) -> Result<Val> {107 pub fn evaluate_file(&self, name: &PathBuf) -> Result<Val> {109 self.begin_state();108 self.begin_state();110 let expr: LocExpr = {109 let expr: LocExpr = {111 let ro_map = self.0.files.borrow();110 let ro_map = self.0.files.borrow();135 let parsed = parse(134 let parsed = parse(136 &code,135 &code,137 &ParserSettings {136 &ParserSettings {138 file_name: "raw.jsonnet".to_owned(),137 file_name: PathBuf::from("raw.jsonnet"),139 loc_data: true,138 loc_data: true,140 },139 },141 );140 );154 use jsonnet_stdlib::STDLIB_STR;153 use jsonnet_stdlib::STDLIB_STR;155 if cfg!(feature = "serialized-stdlib") {154 if cfg!(feature = "serialized-stdlib") {156 self.add_parsed_file(155 self.add_parsed_file(157 "std.jsonnet".to_owned(),156 PathBuf::from("std.jsonnet"),158 STDLIB_STR.to_owned(),157 STDLIB_STR.to_owned(),159 bincode::deserialize(include_bytes!(concat!(env!("OUT_DIR"), "/stdlib.bincode")))158 bincode::deserialize(include_bytes!(concat!(env!("OUT_DIR"), "/stdlib.bincode")))160 .expect("deserialize stdlib"),159 .expect("deserialize stdlib"),161 )160 )162 .unwrap();161 .unwrap();163 } else {162 } else {164 self.add_file("std.jsonnet".to_owned(), STDLIB_STR.to_owned())163 self.add_file(PathBuf::from("std.jsonnet"), STDLIB_STR.to_owned())165 .unwrap();164 .unwrap();166 }165 }167 let val = self.evaluate_file("std.jsonnet").unwrap();166 let val = self.evaluate_file(&PathBuf::from("std.jsonnet")).unwrap();168 self.add_global("std".to_owned(), val);167 self.add_global("std".to_owned(), val);169 self.end_state();168 self.end_state();170 }169 }183 Context::new().extend(new_bindings, None, None, None)182 Context::new().extend(new_bindings, None, None, None)184 }183 }185184186 pub fn push<T>(&self, e: LocExpr, comment: String, f: impl FnOnce() -> T) -> T {185 pub fn push<T>(&self, e: LocExpr, comment: String, f: impl FnOnce() -> Result<T>) -> Result<T> {186 {187 self.0187 let mut stack = self.0.stack.borrow_mut();188 .stack188 if stack.len() > 5000 {189 .borrow_mut()189 drop(stack);190 return self.error(Error::StackOverflow);191 } else {190 .push(StackTraceElement(e, comment));192 stack.push(StackTraceElement(e, comment));193 }194 }191 let result = f();195 let result = f();192 self.0.stack.borrow_mut().pop();196 self.0.stack.borrow_mut().pop();193 result197 result217 use super::Val;221 use super::Val;218 use crate::EvaluationState;222 use crate::EvaluationState;219 use jsonnet_parser::*;223 use jsonnet_parser::*;224 use std::path::PathBuf;220225221 #[test]226 #[test]222 fn eval_state_stacktrace() {227 fn eval_state_stacktrace() {223 let state = EvaluationState::default();228 let state = EvaluationState::default();224 state.push(229 state230 .push(225 loc_expr!(Expr::Num(0.0), true, ("test1.jsonnet".to_owned(), 10, 20)),231 loc_expr!(232 Expr::Num(0.0),233 true,234 (PathBuf::from("test1.jsonnet"), 10, 20)235 ),226 "outer".to_owned(),236 "outer".to_owned(),227 || {237 || {228 state.push(238 state.push(229 loc_expr!(Expr::Num(0.0), true, ("test2.jsonnet".to_owned(), 30, 40)),239 loc_expr!(240 Expr::Num(0.0),241 true,242 (PathBuf::from("test2.jsonnet"), 30, 40)243 ),230 "inner".to_owned(),244 "inner".to_owned(),231 || state.print_stack_trace(),245 || {246 state.print_stack_trace();247 Ok(())248 },232 );249 )?;250 Ok(())233 },251 },234 );252 )253 .unwrap();235 }254 }236255237 #[test]256 #[test]240 state.add_stdlib();259 state.add_stdlib();241 assert_eq!(260 assert_eq!(242 state261 state243 .parse_evaluate_raw(r#"std.assertEqual(std.base64("test"), "dGVzdA==w")"#)262 .parse_evaluate_raw(r#"std.assertEqual(std.base64("test"), "dGVzdA==")"#)244 .unwrap(),263 .unwrap(),245 Val::Bool(true)264 Val::Bool(true)246 );265 );