difftreelog
refactor remove future_wrapper
in: master
3 files changed
crates/jrsonnet-evaluator/src/ctx.rsdiffbeforeafterboth1use crate::{2 error::Error::*, future_wrapper, map::LayeredHashMap, rc_fn_helper, resolved_lazy_val,3 LazyBinding, LazyVal, ObjValue, Result, Val,4};5use jrsonnet_interner::IStr;6use rustc_hash::FxHashMap;7use std::hash::BuildHasherDefault;8use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc};910rc_fn_helper!(11 ContextCreator,12 context_creator,13 dyn Fn(Option<ObjValue>, Option<ObjValue>) -> Result<Context>14);1516future_wrapper!(Context, FutureContext);1718struct ContextInternals {19 dollar: Option<ObjValue>,20 this: Option<ObjValue>,21 super_obj: Option<ObjValue>,22 bindings: LayeredHashMap<LazyVal>,23}24impl Debug for ContextInternals {25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {26 f.debug_struct("Context")27 .field("this", &self.this.as_ref().map(|e| Rc::as_ptr(&e.0)))28 .field("bindings", &self.bindings)29 .finish()30 }31}3233#[derive(Debug, Clone)]34pub struct Context(Rc<ContextInternals>);35impl Context {36 pub fn new_future() -> FutureContext {37 FutureContext(Rc::new(RefCell::new(None)))38 }3940 pub fn dollar(&self) -> &Option<ObjValue> {41 &self.0.dollar42 }4344 pub fn this(&self) -> &Option<ObjValue> {45 &self.0.this46 }4748 pub fn super_obj(&self) -> &Option<ObjValue> {49 &self.0.super_obj50 }5152 pub fn new() -> Self {53 Self(Rc::new(ContextInternals {54 dollar: None,55 this: None,56 super_obj: None,57 bindings: LayeredHashMap::default(),58 }))59 }6061 pub fn binding(&self, name: IStr) -> Result<LazyVal> {62 Ok(self63 .064 .bindings65 .get(&name)66 .cloned()67 .ok_or(VariableIsNotDefined(name))?)68 }69 pub fn into_future(self, ctx: FutureContext) -> Self {70 {71 ctx.0.borrow_mut().replace(self);72 }73 ctx.unwrap()74 }7576 pub fn with_var(self, name: IStr, value: Val) -> Self {77 let mut new_bindings =78 FxHashMap::with_capacity_and_hasher(1, BuildHasherDefault::default());79 new_bindings.insert(name, resolved_lazy_val!(value));80 self.extend(new_bindings, None, None, None)81 }8283 pub fn extend(84 self,85 new_bindings: FxHashMap<IStr, LazyVal>,86 new_dollar: Option<ObjValue>,87 new_this: Option<ObjValue>,88 new_super_obj: Option<ObjValue>,89 ) -> Self {90 match Rc::try_unwrap(self.0) {91 Ok(mut ctx) => {92 // Extended context aren't used by anything else, we can freely mutate it without cloning93 if let Some(dollar) = new_dollar {94 ctx.dollar = Some(dollar);95 }96 if let Some(this) = new_this {97 ctx.this = Some(this);98 }99 if let Some(super_obj) = new_super_obj {100 ctx.super_obj = Some(super_obj);101 }102 if !new_bindings.is_empty() {103 ctx.bindings = ctx.bindings.extend(new_bindings);104 }105 Self(Rc::new(ctx))106 }107 Err(ctx) => {108 let dollar = new_dollar.or_else(|| ctx.dollar.clone());109 let this = new_this.or_else(|| ctx.this.clone());110 let super_obj = new_super_obj.or_else(|| ctx.super_obj.clone());111 let bindings = if new_bindings.is_empty() {112 ctx.bindings.clone()113 } else {114 ctx.bindings.clone().extend(new_bindings)115 };116 Self(Rc::new(ContextInternals {117 dollar,118 this,119 super_obj,120 bindings,121 }))122 }123 }124 }125 pub fn extend_unbound(126 self,127 new_bindings: HashMap<IStr, LazyBinding>,128 new_dollar: Option<ObjValue>,129 new_this: Option<ObjValue>,130 new_super_obj: Option<ObjValue>,131 ) -> Result<Self> {132 let this = new_this.or_else(|| self.0.this.clone());133 let super_obj = new_super_obj.or_else(|| self.0.super_obj.clone());134 let mut new =135 FxHashMap::with_capacity_and_hasher(new_bindings.len(), BuildHasherDefault::default());136 for (k, v) in new_bindings.into_iter() {137 new.insert(k, v.evaluate(this.clone(), super_obj.clone())?);138 }139 Ok(self.extend(new, new_dollar, this, super_obj))140 }141 #[cfg(feature = "unstable")]142 pub fn into_weak(self) -> WeakContext {143 WeakContext(Rc::downgrade(&self.0))144 }145}146147impl Default for Context {148 fn default() -> Self {149 Self::new()150 }151}152153impl PartialEq for Context {154 fn eq(&self, other: &Self) -> bool {155 Rc::ptr_eq(&self.0, &other.0)156 }157}158159#[cfg(feature = "unstable")]160#[derive(Debug, Clone)]161pub struct WeakContext(std::rc::Weak<ContextInternals>);162#[cfg(feature = "unstable")]163impl WeakContext {164 pub fn upgrade(&self) -> Context {165 Context(self.0.upgrade().expect("context is removed"))166 }167}168#[cfg(feature = "unstable")]169impl PartialEq for WeakContext {170 fn eq(&self, other: &Self) -> bool {171 self.0.ptr_eq(&other.0)172 }173}crates/jrsonnet-evaluator/src/dynamic.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/dynamic.rs
+++ b/crates/jrsonnet-evaluator/src/dynamic.rs
@@ -1,31 +1,26 @@
-#[macro_export]
-macro_rules! future_wrapper {
- ($orig: ty, $wrapper: ident) => {
- #[derive(Debug, Clone)]
- pub struct $wrapper(pub std::rc::Rc<std::cell::RefCell<Option<$orig>>>);
- impl $wrapper {
- pub fn unwrap(self) -> $orig {
- self.0.borrow().as_ref().map(|e| e.clone()).unwrap()
- }
- pub fn new() -> Self {
- $wrapper(std::rc::Rc::new(std::cell::RefCell::new(None)))
- }
- pub fn fill(self, val: $orig) -> $orig {
- if self.0.borrow().is_some() {
- panic!("wrapper is filled already");
- }
- {
- self.0.borrow_mut().replace(val);
- }
- self.unwrap()
- }
- }
- impl Default for $wrapper {
- fn default() -> Self {
- Self::new()
- }
- }
- };
+use std::{cell::RefCell, rc::Rc};
+
+#[derive(Clone)]
+pub struct FutureWrapper<V>(pub Rc<RefCell<Option<V>>>);
+impl<T> FutureWrapper<T> {
+ pub fn new() -> Self {
+ Self(Rc::new(RefCell::new(None)))
+ }
+ pub fn fill(self, value: T) {
+ assert!(self.0.borrow().is_none(), "wrapper is filled already");
+ self.0.borrow_mut().replace(value);
+ }
+}
+impl<T: Clone> FutureWrapper<T> {
+ pub fn unwrap(self) -> T {
+ self.0.borrow().as_ref().cloned().unwrap()
+ }
+}
+
+impl<T> Default for FutureWrapper<T> {
+ fn default() -> Self {
+ Self::new()
+ }
}
#[macro_export]
crates/jrsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate.rs
@@ -1,6 +1,6 @@
use crate::{
- context_creator, error::Error::*, future_wrapper, lazy_val, push, throw, with_state, Context,
- ContextCreator, FuncDesc, FuncVal, LazyBinding, LazyVal, ObjMember, ObjValue, Result, Val,
+ context_creator, error::Error::*, lazy_val, push, throw, with_state, Context, ContextCreator,
+ FuncDesc, FuncVal, FutureWrapper, LazyBinding, LazyVal, ObjMember, ObjValue, Result, Val,
};
use closure::closure;
use jrsonnet_interner::IStr;
@@ -182,9 +182,6 @@
)),
})
}
-
-future_wrapper!(HashMap<IStr, LazyBinding>, FutureNewBindings);
-future_wrapper!(ObjValue, FutureObjValue);
pub fn evaluate_comp<T>(
context: Context,
@@ -218,8 +215,8 @@
}
pub fn evaluate_member_list_object(context: Context, members: &[Member]) -> Result<ObjValue> {
- let new_bindings = FutureNewBindings::new();
- let future_this = FutureObjValue::new();
+ let new_bindings = FutureWrapper::new();
+ let future_this = FutureWrapper::new();
let context_creator = context_creator!(
closure!(clone context, clone new_bindings, |this: Option<ObjValue>, super_obj: Option<ObjValue>| {
context.clone().extend_unbound(
@@ -312,19 +309,21 @@
Member::AssertStmt(_) => {}
}
}
- Ok(future_this.fill(ObjValue::new(None, Rc::new(new_members))))
+ let this = ObjValue::new(None, Rc::new(new_members));
+ future_this.fill(this.clone());
+ Ok(this)
}
pub fn evaluate_object(context: Context, object: &ObjBody) -> Result<ObjValue> {
Ok(match object {
ObjBody::MemberList(members) => evaluate_member_list_object(context, members)?,
ObjBody::ObjComp(obj) => {
- let future_this = FutureObjValue::new();
+ let future_this = FutureWrapper::new();
let mut new_members = FxHashMap::default();
for (k, v) in evaluate_comp(
context.clone(),
&|ctx| {
- let new_bindings = FutureNewBindings::new();
+ let new_bindings = FutureWrapper::new();
let context_creator = context_creator!(
closure!(clone context, clone new_bindings, |this: Option<ObjValue>, super_obj: Option<ObjValue>| {
context.clone().extend_unbound(
@@ -344,7 +343,7 @@
{
bindings.insert(n, b);
}
- let bindings = new_bindings.fill(bindings);
+ new_bindings.fill(bindings.clone());
let ctx = ctx.extend_unbound(bindings, None, None, None)?;
let key = evaluate(ctx.clone(), &obj.key)?;
let value = LazyBinding::Bindable(Rc::new(
@@ -376,7 +375,9 @@
}
}
- future_this.fill(ObjValue::new(None, Rc::new(new_members)))
+ let this = ObjValue::new(None, Rc::new(new_members));
+ future_this.fill(this.clone());
+ this
}
})
}