git.delta.rocks / jrsonnet / refs/commits / 2e6febe0ffcd

difftreelog

fix(evaluator) indirect_self bug

Лач2020-05-30parent: #abae2f2.patch.diff
in: master

4 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1,9 +1,16 @@
 # This file is automatically @generated by Cargo.
 # It is not intended for manual editing.
 [[package]]
+name = "closure"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d6173fd61b610d15a7566dd7b7620775627441c4ab9dac8906e17cb93a24b782"
+
+[[package]]
 name = "jsonnet-evaluator"
 version = "0.1.0"
 dependencies = [
+ "closure",
  "jsonnet-parser",
  "jsonnet-stdlib",
 ]
modifiedcrates/jsonnet-evaluator/src/ctx.rsdiffbeforeafterboth
before · crates/jsonnet-evaluator/src/ctx.rs
1use crate::{future_wrapper, rc_fn_helper, Binding, ObjValue};2use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc};34rc_fn_helper!(5	ContextCreator,6	context_creator,7	dyn Fn(Option<ObjValue>, Option<ObjValue>) -> Context8);910future_wrapper!(Context, FutureContext);1112#[derive(Debug)]13struct ContextInternals {14	dollar: Option<ObjValue>,15	this: Option<ObjValue>,16	super_obj: Option<ObjValue>,17	bindings: Rc<RefCell<HashMap<String, Binding>>>,18}19pub struct Context(Rc<ContextInternals>);20impl Debug for Context {21	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {22		f.debug_struct("Context")23			.field("this", &self.0.this.clone().map(|e| Rc::as_ptr(&e.0)))24			.finish()25	}26}27impl Context {28	pub fn new_future() -> FutureContext {29		FutureContext(Rc::new(RefCell::new(None)))30	}3132	pub fn dollar(&self) -> &Option<ObjValue> {33		&self.0.dollar34	}3536	pub fn this(&self) -> &Option<ObjValue> {37		&self.0.this38	}3940	pub fn super_obj(&self) -> &Option<ObjValue> {41		&self.0.super_obj42	}4344	pub fn new() -> Context {45		Context(Rc::new(ContextInternals {46			dollar: None,47			this: None,48			super_obj: None,49			bindings: Rc::new(RefCell::new(HashMap::new())),50		}))51	}5253	pub fn binding(&self, name: &str) -> Binding {54		self.055			.bindings56			.borrow()57			.get(name)58			.cloned()59			.unwrap_or_else(|| {60				panic!("can't find {} in {:?}", name, self);61			})62	}63	pub fn into_future(self, ctx: FutureContext) -> Context {64		{65			ctx.0.borrow_mut().replace(self);66		}67		ctx.unwrap()68	}6970	pub fn extend(71		&self,72		new_bindings: HashMap<String, Binding>,73		new_dollar: Option<ObjValue>,74		new_this: Option<ObjValue>,75		new_super_obj: Option<ObjValue>,76	) -> Context {77		println!("Extend with {:?} {:?}", new_dollar, new_this);78		let dollar = new_dollar.or_else(|| self.0.dollar.clone());79		let this = new_this.or_else(|| self.0.this.clone());80		let super_obj = new_super_obj.or_else(|| self.0.super_obj.clone());81		let bindings = if new_bindings.is_empty() {82			self.0.bindings.clone()83		} else {84			let new = self.0.bindings.clone();85			for (k, v) in new_bindings.into_iter() {86				new.borrow_mut().insert(k, v);87			}88			new89		};90		Context(Rc::new(ContextInternals {91			dollar,92			this,93			super_obj,94			bindings,95		}))96	}97}9899impl Default for Context {100	fn default() -> Self {101		Self::new()102	}103}104105impl PartialEq for Context {106	fn eq(&self, other: &Self) -> bool {107		Rc::ptr_eq(&self.0, &other.0)108	}109}110111impl Clone for Context {112	fn clone(&self) -> Self {113		Context(self.0.clone())114	}115}
modifiedcrates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
--- a/crates/jsonnet-evaluator/src/evaluate.rs
+++ b/crates/jsonnet-evaluator/src/evaluate.rs
@@ -29,9 +29,8 @@
 	} else {
 		(
 			b.name.clone(),
-				binding!(move |this, super_obj| {
-					println!("Evaluating binding");
-					Val::Lazy(lazy_val!(
+			binding!(move |this, super_obj| {
+				Val::Lazy(lazy_val!(
 					closure!(clone context_creator, clone b, || evaluate(
 						context_creator.0(this.clone(), super_obj.clone()),
 						&b.value
@@ -137,12 +136,11 @@
 			let future_bindings = FutureNewBindings::new();
 			let future_this = FutureObjValue::new();
 			let context_creator = context_creator!(
-				closure!(clone context, clone future_bindings, |this: Option<ObjValue>, super_obj: Option<ObjValue>| {
-					println!("Context created");
+				closure!(clone context, clone future_bindings, clone future_this, |this: Option<ObjValue>, super_obj: Option<ObjValue>| {
 					context.clone().extend(
 						future_bindings.clone().unwrap(),
 						context.clone().dollar().clone().or_else(||this.clone()),
-						this,
+						Some(future_this.clone().unwrap()),
 						super_obj
 					)
 				})
@@ -154,15 +152,12 @@
 					Member::BindStmt(b) => Some(b.clone()),
 					_ => None,
 				})
-				.map(|b| {
-					evaluate_binding(&b, context_creator.clone())
-				})
+				.map(|b| evaluate_binding(&b, context_creator.clone()))
 			{
 				bindings.insert(n, b);
 			}
 			future_bindings.fill(bindings);
 
-			println!("Bindings filled");
 			let mut new_members = BTreeMap::new();
 			for member in members.into_iter() {
 				match member {
@@ -180,8 +175,7 @@
 								add: plus,
 								visibility: visibility.clone(),
 								invoke: binding!(
-									closure!(clone value, clone context_creator, clone future_this, |this, super_obj| {
-										// FIXME: I should take "this" instead of "future_this" there?
+									closure!(clone value, clone context_creator, |this, super_obj| {
 										// TODO: Assert
 										evaluate(
 											context_creator.0(this, super_obj),
@@ -205,8 +199,7 @@
 								add: false,
 								visibility: Visibility::Hidden,
 								invoke: binding!(
-									closure!(clone value, clone context_creator, clone future_this, |this, super_obj| {
-										// FIXME: I should take "this" instead of "future_this" there?
+									closure!(clone value, clone context_creator, |this, super_obj| {
 										// TODO: Assert
 										evaluate_method(
 											context_creator.0(this, super_obj),
@@ -231,15 +224,12 @@
 pub fn evaluate(context: Context, expr: &Expr) -> Val {
 	use Expr::*;
 	match &*expr {
-		Literal(LiteralType::This) => {
-			println!("{:?}", context.this());
-			Val::Obj(
-				context
-					.this()
-					.clone()
-					.unwrap_or_else(|| panic!("this not found")),
-			)
-		}
+		Literal(LiteralType::This) => Val::Obj(
+			context
+				.this()
+				.clone()
+				.unwrap_or_else(|| panic!("this not found")),
+		),
 		Literal(LiteralType::Super) => Val::Obj(
 			context
 				.super_obj()
modifiedcrates/jsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jsonnet-evaluator/src/lib.rs
+++ b/crates/jsonnet-evaluator/src/lib.rs
@@ -193,7 +193,7 @@
 		// referenced from field
 		eval_stdlib!(
 			r#"{
-				local me = std.trace("test", self),
+				local me = self,
 				b: me,
 			}.b"#
 		);