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

difftreelog

feat support legacy std.thisFile

Yaroslav Bolyukin2022-04-22parent: #e082575.patch.diff
in: master

5 files changed

modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
140 #[error("sort error: {0}")]140 #[error("sort error: {0}")]
141 Sort(#[from] SortError),141 Sort(#[from] SortError),
142
143 /// Thrown as error, as this is legacy feature, and error here
144 /// is acceptable for defeating object field cache
145 #[error("should not reach outside: std.thisFile")]
146 MagicThisFileUsed,
142147
143 #[cfg(feature = "anyhow-error")]148 #[cfg(feature = "anyhow-error")]
144 #[error(transparent)]149 #[error(transparent)]
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs
@@ -568,12 +568,13 @@
 				(Val::Obj(v), Val::Str(key)) => s.push(
 					CallLocation::new(loc),
 					|| format!("field <{}> access", key),
-					|| {
-						if let Some(v) = v.get(s.clone(), key.clone())? {
-							Ok(v)
-						} else {
-							throw!(NoSuchField(key.clone()))
+					|| match v.get(s.clone(), key.clone()) {
+						Ok(Some(v)) => Ok(v),
+						Ok(None) => throw!(NoSuchField(key.clone())),
+						Err(e) if matches!(e.error(), MagicThisFileUsed) => {
+							Ok(Val::Str(loc.0.to_string_lossy().into()))
 						}
+						Err(e) => Err(e),
 					},
 				)?,
 				(Val::Obj(_), n) => throw!(ValueIndexMustBeTypeGot(
@@ -674,6 +675,7 @@
 				.with(|b| b.get(name).copied())
 				.ok_or_else(|| IntrinsicNotFound(name.clone()))?,
 		)),
+		IntrinsicThisFile => return Err(MagicThisFileUsed.into()),
 		AssertExpr(assert, returned) => {
 			evaluate_assert(s.clone(), ctx.clone(), assert)?;
 			evaluate(s, ctx, returned)?
modifiedcrates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth
--- a/crates/jrsonnet-parser/src/expr.rs
+++ b/crates/jrsonnet-parser/src/expr.rs
@@ -296,6 +296,8 @@
 	Index(LocExpr, LocExpr),
 	/// function(x) x
 	Function(ParamsDesc, LocExpr),
+	/// std.thisFile
+	IntrinsicThisFile,
 	/// std.primitiveEquals
 	Intrinsic(IStr),
 	/// if true == false then 1 else 2
modifiedcrates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-parser/src/lib.rs
+++ b/crates/jrsonnet-parser/src/lib.rs
@@ -210,6 +210,7 @@
 		pub rule expr_basic(s: &ParserSettings) -> Expr
 			= literal(s)
 
+			/ quiet!{"$intrinsicThisFile" {Expr::IntrinsicThisFile}}
 			/ quiet!{"$intrinsic(" name:$(id()) ")" {Expr::Intrinsic(name.into())}}
 
 			/ string_expr(s) / number_expr(s)
modifiedcrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/std.jsonnet
+++ b/crates/jrsonnet-stdlib/src/std.jsonnet
@@ -2,6 +2,9 @@
   local std = self,
   local id = std.id,
 
+  # Magic legacy field
+  thisFile:: $intrinsicThisFile,
+
   # Those functions aren't normally located in stdlib
   length:: $intrinsic(length),
   type:: $intrinsic(type),