difftreelog
refactor get rid of LazyBinding variants
in: master
5 files changed
crates/jrsonnet-evaluator/src/ctx.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/ctx.rs
+++ b/crates/jrsonnet-evaluator/src/ctx.rs
@@ -1,17 +1,24 @@
use crate::{
- error::Error::*, map::LayeredHashMap, rc_fn_helper, resolved_lazy_val, FutureWrapper,
- LazyBinding, LazyVal, ObjValue, Result, Val,
+ error::Error::*, map::LayeredHashMap, resolved_lazy_val, FutureWrapper, LazyBinding, LazyVal,
+ ObjValue, Result, Val,
};
use jrsonnet_interner::IStr;
use rustc_hash::FxHashMap;
use std::hash::BuildHasherDefault;
-use std::{collections::HashMap, fmt::Debug, rc::Rc};
+use std::{fmt::Debug, rc::Rc};
-rc_fn_helper!(
- ContextCreator,
- context_creator,
- dyn Fn(Option<ObjValue>, Option<ObjValue>) -> Result<Context>
-);
+#[derive(Clone)]
+pub struct ContextCreator(pub Context, pub FutureWrapper<FxHashMap<IStr, LazyBinding>>);
+impl ContextCreator {
+ pub fn create(&self, this: Option<ObjValue>, super_obj: Option<ObjValue>) -> Result<Context> {
+ self.0.clone().extend_unbound(
+ self.1.clone().unwrap(),
+ self.0.dollar().clone().or_else(|| this.clone()),
+ this,
+ super_obj,
+ )
+ }
+}
struct ContextInternals {
dollar: Option<ObjValue>,
@@ -120,9 +127,14 @@
}
}
}
+ pub fn extend_bound(self, new_bindings: FxHashMap<IStr, LazyVal>) -> Self {
+ let new_this = self.0.this.clone();
+ let new_super_obj = self.0.super_obj.clone();
+ self.extend(new_bindings, None, new_this, new_super_obj)
+ }
pub fn extend_unbound(
self,
- new_bindings: HashMap<IStr, LazyBinding>,
+ new_bindings: FxHashMap<IStr, LazyBinding>,
new_dollar: Option<ObjValue>,
new_this: Option<ObjValue>,
new_super_obj: Option<ObjValue>,
crates/jrsonnet-evaluator/src/dynamic.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/dynamic.rs
+++ b/crates/jrsonnet-evaluator/src/dynamic.rs
@@ -12,7 +12,7 @@
}
}
impl<T: Clone> FutureWrapper<T> {
- pub fn unwrap(self) -> T {
+ pub fn unwrap(&self) -> T {
self.0.borrow().as_ref().cloned().unwrap()
}
}
@@ -21,30 +21,4 @@
fn default() -> Self {
Self::new()
}
-}
-
-#[macro_export]
-macro_rules! rc_fn_helper {
- ($name: ident, $macro_name: ident, $fn: ty) => {
- #[derive(Clone)]
- #[doc = "Function wrapper"]
- pub struct $name(pub std::rc::Rc<$fn>);
- impl std::fmt::Debug for $name {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct(std::stringify!($name)).finish()
- }
- }
- impl std::cmp::PartialEq for $name {
- fn eq(&self, other: &$name) -> bool {
- std::ptr::eq(&self.0, &other.0)
- }
- }
- #[doc = "Macro to ease wrapper creation"]
- #[macro_export]
- macro_rules! $macro_name {
- ($val: expr) => {
- $crate::$name(std::rc::Rc::new($val))
- };
- }
- };
}
crates/jrsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth1use 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};1516pub 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}153716pub 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_obj227 )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 members233 .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: Assert296 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_obj334 )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 obj339 .pre_locals344 .pre_locals340 .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();502503 let context_creator = context_creator!(504 closure!(clone future_context, |_, _| Ok(future_context.clone().unwrap()))505 );506507 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 }513514 let context = context516 let context = context515 .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 }crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -27,10 +27,12 @@
use jrsonnet_parser::*;
use native::NativeCallback;
pub use obj::*;
+use rustc_hash::FxHashMap;
use std::{
cell::{Ref, RefCell, RefMut},
collections::HashMap,
fmt::Debug,
+ hash::BuildHasherDefault,
path::PathBuf,
rc::Rc,
};
@@ -230,7 +232,7 @@
}
value.parsed.clone()
};
- let value = evaluate(self.create_default_context()?, &expr)?;
+ let value = evaluate(self.create_default_context(), &expr)?;
{
self.data_mut()
.files
@@ -260,16 +262,14 @@
}
/// Creates context with all passed global variables
- pub fn create_default_context(&self) -> Result<Context> {
+ pub fn create_default_context(&self) -> Context {
let globals = &self.settings().globals;
- let mut new_bindings: HashMap<IStr, LazyBinding> = HashMap::new();
+ let mut new_bindings: FxHashMap<IStr, LazyVal> =
+ FxHashMap::with_capacity_and_hasher(globals.len(), BuildHasherDefault::default());
for (name, value) in globals.iter() {
- new_bindings.insert(
- name.clone(),
- LazyBinding::Bound(resolved_lazy_val!(value.clone())),
- );
+ new_bindings.insert(name.clone(), resolved_lazy_val!(value.clone()));
}
- Context::new().extend_unbound(new_bindings, None, None, None)
+ Context::new().extend_bound(new_bindings)
}
/// Executes code creating a new stack frame
@@ -345,7 +345,7 @@
|| "during TLA call".to_owned(),
|| {
func.evaluate_map(
- self.create_default_context()?,
+ self.create_default_context(),
&self.settings().tla_vars,
true,
)
@@ -396,7 +396,7 @@
}
/// Evaluates the parsed expression
pub fn evaluate_expr_raw(&self, code: LocExpr) -> Result<Val> {
- self.run_in_state(|| evaluate(self.create_default_context()?, &code))
+ self.run_in_state(|| evaluate(self.create_default_context(), &code))
}
}
@@ -950,6 +950,23 @@
Ok(())
}
+ #[test]
+ fn comp_self() -> crate::error::Result<()> {
+ assert_eval!(
+ r#"
+ std.objectFields({
+ a:{
+ [name]: name for name in std.objectFields(self)
+ },
+ b: 2,
+ c: 3,
+ }.a) == ['a', 'b', 'c']
+ "#
+ );
+
+ Ok(())
+ }
+
struct TestImportResolver(IStr);
impl crate::import::ImportResolver for TestImportResolver {
fn resolve_file(&self, _: &PathBuf, _: &PathBuf) -> crate::error::Result<Rc<PathBuf>> {
crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/val.rs
+++ b/crates/jrsonnet-evaluator/src/val.rs
@@ -535,7 +535,7 @@
pub fn to_yaml(&self, padding: usize) -> Result<IStr> {
with_state(|s| {
let ctx = s
- .create_default_context()?
+ .create_default_context()
.with_var("__tmp__to_json__".into(), self.clone());
evaluate(
ctx,