git.delta.rocks / jrsonnet / refs/commits / 1f53e1f057f6

difftreelog

refactor remove future_wrapper

Yaroslav Bolyukin2021-02-21parent: #be90068.patch.diff
in: master

3 files changed

modifiedcrates/jrsonnet-evaluator/src/ctx.rsdiffbeforeafterboth
before · crates/jrsonnet-evaluator/src/ctx.rs
1use 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}
modifiedcrates/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]
modifiedcrates/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
 		}
 	})
 }