git.delta.rocks / jrsonnet / refs/commits / ec654c44d309

difftreelog

refactor get rid of LazyBinding variants

Yaroslav Bolyukin2021-02-22parent: #3154bc9.patch.diff
in: master

5 files changed

modifiedcrates/jrsonnet-evaluator/src/ctx.rsdiffbeforeafterboth
1use crate::{1use crate::{
2 error::Error::*, map::LayeredHashMap, rc_fn_helper, resolved_lazy_val, FutureWrapper,2 error::Error::*, map::LayeredHashMap, resolved_lazy_val, FutureWrapper, LazyBinding, LazyVal,
3 LazyBinding, LazyVal, ObjValue, Result, Val,3 ObjValue, Result, Val,
4};4};
5use jrsonnet_interner::IStr;5use jrsonnet_interner::IStr;
6use rustc_hash::FxHashMap;6use rustc_hash::FxHashMap;
7use std::hash::BuildHasherDefault;7use std::hash::BuildHasherDefault;
8use std::{collections::HashMap, fmt::Debug, rc::Rc};8use std::{fmt::Debug, rc::Rc};
99
10rc_fn_helper!(10#[derive(Clone)]
11pub struct ContextCreator(pub Context, pub FutureWrapper<FxHashMap<IStr, LazyBinding>>);
11 ContextCreator,12impl ContextCreator {
12 context_creator,
13 dyn Fn(Option<ObjValue>, Option<ObjValue>) -> Result<Context>13 pub fn create(&self, this: Option<ObjValue>, super_obj: Option<ObjValue>) -> Result<Context> {
14);14 self.0.clone().extend_unbound(
15 self.1.clone().unwrap(),
16 self.0.dollar().clone().or_else(|| this.clone()),
17 this,
18 super_obj,
19 )
20 }
21}
1522
16struct ContextInternals {23struct ContextInternals {
17 dollar: Option<ObjValue>,24 dollar: Option<ObjValue>,
120 }127 }
121 }128 }
122 }129 }
130 pub fn extend_bound(self, new_bindings: FxHashMap<IStr, LazyVal>) -> Self {
131 let new_this = self.0.this.clone();
132 let new_super_obj = self.0.super_obj.clone();
133 self.extend(new_bindings, None, new_this, new_super_obj)
134 }
123 pub fn extend_unbound(135 pub fn extend_unbound(
124 self,136 self,
125 new_bindings: HashMap<IStr, LazyBinding>,137 new_bindings: FxHashMap<IStr, LazyBinding>,
126 new_dollar: Option<ObjValue>,138 new_dollar: Option<ObjValue>,
127 new_this: Option<ObjValue>,139 new_this: Option<ObjValue>,
128 new_super_obj: Option<ObjValue>,140 new_super_obj: Option<ObjValue>,
modifiedcrates/jrsonnet-evaluator/src/dynamic.rsdiffbeforeafterboth
12 }12 }
13}13}
14impl<T: Clone> FutureWrapper<T> {14impl<T: Clone> FutureWrapper<T> {
15 pub fn unwrap(self) -> T {15 pub fn unwrap(&self) -> T {
16 self.0.borrow().as_ref().cloned().unwrap()16 self.0.borrow().as_ref().cloned().unwrap()
17 }17 }
18}18}
23 }23 }
24}24}
25
26#[macro_export]
27macro_rules! rc_fn_helper {
28 ($name: ident, $macro_name: ident, $fn: ty) => {
29 #[derive(Clone)]
30 #[doc = "Function wrapper"]
31 pub struct $name(pub std::rc::Rc<$fn>);
32 impl std::fmt::Debug for $name {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 f.debug_struct(std::stringify!($name)).finish()
35 }
36 }
37 impl std::cmp::PartialEq for $name {
38 fn eq(&self, other: &$name) -> bool {
39 std::ptr::eq(&self.0, &other.0)
40 }
41 }
42 #[doc = "Macro to ease wrapper creation"]
43 #[macro_export]
44 macro_rules! $macro_name {
45 ($val: expr) => {
46 $crate::$name(std::rc::Rc::new($val))
47 };
48 }
49 };
50}
5125
modifiedcrates/jrsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
1use crate::{1use crate::{
2 context_creator, error::Error::*, lazy_val, push, throw, with_state, Context, ContextCreator,2 error::Error::*, lazy_val, push, throw, with_state, Context, ContextCreator, FuncDesc, FuncVal,
3 FuncDesc, FuncVal, FutureWrapper, LazyBinding, LazyVal, ObjMember, ObjValue, Result, Val,3 FutureWrapper, LazyBinding, LazyVal, ObjMember, ObjValue, Result, Val,
4};4};
5use closure::closure;5use closure::closure;
10 Visibility,10 Visibility,
11};11};
12use jrsonnet_types::ValType;12use jrsonnet_types::ValType;
13use rustc_hash::FxHashMap;13use rustc_hash::{FxHashMap, FxHasher};
14use std::{collections::HashMap, rc::Rc};14use std::{collections::HashMap, hash::BuildHasherDefault, rc::Rc};
15
16pub fn evaluate_binding_in_future(
17 b: &BindSpec,
18 context_creator: FutureWrapper<Context>,
19) -> LazyVal {
20 let b = b.clone();
21 if let Some(params) = &b.params {
22 let params = params.clone();
23 LazyVal::new(Box::new(move || {
24 Ok(evaluate_method(
25 context_creator.unwrap(),
26 b.name.clone(),
27 params.clone(),
28 b.value.clone(),
29 ))
30 }))
31 } else {
32 LazyVal::new(Box::new(move || {
33 evaluate_named(context_creator.unwrap(), &b.value, b.name.clone())
34 }))
35 }
36}
1537
16pub fn evaluate_binding(b: &BindSpec, context_creator: ContextCreator) -> (IStr, LazyBinding) {38pub fn evaluate_binding(b: &BindSpec, context_creator: ContextCreator) -> (IStr, LazyBinding) {
17 let b = b.clone();39 let b = b.clone();
22 LazyBinding::Bindable(Rc::new(move |this, super_obj| {44 LazyBinding::Bindable(Rc::new(move |this, super_obj| {
23 Ok(lazy_val!(45 Ok(lazy_val!(
24 closure!(clone b, clone params, clone context_creator, || Ok(evaluate_method(46 closure!(clone b, clone params, clone context_creator, || Ok(evaluate_method(
25 context_creator.0(this.clone(), super_obj.clone())?,47 context_creator.create(this.clone(), super_obj.clone())?,
26 b.name.clone(),48 b.name.clone(),
27 params.clone(),49 params.clone(),
28 b.value.clone(),50 b.value.clone(),
36 LazyBinding::Bindable(Rc::new(move |this, super_obj| {58 LazyBinding::Bindable(Rc::new(move |this, super_obj| {
37 Ok(lazy_val!(closure!(clone context_creator, clone b, ||59 Ok(lazy_val!(closure!(clone context_creator, clone b, ||
38 evaluate_named(60 evaluate_named(
39 context_creator.0(this.clone(), super_obj.clone())?,61 context_creator.create(this.clone(), super_obj.clone())?,
40 &b.value,62 &b.value,
41 b.name.clone()63 b.name.clone()
42 )64 )
217pub fn evaluate_member_list_object(context: Context, members: &[Member]) -> Result<ObjValue> {239pub fn evaluate_member_list_object(context: Context, members: &[Member]) -> Result<ObjValue> {
218 let new_bindings = FutureWrapper::new();240 let new_bindings = FutureWrapper::new();
219 let future_this = FutureWrapper::new();241 let future_this = FutureWrapper::new();
220 let context_creator = context_creator!(242 let context_creator = ContextCreator(context.clone(), new_bindings.clone());
221 closure!(clone context, clone new_bindings, |this: Option<ObjValue>, super_obj: Option<ObjValue>| {
222 context.clone().extend_unbound(
223 new_bindings.clone().unwrap(),
224 context.dollar().clone().or_else(||this.clone()),
225 Some(this.unwrap()),
226 super_obj
227 )
228 })
229 );
230 {243 {
231 let mut bindings: HashMap<IStr, LazyBinding> = HashMap::new();244 let mut bindings: FxHashMap<IStr, LazyBinding> =
245 FxHashMap::with_capacity_and_hasher(members.len(), BuildHasherDefault::default());
232 for (n, b) in members246 for (n, b) in members
233 .iter()247 .iter()
234 .filter_map(|m| match m {248 .filter_map(|m| match m {
265 invoke: LazyBinding::Bindable(Rc::new(279 invoke: LazyBinding::Bindable(Rc::new(
266 closure!(clone name, clone value, clone context_creator, |this, super_obj| {280 closure!(clone name, clone value, clone context_creator, |this, super_obj| {
267 Ok(LazyVal::new_resolved(evaluate(281 Ok(LazyVal::new_resolved(evaluate(
268 context_creator.0(this, super_obj)?,282 context_creator.create(this, super_obj)?,
269 &value,283 &value,
270 )?))284 )?))
271 }),285 }),
294 closure!(clone value, clone context_creator, clone params, clone name, |this, super_obj| {308 closure!(clone value, clone context_creator, clone params, clone name, |this, super_obj| {
295 // TODO: Assert309 // TODO: Assert
296 Ok(LazyVal::new_resolved(evaluate_method(310 Ok(LazyVal::new_resolved(evaluate_method(
297 context_creator.0(this, super_obj)?,311 context_creator.create(this, super_obj)?,
298 name.clone(),312 name.clone(),
299 params.clone(),313 params.clone(),
300 value.clone(),314 value.clone(),
324 context.clone(),338 context.clone(),
325 &|ctx| {339 &|ctx| {
326 let new_bindings = FutureWrapper::new();340 let new_bindings = FutureWrapper::new();
327 let context_creator = context_creator!(341 let context_creator = ContextCreator(context.clone(), new_bindings.clone());
328 closure!(clone context, clone new_bindings, |this: Option<ObjValue>, super_obj: Option<ObjValue>| {
329 context.clone().extend_unbound(
330 new_bindings.clone().unwrap(),
331 context.dollar().clone().or_else(||this.clone()),
332 None,
333 super_obj
334 )
335 })
336 );
337 let mut bindings: HashMap<IStr, LazyBinding> = HashMap::new();342 let mut bindings: FxHashMap<IStr, LazyBinding> = FxHashMap::with_capacity_and_hasher(obj.pre_locals.len() + obj.post_locals.len(), BuildHasherDefault::default());
338 for (n, b) in obj343 for (n, b) in obj
339 .pre_locals344 .pre_locals
340 .iter()345 .iter()
497 }502 }
498 }503 }
499 LocalExpr(bindings, returned) => {504 LocalExpr(bindings, returned) => {
500 let mut new_bindings: HashMap<IStr, LazyBinding> = HashMap::new();505 let mut new_bindings: FxHashMap<IStr, LazyVal> = HashMap::with_capacity_and_hasher(
506 bindings.len(),
507 BuildHasherDefault::<FxHasher>::default(),
508 );
501 let future_context = Context::new_future();509 let future_context = Context::new_future();
502
503 let context_creator = context_creator!(
504 closure!(clone future_context, |_, _| Ok(future_context.clone().unwrap()))
505 );
506
507 for (k, v) in bindings510 for b in bindings {
508 .iter()511 new_bindings.insert(
509 .map(|b| evaluate_binding(b, context_creator.clone()))512 b.name.clone(),
510 {513 evaluate_binding_in_future(b, future_context.clone()),
511 new_bindings.insert(k, v);514 );
512 }515 }
513
514 let context = context516 let context = context
515 .extend_unbound(new_bindings, None, None, None)?517 .extend_bound(new_bindings)
516 .into_future(future_context);518 .into_future(future_context);
517 evaluate(context, &returned.clone())?519 evaluate(context, &returned.clone())?
518 }520 }
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
27use jrsonnet_parser::*;27use jrsonnet_parser::*;
28use native::NativeCallback;28use native::NativeCallback;
29pub use obj::*;29pub use obj::*;
30use rustc_hash::FxHashMap;
30use std::{31use std::{
31 cell::{Ref, RefCell, RefMut},32 cell::{Ref, RefCell, RefMut},
32 collections::HashMap,33 collections::HashMap,
33 fmt::Debug,34 fmt::Debug,
35 hash::BuildHasherDefault,
34 path::PathBuf,36 path::PathBuf,
35 rc::Rc,37 rc::Rc,
36};38};
230 }232 }
231 value.parsed.clone()233 value.parsed.clone()
232 };234 };
233 let value = evaluate(self.create_default_context()?, &expr)?;235 let value = evaluate(self.create_default_context(), &expr)?;
234 {236 {
235 self.data_mut()237 self.data_mut()
236 .files238 .files
260 }262 }
261263
262 /// Creates context with all passed global variables264 /// Creates context with all passed global variables
263 pub fn create_default_context(&self) -> Result<Context> {265 pub fn create_default_context(&self) -> Context {
264 let globals = &self.settings().globals;266 let globals = &self.settings().globals;
265 let mut new_bindings: HashMap<IStr, LazyBinding> = HashMap::new();267 let mut new_bindings: FxHashMap<IStr, LazyVal> =
268 FxHashMap::with_capacity_and_hasher(globals.len(), BuildHasherDefault::default());
266 for (name, value) in globals.iter() {269 for (name, value) in globals.iter() {
267 new_bindings.insert(270 new_bindings.insert(name.clone(), resolved_lazy_val!(value.clone()));
268 name.clone(),
269 LazyBinding::Bound(resolved_lazy_val!(value.clone())),
270 );
271 }271 }
272 Context::new().extend_unbound(new_bindings, None, None, None)272 Context::new().extend_bound(new_bindings)
273 }273 }
274274
275 /// Executes code creating a new stack frame275 /// Executes code creating a new stack frame
345 || "during TLA call".to_owned(),345 || "during TLA call".to_owned(),
346 || {346 || {
347 func.evaluate_map(347 func.evaluate_map(
348 self.create_default_context()?,348 self.create_default_context(),
349 &self.settings().tla_vars,349 &self.settings().tla_vars,
350 true,350 true,
351 )351 )
396 }396 }
397 /// Evaluates the parsed expression397 /// Evaluates the parsed expression
398 pub fn evaluate_expr_raw(&self, code: LocExpr) -> Result<Val> {398 pub fn evaluate_expr_raw(&self, code: LocExpr) -> Result<Val> {
399 self.run_in_state(|| evaluate(self.create_default_context()?, &code))399 self.run_in_state(|| evaluate(self.create_default_context(), &code))
400 }400 }
401}401}
402402
950 Ok(())950 Ok(())
951 }951 }
952
953 #[test]
954 fn comp_self() -> crate::error::Result<()> {
955 assert_eval!(
956 r#"
957 std.objectFields({
958 a:{
959 [name]: name for name in std.objectFields(self)
960 },
961 b: 2,
962 c: 3,
963 }.a) == ['a', 'b', 'c']
964 "#
965 );
966
967 Ok(())
968 }
952969
953 struct TestImportResolver(IStr);970 struct TestImportResolver(IStr);
954 impl crate::import::ImportResolver for TestImportResolver {971 impl crate::import::ImportResolver for TestImportResolver {
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
535 pub fn to_yaml(&self, padding: usize) -> Result<IStr> {535 pub fn to_yaml(&self, padding: usize) -> Result<IStr> {
536 with_state(|s| {536 with_state(|s| {
537 let ctx = s537 let ctx = s
538 .create_default_context()?538 .create_default_context()
539 .with_var("__tmp__to_json__".into(), self.clone());539 .with_var("__tmp__to_json__".into(), self.clone());
540 evaluate(540 evaluate(
541 ctx,541 ctx,