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

difftreelog

refactor more spans wanted from IR

uvqsltluYaroslav Bolyukin2026-03-22parent: #d34410c.patch.diff
in: master

222 files changed

modifiedCargo.lockdiffbeforeafterboth
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -672,6 +672,7 @@
  "hi-doc",
  "indoc",
  "insta",
+ "jrsonnet-lexer",
  "jrsonnet-rowan-parser",
 ]
 
@@ -716,6 +717,16 @@
 ]
 
 [[package]]
+name = "jrsonnet-ir-parser"
+version = "0.5.0-pre97"
+dependencies = [
+ "insta",
+ "jrsonnet-gcmodule",
+ "jrsonnet-ir",
+ "jrsonnet-lexer",
+]
+
+[[package]]
 name = "jrsonnet-lexer"
 version = "0.5.0-pre97"
 dependencies = [
modifiedCargo.tomldiffbeforeafterboth
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,7 @@
 jrsonnet-evaluator = { path = "./crates/jrsonnet-evaluator", version = "0.5.0-pre97" }
 jrsonnet-macros = { path = "./crates/jrsonnet-macros", version = "0.5.0-pre97" }
 jrsonnet-ir = { path = "./crates/jrsonnet-ir", version = "0.5.0-pre97" }
+jrsonnet-ir-parser = { path = "./crates/jrsonnet-rowan-parser", version = "0.5.0-pre97" }
 jrsonnet-peg-parser = { path = "./crates/jrsonnet-peg-parser", version = "0.5.0-pre97" }
 jrsonnet-rowan-parser = { path = "./crates/jrsonnet-rowan-parser", version = "0.5.0-pre97" }
 jrsonnet-interner = { path = "./crates/jrsonnet-interner", version = "0.5.0-pre97" }
modifiedcrates/jrsonnet-evaluator/src/arr/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/arr/mod.rs
+++ b/crates/jrsonnet-evaluator/src/arr/mod.rs
@@ -7,7 +7,7 @@
 
 use jrsonnet_gcmodule::{cc_dyn, Cc};
 use jrsonnet_interner::IBytes;
-use jrsonnet_ir::{Expr, Spanned};
+use jrsonnet_ir::Expr;
 
 use crate::{function::NativeFn, Context, Result, Thunk, Val};
 
modifiedcrates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/arr/spec.rs
+++ b/crates/jrsonnet-evaluator/src/arr/spec.rs
@@ -3,7 +3,7 @@
 
 use jrsonnet_gcmodule::{Cc, Trace};
 use jrsonnet_interner::{IBytes, IStr};
-use jrsonnet_ir::{Expr, Spanned};
+use jrsonnet_ir::Expr;
 
 use super::ArrValue;
 use crate::function::NativeFn;
modifiedcrates/jrsonnet-evaluator/src/error.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/error.rs
+++ b/crates/jrsonnet-evaluator/src/error.rs
@@ -290,7 +290,7 @@
 }
 impl<T: Acyclic> ErrorSource for &Spanned<T> {
 	fn to_location(self) -> Option<Span> {
-		Some(self.span())
+		Some(self.span.clone())
 	}
 }
 impl ErrorSource for &Span {
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs
@@ -49,15 +49,15 @@
 
 pub fn evaluate_trivial(expr: &Expr) -> Option<Val> {
 	fn is_trivial(expr: &Expr) -> bool {
-		match &*expr {
+		match expr {
 			Expr::Str(_)
 			| Expr::Num(_)
 			| Expr::Literal(LiteralType::False | LiteralType::True | LiteralType::Null) => true,
-			Expr::Arr(a) => a.iter().all(|e| is_trivial(&*e)),
+			Expr::Arr(a) => a.iter().all(is_trivial),
 			_ => false,
 		}
 	}
-	Some(match &*expr {
+	Some(match expr {
 		Expr::Str(s) => Val::string(s.clone()),
 		Expr::Num(n) => {
 			Val::Num(NumValue::new(*n).expect("parser will not allow non-finite values"))
@@ -71,7 +71,7 @@
 			}
 			Val::Arr(ArrValue::eager(
 				n.iter()
-					.map(|e| evaluate_trivial(&*e))
+					.map(evaluate_trivial)
 					.map(|e| e.expect("checked trivial"))
 					.collect(),
 			))
@@ -89,24 +89,21 @@
 	})))
 }
 
-pub fn evaluate_field_name(ctx: Context, field_name: &FieldName) -> Result<Option<IStr>> {
-	Ok(match field_name {
+pub fn evaluate_field_name(ctx: Context, field_name: &Spanned<FieldName>) -> Result<Option<IStr>> {
+	Ok(match &field_name.value {
 		FieldName::Fixed(n) => Some(n.clone()),
-		FieldName::Dyn(expr) => {
-			// FIXME: Span
-			let value = evaluate(ctx, expr)?;
-			if matches!(value, Val::Null) {
-				None
-			} else {
-				Some(IStr::from_untyped(value)?)
-			}
-		} //
-		  // 	in_frame(
-		  // 	CallLocation::new(&expr.span()),
-		  // 	|| "evaluating field name".to_string(),
-		  // 	|| {
-		  // 	},
-		  // )?,
+		FieldName::Dyn(expr) => in_frame(
+			CallLocation::new(&field_name.span),
+			|| "evaluating field name".to_string(),
+			|| {
+				let v = evaluate(ctx, expr)?;
+				Ok(if matches!(v, Val::Null) {
+					None
+				} else {
+					Some(IStr::from_untyped(v)?)
+				})
+			},
+		)?,
 	})
 }
 
@@ -117,18 +114,21 @@
 ) -> Result<()> {
 	match specs.first() {
 		None => callback(ctx)?,
-		Some(CompSpec::IfSpec(Spanned(IfSpecData(cond), _))) => {
+		Some(CompSpec::IfSpec(IfSpecData { cond, span: _ })) => {
 			if bool::from_untyped(evaluate(ctx.clone(), cond)?)? {
 				evaluate_comp(ctx, &specs[1..], callback)?;
 			}
 		}
-		Some(CompSpec::ForSpec(Spanned(ForSpecData(var, expr), _))) => {
-			match evaluate(ctx.clone(), expr)? {
+		Some(CompSpec::ForSpec(ForSpecData {
+			destruct: into,
+			over,
+		})) => {
+			match evaluate(ctx.clone(), over)? {
 				Val::Arr(list) => {
 					for item in list.iter_lazy() {
 						let fctx = Pending::new();
-						let mut new_bindings = FxHashMap::with_capacity(var.binds_len());
-						destruct(var, item, fctx.clone(), &mut new_bindings)?;
+						let mut new_bindings = FxHashMap::with_capacity(into.binds_len());
+						destruct(into, item, fctx.clone(), &mut new_bindings)?;
 						let ctx = ctx.clone().extend_bindings(new_bindings).into_future(fctx);
 
 						evaluate_comp(ctx, &specs[1..], callback)?;
@@ -235,8 +235,7 @@
 				.field(name.clone())
 				.with_add(*plus)
 				.with_visibility(*visibility)
-				// FIXME
-				// .with_location(value.span())
+				.with_location(field.name.span.clone())
 				.bindable(UnboundValue {
 					uctx,
 					value: value.clone(),
@@ -361,13 +360,13 @@
 	let value = &assertion.0;
 	let msg = &assertion.1;
 	let assertion_result = in_frame(
-		CallLocation::new(&value.span()),
+		CallLocation::new(&value.span),
 		|| "assertion condition".to_owned(),
 		|| bool::from_untyped(evaluate(ctx.clone(), value)?),
 	)?;
 	if !assertion_result {
 		in_frame(
-			CallLocation::new(&value.span()),
+			CallLocation::new(&value.span),
 			|| "assertion failure".to_owned(),
 			|| {
 				if let Some(msg) = msg {
@@ -389,7 +388,7 @@
 
 pub fn evaluate_named(ctx: Context, expr: &Expr, name: IStr) -> Result<Val> {
 	use Expr::*;
-	Ok(match &*expr {
+	Ok(match expr {
 		Function(params, body) => evaluate_method(ctx, name, params.clone(), body.clone()),
 		_ => evaluate(ctx, expr)?,
 	})
@@ -433,7 +432,7 @@
 		BinaryOp(bin) => evaluate_binary_op_special(ctx, &bin.lhs, bin.op, &bin.rhs)?,
 		UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(ctx, v)?)?,
 		Var(name) => in_frame(
-			CallLocation::new(&name.span()),
+			CallLocation::new(&name.span),
 			|| format!("local <{}> access", &**name),
 			|| ctx.binding((**name).clone())?.evaluate(),
 		)?,
@@ -591,13 +590,7 @@
 			&Val::Obj(evaluate_object(ctx, b)?),
 		)?,
 		Apply(value, args, tailstrict) => ensure_sufficient_stack(|| {
-			evaluate_apply(
-				ctx,
-				value,
-				args,
-				CallLocation::new(&args.span()),
-				*tailstrict,
-			)
+			evaluate_apply(ctx, value, args, CallLocation::new(&args.span), *tailstrict)
 		})?,
 		Function(params, body) => {
 			evaluate_method(ctx, "anonymous".into(), params.clone(), body.clone())
@@ -607,20 +600,16 @@
 			evaluate(ctx, &assert.rest)?
 		}
 		ErrorStmt(s, e) => in_frame(
-			CallLocation::new(&s),
+			CallLocation::new(s),
 			|| "error statement".to_owned(),
 			|| bail!(RuntimeError(evaluate(ctx, e)?.to_string()?,)),
 		)?,
 		IfElse(if_else) => {
-			if
-			// FIXME
-			//in_frame(
-			// CallLocation::new(&if_else.cond.0.span()),
-			// || "if condition".to_owned(),
-			// ||
-			bool::from_untyped(evaluate(ctx.clone(), &if_else.cond.0)?)?
-			// )?
-			{
+			if in_frame(
+				CallLocation::new(&if_else.cond.span),
+				|| "if condition".to_owned(),
+				|| bool::from_untyped(evaluate(ctx.clone(), &if_else.cond.cond)?),
+			)? {
 				evaluate(ctx, &if_else.cond_then)?
 			} else {
 				match &if_else.cond_else {
@@ -637,7 +626,7 @@
 			) -> Result<Option<T>> {
 				if let Some(value) = expr {
 					Ok(in_frame(
-						CallLocation::new(&value.span()),
+						CallLocation::new(&value.span),
 						|| format!("slice {desc}"),
 						|| <Option<T>>::from_untyped(evaluate(ctx, value)?),
 					)?)
@@ -659,11 +648,11 @@
 				bail!("computed imports are not supported")
 			};
 			with_state(|s| {
-				let span = kind.span();
+				let span = &kind.span;
 				let resolved_path = s.resolve_from(span.0.source_path(), path)?;
 				Ok(match &**kind {
 					ImportKind::Normal => in_frame(
-						CallLocation::new(&span),
+						CallLocation::new(span),
 						|| format!("import {:?}", path.clone()),
 						|| s.import_resolved(resolved_path),
 					)?,
modifiedcrates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/operator.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/operator.rs
@@ -1,6 +1,6 @@
 use std::cmp::Ordering;
 
-use jrsonnet_ir::{BinaryOpType, Expr, Spanned, UnaryOpType};
+use jrsonnet_ir::{BinaryOpType, Expr, UnaryOpType};
 
 use crate::{
 	arr::ArrValue,
modifiedcrates/jrsonnet-evaluator/src/function/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/function/mod.rs
+++ b/crates/jrsonnet-evaluator/src/function/mod.rs
@@ -3,7 +3,7 @@
 use educe::Educe;
 use jrsonnet_gcmodule::{Cc, Trace};
 use jrsonnet_interner::IStr;
-use jrsonnet_ir::{ArgsDesc, Destruct, Expr, ExprParams, Span, Spanned};
+use jrsonnet_ir::{ArgsDesc, Destruct, Expr, ExprParams, Span};
 pub use jrsonnet_macros::builtin;
 
 use self::{
modifiedcrates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -42,10 +42,10 @@
 pub use import::*;
 use jrsonnet_gcmodule::{cc_dyn, Cc, Trace};
 pub use jrsonnet_interner::{IBytes, IStr};
+pub use jrsonnet_ir as parser;
+use jrsonnet_ir::{Expr, Source, SourcePath};
 #[doc(hidden)]
 pub use jrsonnet_macros;
-pub use jrsonnet_ir as parser;
-use jrsonnet_ir::{Expr, Source, SourcePath, Spanned};
 use jrsonnet_peg_parser::ParserSettings;
 pub use obj::*;
 pub use rustc_hash;
addedcrates/jrsonnet-ir-parser/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-ir-parser/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "jrsonnet-ir-parser"
+authors.workspace = true
+edition.workspace = true
+license.workspace = true
+repository.workspace = true
+version.workspace = true
+
+[dependencies]
+insta.workspace = true
+jrsonnet-gcmodule.workspace = true
+jrsonnet-ir.workspace = true
+jrsonnet-lexer = { version = "0.5.0-pre97", path = "../jrsonnet-lexer" }
+
+[lints]
+workspace = true
addedcrates/jrsonnet-ir-parser/src/lib.rsdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-ir-parser/src/lib.rs
@@ -0,0 +1,183 @@
+use std::rc::Rc;
+
+use insta::assert_snapshot;
+use jrsonnet_gcmodule::Acyclic;
+use jrsonnet_ir::{
+	AssertExpr, AssertStmt, Expr, IfElse, IfSpecData, LiteralType, Slice, SliceDesc, Source,
+	SourceVirtual, Span, Spanned,
+};
+use jrsonnet_lexer::{Lexeme, Lexer, SyntaxKind, T};
+
+struct Parser<'a> {
+	lexemes: Vec<Lexeme<'a>>,
+	offset: usize,
+	source: Source,
+}
+
+impl<'a> Parser<'a> {
+	fn new(s: &'a str) -> Self {
+		Self {
+			lexemes: Lexer::new(s)
+				.filter(|l| l.kind != SyntaxKind::WHITESPACE)
+				.collect(),
+			offset: 0,
+			source: Source::new_virtual("<test>".into(), s.into()),
+		}
+	}
+	fn peek(&self) -> SyntaxKind {
+		self.lexemes[self.offset].kind
+	}
+	fn text(&self) -> &str {
+		self.lexemes[self.offset].text
+	}
+	fn at(&self, kind: SyntaxKind) -> bool {
+		!self.at_eof() && self.peek() == kind
+	}
+	fn eat_any(&mut self) {
+		self.offset += 1
+	}
+
+	fn at_eof(&self) -> bool {
+		self.offset == self.lexemes.len()
+	}
+
+	fn try_eat(&mut self, t: SyntaxKind) -> bool {
+		if self.at(t) {
+			self.eat_any();
+			return true;
+		}
+		false
+	}
+	fn eat(&mut self, t: SyntaxKind) {
+		assert_eq!(self.peek(), t);
+		self.eat_any();
+	}
+
+	fn span_start(&self) -> u32 {
+		self.lexemes[self.offset].range.0
+	}
+	fn span_end(&self) -> u32 {
+		self.lexemes[self.offset - 1].range.1
+	}
+}
+
+fn literal(p: &mut Parser<'_>) -> Option<LiteralType> {
+	let t = match p.peek() {
+		T![self] => LiteralType::This,
+		T![super] => LiteralType::Super,
+		T!['$'] => LiteralType::Dollar,
+		T![null] => LiteralType::Null,
+		T![true] => LiteralType::True,
+		T![false] => LiteralType::False,
+		_ => return None,
+	};
+	p.eat_any();
+	Some(t)
+}
+
+fn spanned<T: Acyclic>(p: &mut Parser<'_>, cb: impl FnOnce(&mut Parser<'_>) -> T) -> Spanned<T> {
+	let start = p.span_start();
+	let v = cb(p);
+	let end = p.span_end();
+
+	Spanned::new(v, Span(p.source.clone(), start, end))
+}
+
+fn assert_stmt(p: &mut Parser<'_>) -> AssertStmt {
+	p.eat(T![assert]);
+	let cond = spanned(p, expr);
+	dbg!(p.peek());
+	let msg = if p.try_eat(T![:]) {
+		Some(spanned(p, expr))
+	} else {
+		None
+	};
+	dbg!(AssertStmt(cond, msg))
+}
+
+fn if_spec_data(p: &mut Parser<'_>) -> IfSpecData {
+	let v = spanned(p, |p| p.eat(T![if]));
+	let cond = expr(p);
+	IfSpecData { span: v.span, cond }
+}
+
+fn if_else(p: &mut Parser<'_>) -> IfElse {
+	let cond = if_spec_data(p);
+	p.eat(T![then]);
+	let cond_then = expr(p);
+	let cond_else = if p.at(T![else]) { Some(expr(p)) } else { None };
+	IfElse {
+		cond,
+		cond_then,
+		cond_else,
+	}
+}
+
+fn slice_desc(p: &mut Parser<'_>, start: Option<Spanned<Expr>>) -> SliceDesc {
+	// start
+	p.eat(T![:]);
+	let end = if !p.at(T![:]) && !p.at(T![']']) {
+		Some(spanned(p, expr))
+	} else {
+		None
+	};
+	let step = if p.try_eat(T![:]) && !p.at(T![']']) {
+		Some(spanned(p, expr))
+	} else {
+		None
+	};
+	SliceDesc { start, end, step }
+}
+
+fn expr_simple(p: &mut Parser<'_>) -> Expr {
+	let mut e = if let Some(literal) = literal(p) {
+		Expr::Literal(literal)
+	} else if p.at(T![assert]) {
+		let assert = assert_stmt(p);
+		p.eat(T![;]);
+		let rest = expr(p);
+		Expr::AssertExpr(Rc::new(AssertExpr { assert, rest }))
+	} else if p.at(T![if]) {
+		Expr::IfElse(Box::new(if_else(p)))
+	} else {
+		panic!("unexpected token: {:?}", p.peek());
+	};
+
+	dbg!(&e);
+
+	loop {
+		if p.try_eat(T!['[']) {
+			if p.at(T![:]) {
+				let slice = slice_desc(p, None);
+				e = Expr::Slice(Box::new(Slice { value: e, slice }));
+				p.eat(T![']']);
+				continue;
+			}
+
+			let idx = spanned(p, expr);
+			if p.at(T![:]) {
+				let slice = slice_desc(p, Some(idx));
+				e = Expr::Slice(Box::new(Slice { value: e, slice }));
+			} else {
+			}
+			p.eat(T![']']);
+		} else {
+			break;
+		}
+	}
+
+	dbg!(e)
+}
+
+fn expr(p: &mut Parser<'_>) -> Expr {
+	expr_simple(p)
+}
+
+#[test]
+fn basic_test() {
+	let mut parser = Parser::new(" assert true[false] : false ; true ");
+	let e = expr(&mut parser);
+	let l = &parser.lexemes;
+
+	assert_snapshot!(format!("{l:#?}\n\n---\n\n{e:#?}"));
+}
addedcrates/jrsonnet-ir-parser/src/snapshots/jrsonnet_ir_parser__basic_test.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-ir-parser/src/snapshots/jrsonnet_ir_parser__basic_test.snap
@@ -0,0 +1,98 @@
+---
+source: crates/jrsonnet-ir-parser/src/lib.rs
+expression: "format!(\"{l:#?}\\n\\n---\\n\\n{e:#?}\")"
+---
+[
+    Lexeme {
+        kind: ASSERT_KW,
+        text: "assert",
+        range: Span(
+            1,
+            7,
+        ),
+    },
+    Lexeme {
+        kind: TRUE_KW,
+        text: "true",
+        range: Span(
+            8,
+            12,
+        ),
+    },
+    Lexeme {
+        kind: L_BRACK,
+        text: "[",
+        range: Span(
+            12,
+            13,
+        ),
+    },
+    Lexeme {
+        kind: FALSE_KW,
+        text: "false",
+        range: Span(
+            13,
+            18,
+        ),
+    },
+    Lexeme {
+        kind: R_BRACK,
+        text: "]",
+        range: Span(
+            18,
+            19,
+        ),
+    },
+    Lexeme {
+        kind: COLON,
+        text: ":",
+        range: Span(
+            20,
+            21,
+        ),
+    },
+    Lexeme {
+        kind: FALSE_KW,
+        text: "false",
+        range: Span(
+            22,
+            27,
+        ),
+    },
+    Lexeme {
+        kind: SEMI,
+        text: ";",
+        range: Span(
+            28,
+            29,
+        ),
+    },
+    Lexeme {
+        kind: TRUE_KW,
+        text: "true",
+        range: Span(
+            30,
+            34,
+        ),
+    },
+]
+
+---
+
+AssertExpr(
+    AssertExpr {
+        assert: AssertStmt(
+            Literal(
+                True,
+            ) from virtual:<test>:8-19,
+            Some(
+                Literal(
+                    False,
+                ) from virtual:<test>:22-27,
+            ),
+        ),
+        rest: Literal(
+            True,
+        ),
+    },
+)
modifiedcrates/jrsonnet-ir/src/expr.rsdiffbeforeafterboth
--- a/crates/jrsonnet-ir/src/expr.rs
+++ b/crates/jrsonnet-ir/src/expr.rs
@@ -42,7 +42,7 @@
 
 #[derive(Debug, PartialEq, Acyclic)]
 pub struct FieldMember {
-	pub name: FieldName,
+	pub name: Spanned<FieldName>,
 	pub plus: bool,
 	pub params: Option<ExprParams>,
 	pub visibility: Visibility,
@@ -295,15 +295,21 @@
 }
 
 #[derive(Debug, PartialEq, Acyclic)]
-pub struct IfSpecData(pub Expr);
+pub struct IfSpecData {
+	pub span: Span,
+	pub cond: Expr,
+}
 
 #[derive(Debug, PartialEq, Acyclic)]
-pub struct ForSpecData(pub Destruct, pub Expr);
+pub struct ForSpecData {
+	pub destruct: Destruct,
+	pub over: Expr,
+}
 
 #[derive(Debug, PartialEq, Acyclic)]
 pub enum CompSpec {
-	IfSpec(Spanned<IfSpecData>),
-	ForSpec(Spanned<ForSpecData>),
+	IfSpec(IfSpecData),
+	ForSpec(ForSpecData),
 }
 
 #[derive(Debug, PartialEq, Acyclic)]
@@ -462,21 +468,20 @@
 }
 
 #[derive(Clone, PartialEq, Acyclic)]
-pub struct Spanned<T: Acyclic>(pub T, pub Span);
+pub struct Spanned<T: Acyclic> {
+	pub value: T,
+	pub span: Span,
+}
 impl<T: Acyclic> Deref for Spanned<T> {
 	type Target = T;
 	fn deref(&self) -> &Self::Target {
-		&self.0
+		&self.value
 	}
 }
 impl<T: Acyclic> Spanned<T> {
 	#[inline]
-	pub fn new(v: T, s: Span) -> Self {
-		Self(v, s)
-	}
-	#[inline]
-	pub fn span(&self) -> Span {
-		self.1.clone()
+	pub fn new(value: T, span: Span) -> Self {
+		Self { value, span }
 	}
 }
 
@@ -488,7 +493,7 @@
 		} else {
 			write!(f, "{:?}", expr)?;
 		}
-		write!(f, " from {:?}", self.span())?;
+		write!(f, " from {:?}", self.span)?;
 		Ok(())
 	}
 }
modifiedcrates/jrsonnet-peg-parser/src/lib.rsdiffbeforeafterboth
before · crates/jrsonnet-peg-parser/src/lib.rs
1use jrsonnet_gcmodule::Acyclic;2use jrsonnet_ir::{3	unescape, ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BindSpec, CompSpec, Destruct,4	DestructRest, Expr, ExprParam, ExprParams, FieldMember, FieldName, ForSpecData, IStr, IfElse,5	IfSpecData, ImportKind, IndexPart, LiteralType, Member, ObjBody, ObjComp, ObjMembers, Slice,6	SliceDesc, Source, Span, Spanned, Visibility,7};8use peg::parser;9use std::rc::Rc;1011pub struct ParserSettings {12	pub source: Source,13}1415macro_rules! expr_bin {16	($a:ident $op:ident $b:ident) => {17		Expr::BinaryOp(Box::new(BinaryOp {18			lhs: $a,19			op: $op,20			rhs: $b,21		}))22	};23}24macro_rules! expr_un {25	($op:ident $a:ident) => {26		Expr::UnaryOp($op, Box::new($a))27	};28}2930parser! {31	grammar jsonnet_parser() for str {32		use peg::ParseLiteral;3334		rule eof() = quiet!{![_]} / expected!("<eof>")35		rule eol() = "\n" / eof()3637		/// Standard C-like comments38		rule comment()39			= "//" (!eol()[_])* eol()40			/ "/*" (!("*/")[_])* "*/"41			/ "#" (!eol()[_])* eol()4243		rule single_whitespace() = quiet!{([' ' | '\r' | '\n' | '\t'] / comment())} / expected!("<whitespace>")44		rule _() = quiet!{([' ' | '\r' | '\n' | '\t']+) / comment()}* / expected!("<whitespace>")4546		/// For comma-delimited elements47		rule comma() = quiet!{_ "," _} / expected!("<comma>")48		rule alpha() -> char = c:$(['_' | 'a'..='z' | 'A'..='Z']) {c.chars().next().unwrap()}49		rule digit() -> char = d:$(['0'..='9']) {d.chars().next().unwrap()}50		rule end_of_ident() = !['0'..='9' | '_' | 'a'..='z' | 'A'..='Z']51		/// Sequence of digits52		rule uint_str() -> &'input str = a:$(digit()+ ("_" digit()+)*) { a }53		/// Number in scientific notation format54		rule number() -> f64 = quiet!{a:$(uint_str() ("." uint_str())? (['e'|'E'] (s:['+'|'-'])? uint_str())?) {? a.replace("_","").parse().map_err(|_| "<number>") }} / expected!("<number>")5556		/// Reserved word followed by any non-alphanumberic57		rule reserved() = ("assert" / "else" / "error" / "false" / "for" / "function" / "if" / "import" / "importstr" / "importbin" / "in" / "local" / "null" / "tailstrict" / "then" / "self" / "super" / "true") end_of_ident()58		rule id() -> IStr = v:$(quiet!{ !reserved() alpha() (alpha() / digit())*} / expected!("<identifier>")) { v.into() }5960		rule keyword(id: &'static str) -> ()61			= ##parse_string_literal(id) end_of_ident()6263		pub rule param(s: &ParserSettings) -> ExprParam = destruct:destruct(s) expr:(_ "=" _ expr:expr(s){expr})? { ExprParam { destruct, default: expr.map(Rc::new) } }64		pub rule params(s: &ParserSettings) -> ExprParams65			= params:param(s) ** comma() comma()? { ExprParams::new(params) }66			/ { ExprParams::new(Vec::new()) }6768		pub rule arg(s: &ParserSettings) -> (Option<IStr>, Rc<Expr>)69			= name:(quiet! { (s:id() _ "=" !['='] _ {s})? } / expected!("<argument name>")) expr:expr(s) {(name, Rc::new(expr))}7071		pub rule args(s: &ParserSettings) -> ArgsDesc72			= args:arg(s)**comma() comma()? {?73				let unnamed_count = args.iter().take_while(|(n, _)| n.is_none()).count();74				let mut unnamed = Vec::with_capacity(unnamed_count);75				let mut named = Vec::with_capacity(args.len() - unnamed_count);76				let mut named_started = false;77				for (name, value) in args {78					if let Some(name) = name {79						named_started = true;80						named.push((name, value));81					} else {82						if named_started {83							return Err("<named argument>")84						}85						unnamed.push(value);86					}87				}88				Ok(ArgsDesc::new(unnamed, named))89			}9091		pub rule destruct_rest() -> DestructRest92			= "..." into:(_ into:id() {into})? {if let Some(into) = into {93				DestructRest::Keep(into)94			} else {DestructRest::Drop}}95		pub rule destruct_array(s: &ParserSettings) -> Destruct96			= "[" _ start:destruct(s)**comma() rest:(97				comma() _ rest:destruct_rest()? end:(98					comma() end:destruct(s)**comma() (_ comma())? {end}99					/ comma()? {Vec::new()}100				) {(rest, end)}101				/ comma()? {(None, Vec::new())}102			) _ "]" {?103				#[cfg(feature = "exp-destruct")] return Ok(expr::Destruct::Array {104					start,105					rest: rest.0,106					end: rest.1,107				});108				#[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")109			}110		pub rule destruct_object(s: &ParserSettings) -> Destruct111			= "{" _112				fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:expr(s) {v})? {(name, into, default.map(Rc::new))})**comma()113				rest:(114					comma() rest:destruct_rest()? {rest}115					/ comma()? {None}116				)117			_ "}" {?118				#[cfg(feature = "exp-destruct")] return Ok(expr::Destruct::Object {119					fields,120					rest,121				});122				#[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")123			}124		pub rule destruct(s: &ParserSettings) -> Destruct125			= v:id() {Destruct::Full(v)}126			/ "?" {?127				#[cfg(feature = "exp-destruct")] return Ok(expr::Destruct::Skip);128				#[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")129			}130			/ arr:destruct_array(s) {arr}131			/ obj:destruct_object(s) {obj}132133		pub rule bind(s: &ParserSettings) -> BindSpec134			= into:destruct(s) _ "=" _ value:expr(s) {BindSpec::Field{into, value: Rc::new(value)}}135			/ name:id() _ "(" _ params:params(s) _ ")" _ "=" _ value:expr(s) {BindSpec::Function{name, params, value: Rc::new(value)}}136137		pub rule assertion(s: &ParserSettings) -> AssertStmt138			= keyword("assert") _ cond:spanned(<expr(s)>, s) msg:(_ ":" _ e:spanned(<expr(s)>, s) {e})? { AssertStmt(cond, msg) }139140		pub rule whole_line() -> &'input str141			= str:$((!['\n'][_])* "\n") {str}142		pub rule string_block() -> String143			= "|||" chomped:"-"? (!['\n']single_whitespace())* "\n"144			empty_lines:$(['\n']*)145			prefix:[' ' | '\t']+ first_line:whole_line()146			lines:("\n" {"\n"} / [' ' | '\t']*<{prefix.len()}> s:whole_line() {s})*147			[' ' | '\t']*<, {prefix.len() - 1}> "|||"148			{149				let mut l = empty_lines.to_owned();150				l.push_str(first_line);151				l.extend(lines);152				if chomped.is_some() {153					debug_assert!(l.ends_with('\n'));154					l.truncate(l.len() - 1);155				}156				l157			}158159		rule hex_char()160			= quiet! { ['0'..='9' | 'a'..='f' | 'A'..='F'] } / expected!("<hex char>")161162		rule string_char(c: rule<()>)163			= (!['\\']!c()[_])+164			/ "\\\\"165			/ "\\u" hex_char() hex_char() hex_char() hex_char()166			/ "\\x" hex_char() hex_char()167			/ ['\\'] (quiet! { ['b' | 'f' | 'n' | 'r' | 't' | '"' | '\''] } / expected!("<escape character>"))168		pub rule string() -> String169			= ['"'] str:$(string_char(<"\"">)*) ['"'] {? unescape::unescape(str).ok_or("<escaped string>")}170			/ ['\''] str:$(string_char(<"\'">)*) ['\''] {? unescape::unescape(str).ok_or("<escaped string>")}171			/ quiet!{ "@'" str:$(("''" / (!['\''][_]))*) "'" {str.replace("''", "'")}172			/ "@\"" str:$(("\"\"" / (!['"'][_]))*) "\"" {str.replace("\"\"", "\"")}173			/ string_block() } / expected!("<string>")174175		pub rule field_name(s: &ParserSettings) -> FieldName176			= name:id() {FieldName::Fixed(name)}177			/ name:string() {FieldName::Fixed(name.into())}178			/ "[" _ expr:expr(s) _ "]" {FieldName::Dyn(expr)}179		pub rule visibility() -> Visibility180			= ":::" {Visibility::Unhide}181			/ "::" {Visibility::Hidden}182			/ ":" {Visibility::Normal}183		pub rule field(s: &ParserSettings) -> FieldMember184			= name:field_name(s) _ plus:"+"? _ visibility:visibility() _ value:expr(s) {FieldMember{185				name,186				plus: plus.is_some(),187				params: None,188				visibility,189				value: Rc::new(value),190			}}191			/ name:field_name(s) _ "(" _ params:params(s) _ ")" _ visibility:visibility() _ value:expr(s) {FieldMember{192				name,193				plus: false,194				params: Some(params),195				visibility,196				value: Rc::new(value),197			}}198		pub rule obj_local(s: &ParserSettings) -> BindSpec199			= keyword("local") _ bind:bind(s) {bind}200		pub rule member(s: &ParserSettings) -> Member201			= bind:obj_local(s) {Member::BindStmt(bind)}202			/ assertion:assertion(s) {Member::AssertStmt(assertion)}203			/ field:field(s) {Member::Field(field)}204		pub rule objinside(s: &ParserSettings) -> ObjBody205			=  members:(member(s) ** comma()) comma()? _ compspecs:compspecs(s)? {?206				Ok(if let Some(compspecs) = compspecs {207					let mut locals = Vec::new();208					let mut field = None;209					for member in members {210						match member {211							Member::Field(field_member) => if field.replace(field_member).is_some() {212								return Err("<object comprehension can only contain one field>")213							},214							Member::BindStmt(bind_spec) => locals.push(bind_spec),215							Member::AssertStmt(assert_stmt) => return Err("<asserts are unsupported in object comprehension>"),216						}217					}218					ObjBody::ObjComp(ObjComp {219						locals: Rc::new(locals),220						field: field.map(Rc::new).ok_or("<missing object comprehension field>")?,221						compspecs222					})223				} else {224					let mut locals = Vec::new();225					let mut asserts = Vec::new();226					let mut fields = Vec::new();227					for member in members {228						match member {229							Member::Field(field_member) => fields.push(field_member),230							Member::BindStmt(bind_spec) => locals.push(bind_spec),231							Member::AssertStmt(assert_stmt) => asserts.push(assert_stmt),232						}233					}234					ObjBody::MemberList(ObjMembers {235						locals: Rc::new(locals),236						asserts: Rc::new(asserts),237						fields238					})239				})240			}241		pub rule ifspec(s: &ParserSettings) -> IfSpecData242			= keyword("if") _ expr:expr(s) {IfSpecData(expr)}243		pub rule forspec(s: &ParserSettings) -> ForSpecData244			= keyword("for") _ id:destruct(s) _ keyword("in") _ cond:expr(s) {ForSpecData(id, cond)}245		rule compspec(s: &ParserSettings) -> CompSpec246			= i:spanned(<ifspec(s)>, s) { CompSpec::IfSpec(i) } / f:spanned(<forspec(s)>, s) {CompSpec::ForSpec(f)}247		pub rule compspecs(s: &ParserSettings) -> Vec<CompSpec>248			= specs:compspec(s) ++ _ {?249				if !matches!(specs[0], CompSpec::ForSpec(_)) {250					return Err("<first compspec should be for>")251				}252				Ok(specs)253			}254		pub rule local_expr(s: &ParserSettings) -> Expr255			= keyword("local") _ binds:bind(s) ** comma() (_ ",")? _ ";" _ expr:expr(s) { Expr::LocalExpr(binds, Box::new(expr)) }256		pub rule string_expr(s: &ParserSettings) -> Expr257			= s:string() {Expr::Str(s.into())}258		pub rule obj_expr(s: &ParserSettings) -> Expr259			= "{" _ body:objinside(s) _ "}" {Expr::Obj(body)}260		pub rule array_expr(s: &ParserSettings) -> Expr261			= "[" _ elems:(expr(s) ** comma()) _ comma()? "]" {Expr::Arr(Rc::new(elems))}262		pub rule array_comp_expr(s: &ParserSettings) -> Expr263			= "[" _ expr:expr(s) _ comma()? _ specs:(r: compspecs(s) _ {r}) "]" {264				Expr::ArrComp(Rc::new(expr), specs)265			}266		pub rule number_expr(s: &ParserSettings) -> Expr267			= n:number() {? if n.is_finite() {268				Ok(Expr::Num(n))269			} else {270				Err("!!!numbers are finite")271			}}272273		rule spanned<T: Acyclic>(x: rule<T>, s: &ParserSettings) -> Spanned<T>274			= a:position!() n:x() b:position!() { Spanned::new(n, Span(s.source.clone(), a as u32, b as u32)) }275276		pub rule var_expr(s: &ParserSettings) -> Expr277			= n:spanned(<id()>, s) { Expr::Var(n) }278		pub rule id_loc(s: &ParserSettings) -> Spanned<Expr>279			= a:position!() n:id() b:position!() { Spanned::new(Expr::Str(n), Span(s.source.clone(), a as u32,b as u32)) }280		pub rule if_then_else_expr(s: &ParserSettings) -> Expr281			= cond:ifspec(s) _ keyword("then") _ cond_then:expr(s) cond_else:(_ keyword("else") _ e:expr(s) {e})? {Expr::IfElse(Box::new(IfElse{282				cond,283				cond_then,284				cond_else,285			}))}286287		pub rule literal(s: &ParserSettings) -> Expr288			= v:(289				keyword("null") {LiteralType::Null}290				/ keyword("true") {LiteralType::True}291				/ keyword("false") {LiteralType::False}292				/ keyword("self") {LiteralType::This}293				/ keyword("$") {LiteralType::Dollar}294				/ keyword("super") {LiteralType::Super}295			) {Expr::Literal(v)}296297		rule import_kind() -> ImportKind298			= keyword("importstr") { ImportKind::Str }299			/ keyword("importbin") { ImportKind::Bin }300			/ keyword("import") { ImportKind::Normal }301302		pub rule expr_basic(s: &ParserSettings) -> Expr303			= literal(s)304305			/ string_expr(s) / number_expr(s)306			/ array_expr(s)307			/ obj_expr(s)308			/ array_expr(s)309			/ array_comp_expr(s)310311			/ kind:spanned(<import_kind()>, s) _ path:expr(s) {Expr::Import(kind, Box::new(path))}312313			/ var_expr(s)314			/ local_expr(s)315			/ if_then_else_expr(s)316317			/ keyword("function") _ "(" _ params:params(s) _ ")" _ expr:expr(s) {Expr::Function(params, Rc::new(expr))}318			/ assert:assertion(s) _ ";" _ rest:expr(s) { Expr::AssertExpr(Rc::new(AssertExpr{319				assert, rest320			})) }321322			/ err_kw:spanned(<keyword("error")>, s) _ expr:expr(s) { Expr::ErrorStmt(err_kw.1, Box::new(expr)) }323324		rule slice_part(s: &ParserSettings) -> Option<Spanned<Expr>>325			= _ e:(e:spanned(<expr(s)>, s) _{e})? {e}326		pub rule slice_desc(s: &ParserSettings) -> SliceDesc327			= start:slice_part(s) ":" pair:(end:slice_part(s) step:(":" e:slice_part(s){e})? {(end, step.flatten())})? {328				let (end, step) = if let Some((end, step)) = pair {329					(end, step)330				}else{331					(None, None)332				};333334				SliceDesc { start, end, step }335			}336337		rule binop(x: rule<()>) -> ()338			= quiet!{ x() } / expected!("<binary op>")339		rule unaryop(x: rule<()>) -> ()340			= quiet!{ x() } / expected!("<unary op>")341342		rule ensure_null_coaelse()343			= "" {?344				#[cfg(not(feature = "exp-null-coaelse"))] return Err("!!!experimental null coaelscing was not enabled");345				#[cfg(feature = "exp-null-coaelse")] Ok(())346			}347		use jrsonnet_ir::BinaryOpType::*;348		use jrsonnet_ir::UnaryOpType::*;349		rule expr(s: &ParserSettings) -> Expr350			= precedence! {351				a:(@) _ binop(<"||">) _ b:@ {expr_bin!(a Or b)}352				a:(@) _ binop(<"??">) _ ensure_null_coaelse() b:@ {353					#[cfg(feature = "exp-null-coaelse")] return expr_bin!(a NullCoaelse b);354					unreachable!("ensure_null_coaelse will fail if feature is not enabled")355				}356				--357				a:(@) _ binop(<"&&">) _ b:@ {expr_bin!(a And b)}358				--359				a:(@) _ binop(<"|">) _ b:@ {expr_bin!(a BitOr b)}360				--361				a:@ _ binop(<"^">) _ b:(@) {expr_bin!(a BitXor b)}362				--363				a:(@) _ binop(<"&">) _ b:@ {expr_bin!(a BitAnd b)}364				--365				a:(@) _ binop(<"==">) _ b:@ {expr_bin!(a Eq b)}366				a:(@) _ binop(<"!=">) _ b:@ {expr_bin!(a Neq b)}367				--368				a:(@) _ binop(<"<">) _ b:@ {expr_bin!(a Lt b)}369				a:(@) _ binop(<">">) _ b:@ {expr_bin!(a Gt b)}370				a:(@) _ binop(<"<=">) _ b:@ {expr_bin!(a Lte b)}371				a:(@) _ binop(<">=">) _ b:@ {expr_bin!(a Gte b)}372				a:(@) _ binop(<keyword("in")>) _ b:@ {expr_bin!(a In b)}373				--374				a:(@) _ binop(<"<<">) _ b:@ {expr_bin!(a Lhs b)}375				a:(@) _ binop(<">>">) _ b:@ {expr_bin!(a Rhs b)}376				--377				a:(@) _ binop(<"+">) _ b:@ {expr_bin!(a Add b)}378				a:(@) _ binop(<"-">) _ b:@ {expr_bin!(a Sub b)}379				--380				a:(@) _ binop(<"*">) _ b:@ {expr_bin!(a Mul b)}381				a:(@) _ binop(<"/">) _ b:@ {expr_bin!(a Div b)}382				a:(@) _ binop(<"%">) _ b:@ {expr_bin!(a Mod b)}383				--384						unaryop(<"+">) _ b:@ {expr_un!(Plus b)}385						unaryop(<"-">) _ b:@ {expr_un!(Minus b)}386						unaryop(<"!">) _ b:@ {expr_un!(Not b)}387						unaryop(<"~">) _ b:@ {expr_un!(BitNot b)}388				--389				value:(@) _ "[" _ slice:slice_desc(s) _ "]" {Expr::Slice(Box::new(Slice{value, slice}))}390				indexable:(@) _ parts:index_part(s)+ {Expr::Index{indexable: Box::new(indexable), parts}}391				a:(@) _ args:spanned(<"(" _ a:args(s) _ ")" {a}>, s) ts:(_ keyword("tailstrict"))? {Expr::Apply(Box::new(a), args, ts.is_some())}392				a:(@) _ "{" _ body:objinside(s) _ "}" {Expr::ObjExtend(Rc::new(a), body)}393				--394				e:expr_basic(s) {e}395				"(" _ e:expr(s) _ ")" {e}396			}397		pub rule index_part(s: &ParserSettings) -> IndexPart398		= n:("?" _ ensure_null_coaelse())? "." _ value:id_loc(s) {IndexPart {399			span: value.1,400			value: value.0,401			#[cfg(feature = "exp-null-coaelse")]402			null_coaelse: n.is_some(),403		}}404		/ n:("?" _ "." _ ensure_null_coaelse())? value:spanned(<"[" _ v:expr(s) _ "]" {v}>, s) {IndexPart {405			span: value.1,406			value: value.0,407			#[cfg(feature = "exp-null-coaelse")]408			null_coaelse: n.is_some(),409		}}410411		pub rule jsonnet(s: &ParserSettings) -> Expr = _ e:expr(s) _ {e}412	}413}414415pub type ParseError = peg::error::ParseError<peg::str::LineCol>;416pub fn parse(str: &str, settings: &ParserSettings) -> Result<Expr, ParseError> {417	jsonnet_parser::jsonnet(str, settings)418}419/// Used for importstr values420pub fn string_to_expr(str: IStr, settings: &ParserSettings) -> Spanned<Expr> {421	let len = str.len();422	Spanned::new(Expr::Str(str), Span(settings.source.clone(), 0, len as u32))423}424425#[cfg(test)]426pub mod tests {427	use insta::assert_snapshot;428	use jrsonnet_ir::{IStr, Source};429430	use super::parse;431	use crate::ParserSettings;432433	fn parsep(s: &str) -> String {434		let v = parse(435			s,436			&ParserSettings {437				source: Source::new_virtual("<test>".into(), IStr::empty()),438			},439		)440		.unwrap();441		format!("{v:#?}")442	}443444	macro_rules! parse {445		($s:expr) => {446			assert_snapshot!(parsep($s));447		};448	}449450	#[test]451	fn multiline_string() {452		parse!("|||\n    Hello world!\n     a\n|||");453		parse!("|||\n  Hello world!\n   a\n|||");454		parse!("|||\n\t\tHello world!\n\t\t\ta\n|||");455		parse!("|||\n   Hello world!\n    a\n |||");456	}457458	#[test]459	fn slice() {460		parse!("a[1:]");461		parse!("a[1::]");462		parse!("a[:1:]");463		parse!("a[::1]");464		parse!("str[:len - 1]");465	}466467	#[test]468	fn string_escaping() {469		parse!(r#""Hello, \"world\"!""#);470		parse!(r#"'Hello \'world\'!'"#);471		parse!(r#"'\\\\'"#);472	}473474	#[test]475	fn string_unescaping() {476		parse!(r#""Hello\nWorld""#);477	}478479	#[test]480	fn string_verbantim() {481		parse!(r#"@"Hello\n""World""""#);482	}483484	#[test]485	fn imports() {486		parse!("import \"hello\"");487		parse!("importstr \"garnish.txt\"");488		parse!("importbin \"garnish.bin\"");489	}490491	#[test]492	fn empty_object() {493		parse!("{}");494	}495496	#[test]497	fn basic_math() {498		parse!("2+2*2");499		parse!("2	+ 	  2	  *	2   	");500		parse!("2+(2+2*2)");501		parse!("2//comment\n+//comment\n3/*test*/*/*test*/4");502	}503504	#[test]505	fn suffix() {506		parse!("std.test");507		parse!("std(2)");508		parse!("std.test(2)");509		parse!("a[b]");510	}511512	#[test]513	fn array_comp() {514		parse!("[std.deepJoin(x) for x in arr]");515	}516517	#[test]518	fn reserved() {519		parse!("null");520		parse!("nulla");521	}522523	#[test]524	fn multiple_args_buf() {525		parse!("a(b, null_fields)");526	}527528	#[test]529	fn infix_precedence() {530		parse!("!a && !b");531		parse!("!a / !b");532	}533534	#[test]535	fn double_negation() {536		parse!("!!a");537	}538539	#[test]540	fn array_test_error() {541		parse!("[a for a in b if c for e in f]");542	}543544	#[test]545	fn missing_newline_between_comment_and_eof() {546		parse!(547			"{a:1}548549			//+213"550		);551	}552553	#[test]554	fn default_param_before_nondefault() {555		parse!("local x(foo = 'foo', bar) = null; null");556	}557558	#[test]559	fn add_location_info_to_all_sub_expressions() {560		parse!("{} { local x = 1, x: x } + {}");561	}562}
after · crates/jrsonnet-peg-parser/src/lib.rs
1use jrsonnet_gcmodule::Acyclic;2use jrsonnet_ir::{3	unescape, ArgsDesc, AssertExpr, AssertStmt, BinaryOp, BindSpec, CompSpec, Destruct,4	DestructRest, Expr, ExprParam, ExprParams, FieldMember, FieldName, ForSpecData, IStr, IfElse,5	IfSpecData, ImportKind, IndexPart, LiteralType, Member, ObjBody, ObjComp, ObjMembers, Slice,6	SliceDesc, Source, Span, Spanned, Visibility,7};8use peg::parser;9use std::rc::Rc;1011pub struct ParserSettings {12	pub source: Source,13}1415macro_rules! expr_bin {16	($a:ident $op:ident $b:ident) => {17		Expr::BinaryOp(Box::new(BinaryOp {18			lhs: $a,19			op: $op,20			rhs: $b,21		}))22	};23}24macro_rules! expr_un {25	($op:ident $a:ident) => {26		Expr::UnaryOp($op, Box::new($a))27	};28}2930parser! {31	grammar jsonnet_parser() for str {32		use peg::ParseLiteral;3334		rule eof() = quiet!{![_]} / expected!("<eof>")35		rule eol() = "\n" / eof()3637		/// Standard C-like comments38		rule comment()39			= "//" (!eol()[_])* eol()40			/ "/*" (!("*/")[_])* "*/"41			/ "#" (!eol()[_])* eol()4243		rule single_whitespace() = quiet!{([' ' | '\r' | '\n' | '\t'] / comment())} / expected!("<whitespace>")44		rule _() = quiet!{([' ' | '\r' | '\n' | '\t']+) / comment()}* / expected!("<whitespace>")4546		/// For comma-delimited elements47		rule comma() = quiet!{_ "," _} / expected!("<comma>")48		rule alpha() -> char = c:$(['_' | 'a'..='z' | 'A'..='Z']) {c.chars().next().unwrap()}49		rule digit() -> char = d:$(['0'..='9']) {d.chars().next().unwrap()}50		rule end_of_ident() = !['0'..='9' | '_' | 'a'..='z' | 'A'..='Z']51		/// Sequence of digits52		rule uint_str() -> &'input str = a:$(digit()+ ("_" digit()+)*) { a }53		/// Number in scientific notation format54		rule number() -> f64 = quiet!{a:$(uint_str() ("." uint_str())? (['e'|'E'] (s:['+'|'-'])? uint_str())?) {? a.replace("_","").parse().map_err(|_| "<number>") }} / expected!("<number>")5556		/// Reserved word followed by any non-alphanumberic57		rule reserved() = ("assert" / "else" / "error" / "false" / "for" / "function" / "if" / "import" / "importstr" / "importbin" / "in" / "local" / "null" / "tailstrict" / "then" / "self" / "super" / "true") end_of_ident()58		rule id() -> IStr = v:$(quiet!{ !reserved() alpha() (alpha() / digit())*} / expected!("<identifier>")) { v.into() }5960		rule keyword(id: &'static str) -> ()61			= ##parse_string_literal(id) end_of_ident()6263		pub rule param(s: &ParserSettings) -> ExprParam = destruct:destruct(s) expr:(_ "=" _ expr:expr(s){expr})? { ExprParam { destruct, default: expr.map(Rc::new) } }64		pub rule params(s: &ParserSettings) -> ExprParams65			= params:param(s) ** comma() comma()? { ExprParams::new(params) }66			/ { ExprParams::new(Vec::new()) }6768		pub rule arg(s: &ParserSettings) -> (Option<IStr>, Rc<Expr>)69			= name:(quiet! { (s:id() _ "=" !['='] _ {s})? } / expected!("<argument name>")) expr:expr(s) {(name, Rc::new(expr))}7071		pub rule args(s: &ParserSettings) -> ArgsDesc72			= args:arg(s)**comma() comma()? {?73				let unnamed_count = args.iter().take_while(|(n, _)| n.is_none()).count();74				let mut unnamed = Vec::with_capacity(unnamed_count);75				let mut named = Vec::with_capacity(args.len() - unnamed_count);76				let mut named_started = false;77				for (name, value) in args {78					if let Some(name) = name {79						named_started = true;80						named.push((name, value));81					} else {82						if named_started {83							return Err("<named argument>")84						}85						unnamed.push(value);86					}87				}88				Ok(ArgsDesc::new(unnamed, named))89			}9091		pub rule destruct_rest() -> DestructRest92			= "..." into:(_ into:id() {into})? {if let Some(into) = into {93				DestructRest::Keep(into)94			} else {DestructRest::Drop}}95		pub rule destruct_array(s: &ParserSettings) -> Destruct96			= "[" _ start:destruct(s)**comma() rest:(97				comma() _ rest:destruct_rest()? end:(98					comma() end:destruct(s)**comma() (_ comma())? {end}99					/ comma()? {Vec::new()}100				) {(rest, end)}101				/ comma()? {(None, Vec::new())}102			) _ "]" {?103				#[cfg(feature = "exp-destruct")] return Ok(expr::Destruct::Array {104					start,105					rest: rest.0,106					end: rest.1,107				});108				#[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")109			}110		pub rule destruct_object(s: &ParserSettings) -> Destruct111			= "{" _112				fields:(name:id() into:(_ ":" _ into:destruct(s) {into})? default:(_ "=" _ v:expr(s) {v})? {(name, into, default.map(Rc::new))})**comma()113				rest:(114					comma() rest:destruct_rest()? {rest}115					/ comma()? {None}116				)117			_ "}" {?118				#[cfg(feature = "exp-destruct")] return Ok(expr::Destruct::Object {119					fields,120					rest,121				});122				#[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")123			}124		pub rule destruct(s: &ParserSettings) -> Destruct125			= v:id() {Destruct::Full(v)}126			/ "?" {?127				#[cfg(feature = "exp-destruct")] return Ok(expr::Destruct::Skip);128				#[cfg(not(feature = "exp-destruct"))] Err("!!!experimental destructuring was not enabled")129			}130			/ arr:destruct_array(s) {arr}131			/ obj:destruct_object(s) {obj}132133		pub rule bind(s: &ParserSettings) -> BindSpec134			= into:destruct(s) _ "=" _ value:expr(s) {BindSpec::Field{into, value: Rc::new(value)}}135			/ name:id() _ "(" _ params:params(s) _ ")" _ "=" _ value:expr(s) {BindSpec::Function{name, params, value: Rc::new(value)}}136137		pub rule assertion(s: &ParserSettings) -> AssertStmt138			= keyword("assert") _ cond:spanned(<expr(s)>, s) msg:(_ ":" _ e:spanned(<expr(s)>, s) {e})? { AssertStmt(cond, msg) }139140		pub rule whole_line() -> &'input str141			= str:$((!['\n'][_])* "\n") {str}142		pub rule string_block() -> String143			= "|||" chomped:"-"? (!['\n']single_whitespace())* "\n"144			empty_lines:$(['\n']*)145			prefix:[' ' | '\t']+ first_line:whole_line()146			lines:("\n" {"\n"} / [' ' | '\t']*<{prefix.len()}> s:whole_line() {s})*147			[' ' | '\t']*<, {prefix.len() - 1}> "|||"148			{149				let mut l = empty_lines.to_owned();150				l.push_str(first_line);151				l.extend(lines);152				if chomped.is_some() {153					debug_assert!(l.ends_with('\n'));154					l.truncate(l.len() - 1);155				}156				l157			}158159		rule hex_char()160			= quiet! { ['0'..='9' | 'a'..='f' | 'A'..='F'] } / expected!("<hex char>")161162		rule string_char(c: rule<()>)163			= (!['\\']!c()[_])+164			/ "\\\\"165			/ "\\u" hex_char() hex_char() hex_char() hex_char()166			/ "\\x" hex_char() hex_char()167			/ ['\\'] (quiet! { ['b' | 'f' | 'n' | 'r' | 't' | '"' | '\''] } / expected!("<escape character>"))168		pub rule string() -> String169			= ['"'] str:$(string_char(<"\"">)*) ['"'] {? unescape::unescape(str).ok_or("<escaped string>")}170			/ ['\''] str:$(string_char(<"\'">)*) ['\''] {? unescape::unescape(str).ok_or("<escaped string>")}171			/ quiet!{ "@'" str:$(("''" / (!['\''][_]))*) "'" {str.replace("''", "'")}172			/ "@\"" str:$(("\"\"" / (!['"'][_]))*) "\"" {str.replace("\"\"", "\"")}173			/ string_block() } / expected!("<string>")174175		pub rule field_name(s: &ParserSettings) -> FieldName176			= name:id() {FieldName::Fixed(name)}177			/ name:string() {FieldName::Fixed(name.into())}178			/ "[" _ expr:expr(s) _ "]" {FieldName::Dyn(expr)}179		pub rule visibility() -> Visibility180			= ":::" {Visibility::Unhide}181			/ "::" {Visibility::Hidden}182			/ ":" {Visibility::Normal}183		pub rule field(s: &ParserSettings) -> FieldMember184			= name:spanned(<field_name(s)>, s) _ plus:"+"? _ visibility:visibility() _ value:expr(s) {FieldMember{185				name,186				plus: plus.is_some(),187				params: None,188				visibility,189				value: Rc::new(value),190			}}191			/ name:spanned(<field_name(s)>, s) _ "(" _ params:params(s) _ ")" _ visibility:visibility() _ value:expr(s) {FieldMember{192				name,193				plus: false,194				params: Some(params),195				visibility,196				value: Rc::new(value),197			}}198		pub rule obj_local(s: &ParserSettings) -> BindSpec199			= keyword("local") _ bind:bind(s) {bind}200		pub rule member(s: &ParserSettings) -> Member201			= bind:obj_local(s) {Member::BindStmt(bind)}202			/ assertion:assertion(s) {Member::AssertStmt(assertion)}203			/ field:field(s) {Member::Field(field)}204		pub rule objinside(s: &ParserSettings) -> ObjBody205			=  members:(member(s) ** comma()) comma()? _ compspecs:compspecs(s)? {?206				Ok(if let Some(compspecs) = compspecs {207					let mut locals = Vec::new();208					let mut field = None;209					for member in members {210						match member {211							Member::Field(field_member) => if field.replace(field_member).is_some() {212								return Err("<object comprehension can only contain one field>")213							},214							Member::BindStmt(bind_spec) => locals.push(bind_spec),215							Member::AssertStmt(assert_stmt) => return Err("<asserts are unsupported in object comprehension>"),216						}217					}218					ObjBody::ObjComp(ObjComp {219						locals: Rc::new(locals),220						field: field.map(Rc::new).ok_or("<missing object comprehension field>")?,221						compspecs222					})223				} else {224					let mut locals = Vec::new();225					let mut asserts = Vec::new();226					let mut fields = Vec::new();227					for member in members {228						match member {229							Member::Field(field_member) => fields.push(field_member),230							Member::BindStmt(bind_spec) => locals.push(bind_spec),231							Member::AssertStmt(assert_stmt) => asserts.push(assert_stmt),232						}233					}234					ObjBody::MemberList(ObjMembers {235						locals: Rc::new(locals),236						asserts: Rc::new(asserts),237						fields238					})239				})240			}241		pub rule ifspec(s: &ParserSettings) -> IfSpecData242			= i:spanned(<keyword("if")>, s) _ cond:expr(s) {IfSpecData { span: i.span, cond }}243		pub rule forspec(s: &ParserSettings) -> ForSpecData244			= keyword("for") _ destruct:destruct(s) _ keyword("in") _ over:expr(s) { ForSpecData { destruct, over } }245		rule compspec(s: &ParserSettings) -> CompSpec246			= i:ifspec(s) { CompSpec::IfSpec(i) } / f:forspec(s) {CompSpec::ForSpec(f)}247		pub rule compspecs(s: &ParserSettings) -> Vec<CompSpec>248			= specs:compspec(s) ++ _ {?249				if !matches!(specs[0], CompSpec::ForSpec(_)) {250					return Err("<first compspec should be for>")251				}252				Ok(specs)253			}254		pub rule local_expr(s: &ParserSettings) -> Expr255			= keyword("local") _ binds:bind(s) ** comma() (_ ",")? _ ";" _ expr:expr(s) { Expr::LocalExpr(binds, Box::new(expr)) }256		pub rule string_expr(s: &ParserSettings) -> Expr257			= s:string() {Expr::Str(s.into())}258		pub rule obj_expr(s: &ParserSettings) -> Expr259			= "{" _ body:objinside(s) _ "}" {Expr::Obj(body)}260		pub rule array_expr(s: &ParserSettings) -> Expr261			= "[" _ elems:(expr(s) ** comma()) _ comma()? "]" {Expr::Arr(Rc::new(elems))}262		pub rule array_comp_expr(s: &ParserSettings) -> Expr263			= "[" _ expr:expr(s) _ comma()? _ specs:(r: compspecs(s) _ {r}) "]" {264				Expr::ArrComp(Rc::new(expr), specs)265			}266		pub rule number_expr(s: &ParserSettings) -> Expr267			= n:number() {? if n.is_finite() {268				Ok(Expr::Num(n))269			} else {270				Err("!!!numbers are finite")271			}}272273		rule spanned<T: Acyclic>(x: rule<T>, s: &ParserSettings) -> Spanned<T>274			= a:position!() n:x() b:position!() { Spanned::new(n, Span(s.source.clone(), a as u32, b as u32)) }275276		pub rule var_expr(s: &ParserSettings) -> Expr277			= n:spanned(<id()>, s) { Expr::Var(n) }278		pub rule id_loc(s: &ParserSettings) -> Spanned<Expr>279			= a:position!() n:id() b:position!() { Spanned::new(Expr::Str(n), Span(s.source.clone(), a as u32,b as u32)) }280		pub rule if_then_else_expr(s: &ParserSettings) -> Expr281			= cond:ifspec(s) _ keyword("then") _ cond_then:expr(s) cond_else:(_ keyword("else") _ e:expr(s) {e})? {Expr::IfElse(Box::new(IfElse{282				cond,283				cond_then,284				cond_else,285			}))}286287		pub rule literal(s: &ParserSettings) -> Expr288			= v:(289				keyword("null") {LiteralType::Null}290				/ keyword("true") {LiteralType::True}291				/ keyword("false") {LiteralType::False}292				/ keyword("self") {LiteralType::This}293				/ keyword("$") {LiteralType::Dollar}294				/ keyword("super") {LiteralType::Super}295			) {Expr::Literal(v)}296297		rule import_kind() -> ImportKind298			= keyword("importstr") { ImportKind::Str }299			/ keyword("importbin") { ImportKind::Bin }300			/ keyword("import") { ImportKind::Normal }301302		pub rule expr_basic(s: &ParserSettings) -> Expr303			= literal(s)304305			/ string_expr(s) / number_expr(s)306			/ array_expr(s)307			/ obj_expr(s)308			/ array_expr(s)309			/ array_comp_expr(s)310311			/ kind:spanned(<import_kind()>, s) _ path:expr(s) {Expr::Import(kind, Box::new(path))}312313			/ var_expr(s)314			/ local_expr(s)315			/ if_then_else_expr(s)316317			/ keyword("function") _ "(" _ params:params(s) _ ")" _ expr:expr(s) {Expr::Function(params, Rc::new(expr))}318			/ assert:assertion(s) _ ";" _ rest:expr(s) { Expr::AssertExpr(Rc::new(AssertExpr{319				assert, rest320			})) }321322			/ err_kw:spanned(<keyword("error")>, s) _ expr:expr(s) { Expr::ErrorStmt(err_kw.span, Box::new(expr)) }323324		rule slice_part(s: &ParserSettings) -> Option<Spanned<Expr>>325			= _ e:(e:spanned(<expr(s)>, s) _{e})? {e}326		pub rule slice_desc(s: &ParserSettings) -> SliceDesc327			= start:slice_part(s) ":" pair:(end:slice_part(s) step:(":" e:slice_part(s){e})? {(end, step.flatten())})? {328				let (end, step) = if let Some((end, step)) = pair {329					(end, step)330				}else{331					(None, None)332				};333334				SliceDesc { start, end, step }335			}336337		rule binop(x: rule<()>) -> ()338			= quiet!{ x() } / expected!("<binary op>")339		rule unaryop(x: rule<()>) -> ()340			= quiet!{ x() } / expected!("<unary op>")341342		rule ensure_null_coaelse()343			= "" {?344				#[cfg(not(feature = "exp-null-coaelse"))] return Err("!!!experimental null coaelscing was not enabled");345				#[cfg(feature = "exp-null-coaelse")] Ok(())346			}347		use jrsonnet_ir::BinaryOpType::*;348		use jrsonnet_ir::UnaryOpType::*;349		rule expr(s: &ParserSettings) -> Expr350			= precedence! {351				a:(@) _ binop(<"||">) _ b:@ {expr_bin!(a Or b)}352				a:(@) _ binop(<"??">) _ ensure_null_coaelse() b:@ {353					#[cfg(feature = "exp-null-coaelse")] return expr_bin!(a NullCoaelse b);354					unreachable!("ensure_null_coaelse will fail if feature is not enabled")355				}356				--357				a:(@) _ binop(<"&&">) _ b:@ {expr_bin!(a And b)}358				--359				a:(@) _ binop(<"|">) _ b:@ {expr_bin!(a BitOr b)}360				--361				a:@ _ binop(<"^">) _ b:(@) {expr_bin!(a BitXor b)}362				--363				a:(@) _ binop(<"&">) _ b:@ {expr_bin!(a BitAnd b)}364				--365				a:(@) _ binop(<"==">) _ b:@ {expr_bin!(a Eq b)}366				a:(@) _ binop(<"!=">) _ b:@ {expr_bin!(a Neq b)}367				--368				a:(@) _ binop(<"<">) _ b:@ {expr_bin!(a Lt b)}369				a:(@) _ binop(<">">) _ b:@ {expr_bin!(a Gt b)}370				a:(@) _ binop(<"<=">) _ b:@ {expr_bin!(a Lte b)}371				a:(@) _ binop(<">=">) _ b:@ {expr_bin!(a Gte b)}372				a:(@) _ binop(<keyword("in")>) _ b:@ {expr_bin!(a In b)}373				--374				a:(@) _ binop(<"<<">) _ b:@ {expr_bin!(a Lhs b)}375				a:(@) _ binop(<">>">) _ b:@ {expr_bin!(a Rhs b)}376				--377				a:(@) _ binop(<"+">) _ b:@ {expr_bin!(a Add b)}378				a:(@) _ binop(<"-">) _ b:@ {expr_bin!(a Sub b)}379				--380				a:(@) _ binop(<"*">) _ b:@ {expr_bin!(a Mul b)}381				a:(@) _ binop(<"/">) _ b:@ {expr_bin!(a Div b)}382				a:(@) _ binop(<"%">) _ b:@ {expr_bin!(a Mod b)}383				--384						unaryop(<"+">) _ b:@ {expr_un!(Plus b)}385						unaryop(<"-">) _ b:@ {expr_un!(Minus b)}386						unaryop(<"!">) _ b:@ {expr_un!(Not b)}387						unaryop(<"~">) _ b:@ {expr_un!(BitNot b)}388				--389				value:(@) _ "[" _ slice:slice_desc(s) _ "]" {Expr::Slice(Box::new(Slice{value, slice}))}390				indexable:(@) _ parts:index_part(s)+ {Expr::Index{indexable: Box::new(indexable), parts}}391				a:(@) _ args:spanned(<"(" _ a:args(s) _ ")" {a}>, s) ts:(_ keyword("tailstrict"))? {Expr::Apply(Box::new(a), args, ts.is_some())}392				a:(@) _ "{" _ body:objinside(s) _ "}" {Expr::ObjExtend(Rc::new(a), body)}393				--394				e:expr_basic(s) {e}395				"(" _ e:expr(s) _ ")" {e}396			}397		pub rule index_part(s: &ParserSettings) -> IndexPart398		= n:("?" _ ensure_null_coaelse())? "." _ value:id_loc(s) {IndexPart {399			span: value.span,400			value: value.value,401			#[cfg(feature = "exp-null-coaelse")]402			null_coaelse: n.is_some(),403		}}404		/ n:("?" _ "." _ ensure_null_coaelse())? value:spanned(<"[" _ v:expr(s) _ "]" {v}>, s) {IndexPart {405			span: value.span,406			value: value.value,407			#[cfg(feature = "exp-null-coaelse")]408			null_coaelse: n.is_some(),409		}}410411		pub rule jsonnet(s: &ParserSettings) -> Expr = _ e:expr(s) _ {e}412	}413}414415pub type ParseError = peg::error::ParseError<peg::str::LineCol>;416pub fn parse(str: &str, settings: &ParserSettings) -> Result<Expr, ParseError> {417	jsonnet_parser::jsonnet(str, settings)418}419/// Used for importstr values420pub fn string_to_expr(str: IStr, settings: &ParserSettings) -> Spanned<Expr> {421	let len = str.len();422	Spanned::new(Expr::Str(str), Span(settings.source.clone(), 0, len as u32))423}424425#[cfg(test)]426mod tests {427	use std::fs;428429	use insta::{assert_snapshot, glob};430	use jrsonnet_ir::{IStr, Source};431432	use crate::{parse, ParserSettings};433434	#[test]435	fn snapshots() {436		glob!("tests/*.jsonnet", |path| {437			let input = fs::read_to_string(path).expect("read test file");438			let v = parse(439				&input,440				&ParserSettings {441					source: Source::new_virtual("<test>".into(), IStr::empty()),442				},443			)444			.unwrap();445			let v = format!("{v:#?}");446			assert_snapshot!(v);447		});448	}449}
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__add_location_info_to_all_sub_expressions.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__add_location_info_to_all_sub_expressions.snap
+++ /dev/null
@@ -1,57 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"{} { local x = 1, x: x } + {}\")"
----
-BinaryOp(
-    BinaryOp {
-        lhs: ObjExtend(
-            Obj(
-                MemberList(
-                    ObjMembers {
-                        locals: [],
-                        asserts: [],
-                        fields: [],
-                    },
-                ),
-            ) from virtual:<test>:0-2,
-            MemberList(
-                ObjMembers {
-                    locals: [
-                        Field {
-                            into: Full(
-                                "x",
-                            ),
-                            value: Num(
-                                1.0,
-                            ) from virtual:<test>:15-16,
-                        },
-                    ],
-                    asserts: [],
-                    fields: [
-                        FieldMember {
-                            name: Fixed(
-                                "x",
-                            ),
-                            plus: false,
-                            params: None,
-                            visibility: Normal,
-                            value: Var(
-                                "x",
-                            ) from virtual:<test>:21-22,
-                        },
-                    ],
-                },
-            ),
-        ) from virtual:<test>:0-24,
-        op: Add,
-        rhs: Obj(
-            MemberList(
-                ObjMembers {
-                    locals: [],
-                    asserts: [],
-                    fields: [],
-                },
-            ),
-        ) from virtual:<test>:27-29,
-    },
-) from virtual:<test>:0-29
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__array_comp.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__array_comp.snap
+++ /dev/null
@@ -1,41 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"[std.deepJoin(x) for x in arr]\")"
----
-ArrComp(
-    Apply(
-        Index {
-            indexable: Var(
-                "std",
-            ) from virtual:<test>:1-4,
-            parts: [
-                IndexPart {
-                    value: Str(
-                        "deepJoin",
-                    ) from virtual:<test>:5-13,
-                },
-            ],
-        } from virtual:<test>:1-13,
-        ArgsDesc {
-            unnamed: [
-                Var(
-                    "x",
-                ) from virtual:<test>:14-15,
-            ],
-            named: [],
-        },
-        false,
-    ) from virtual:<test>:1-16,
-    [
-        ForSpec(
-            ForSpecData(
-                Full(
-                    "x",
-                ),
-                Var(
-                    "arr",
-                ) from virtual:<test>:26-29,
-            ),
-        ),
-    ],
-) from virtual:<test>:0-30
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__array_test_error.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__array_test_error.snap
+++ /dev/null
@@ -1,38 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"[a for a in b if c for e in f]\")"
----
-ArrComp(
-    Var(
-        "a",
-    ) from virtual:<test>:1-2,
-    [
-        ForSpec(
-            ForSpecData(
-                Full(
-                    "a",
-                ),
-                Var(
-                    "b",
-                ) from virtual:<test>:12-13,
-            ),
-        ),
-        IfSpec(
-            IfSpecData(
-                Var(
-                    "c",
-                ) from virtual:<test>:17-18,
-            ),
-        ),
-        ForSpec(
-            ForSpecData(
-                Full(
-                    "e",
-                ),
-                Var(
-                    "f",
-                ) from virtual:<test>:28-29,
-            ),
-        ),
-    ],
-) from virtual:<test>:0-30
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__basic_math.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__basic_math.snap
+++ /dev/null
@@ -1,23 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"2+2*2\")"
----
-BinaryOp(
-    BinaryOp {
-        lhs: Num(
-            2.0,
-        ) from virtual:<test>:0-1,
-        op: Add,
-        rhs: BinaryOp(
-            BinaryOp {
-                lhs: Num(
-                    2.0,
-                ) from virtual:<test>:2-3,
-                op: Mul,
-                rhs: Num(
-                    2.0,
-                ) from virtual:<test>:4-5,
-            },
-        ) from virtual:<test>:2-5,
-    },
-) from virtual:<test>:0-5
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__default_param_before_nondefault.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__default_param_before_nondefault.snap
+++ /dev/null
@@ -1,54 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"local x(foo = 'foo', bar) = null; null\")"
----
-LocalExpr(
-    [
-        Function {
-            name: "x",
-            params: ExprParams {
-                exprs: [
-                    ExprParam {
-                        destruct: Full(
-                            "foo",
-                        ),
-                        default: Some(
-                            Str(
-                                "foo",
-                            ) from virtual:<test>:14-19,
-                        ),
-                    },
-                    ExprParam {
-                        destruct: Full(
-                            "bar",
-                        ),
-                        default: None,
-                    },
-                ],
-                signature: FunctionSignature(
-                    [
-                        ParamParse {
-                            name: Named(
-                                "foo",
-                            ),
-                            default: Exists,
-                        },
-                        ParamParse {
-                            name: Named(
-                                "bar",
-                            ),
-                            default: None,
-                        },
-                    ],
-                ),
-                binds_len: 2,
-            },
-            value: Literal(
-                Null,
-            ) from virtual:<test>:28-32,
-        },
-    ],
-    Literal(
-        Null,
-    ) from virtual:<test>:34-38,
-) from virtual:<test>:0-38
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__double_negation.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__double_negation.snap
+++ /dev/null
@@ -1,13 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"!!a\")"
----
-UnaryOp(
-    Not,
-    UnaryOp(
-        Not,
-        Var(
-            "a",
-        ) from virtual:<test>:2-3,
-    ) from virtual:<test>:1-3,
-) from virtual:<test>:0-3
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__empty_object.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__empty_object.snap
+++ /dev/null
@@ -1,13 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"{}\")"
----
-Obj(
-    MemberList(
-        ObjMembers {
-            locals: [],
-            asserts: [],
-            fields: [],
-        },
-    ),
-) from virtual:<test>:0-2
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__imports.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__imports.snap
+++ /dev/null
@@ -1,10 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"import \\\"hello\\\"\")"
----
-Import(
-    Normal,
-    Str(
-        "hello",
-    ) from virtual:<test>:7-14,
-) from virtual:<test>:0-14
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__infix_precedence.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__infix_precedence.snap
+++ /dev/null
@@ -1,21 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"!a && !b\")"
----
-BinaryOp(
-    BinaryOp {
-        lhs: UnaryOp(
-            Not,
-            Var(
-                "a",
-            ) from virtual:<test>:1-2,
-        ) from virtual:<test>:0-2,
-        op: And,
-        rhs: UnaryOp(
-            Not,
-            Var(
-                "b",
-            ) from virtual:<test>:7-8,
-        ) from virtual:<test>:6-8,
-    },
-) from virtual:<test>:0-8
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__missing_newline_between_comment_and_eof.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__missing_newline_between_comment_and_eof.snap
+++ /dev/null
@@ -1,25 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"{a:1}\n\n\t\t\t//+213\")"
----
-Obj(
-    MemberList(
-        ObjMembers {
-            locals: [],
-            asserts: [],
-            fields: [
-                FieldMember {
-                    name: Fixed(
-                        "a",
-                    ),
-                    plus: false,
-                    params: None,
-                    visibility: Normal,
-                    value: Num(
-                        1.0,
-                    ) from virtual:<test>:3-4,
-                },
-            ],
-        },
-    ),
-) from virtual:<test>:0-5
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__multiline_string.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__multiline_string.snap
+++ /dev/null
@@ -1,7 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"|||\\n    Hello world!\\n     a\\n|||\")"
----
-Str(
-    "Hello world!\n a\n",
-) from virtual:<test>:0-31
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__multiple_args_buf.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__multiple_args_buf.snap
+++ /dev/null
@@ -1,21 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"a(b, null_fields)\")"
----
-Apply(
-    Var(
-        "a",
-    ) from virtual:<test>:0-1,
-    ArgsDesc {
-        unnamed: [
-            Var(
-                "b",
-            ) from virtual:<test>:2-3,
-            Var(
-                "null_fields",
-            ) from virtual:<test>:5-16,
-        ],
-        named: [],
-    },
-    false,
-) from virtual:<test>:0-17
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__reserved.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__reserved.snap
+++ /dev/null
@@ -1,7 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"null\")"
----
-Literal(
-    Null,
-) from virtual:<test>:0-4
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__slice.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__slice.snap
+++ /dev/null
@@ -1,20 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"a[1:]\")"
----
-Slice(
-    Slice {
-        value: Var(
-            "a",
-        ) from virtual:<test>:0-1,
-        slice: SliceDesc {
-            start: Some(
-                Num(
-                    1.0,
-                ) from virtual:<test>:2-3,
-            ),
-            end: None,
-            step: None,
-        },
-    },
-) from virtual:<test>:0-5
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@array_comp.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@array_comp.jsonnet.snap
@@ -0,0 +1,82 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/array_comp.jsonnet
+---
+Arr(
+    [
+        ArrComp(
+            Apply(
+                Index {
+                    indexable: Var(
+                        "std" from virtual:<test>:3-6,
+                    ),
+                    parts: [
+                        IndexPart {
+                            span: virtual:<test>:7-15,
+                            value: Str(
+                                "deepJoin",
+                            ),
+                        },
+                    ],
+                },
+                ArgsDesc {
+                    unnamed: [
+                        Var(
+                            "x" from virtual:<test>:16-17,
+                        ),
+                    ],
+                    named: [],
+                } from virtual:<test>:15-18,
+                false,
+            ),
+            [
+                ForSpec(
+                    ForSpecData {
+                        destruct: Full(
+                            "x",
+                        ),
+                        over: Var(
+                            "arr" from virtual:<test>:28-31,
+                        ),
+                    },
+                ),
+            ],
+        ),
+        ArrComp(
+            Var(
+                "a" from virtual:<test>:35-36,
+            ),
+            [
+                ForSpec(
+                    ForSpecData {
+                        destruct: Full(
+                            "a",
+                        ),
+                        over: Var(
+                            "b" from virtual:<test>:46-47,
+                        ),
+                    },
+                ),
+                IfSpec(
+                    IfSpecData {
+                        span: virtual:<test>:48-50,
+                        cond: Var(
+                            "c" from virtual:<test>:51-52,
+                        ),
+                    },
+                ),
+                ForSpec(
+                    ForSpecData {
+                        destruct: Full(
+                            "e",
+                        ),
+                        over: Var(
+                            "f" from virtual:<test>:62-63,
+                        ),
+                    },
+                ),
+            ],
+        ),
+    ],
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@basic_math.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@basic_math.jsonnet.snap
@@ -0,0 +1,120 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/basic_math.jsonnet
+---
+Arr(
+    [
+        BinaryOp(
+            BinaryOp {
+                lhs: Num(
+                    2.0,
+                ),
+                op: Add,
+                rhs: BinaryOp(
+                    BinaryOp {
+                        lhs: Num(
+                            2.0,
+                        ),
+                        op: Mul,
+                        rhs: Num(
+                            2.0,
+                        ),
+                    },
+                ),
+            },
+        ),
+        BinaryOp(
+            BinaryOp {
+                lhs: Num(
+                    2.0,
+                ),
+                op: Add,
+                rhs: BinaryOp(
+                    BinaryOp {
+                        lhs: Num(
+                            2.0,
+                        ),
+                        op: Mul,
+                        rhs: Num(
+                            2.0,
+                        ),
+                    },
+                ),
+            },
+        ),
+        BinaryOp(
+            BinaryOp {
+                lhs: BinaryOp(
+                    BinaryOp {
+                        lhs: Num(
+                            2.0,
+                        ),
+                        op: Add,
+                        rhs: Num(
+                            2.0,
+                        ),
+                    },
+                ),
+                op: Add,
+                rhs: BinaryOp(
+                    BinaryOp {
+                        lhs: Num(
+                            2.0,
+                        ),
+                        op: Mul,
+                        rhs: Num(
+                            2.0,
+                        ),
+                    },
+                ),
+            },
+        ),
+        BinaryOp(
+            BinaryOp {
+                lhs: Num(
+                    2.0,
+                ),
+                op: Add,
+                rhs: BinaryOp(
+                    BinaryOp {
+                        lhs: Num(
+                            2.0,
+                        ),
+                        op: Add,
+                        rhs: BinaryOp(
+                            BinaryOp {
+                                lhs: Num(
+                                    2.0,
+                                ),
+                                op: Mul,
+                                rhs: Num(
+                                    2.0,
+                                ),
+                            },
+                        ),
+                    },
+                ),
+            },
+        ),
+        BinaryOp(
+            BinaryOp {
+                lhs: Num(
+                    2.0,
+                ),
+                op: Add,
+                rhs: BinaryOp(
+                    BinaryOp {
+                        lhs: Num(
+                            3.0,
+                        ),
+                        op: Mul,
+                        rhs: Num(
+                            4.0,
+                        ),
+                    },
+                ),
+            },
+        ),
+    ],
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@comment_eof.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@comment_eof.jsonnet.snap
@@ -0,0 +1,26 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/comment_eof.jsonnet
+---
+Obj(
+    MemberList(
+        ObjMembers {
+            locals: [],
+            asserts: [],
+            fields: [
+                FieldMember {
+                    name: Fixed(
+                        "a",
+                    ) from virtual:<test>:1-2,
+                    plus: false,
+                    params: None,
+                    visibility: Normal,
+                    value: Num(
+                        1.0,
+                    ),
+                },
+            ],
+        },
+    ),
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@default_nondefault.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@default_nondefault.jsonnet.snap
@@ -0,0 +1,55 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/default_nondefault.jsonnet
+---
+LocalExpr(
+    [
+        Function {
+            name: "x",
+            params: ExprParams {
+                exprs: [
+                    ExprParam {
+                        destruct: Full(
+                            "foo",
+                        ),
+                        default: Some(
+                            Str(
+                                "foo",
+                            ),
+                        ),
+                    },
+                    ExprParam {
+                        destruct: Full(
+                            "bar",
+                        ),
+                        default: None,
+                    },
+                ],
+                signature: FunctionSignature(
+                    [
+                        ParamParse {
+                            name: Named(
+                                "foo",
+                            ),
+                            default: Exists,
+                        },
+                        ParamParse {
+                            name: Named(
+                                "bar",
+                            ),
+                            default: None,
+                        },
+                    ],
+                ),
+                binds_len: 2,
+            },
+            value: Literal(
+                Null,
+            ),
+        },
+    ],
+    Literal(
+        Null,
+    ),
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@empty_object.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@empty_object.jsonnet.snap
@@ -0,0 +1,14 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/empty_object.jsonnet
+---
+Obj(
+    MemberList(
+        ObjMembers {
+            locals: [],
+            asserts: [],
+            fields: [],
+        },
+    ),
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@imports.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@imports.jsonnet.snap
@@ -0,0 +1,27 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/imports.jsonnet
+---
+Arr(
+    [
+        Import(
+            Normal from virtual:<test>:2-8,
+            Str(
+                "hello",
+            ),
+        ),
+        Import(
+            Str from virtual:<test>:18-27,
+            Str(
+                "garnish.txt",
+            ),
+        ),
+        Import(
+            Bin from virtual:<test>:43-52,
+            Str(
+                "garnish.bin",
+            ),
+        ),
+    ],
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@infix.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@infix.jsonnet.snap
@@ -0,0 +1,52 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/infix.jsonnet
+---
+Arr(
+    [
+        BinaryOp(
+            BinaryOp {
+                lhs: UnaryOp(
+                    Not,
+                    Var(
+                        "a" from virtual:<test>:3-4,
+                    ),
+                ),
+                op: And,
+                rhs: UnaryOp(
+                    Not,
+                    Var(
+                        "b" from virtual:<test>:9-10,
+                    ),
+                ),
+            },
+        ),
+        BinaryOp(
+            BinaryOp {
+                lhs: UnaryOp(
+                    Not,
+                    Var(
+                        "a" from virtual:<test>:13-14,
+                    ),
+                ),
+                op: Div,
+                rhs: UnaryOp(
+                    Not,
+                    Var(
+                        "b" from virtual:<test>:18-19,
+                    ),
+                ),
+            },
+        ),
+        UnaryOp(
+            Not,
+            UnaryOp(
+                Not,
+                Var(
+                    "a" from virtual:<test>:23-24,
+                ),
+            ),
+        ),
+    ],
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@multiline.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@multiline.jsonnet.snap
@@ -0,0 +1,21 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/multiline.jsonnet
+---
+Arr(
+    [
+        Str(
+            "Hello world!\na\n",
+        ),
+        Str(
+            "Hello world!\na\n",
+        ),
+        Str(
+            "Hello world!\n\ta\n",
+        ),
+        Str(
+            "Hello world!\n a\n",
+        ),
+    ],
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@reserved.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@reserved.jsonnet.snap
@@ -0,0 +1,32 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/reserved.jsonnet
+---
+Arr(
+    [
+        Literal(
+            Null,
+        ),
+        Var(
+            "nulla" from virtual:<test>:8-13,
+        ),
+        Apply(
+            Var(
+                "a" from virtual:<test>:15-16,
+            ),
+            ArgsDesc {
+                unnamed: [
+                    Var(
+                        "b" from virtual:<test>:17-18,
+                    ),
+                    Var(
+                        "null_fields" from virtual:<test>:20-31,
+                    ),
+                ],
+                named: [],
+            } from virtual:<test>:16-32,
+            false,
+        ),
+    ],
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@slice.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@slice.jsonnet.snap
@@ -0,0 +1,97 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/slice.jsonnet
+---
+Arr(
+    [
+        Slice(
+            Slice {
+                value: Var(
+                    "a" from virtual:<test>:2-3,
+                ),
+                slice: SliceDesc {
+                    start: Some(
+                        Num(
+                            1.0,
+                        ) from virtual:<test>:4-5,
+                    ),
+                    end: None,
+                    step: None,
+                },
+            },
+        ),
+        Slice(
+            Slice {
+                value: Var(
+                    "a" from virtual:<test>:9-10,
+                ),
+                slice: SliceDesc {
+                    start: Some(
+                        Num(
+                            1.0,
+                        ) from virtual:<test>:11-12,
+                    ),
+                    end: None,
+                    step: None,
+                },
+            },
+        ),
+        Slice(
+            Slice {
+                value: Var(
+                    "a" from virtual:<test>:17-18,
+                ),
+                slice: SliceDesc {
+                    start: None,
+                    end: Some(
+                        Num(
+                            1.0,
+                        ) from virtual:<test>:20-21,
+                    ),
+                    step: None,
+                },
+            },
+        ),
+        Slice(
+            Slice {
+                value: Var(
+                    "a" from virtual:<test>:25-26,
+                ),
+                slice: SliceDesc {
+                    start: None,
+                    end: None,
+                    step: Some(
+                        Num(
+                            1.0,
+                        ) from virtual:<test>:29-30,
+                    ),
+                },
+            },
+        ),
+        Slice(
+            Slice {
+                value: Var(
+                    "str" from virtual:<test>:33-36,
+                ),
+                slice: SliceDesc {
+                    start: None,
+                    end: Some(
+                        BinaryOp(
+                            BinaryOp {
+                                lhs: Var(
+                                    "len" from virtual:<test>:38-41,
+                                ),
+                                op: Sub,
+                                rhs: Num(
+                                    1.0,
+                                ),
+                            },
+                        ) from virtual:<test>:38-45,
+                    ),
+                    step: None,
+                },
+            },
+        ),
+    ],
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@string_escaping.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@string_escaping.jsonnet.snap
@@ -0,0 +1,24 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/string_escaping.jsonnet
+---
+Arr(
+    [
+        Str(
+            "Hello, \"world\"!",
+        ),
+        Str(
+            "Hello 'world'!",
+        ),
+        Str(
+            "\\\\",
+        ),
+        Str(
+            "Hello\nWorld",
+        ),
+        Str(
+            "Hello\\n\"World\"",
+        ),
+    ],
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@subexp.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@subexp.jsonnet.snap
@@ -0,0 +1,58 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/subexp.jsonnet
+---
+BinaryOp(
+    BinaryOp {
+        lhs: ObjExtend(
+            Obj(
+                MemberList(
+                    ObjMembers {
+                        locals: [],
+                        asserts: [],
+                        fields: [],
+                    },
+                ),
+            ),
+            MemberList(
+                ObjMembers {
+                    locals: [
+                        Field {
+                            into: Full(
+                                "x",
+                            ),
+                            value: Num(
+                                1.0,
+                            ),
+                        },
+                    ],
+                    asserts: [],
+                    fields: [
+                        FieldMember {
+                            name: Fixed(
+                                "x",
+                            ) from virtual:<test>:18-19,
+                            plus: false,
+                            params: None,
+                            visibility: Normal,
+                            value: Var(
+                                "x" from virtual:<test>:21-22,
+                            ),
+                        },
+                    ],
+                },
+            ),
+        ),
+        op: Add,
+        rhs: Obj(
+            MemberList(
+                ObjMembers {
+                    locals: [],
+                    asserts: [],
+                    fields: [],
+                },
+            ),
+        ),
+    },
+)
addedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@suffix.jsonnet.snapdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__snapshots@suffix.jsonnet.snap
@@ -0,0 +1,73 @@
+---
+source: crates/jrsonnet-peg-parser/src/lib.rs
+expression: v
+input_file: crates/jrsonnet-peg-parser/src/tests/suffix.jsonnet
+---
+Arr(
+    [
+        Index {
+            indexable: Var(
+                "std" from virtual:<test>:2-5,
+            ),
+            parts: [
+                IndexPart {
+                    span: virtual:<test>:6-10,
+                    value: Str(
+                        "test",
+                    ),
+                },
+            ],
+        },
+        Apply(
+            Var(
+                "std" from virtual:<test>:12-15,
+            ),
+            ArgsDesc {
+                unnamed: [
+                    Num(
+                        2.0,
+                    ),
+                ],
+                named: [],
+            } from virtual:<test>:15-18,
+            false,
+        ),
+        Apply(
+            Index {
+                indexable: Var(
+                    "std" from virtual:<test>:20-23,
+                ),
+                parts: [
+                    IndexPart {
+                        span: virtual:<test>:24-28,
+                        value: Str(
+                            "test",
+                        ),
+                    },
+                ],
+            },
+            ArgsDesc {
+                unnamed: [
+                    Num(
+                        2.0,
+                    ),
+                ],
+                named: [],
+            } from virtual:<test>:28-31,
+            false,
+        ),
+        Index {
+            indexable: Var(
+                "a" from virtual:<test>:33-34,
+            ),
+            parts: [
+                IndexPart {
+                    span: virtual:<test>:34-37,
+                    value: Var(
+                        "b" from virtual:<test>:35-36,
+                    ),
+                },
+            ],
+        },
+    ],
+)
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__string_escaping.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__string_escaping.snap
+++ /dev/null
@@ -1,7 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(r#\"\"Hello, \\\"world\\\"!\"\"#)"
----
-Str(
-    "Hello, \"world\"!",
-) from virtual:<test>:0-19
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__string_unescaping.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__string_unescaping.snap
+++ /dev/null
@@ -1,7 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(r#\"\"Hello\\nWorld\"\"#)"
----
-Str(
-    "Hello\nWorld",
-) from virtual:<test>:0-14
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__string_verbantim.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__string_verbantim.snap
+++ /dev/null
@@ -1,7 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(r#\"@\"Hello\\n\"\"World\"\"\"\"#)"
----
-Str(
-    "Hello\\n\"World\"",
-) from virtual:<test>:0-19
deletedcrates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__suffix.snapdiffbeforeafterboth
--- a/crates/jrsonnet-peg-parser/src/snapshots/jrsonnet_peg_parser__tests__suffix.snap
+++ /dev/null
@@ -1,16 +0,0 @@
----
-source: crates/jrsonnet-peg-parser/src/lib.rs
-expression: "parsep(\"std.test\")"
----
-Index {
-    indexable: Var(
-        "std",
-    ) from virtual:<test>:0-3,
-    parts: [
-        IndexPart {
-            value: Str(
-                "test",
-            ) from virtual:<test>:4-8,
-        },
-    ],
-} from virtual:<test>:0-8
addedcrates/jrsonnet-peg-parser/src/tests/array_comp.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/array_comp.jsonnet
@@ -0,0 +1,4 @@
+[
+[std.deepJoin(x) for x in arr],
+[a for a in b if c for e in f],
+]
addedcrates/jrsonnet-peg-parser/src/tests/basic_math.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/basic_math.jsonnet
@@ -0,0 +1,9 @@
+[
+2+2*2,
+2	+ 	  2	  *	2   	,
+2+2+2*2,
+2+(2+2*2),
+2//comment
++//comment
+3/*test*/*/*test*/4,
+]
addedcrates/jrsonnet-peg-parser/src/tests/comment_eof.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/comment_eof.jsonnet
@@ -0,0 +1,4 @@
+{a:1}
+
+//+213
+
addedcrates/jrsonnet-peg-parser/src/tests/default_nondefault.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/default_nondefault.jsonnet
@@ -0,0 +1 @@
+local x(foo = 'foo', bar) = null; null
addedcrates/jrsonnet-peg-parser/src/tests/empty_object.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/empty_object.jsonnet
@@ -0,0 +1 @@
+{}
addedcrates/jrsonnet-peg-parser/src/tests/imports.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/imports.jsonnet
@@ -0,0 +1,5 @@
+[
+import "hello",
+importstr "garnish.txt",
+importbin "garnish.bin",
+]
addedcrates/jrsonnet-peg-parser/src/tests/infix.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/infix.jsonnet
@@ -0,0 +1,5 @@
+[
+!a && !b,
+!a / !b,
+!!a,
+]
addedcrates/jrsonnet-peg-parser/src/tests/multiline.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/multiline.jsonnet
@@ -0,0 +1,18 @@
+[
+|||
+    Hello world!
+    a
+|||,
+|||
+  Hello world!
+  a
+|||,
+|||
+		Hello world!
+			a
+|||,
+|||
+   Hello world!
+    a
+ |||,
+]
addedcrates/jrsonnet-peg-parser/src/tests/reserved.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/reserved.jsonnet
@@ -0,0 +1,5 @@
+[
+null,
+nulla,
+a(b, null_fields),
+]
addedcrates/jrsonnet-peg-parser/src/tests/slice.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/slice.jsonnet
@@ -0,0 +1,7 @@
+[
+a[1:],
+a[1::],
+a[:1:],
+a[::1],
+str[:len - 1],
+]
addedcrates/jrsonnet-peg-parser/src/tests/string_escaping.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/string_escaping.jsonnet
@@ -0,0 +1,7 @@
+[
+"Hello, \"world\"!",
+'Hello \'world\'!',
+'\\\\',
+"Hello\nWorld",
+@"Hello\n""World""",
+]
addedcrates/jrsonnet-peg-parser/src/tests/subexp.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/subexp.jsonnet
@@ -0,0 +1 @@
+{} { local x = 1, x: x } + {}
addedcrates/jrsonnet-peg-parser/src/tests/suffix.jsonnetdiffbeforeafterboth
--- /dev/null
+++ b/crates/jrsonnet-peg-parser/src/tests/suffix.jsonnet
@@ -0,0 +1,6 @@
+[
+std.test,
+std(2),
+std.test(2),
+a[b],
+]
modifiedtests/cpp_test_suite_golden_override/error.01.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.01.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.01.jsonnet.golden
@@ -1,5 +1,5 @@
 runtime error: foo
-    error.01.jsonnet:17:29-41: error statement
-    error.01.jsonnet:18:29-40: function <bananas> call
-    error.01.jsonnet:19:28-39: function <oranges> call
-    error.01.jsonnet:20:1-11:  function <apples> call
+    error.01.jsonnet:17:29-35: error statement
+    error.01.jsonnet:18:36-40: function <bananas> call
+    error.01.jsonnet:19:35-39: function <oranges> call
+    error.01.jsonnet:20:7-11:  function <apples> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.02.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.02.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.02.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: Foo.
-    error.02.jsonnet:17:1-14: error statement
+    error.02.jsonnet:17:1-7: error statement
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.03.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.03.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.03.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: foo
-    error.03.jsonnet:17:21-33: error statement
-    error.03.jsonnet:18:8-10:  field <x> access
+    error.03.jsonnet:17:21-27: error statement
+    error.03.jsonnet:18:8-10:  field <x> access
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.04.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.04.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.04.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: foo
-    error.04.jsonnet:17:21-33: error statement
-    field <x> evaluation
+    error.04.jsonnet:17:21-27: error statement
+    field <x> evaluation
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.05.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.05.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.05.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: foo
-    error.05.jsonnet:17:21-33: error statement
+    error.05.jsonnet:17:21-27: error statement
     field <x> evaluation
-    field <y> manifestification
+    field <y> manifestification
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.06.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.06.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.06.jsonnet.golden
@@ -1,3 +1,3 @@
 attempted to divide by zero
     error.06.jsonnet:18:22-26: local <err> access
-    error.06.jsonnet:19:1-5:   function <f> call
\ No newline at end of file
+    error.06.jsonnet:19:2-5:   function <f> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.07.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.07.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.07.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: sarcasm
-    error.07.jsonnet:18:31-47: error statement
-    error.07.jsonnet:18:15-55: function <third> call
+    error.07.jsonnet:18:31-37: error statement
+    error.07.jsonnet:18:20-55: function <third> call
     error.07.jsonnet:19:1-7:   local <toxic> access
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.08.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.08.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.08.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: {"a": 1, "b": 2, "c": 3}
-    error.08.jsonnet:18:1-9: error statement
\ No newline at end of file
+    error.08.jsonnet:18:1-7: error statement
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.assert_equal_obj.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.assert_equal_obj.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.assert_equal_obj.jsonnet.golden
@@ -5,4 +5,4 @@
 B: {
   "b": 1
 }
-    error.assert_equal_obj.jsonnet:17:1-37: function <builtin_assert_equal> call
\ No newline at end of file
+    error.assert_equal_obj.jsonnet:17:16-37: function <builtin_assert_equal> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.assert_equal_str.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.assert_equal_str.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.assert_equal_str.jsonnet.golden
@@ -8,4 +8,4 @@
 four
 
 </B>
-    error.assert_equal_str.jsonnet:17:1-46: function <builtin_assert_equal> call
\ No newline at end of file
+    error.assert_equal_str.jsonnet:17:16-46: function <builtin_assert_equal> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.computed_field_scope.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.computed_field_scope.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.computed_field_scope.jsonnet.golden
@@ -1,3 +1,3 @@
 local is not defined: x
     error.computed_field_scope.jsonnet:17:21-23: local <x> access
-    error.computed_field_scope.jsonnet:17:21-23: evaluating field name
\ No newline at end of file
+    error.computed_field_scope.jsonnet:17:20-24: evaluating field name
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.decodeUTF8_float.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.decodeUTF8_float.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.decodeUTF8_float.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: cannot convert number with fractional part to u8
     argument <arr> evaluation
-    error.decodeUTF8_float.jsonnet:1:1-24: function <builtin_decode_utf8> call
\ No newline at end of file
+    error.decodeUTF8_float.jsonnet:1:15-24: function <builtin_decode_utf8> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.decodeUTF8_nan.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.decodeUTF8_nan.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.decodeUTF8_nan.jsonnet.golden
@@ -1,4 +1,4 @@
 type error: expected BoundedNumber<0, 255>, got string at self[0]
     array index 0
     argument <arr> evaluation
-    error.decodeUTF8_nan.jsonnet:1:1-25: function <builtin_decode_utf8> call
\ No newline at end of file
+    error.decodeUTF8_nan.jsonnet:1:15-25: function <builtin_decode_utf8> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.function_duplicate_arg.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.function_duplicate_arg.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.function_duplicate_arg.jsonnet.golden
@@ -1,2 +1,2 @@
 argument x is already bound
-    error.function_duplicate_arg.jsonnet:17:1-30: function <anonymous> call
\ No newline at end of file
+    error.function_duplicate_arg.jsonnet:17:21-30: function <anonymous> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.function_too_many_args.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.function_too_many_args.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.function_too_many_args.jsonnet.golden
@@ -1,3 +1,3 @@
 too many args, function has 2
 Function has the following signature: (a, b)
-    error.function_too_many_args.jsonnet:19:1-14: function <foo> call
\ No newline at end of file
+    error.function_too_many_args.jsonnet:19:4-14: function <foo> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.import_static-check-failure.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.import_static-check-failure.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.import_static-check-failure.jsonnet.golden
@@ -1,3 +1,3 @@
 local is not defined: x
-    static_check_failure.jsonnet:2:1-3:               local <x> access
-    error.import_static-check-failure.jsonnet:1:1-43: import "lib/static_check_failure.jsonnet"
\ No newline at end of file
+    static_check_failure.jsonnet:2:1-3:              local <x> access
+    error.import_static-check-failure.jsonnet:1:1-8: import "lib/static_check_failure.jsonnet"
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.import_syntax-error.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.import_syntax-error.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.import_syntax-error.jsonnet.golden
@@ -1,3 +1,3 @@
 syntax error: expected one of "\\\\", "\\u", "\\x", ['"'], ['\\'], [_], got "EOF"
     syntax_error.jsonnet:1:3
-    error.import_syntax-error.jsonnet:1:1-35: import "lib/syntax_error.jsonnet"
\ No newline at end of file
+    error.import_syntax-error.jsonnet:1:1-8: import "lib/syntax_error.jsonnet"
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.inside_equals_array.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.inside_equals_array.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.inside_equals_array.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: foobar
-    error.inside_equals_array.jsonnet:18:18-33: error statement
\ No newline at end of file
+    error.inside_equals_array.jsonnet:18:18-24: error statement
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.inside_equals_object.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.inside_equals_object.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.inside_equals_object.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: foobar
-    error.inside_equals_object.jsonnet:18:22-37: error statement
\ No newline at end of file
+    error.inside_equals_object.jsonnet:18:22-28: error statement
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.inside_tostring_array.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.inside_tostring_array.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.inside_tostring_array.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: foobar
-    error.inside_tostring_array.jsonnet:17:8-23: error statement
+    error.inside_tostring_array.jsonnet:17:8-14: error statement
     elem <2> evaluation
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.inside_tostring_object.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.inside_tostring_object.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.inside_tostring_object.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: foobar
-    error.inside_tostring_object.jsonnet:17:12-27: error statement
+    error.inside_tostring_object.jsonnet:17:12-18: error statement
     field <b> evaluation
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.invariant.option.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.invariant.option.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.invariant.option.jsonnet.golden
@@ -1,6 +1,6 @@
 type error: expected array, got string
     argument <a> evaluation
-    error.invariant.option.jsonnet:19:21-56: function <builtin_set_inter> call
+    error.invariant.option.jsonnet:19:33-56: function <builtin_set_inter> call
     argument <x> evaluation
-    error.invariant.option.jsonnet:19:10-57: function <builtin_length> call
+    error.invariant.option.jsonnet:19:20-57: function <builtin_length> call
     error.invariant.option.jsonnet:19:10-61: assertion condition
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.invariant.simple3.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.invariant.simple3.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.invariant.simple3.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: my error message
-    error.invariant.simple3.jsonnet:18:10-35: error statement
+    error.invariant.simple3.jsonnet:18:10-16: error statement
     error.invariant.simple3.jsonnet:18:10-35: assertion condition
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.manifest_toml_null_value.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.manifest_toml_null_value.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.manifest_toml_null_value.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: tried to manifest null
-    error.manifest_toml_null_value.jsonnet:17:1-55: function <builtin_manifest_toml_ex> call
\ No newline at end of file
+    error.manifest_toml_null_value.jsonnet:17:19-55: function <builtin_manifest_toml_ex> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.manifest_toml_wrong_type.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.manifest_toml_wrong_type.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.manifest_toml_wrong_type.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected object, got array
     argument <value> evaluation
-    error.manifest_toml_wrong_type.jsonnet:17:1-30: function <builtin_manifest_toml_ex> call
\ No newline at end of file
+    error.manifest_toml_wrong_type.jsonnet:17:19-30: function <builtin_manifest_toml_ex> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.parse_json.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.parse_json.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.parse_json.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: failed to parse json: expected value at line 1 column 1
-    error.parse_json.jsonnet:1:1-30: function <builtin_parse_json> call
\ No newline at end of file
+    error.parse_json.jsonnet:1:14-30: function <builtin_parse_json> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.recursive_function_nonterm.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.recursive_function_nonterm.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.recursive_function_nonterm.jsonnet.golden
@@ -1,201 +1,201 @@
 stack overflow, try to reduce recursion, or set --max-stack to bigger value
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:18:3-8: function <f> call
-    error.recursive_function_nonterm.jsonnet:20:1-7: function <f> call
\ No newline at end of file
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:18:4-8: function <f> call
+    error.recursive_function_nonterm.jsonnet:20:2-7: function <f> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.recursive_import.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.recursive_import.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.recursive_import.jsonnet.golden
@@ -1,2 +1,2 @@
 infinite recursion detected
-    error.recursive_import.jsonnet:17:15-55: import "error.recursive_import.jsonnet"
\ No newline at end of file
+    error.recursive_import.jsonnet:17:15-22: import "error.recursive_import.jsonnet"
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.sanity.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.sanity.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.sanity.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: assertion failed: A != B
 A: 1
 B: 2
-    error.sanity.jsonnet:17:1-23: function <builtin_assert_equal> call
\ No newline at end of file
+    error.sanity.jsonnet:17:16-23: function <builtin_assert_equal> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.std_join_types1.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.std_join_types1.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.std_join_types1.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: in std.join all items should be strings
-    error.std_join_types1.jsonnet:17:1-27: function <builtin_join> call
\ No newline at end of file
+    error.std_join_types1.jsonnet:17:9-27: function <builtin_join> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.std_join_types2.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.std_join_types2.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.std_join_types2.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: in std.join all items should be arrays
-    error.std_join_types2.jsonnet:17:1-32: function <builtin_join> call
\ No newline at end of file
+    error.std_join_types2.jsonnet:17:9-32: function <builtin_join> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.std_makeArray_negative.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.std_makeArray_negative.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.std_makeArray_negative.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: number out of bounds: -10 not in 0..2147483647
     argument <sz> evaluation
-    error.std_makeArray_negative.jsonnet:17:1-38: function <builtin_make_array> call
\ No newline at end of file
+    error.std_makeArray_negative.jsonnet:17:14-38: function <builtin_make_array> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.std_maxArray.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.std_maxArray.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.std_maxArray.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: expected non-empty array
-    error.std_maxArray.jsonnet:1:1-18: function <builtin_max_array> call
\ No newline at end of file
+    error.std_maxArray.jsonnet:1:13-18: function <builtin_max_array> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.std_minArray.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.std_minArray.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.std_minArray.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: expected non-empty array
-    error.std_minArray.jsonnet:1:1-18: function <builtin_min_array> call
\ No newline at end of file
+    error.std_minArray.jsonnet:1:13-18: function <builtin_min_array> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.std_parseJson.nodigitsep.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.std_parseJson.nodigitsep.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.std_parseJson.nodigitsep.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: failed to parse json: trailing characters at line 1 column 4
-    error.std_parseJson.nodigitsep.jsonnet:1:1-26: function <builtin_parse_json> call
\ No newline at end of file
+    error.std_parseJson.nodigitsep.jsonnet:1:14-26: function <builtin_parse_json> call
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.trace_three_param.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.trace_three_param.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.trace_three_param.jsonnet.golden
@@ -1,5 +1,5 @@
 too many args, function has 2
 Function has the following signature: (str, rest = <default>)
-    error.trace_three_param.jsonnet:17:11-33: function <builtin_trace> call
+    error.trace_three_param.jsonnet:17:20-33: function <builtin_trace> call
     error.trace_three_param.jsonnet:19:6-8:   local <v> access
     field <a> evaluation
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.trace_zero_param.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.trace_zero_param.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.trace_zero_param.jsonnet.golden
@@ -1,5 +1,5 @@
 function argument is not passed: str
 Function has the following signature: (str, rest = <default>)
-    error.trace_zero_param.jsonnet:17:11-23: function <builtin_trace> call
+    error.trace_zero_param.jsonnet:17:20-23: function <builtin_trace> call
     error.trace_zero_param.jsonnet:19:6-8:   local <v> access
     field <a> evaluation
\ No newline at end of file
modifiedtests/cpp_test_suite_golden_override/error.wrong_type.jsonnet.goldendiffbeforeafterboth
--- a/tests/cpp_test_suite_golden_override/error.wrong_type.jsonnet.golden
+++ b/tests/cpp_test_suite_golden_override/error.wrong_type.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected char, got number
     argument <str> evaluation
-    error.wrong_type.jsonnet:1:1-19: function <builtin_codepoint> call
\ No newline at end of file
+    error.wrong_type.jsonnet:1:14-19: function <builtin_codepoint> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/arrcomp_if6.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/arrcomp_if6.jsonnet.golden
+++ b/tests/go_testdata_golden_override/arrcomp_if6.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: x
-    arrcomp_if6.jsonnet:1:20-30: error statement
\ No newline at end of file
+    arrcomp_if6.jsonnet:1:20-26: error statement
\ No newline at end of file
modifiedtests/go_testdata_golden_override/assert_equal4.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/assert_equal4.jsonnet.golden
+++ b/tests/go_testdata_golden_override/assert_equal4.jsonnet.golden
@@ -5,4 +5,4 @@
 B: {
   "x": 2
 }
-    assert_equal4.jsonnet:1:1-33: function <builtin_assert_equal> call
\ No newline at end of file
+    assert_equal4.jsonnet:1:16-33: function <builtin_assert_equal> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/assert_equal5.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/assert_equal5.jsonnet.golden
+++ b/tests/go_testdata_golden_override/assert_equal5.jsonnet.golden
@@ -7,4 +7,4 @@
 
 
 </B>
-    assert_equal5.jsonnet:1:1-30: function <builtin_assert_equal> call
\ No newline at end of file
+    assert_equal5.jsonnet:1:16-30: function <builtin_assert_equal> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/assert_equal6.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/assert_equal6.jsonnet.golden
+++ b/tests/go_testdata_golden_override/assert_equal6.jsonnet.golden
@@ -5,4 +5,4 @@
 B: <B>
 
 </B>
-    assert_equal6.jsonnet:1:1-35: function <builtin_assert_equal> call
\ No newline at end of file
+    assert_equal6.jsonnet:1:16-35: function <builtin_assert_equal> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/bad_function_call.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/bad_function_call.jsonnet.golden
+++ b/tests/go_testdata_golden_override/bad_function_call.jsonnet.golden
@@ -1,3 +1,3 @@
 function argument is not passed: x
 Function has the following signature: (x)
-    bad_function_call.jsonnet:1:1-19: function <anonymous> call
\ No newline at end of file
+    bad_function_call.jsonnet:1:16-19: function <anonymous> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/bad_function_call2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/bad_function_call2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/bad_function_call2.jsonnet.golden
@@ -1,3 +1,3 @@
 too many args, function has 1
 Function has the following signature: (x)
-    bad_function_call2.jsonnet:1:1-23: function <anonymous> call
\ No newline at end of file
+    bad_function_call2.jsonnet:1:16-23: function <anonymous> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/bad_function_call_and_error.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/bad_function_call_and_error.jsonnet.golden
+++ b/tests/go_testdata_golden_override/bad_function_call_and_error.jsonnet.golden
@@ -1,3 +1,3 @@
 too many args, function has 1
 Function has the following signature: (x)
-    bad_function_call_and_error.jsonnet:1:1-39: function <anonymous> call
\ No newline at end of file
+    bad_function_call_and_error.jsonnet:1:16-39: function <anonymous> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/bitwise_and4.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/bitwise_and4.jsonnet.golden
+++ b/tests/go_testdata_golden_override/bitwise_and4.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: x
-    bitwise_and4.jsonnet:1:5-15: error statement
\ No newline at end of file
+    bitwise_and4.jsonnet:1:5-11: error statement
\ No newline at end of file
modifiedtests/go_testdata_golden_override/bitwise_xor7.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/bitwise_xor7.jsonnet.golden
+++ b/tests/go_testdata_golden_override/bitwise_xor7.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: x
-    bitwise_xor7.jsonnet:1:5-15: error statement
\ No newline at end of file
+    bitwise_xor7.jsonnet:1:5-11: error statement
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64DecodeBytes_high_codepoint.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64DecodeBytes_high_codepoint.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64DecodeBytes_high_codepoint.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: invalid base64: Invalid symbol 196, offset 0.
-    builtinBase64DecodeBytes_high_codepoint.jsonnet:1:1-30: function <builtin_base64_decode_bytes> call
\ No newline at end of file
+    builtinBase64DecodeBytes_high_codepoint.jsonnet:1:22-30: function <builtin_base64_decode_bytes> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64DecodeBytes_invalid_base64_data.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64DecodeBytes_invalid_base64_data.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64DecodeBytes_invalid_base64_data.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: invalid base64: Invalid input length: 5
-    builtinBase64DecodeBytes_invalid_base64_data.jsonnet:1:1-32: function <builtin_base64_decode_bytes> call
\ No newline at end of file
+    builtinBase64DecodeBytes_invalid_base64_data.jsonnet:1:22-32: function <builtin_base64_decode_bytes> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64DecodeBytes_wrong_type.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64DecodeBytes_wrong_type.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64DecodeBytes_wrong_type.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected string, got number
     argument <str> evaluation
-    builtinBase64DecodeBytes_wrong_type.jsonnet:1:1-26: function <builtin_base64_decode_bytes> call
\ No newline at end of file
+    builtinBase64DecodeBytes_wrong_type.jsonnet:1:22-26: function <builtin_base64_decode_bytes> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64Decode_high_codepoint.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64Decode_high_codepoint.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64Decode_high_codepoint.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: invalid base64: Invalid symbol 196, offset 0.
-    builtinBase64Decode_high_codepoint.jsonnet:1:1-25: function <builtin_base64_decode> call
\ No newline at end of file
+    builtinBase64Decode_high_codepoint.jsonnet:1:17-25: function <builtin_base64_decode> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64Decode_invalid_base64_data.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64Decode_invalid_base64_data.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64Decode_invalid_base64_data.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: invalid base64: Invalid input length: 5
-    builtinBase64Decode_invalid_base64_data.jsonnet:1:1-27: function <builtin_base64_decode> call
\ No newline at end of file
+    builtinBase64Decode_invalid_base64_data.jsonnet:1:17-27: function <builtin_base64_decode> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64Decode_wrong_type.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64Decode_wrong_type.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64Decode_wrong_type.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected string, got number
     argument <str> evaluation
-    builtinBase64Decode_wrong_type.jsonnet:1:1-21: function <builtin_base64_decode> call
\ No newline at end of file
+    builtinBase64Decode_wrong_type.jsonnet:1:17-21: function <builtin_base64_decode> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64_invalid_byte_array.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64_invalid_byte_array.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64_invalid_byte_array.jsonnet.golden
@@ -2,4 +2,4 @@
   - expected string, got array
   - expected BoundedNumber<0, 255>, got string at self[1]
     argument <input> evaluation
-    builtinBase64_invalid_byte_array.jsonnet:1:1-24: function <builtin_base64> call
\ No newline at end of file
+    builtinBase64_invalid_byte_array.jsonnet:1:11-24: function <builtin_base64> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64_invalid_byte_array1.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64_invalid_byte_array1.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64_invalid_byte_array1.jsonnet.golden
@@ -2,4 +2,4 @@
   - expected string, got array
   - number out of bounds: -1 not in 0..255 at self[1]
     argument <input> evaluation
-    builtinBase64_invalid_byte_array1.jsonnet:1:1-21: function <builtin_base64> call
\ No newline at end of file
+    builtinBase64_invalid_byte_array1.jsonnet:1:11-21: function <builtin_base64> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64_invalid_byte_array2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64_invalid_byte_array2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64_invalid_byte_array2.jsonnet.golden
@@ -2,4 +2,4 @@
   - expected string, got array
   - number out of bounds: 256 not in 0..255 at self[1]
     argument <input> evaluation
-    builtinBase64_invalid_byte_array2.jsonnet:1:1-22: function <builtin_base64> call
\ No newline at end of file
+    builtinBase64_invalid_byte_array2.jsonnet:1:11-22: function <builtin_base64> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinBase64_non_string_non_array.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinBase64_non_string_non_array.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinBase64_non_string_non_array.jsonnet.golden
@@ -2,4 +2,4 @@
   - expected string, got number
   - expected Array<BoundedNumber<0, 255>>, got number
     argument <input> evaluation
-    builtinBase64_non_string_non_array.jsonnet:1:1-15: function <builtin_base64> call
\ No newline at end of file
+    builtinBase64_non_string_non_array.jsonnet:1:11-15: function <builtin_base64> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinChar3.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinChar3.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinChar3.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: number out of bounds: -1 not in 0..4294967295
     argument <n> evaluation
-    builtinChar3.jsonnet:1:1-14: function <builtin_char> call
\ No newline at end of file
+    builtinChar3.jsonnet:1:9-14: function <builtin_char> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinChar5.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinChar5.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinChar5.jsonnet.golden
@@ -1,2 +1,2 @@
 invalid unicode codepoint: 1114112
-    builtinChar5.jsonnet:2:1-19: function <builtin_char> call
\ No newline at end of file
+    builtinChar5.jsonnet:2:9-19: function <builtin_char> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinChar7.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinChar7.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinChar7.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected BoundedNumber<0, 4294967295>, got string
     argument <n> evaluation
-    builtinChar7.jsonnet:1:1-17: function <builtin_char> call
\ No newline at end of file
+    builtinChar7.jsonnet:1:9-17: function <builtin_char> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinIsEmpty2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinIsEmpty2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinIsEmpty2.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected string, got number
     argument <str> evaluation
-    builtinIsEmpty2.jsonnet:1:1-17: function <builtin_is_empty> call
\ No newline at end of file
+    builtinIsEmpty2.jsonnet:1:12-17: function <builtin_is_empty> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinObjectFieldsEx_bad.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinObjectFieldsEx_bad.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinObjectFieldsEx_bad.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected object, got number
     argument <obj> evaluation
-    builtinObjectFieldsEx_bad.jsonnet:1:1-30: function <builtin_object_fields_ex> call
\ No newline at end of file
+    builtinObjectFieldsEx_bad.jsonnet:1:19-30: function <builtin_object_fields_ex> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinObjectFieldsEx_bad2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinObjectFieldsEx_bad2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinObjectFieldsEx_bad2.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected boolean, got string
     argument <hidden> evaluation
-    builtinObjectFieldsEx_bad2.jsonnet:1:1-31: function <builtin_object_fields_ex> call
\ No newline at end of file
+    builtinObjectFieldsEx_bad2.jsonnet:1:19-31: function <builtin_object_fields_ex> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinObjectHasExBadBoolean.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinObjectHasExBadBoolean.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinObjectHasExBadBoolean.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected boolean, got string
     argument <hidden> evaluation
-    builtinObjectHasExBadBoolean.jsonnet:1:1-35: function <builtin_object_has_ex> call
\ No newline at end of file
+    builtinObjectHasExBadBoolean.jsonnet:1:16-35: function <builtin_object_has_ex> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinObjectHasExBadField.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinObjectHasExBadField.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinObjectHasExBadField.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected string, got number
     argument <fname> evaluation
-    builtinObjectHasExBadField.jsonnet:1:1-32: function <builtin_object_has_ex> call
\ No newline at end of file
+    builtinObjectHasExBadField.jsonnet:1:16-32: function <builtin_object_has_ex> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinObjectHasExBadObject.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinObjectHasExBadObject.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinObjectHasExBadObject.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected object, got number
     argument <obj> evaluation
-    builtinObjectHasExBadObject.jsonnet:1:1-33: function <builtin_object_has_ex> call
\ No newline at end of file
+    builtinObjectHasExBadObject.jsonnet:1:16-33: function <builtin_object_has_ex> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinReverse_not_array.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinReverse_not_array.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinReverse_not_array.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected array, got boolean
     argument <arr> evaluation
-    builtinReverse_not_array.jsonnet:1:1-20: function <builtin_reverse> call
\ No newline at end of file
+    builtinReverse_not_array.jsonnet:1:12-20: function <builtin_reverse> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinSplitLimitR5.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinSplitLimitR5.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinSplitLimitR5.jsonnet.golden
@@ -2,4 +2,4 @@
   - number out of bounds: -2 not in 0..9007199254740991
   - number out of bounds: -2 not in -1..-1
     argument <maxsplits> evaluation
-    builtinSplitLimitR5.jsonnet:1:1-45: function <builtin_splitlimitr> call
\ No newline at end of file
+    builtinSplitLimitR5.jsonnet:1:16-45: function <builtin_splitlimitr> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinSubStr_first_param_not_string.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinSubStr_first_param_not_string.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinSubStr_first_param_not_string.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected string, got number
     argument <str> evaluation
-    builtinSubStr_first_param_not_string.jsonnet:1:1-21: function <builtin_substr> call
\ No newline at end of file
+    builtinSubStr_first_param_not_string.jsonnet:1:11-21: function <builtin_substr> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinSubStr_second_parameter_not_integer.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinSubStr_second_parameter_not_integer.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinSubStr_second_parameter_not_integer.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: cannot convert number with fractional part to usize
     argument <from> evaluation
-    builtinSubStr_second_parameter_not_integer.jsonnet:1:1-29: function <builtin_substr> call
\ No newline at end of file
+    builtinSubStr_second_parameter_not_integer.jsonnet:1:11-29: function <builtin_substr> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinSubStr_second_parameter_not_number.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinSubStr_second_parameter_not_number.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinSubStr_second_parameter_not_number.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected BoundedNumber<0, 9007199254740991>, got string
     argument <from> evaluation
-    builtinSubStr_second_parameter_not_number.jsonnet:1:1-31: function <builtin_substr> call
\ No newline at end of file
+    builtinSubStr_second_parameter_not_number.jsonnet:1:11-31: function <builtin_substr> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinSubStr_third_parameter_less_then_zero.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinSubStr_third_parameter_less_then_zero.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinSubStr_third_parameter_less_then_zero.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: number out of bounds: -1 not in 0..9007199254740991
     argument <len> evaluation
-    builtinSubStr_third_parameter_less_then_zero.jsonnet:1:1-28: function <builtin_substr> call
\ No newline at end of file
+    builtinSubStr_third_parameter_less_then_zero.jsonnet:1:11-28: function <builtin_substr> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinSubStr_third_parameter_not_integer.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinSubStr_third_parameter_not_integer.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinSubStr_third_parameter_not_integer.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: cannot convert number with fractional part to usize
     argument <len> evaluation
-    builtinSubStr_third_parameter_not_integer.jsonnet:1:1-29: function <builtin_substr> call
\ No newline at end of file
+    builtinSubStr_third_parameter_not_integer.jsonnet:1:11-29: function <builtin_substr> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinSubStr_third_parameter_not_number.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinSubStr_third_parameter_not_number.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinSubStr_third_parameter_not_number.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected BoundedNumber<0, 9007199254740991>, got string
     argument <len> evaluation
-    builtinSubStr_third_parameter_not_number.jsonnet:1:1-31: function <builtin_substr> call
\ No newline at end of file
+    builtinSubStr_third_parameter_not_number.jsonnet:1:11-31: function <builtin_substr> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinTrim4.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinTrim4.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinTrim4.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected string, got number
     argument <str> evaluation
-    builtinTrim4.jsonnet:1:1-14: function <builtin_trim> call
\ No newline at end of file
+    builtinTrim4.jsonnet:1:9-14: function <builtin_trim> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinXnor2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinXnor2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinXnor2.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected boolean, got string
     argument <x> evaluation
-    builtinXnor2.jsonnet:1:1-25: function <builtin_xnor> call
\ No newline at end of file
+    builtinXnor2.jsonnet:1:9-25: function <builtin_xnor> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtinXor2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtinXor2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtinXor2.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected boolean, got string
     argument <x> evaluation
-    builtinXor2.jsonnet:1:1-24: function <builtin_xor> call
\ No newline at end of file
+    builtinXor2.jsonnet:1:8-24: function <builtin_xor> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_exp3.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_exp3.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_exp3.jsonnet.golden
@@ -1,2 +1,2 @@
 convert num value: non-finite
-    builtin_exp3.jsonnet:1:1-15: function <builtin_exp> call
\ No newline at end of file
+    builtin_exp3.jsonnet:1:8-15: function <builtin_exp> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_exp5.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_exp5.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_exp5.jsonnet.golden
@@ -1,2 +1,2 @@
 convert num value: non-finite
-    builtin_exp5.jsonnet:1:1-32: function <builtin_exp> call
\ No newline at end of file
+    builtin_exp5.jsonnet:1:8-32: function <builtin_exp> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_log5.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_log5.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_log5.jsonnet.golden
@@ -1,2 +1,2 @@
 convert num value: non-finite
-    builtin_log5.jsonnet:1:1-12: function <builtin_log> call
\ No newline at end of file
+    builtin_log5.jsonnet:1:8-12: function <builtin_log> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_log7.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_log7.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_log7.jsonnet.golden
@@ -1,2 +1,2 @@
 convert num value: non-finite
-    builtin_log7.jsonnet:1:1-13: function <builtin_log> call
\ No newline at end of file
+    builtin_log7.jsonnet:1:8-13: function <builtin_log> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_log8.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_log8.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_log8.jsonnet.golden
@@ -1,2 +1,2 @@
 convert num value: non-finite
-    builtin_log8.jsonnet:1:1-25: function <builtin_log> call
\ No newline at end of file
+    builtin_log8.jsonnet:1:8-25: function <builtin_log> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_manifestTomlEx_array.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_manifestTomlEx_array.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_manifestTomlEx_array.jsonnet.golden
@@ -1,4 +1,4 @@
 type error: expected object, got array
     argument <value> evaluation
-    builtin_manifestTomlEx_array.jsonnet:11:10-42: function <builtin_manifest_toml_ex> call
+    builtin_manifestTomlEx_array.jsonnet:11:28-42: function <builtin_manifest_toml_ex> call
     field <array> evaluation
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_manifestTomlEx_null.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_manifestTomlEx_null.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_manifestTomlEx_null.jsonnet.golden
@@ -1,4 +1,4 @@
 type error: expected object, got null
     argument <value> evaluation
-    builtin_manifestTomlEx_null.jsonnet:2:11-43: function <builtin_manifest_toml_ex> call
+    builtin_manifestTomlEx_null.jsonnet:2:29-43: function <builtin_manifest_toml_ex> call
     field <null> evaluation
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_member_object_invalid.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_member_object_invalid.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_member_object_invalid.jsonnet.golden
@@ -2,4 +2,4 @@
   - expected array, got object
   - expected string, got object
     argument <arr> evaluation
-    builtin_member_object_invalid.jsonnet:1:1-32: function <builtin_member> call
\ No newline at end of file
+    builtin_member_object_invalid.jsonnet:1:11-32: function <builtin_member> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_parseInt_invalid.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_parseInt_invalid.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_parseInt_invalid.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: "hello" is not a base 10 integer
-    builtin_parseInt_invalid.jsonnet:1:1-23: function <builtin_parse_int> call
\ No newline at end of file
+    builtin_parseInt_invalid.jsonnet:1:13-23: function <builtin_parse_int> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_parseInt_invalid_decimal.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_parseInt_invalid_decimal.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_parseInt_invalid_decimal.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: "123.12" is not a base 10 integer
-    builtin_parseInt_invalid_decimal.jsonnet:1:1-24: function <builtin_parse_int> call
\ No newline at end of file
+    builtin_parseInt_invalid_decimal.jsonnet:1:13-24: function <builtin_parse_int> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_parseInt_invalid_hexadecimal.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_parseInt_invalid_hexadecimal.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_parseInt_invalid_hexadecimal.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: "7B316" is not a base 10 integer
-    builtin_parseInt_invalid_hexadecimal.jsonnet:1:1-23: function <builtin_parse_int> call
\ No newline at end of file
+    builtin_parseInt_invalid_hexadecimal.jsonnet:1:13-23: function <builtin_parse_int> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_sqrt2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_sqrt2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_sqrt2.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected BoundedNumber<0, open>, got string
     argument <x> evaluation
-    builtin_sqrt2.jsonnet:1:1-20: function <builtin_sqrt> call
\ No newline at end of file
+    builtin_sqrt2.jsonnet:1:9-20: function <builtin_sqrt> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/builtin_stripChars_invalid.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/builtin_stripChars_invalid.jsonnet.golden
+++ b/tests/go_testdata_golden_override/builtin_stripChars_invalid.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected string, got object
     argument <str> evaluation
-    builtin_stripChars_invalid.jsonnet:1:1-4133: function <builtin_strip_chars> call
\ No newline at end of file
+    builtin_stripChars_invalid.jsonnet:1:15-4133: function <builtin_strip_chars> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/double_thunk.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/double_thunk.jsonnet.golden
+++ b/tests/go_testdata_golden_override/double_thunk.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: xxx
-    double_thunk.jsonnet:1:21-33: error statement
+    double_thunk.jsonnet:1:21-27: error statement
     double_thunk.jsonnet:1:34-36: local <y> access
     double_thunk.jsonnet:1:37-39: local <x> access
\ No newline at end of file
modifiedtests/go_testdata_golden_override/error.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/error.jsonnet.golden
+++ b/tests/go_testdata_golden_override/error.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: 42
-    error.jsonnet:1:1-12: error statement
\ No newline at end of file
+    error.jsonnet:1:1-7: error statement
\ No newline at end of file
modifiedtests/go_testdata_golden_override/error_from_array.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/error_from_array.jsonnet.golden
+++ b/tests/go_testdata_golden_override/error_from_array.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: xxx
-    error_from_array.jsonnet:1:2-14: error statement
\ No newline at end of file
+    error_from_array.jsonnet:1:2-8: error statement
\ No newline at end of file
modifiedtests/go_testdata_golden_override/error_from_func.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/error_from_func.jsonnet.golden
+++ b/tests/go_testdata_golden_override/error_from_func.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: xxx
-    error_from_func.jsonnet:1:25-33: error statement
-    error_from_func.jsonnet:1:34-45: function <foo> call
\ No newline at end of file
+    error_from_func.jsonnet:1:25-31: error statement
+    error_from_func.jsonnet:1:37-45: function <foo> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/error_function_fail.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/error_function_fail.jsonnet.golden
+++ b/tests/go_testdata_golden_override/error_function_fail.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: tried to manifest function
-    error_function_fail.jsonnet:1:1-24: error statement
\ No newline at end of file
+    error_function_fail.jsonnet:1:1-7: error statement
\ No newline at end of file
modifiedtests/go_testdata_golden_override/error_in_method.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/error_in_method.jsonnet.golden
+++ b/tests/go_testdata_golden_override/error_in_method.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: xxx
-    error_in_method.jsonnet:1:23-31: error statement
-    error_in_method.jsonnet:1:34-49: function <foo> call
\ No newline at end of file
+    error_in_method.jsonnet:1:23-29: error statement
+    error_in_method.jsonnet:1:41-49: function <foo> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/error_in_object_local.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/error_in_object_local.jsonnet.golden
+++ b/tests/go_testdata_golden_override/error_in_object_local.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: xxx
-    error_in_object_local.jsonnet:1:20-30: error statement
-    error_in_object_local.jsonnet:1:36-47: function <foo> call
+    error_in_object_local.jsonnet:1:20-26: error statement
+    error_in_object_local.jsonnet:1:39-47: function <foo> call
     field <baz> evaluation
\ No newline at end of file
modifiedtests/go_testdata_golden_override/error_object.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/error_object.jsonnet.golden
+++ b/tests/go_testdata_golden_override/error_object.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: {"blah": 42}
-    error_object.jsonnet:1:1-22: error statement
\ No newline at end of file
+    error_object.jsonnet:1:1-7: error statement
\ No newline at end of file
modifiedtests/go_testdata_golden_override/extvar_error.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/extvar_error.jsonnet.golden
+++ b/tests/go_testdata_golden_override/extvar_error.jsonnet.golden
@@ -1,2 +1,2 @@
 external variable is not defined: errorVar
-    extvar_error.jsonnet:1:1-24: function <builtin_ext_var> call
\ No newline at end of file
+    extvar_error.jsonnet:1:11-24: function <builtin_ext_var> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/extvar_hermetic.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/extvar_hermetic.jsonnet.golden
+++ b/tests/go_testdata_golden_override/extvar_hermetic.jsonnet.golden
@@ -1,2 +1,2 @@
 external variable is not defined: UndeclaredX
-    extvar_hermetic.jsonnet:1:15-41: function <builtin_ext_var> call
\ No newline at end of file
+    extvar_hermetic.jsonnet:1:25-41: function <builtin_ext_var> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/extvar_not_a_string.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/extvar_not_a_string.jsonnet.golden
+++ b/tests/go_testdata_golden_override/extvar_not_a_string.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected string, got number
     argument <x> evaluation
-    extvar_not_a_string.jsonnet:1:1-16: function <builtin_ext_var> call
\ No newline at end of file
+    extvar_not_a_string.jsonnet:1:11-16: function <builtin_ext_var> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/extvar_static_error.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/extvar_static_error.jsonnet.golden
+++ b/tests/go_testdata_golden_override/extvar_static_error.jsonnet.golden
@@ -1,2 +1,2 @@
 external variable is not defined: staticErrorVar
-    extvar_static_error.jsonnet:1:1-30: function <builtin_ext_var> call
\ No newline at end of file
+    extvar_static_error.jsonnet:1:11-30: function <builtin_ext_var> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/extvar_unknown.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/extvar_unknown.jsonnet.golden
+++ b/tests/go_testdata_golden_override/extvar_unknown.jsonnet.golden
@@ -1,2 +1,2 @@
 external variable is not defined: UNKNOWN
-    extvar_unknown.jsonnet:1:1-23: function <builtin_ext_var> call
\ No newline at end of file
+    extvar_unknown.jsonnet:1:11-23: function <builtin_ext_var> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/fieldname_not_string.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/fieldname_not_string.jsonnet.golden
+++ b/tests/go_testdata_golden_override/fieldname_not_string.jsonnet.golden
@@ -1,2 +1,2 @@
 type error: expected string, got number
-    fieldname_not_string.jsonnet:1:4-9: evaluating field name
\ No newline at end of file
+    fieldname_not_string.jsonnet:1:3-10: evaluating field name
\ No newline at end of file
modifiedtests/go_testdata_golden_override/import_syntax_error.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/import_syntax_error.jsonnet.golden
+++ b/tests/go_testdata_golden_override/import_syntax_error.jsonnet.golden
@@ -1,3 +1,3 @@
 syntax error: expected one of "(", "[", "{", <identifier>, <number>, <string>, <unary op>, ['"'], ['\''], got "EOF"
     syntax_error.jsonnet:1:5
-    import_syntax_error.jsonnet:1:1-31: import "syntax_error.jsonnet"
\ No newline at end of file
+    import_syntax_error.jsonnet:1:1-8: import "syntax_error.jsonnet"
\ No newline at end of file
modifiedtests/go_testdata_golden_override/lazy_operator2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/lazy_operator2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/lazy_operator2.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: should happen
-    lazy_operator2.jsonnet:1:9-31: error statement
\ No newline at end of file
+    lazy_operator2.jsonnet:1:9-15: error statement
\ No newline at end of file
modifiedtests/go_testdata_golden_override/object_comp_assert.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/object_comp_assert.jsonnet.golden
+++ b/tests/go_testdata_golden_override/object_comp_assert.jsonnet.golden
@@ -1,2 +1,2 @@
-syntax error: expected one of "(", ".", "?", "[", "{", "}", <binary op>, got "f"
-    object_comp_assert.jsonnet:1:32
\ No newline at end of file
+syntax error: expected one of "(", ".", "?", "[", "{", <binary op>, got "}"
+    object_comp_assert.jsonnet:1:46
\ No newline at end of file
modifiedtests/go_testdata_golden_override/object_comp_bad_field.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/object_comp_bad_field.jsonnet.golden
+++ b/tests/go_testdata_golden_override/object_comp_bad_field.jsonnet.golden
@@ -1,2 +1,3 @@
-syntax error: expected one of "(", ".", "?", "[", "{", "}", <binary op>, got "f"
-    object_comp_bad_field.jsonnet:1:9
\ No newline at end of file
+{
+    "x": 42
+}
\ No newline at end of file
modifiedtests/go_testdata_golden_override/object_comp_bad_field2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/object_comp_bad_field2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/object_comp_bad_field2.jsonnet.golden
@@ -1,2 +1,3 @@
-syntax error: expected one of "(", ".", "?", "[", "{", "}", <binary op>, got "f"
-    object_comp_bad_field2.jsonnet:1:11
\ No newline at end of file
+{
+    "x": 42
+}
\ No newline at end of file
modifiedtests/go_testdata_golden_override/object_comp_duplicate.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/object_comp_duplicate.jsonnet.golden
+++ b/tests/go_testdata_golden_override/object_comp_duplicate.jsonnet.golden
@@ -1,2 +1,2 @@
 duplicate field name: x
-    object_comp_duplicate.jsonnet:1:8-10: field <x> initializtion
\ No newline at end of file
+    object_comp_duplicate.jsonnet:1:3-7: field <x> initializtion
\ No newline at end of file
modifiedtests/go_testdata_golden_override/object_comp_err_elem.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/object_comp_err_elem.jsonnet.golden
+++ b/tests/go_testdata_golden_override/object_comp_err_elem.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: xxx
-    object_comp_err_elem.jsonnet:1:11-23: error statement
+    object_comp_err_elem.jsonnet:1:11-17: error statement
     field <x> evaluation
\ No newline at end of file
modifiedtests/go_testdata_golden_override/object_comp_err_index.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/object_comp_err_index.jsonnet.golden
+++ b/tests/go_testdata_golden_override/object_comp_err_index.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: xxx
-    object_comp_err_index.jsonnet:1:4-16: error statement
-    object_comp_err_index.jsonnet:1:4-16: evaluating field name
\ No newline at end of file
+    object_comp_err_index.jsonnet:1:4-10: error statement
+    object_comp_err_index.jsonnet:1:3-17: evaluating field name
\ No newline at end of file
modifiedtests/go_testdata_golden_override/object_comp_illegal.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/object_comp_illegal.jsonnet.golden
+++ b/tests/go_testdata_golden_override/object_comp_illegal.jsonnet.golden
@@ -1,2 +1,2 @@
-syntax error: expected one of "(", ".", "?", "[", "{", "}", <binary op>, got "f"
-    object_comp_illegal.jsonnet:1:15
\ No newline at end of file
+syntax error: expected one of "(", ".", "?", "[", "{", <binary op>, got "}"
+    object_comp_illegal.jsonnet:1:34
\ No newline at end of file
modifiedtests/go_testdata_golden_override/object_comp_int_index.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/object_comp_int_index.jsonnet.golden
+++ b/tests/go_testdata_golden_override/object_comp_int_index.jsonnet.golden
@@ -1,2 +1,2 @@
 type error: expected string, got number
-    object_comp_int_index.jsonnet:1:4-6: evaluating field name
\ No newline at end of file
+    object_comp_int_index.jsonnet:1:3-7: evaluating field name
\ No newline at end of file
modifiedtests/go_testdata_golden_override/object_invariant13.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/object_invariant13.jsonnet.golden
+++ b/tests/go_testdata_golden_override/object_invariant13.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: x
-    object_invariant13.jsonnet:1:10-20: error statement
+    object_invariant13.jsonnet:1:10-16: error statement
     object_invariant13.jsonnet:1:10-20: assertion condition
\ No newline at end of file
modifiedtests/go_testdata_golden_override/optional_args11.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/optional_args11.jsonnet.golden
+++ b/tests/go_testdata_golden_override/optional_args11.jsonnet.golden
@@ -1,2 +1,2 @@
 argument x is already bound
-    optional_args11.jsonnet:1:1-31: function <anonymous> call
\ No newline at end of file
+    optional_args11.jsonnet:1:20-31: function <anonymous> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/optional_args13.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/optional_args13.jsonnet.golden
+++ b/tests/go_testdata_golden_override/optional_args13.jsonnet.golden
@@ -1,3 +1,3 @@
 function argument is not passed: y
 Function has the following signature: (x, y)
-    optional_args13.jsonnet:1:1-27: function <anonymous> call
\ No newline at end of file
+    optional_args13.jsonnet:1:20-27: function <anonymous> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/optional_args8.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/optional_args8.jsonnet.golden
+++ b/tests/go_testdata_golden_override/optional_args8.jsonnet.golden
@@ -1,2 +1,2 @@
 parameter y is not defined
-    optional_args8.jsonnet:2:1-11: function <foo> call
\ No newline at end of file
+    optional_args8.jsonnet:2:4-11: function <foo> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/optional_args9.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/optional_args9.jsonnet.golden
+++ b/tests/go_testdata_golden_override/optional_args9.jsonnet.golden
@@ -1,2 +1,2 @@
 argument x is already bound
-    optional_args9.jsonnet:1:1-27: function <anonymous> call
\ No newline at end of file
+    optional_args9.jsonnet:1:16-27: function <anonymous> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/or4.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/or4.jsonnet.golden
+++ b/tests/go_testdata_golden_override/or4.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: xxx
-    or4.jsonnet:1:10-22: error statement
\ No newline at end of file
+    or4.jsonnet:1:10-16: error statement
\ No newline at end of file
modifiedtests/go_testdata_golden_override/pow4.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/pow4.jsonnet.golden
+++ b/tests/go_testdata_golden_override/pow4.jsonnet.golden
@@ -1,2 +1,2 @@
 convert num value: non-finite
-    pow4.jsonnet:1:1-18: function <builtin_pow> call
\ No newline at end of file
+    pow4.jsonnet:1:8-18: function <builtin_pow> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/pow7.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/pow7.jsonnet.golden
+++ b/tests/go_testdata_golden_override/pow7.jsonnet.golden
@@ -1,2 +1,2 @@
 convert num value: non-finite
-    pow7.jsonnet:2:1-24: function <builtin_pow> call
\ No newline at end of file
+    pow7.jsonnet:2:8-24: function <builtin_pow> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/pow8.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/pow8.jsonnet.golden
+++ b/tests/go_testdata_golden_override/pow8.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected number, got string
     argument <x> evaluation
-    pow8.jsonnet:1:1-20: function <builtin_pow> call
\ No newline at end of file
+    pow8.jsonnet:1:8-20: function <builtin_pow> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/pow9.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/pow9.jsonnet.golden
+++ b/tests/go_testdata_golden_override/pow9.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected number, got string
     argument <n> evaluation
-    pow9.jsonnet:1:1-20: function <builtin_pow> call
\ No newline at end of file
+    pow9.jsonnet:1:8-20: function <builtin_pow> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/recursive_thunk.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/recursive_thunk.jsonnet.golden
+++ b/tests/go_testdata_golden_override/recursive_thunk.jsonnet.golden
@@ -1,10 +1,10 @@
 runtime error: xxx
-    recursive_thunk.jsonnet:1:35-47: error statement
-    recursive_thunk.jsonnet:2:16-39: function <bar> call
-    recursive_thunk.jsonnet:2:20-31: function <foo> call
+    recursive_thunk.jsonnet:1:35-41: error statement
+    recursive_thunk.jsonnet:2:19-39: function <bar> call
+    recursive_thunk.jsonnet:2:23-31: function <foo> call
     recursive_thunk.jsonnet:1:52-55: local <th> access
-    recursive_thunk.jsonnet:2:16-39: function <bar> call
-    recursive_thunk.jsonnet:2:20-31: function <foo> call
+    recursive_thunk.jsonnet:2:19-39: function <bar> call
+    recursive_thunk.jsonnet:2:23-31: function <foo> call
     recursive_thunk.jsonnet:1:52-55: local <th> access
-    recursive_thunk.jsonnet:2:16-39: function <bar> call
-    recursive_thunk.jsonnet:3:1-8:   function <foo> call
\ No newline at end of file
+    recursive_thunk.jsonnet:2:19-39: function <bar> call
+    recursive_thunk.jsonnet:3:4-8:   function <foo> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.codepoint3.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.codepoint3.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.codepoint3.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected char, got string
     argument <str> evaluation
-    std.codepoint3.jsonnet:1:1-21: function <builtin_codepoint> call
\ No newline at end of file
+    std.codepoint3.jsonnet:1:14-21: function <builtin_codepoint> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.codepoint6.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.codepoint6.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.codepoint6.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected char, got string
     argument <str> evaluation
-    std.codepoint6.jsonnet:1:1-19: function <builtin_codepoint> call
\ No newline at end of file
+    std.codepoint6.jsonnet:1:14-19: function <builtin_codepoint> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.codepoint8.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.codepoint8.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.codepoint8.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected char, got number
     argument <str> evaluation
-    std.codepoint8.jsonnet:1:1-19: function <builtin_codepoint> call
\ No newline at end of file
+    std.codepoint8.jsonnet:1:14-19: function <builtin_codepoint> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.filter2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.filter2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.filter2.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: x
-    std.filter2.jsonnet:1:12-22: error statement
+    std.filter2.jsonnet:1:12-18: error statement
     argument <func> evaluation
-    std.filter2.jsonnet:1:1-27:  function <builtin_filter> call
\ No newline at end of file
+    std.filter2.jsonnet:1:11-27: function <builtin_filter> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.filter4.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.filter4.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.filter4.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected function, got number
     argument <func> evaluation
-    std.filter4.jsonnet:1:1-20: function <builtin_filter> call
\ No newline at end of file
+    std.filter4.jsonnet:1:11-20: function <builtin_filter> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.filter5.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.filter5.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.filter5.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected array, got number
     argument <arr> evaluation
-    std.filter5.jsonnet:1:1-32: function <builtin_filter> call
\ No newline at end of file
+    std.filter5.jsonnet:1:11-32: function <builtin_filter> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.filter6.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.filter6.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.filter6.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected function, got number
     argument <func> evaluation
-    std.filter6.jsonnet:1:1-22: function <builtin_filter> call
\ No newline at end of file
+    std.filter6.jsonnet:1:11-22: function <builtin_filter> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.filter8.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.filter8.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.filter8.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected function, got array
     argument <func> evaluation
-    std.filter8.jsonnet:1:1-37: function <builtin_filter> call
\ No newline at end of file
+    std.filter8.jsonnet:1:11-37: function <builtin_filter> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.filter_swapped_args.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.filter_swapped_args.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.filter_swapped_args.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected function, got array
     argument <func> evaluation
-    std.filter_swapped_args.jsonnet:1:1-39: function <builtin_filter> call
\ No newline at end of file
+    std.filter_swapped_args.jsonnet:1:11-39: function <builtin_filter> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.flatmap5.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.flatmap5.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.flatmap5.jsonnet.golden
@@ -1,5 +1,5 @@
 runtime error: a
-    std.flatmap5.jsonnet:1:21-29: error statement
-    std.flatmap5.jsonnet:2:10-49: function <builtin_flatmap> call
+    std.flatmap5.jsonnet:1:21-27: error statement
+    std.flatmap5.jsonnet:2:21-49: function <builtin_flatmap> call
     argument <x> evaluation
-    std.flatmap5.jsonnet:2:1-50:  function <builtin_type> call
\ No newline at end of file
+    std.flatmap5.jsonnet:2:9-50:  function <builtin_type> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.join7.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.join7.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.join7.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: in std.join all items should be strings
-    std.join7.jsonnet:1:1-28: function <builtin_join> call
\ No newline at end of file
+    std.join7.jsonnet:1:9-28: function <builtin_join> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.join8.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.join8.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.join8.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: in std.join all items should be arrays
-    std.join8.jsonnet:1:1-34: function <builtin_join> call
\ No newline at end of file
+    std.join8.jsonnet:1:9-34: function <builtin_join> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.makeArrayNamed3.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.makeArrayNamed3.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.makeArrayNamed3.jsonnet.golden
@@ -1,2 +1,2 @@
 parameter blahblah is not defined
-    std.makeArrayNamed3.jsonnet:1:1-55: function <builtin_make_array> call
\ No newline at end of file
+    std.makeArrayNamed3.jsonnet:1:14-55: function <builtin_make_array> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.makeArray_bad.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.makeArray_bad.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.makeArray_bad.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected BoundedNumber<0, 2147483647>, got string
     argument <sz> evaluation
-    std.makeArray_bad.jsonnet:1:1-37: function <builtin_make_array> call
\ No newline at end of file
+    std.makeArray_bad.jsonnet:1:14-37: function <builtin_make_array> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.makeArray_bad2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.makeArray_bad2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.makeArray_bad2.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected function, got string
     argument <func> evaluation
-    std.makeArray_bad2.jsonnet:1:1-26: function <builtin_make_array> call
\ No newline at end of file
+    std.makeArray_bad2.jsonnet:1:14-26: function <builtin_make_array> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.makeArray_noninteger.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.makeArray_noninteger.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.makeArray_noninteger.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: cannot convert number with fractional part to i32
     argument <sz> evaluation
-    std.makeArray_noninteger.jsonnet:1:1-35: function <builtin_make_array> call
\ No newline at end of file
+    std.makeArray_noninteger.jsonnet:1:14-35: function <builtin_make_array> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.makeArray_noninteger_big.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.makeArray_noninteger_big.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.makeArray_noninteger_big.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: number out of bounds: 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 not in 0..2147483647
     argument <sz> evaluation
-    std.makeArray_noninteger_big.jsonnet:1:1-37: function <builtin_make_array> call
\ No newline at end of file
+    std.makeArray_noninteger_big.jsonnet:1:14-37: function <builtin_make_array> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.manifestYamlDoc_error.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.manifestYamlDoc_error.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.manifestYamlDoc_error.jsonnet.golden
@@ -1,5 +1,5 @@
 runtime error: foo
-    std.manifestYamlDoc_error.jsonnet:1:31-43: error statement
+    std.manifestYamlDoc_error.jsonnet:1:31-37: error statement
     field <y> evaluation
     field <x> manifestification
-    std.manifestYamlDoc_error.jsonnet:1:1-48:  function <builtin_manifest_yaml_doc> call
\ No newline at end of file
+    std.manifestYamlDoc_error.jsonnet:1:20-48: function <builtin_manifest_yaml_doc> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.maxArrayOnEmpty.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.maxArrayOnEmpty.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.maxArrayOnEmpty.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: expected non-empty array
-    std.maxArrayOnEmpty.jsonnet:1:1-18: function <builtin_max_array> call
\ No newline at end of file
+    std.maxArrayOnEmpty.jsonnet:1:13-18: function <builtin_max_array> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.md5_6.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.md5_6.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.md5_6.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected string, got number
     argument <s> evaluation
-    std.md5_6.jsonnet:1:1-13: function <builtin_md5> call
\ No newline at end of file
+    std.md5_6.jsonnet:1:8-13: function <builtin_md5> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.minArrayOnEmpty.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.minArrayOnEmpty.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.minArrayOnEmpty.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: expected non-empty array
-    std.minArrayOnEmpty.jsonnet:1:1-18: function <builtin_min_array> call
\ No newline at end of file
+    std.minArrayOnEmpty.jsonnet:1:13-18: function <builtin_min_array> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.modulo2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.modulo2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.modulo2.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected number, got string
     argument <x> evaluation
-    std.modulo2.jsonnet:1:1-23: function <builtin_modulo> call
\ No newline at end of file
+    std.modulo2.jsonnet:1:11-23: function <builtin_modulo> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.modulo3.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.modulo3.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.modulo3.jsonnet.golden
@@ -1,3 +1,3 @@
 type error: expected number, got string
     argument <x> evaluation
-    std.modulo3.jsonnet:1:1-23: function <builtin_modulo> call
\ No newline at end of file
+    std.modulo3.jsonnet:1:11-23: function <builtin_modulo> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.primitiveEquals10.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.primitiveEquals10.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.primitiveEquals10.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: x
-    std.primitiveEquals10.jsonnet:1:21-31: error statement
+    std.primitiveEquals10.jsonnet:1:21-27: error statement
     argument <x> evaluation
-    std.primitiveEquals10.jsonnet:1:1-36:  function <builtin_primitive_equals> call
\ No newline at end of file
+    std.primitiveEquals10.jsonnet:1:20-36: function <builtin_primitive_equals> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.primitiveEquals13.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.primitiveEquals13.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.primitiveEquals13.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: primitiveEquals operates on primitive types, got array
-    std.primitiveEquals13.jsonnet:1:1-29: function <builtin_primitive_equals> call
\ No newline at end of file
+    std.primitiveEquals13.jsonnet:1:20-29: function <builtin_primitive_equals> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.primitiveEquals6.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.primitiveEquals6.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.primitiveEquals6.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: primitiveEquals operates on primitive types, got object
-    std.primitiveEquals6.jsonnet:1:1-29: function <builtin_primitive_equals> call
\ No newline at end of file
+    std.primitiveEquals6.jsonnet:1:20-29: function <builtin_primitive_equals> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.primitiveEquals7.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.primitiveEquals7.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.primitiveEquals7.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: cannot test equality of functions
-    std.primitiveEquals7.jsonnet:1:1-51: function <builtin_primitive_equals> call
\ No newline at end of file
+    std.primitiveEquals7.jsonnet:1:20-51: function <builtin_primitive_equals> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.primitiveEquals9.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.primitiveEquals9.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.primitiveEquals9.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: x
-    std.primitiveEquals9.jsonnet:1:25-35: error statement
+    std.primitiveEquals9.jsonnet:1:25-31: error statement
     argument <y> evaluation
-    std.primitiveEquals9.jsonnet:1:1-36:  function <builtin_primitive_equals> call
\ No newline at end of file
+    std.primitiveEquals9.jsonnet:1:20-36: function <builtin_primitive_equals> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.sort3.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.sort3.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.sort3.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: foo
-    std.sort3.jsonnet:1:16-28: error statement
-    std.sort3.jsonnet:1:1-30:  function <builtin_sort> call
\ No newline at end of file
+    std.sort3.jsonnet:1:16-22: error statement
+    std.sort3.jsonnet:1:9-30:  function <builtin_sort> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.sort4.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.sort4.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.sort4.jsonnet.golden
@@ -1,2 +1,2 @@
 binary operation array < number is not implemented
-    std.sort4.jsonnet:1:1-30: function <builtin_sort> call
\ No newline at end of file
+    std.sort4.jsonnet:1:9-30: function <builtin_sort> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/std.toString5.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/std.toString5.jsonnet.golden
+++ b/tests/go_testdata_golden_override/std.toString5.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: x
-    std.toString5.jsonnet:1:14-24: error statement
+    std.toString5.jsonnet:1:14-20: error statement
     argument <a> evaluation
-    std.toString5.jsonnet:1:1-25:  function <builtin_to_string> call
\ No newline at end of file
+    std.toString5.jsonnet:1:13-25: function <builtin_to_string> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/strReplace3.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/strReplace3.jsonnet.golden
+++ b/tests/go_testdata_golden_override/strReplace3.jsonnet.golden
@@ -1,2 +1,2 @@
 runtime error: 'from' string must not be zero length
-    strReplace3.jsonnet:1:1-36: function <builtin_str_replace> call
\ No newline at end of file
+    strReplace3.jsonnet:1:15-36: function <builtin_str_replace> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/tailstrict2.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/tailstrict2.jsonnet.golden
+++ b/tests/go_testdata_golden_override/tailstrict2.jsonnet.golden
@@ -1,3 +1,3 @@
 runtime error: xxx
-    tailstrict2.jsonnet:1:13-21: error statement
-    tailstrict2.jsonnet:2:14-19: function <e> call
\ No newline at end of file
+    tailstrict2.jsonnet:1:13-19: error statement
+    tailstrict2.jsonnet:2:15-19: function <e> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/too_many_arguments.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/too_many_arguments.jsonnet.golden
+++ b/tests/go_testdata_golden_override/too_many_arguments.jsonnet.golden
@@ -1,3 +1,3 @@
 too many args, function has 3
 Function has the following signature: (x, y, z)
-    too_many_arguments.jsonnet:1:1-36: function <anonymous> call
\ No newline at end of file
+    too_many_arguments.jsonnet:1:23-36: function <anonymous> call
\ No newline at end of file
modifiedtests/go_testdata_golden_override/type_error.jsonnet.goldendiffbeforeafterboth
--- a/tests/go_testdata_golden_override/type_error.jsonnet.golden
+++ b/tests/go_testdata_golden_override/type_error.jsonnet.golden
@@ -1,4 +1,4 @@
 runtime error: xxx
-    type_error.jsonnet:1:10-22: error statement
+    type_error.jsonnet:1:10-16: error statement
     argument <x> evaluation
-    type_error.jsonnet:1:1-23:  function <builtin_type> call
\ No newline at end of file
+    type_error.jsonnet:1:9-23:  function <builtin_type> call
\ No newline at end of file
modifiedtests/tests/snapshots/golden__golden@issue187.rev.jsonnet.snapdiffbeforeafterboth
--- a/tests/tests/snapshots/golden__golden@issue187.rev.jsonnet.snap
+++ b/tests/tests/snapshots/golden__golden@issue187.rev.jsonnet.snap
@@ -4,4 +4,4 @@
 input_file: tests/golden/issue187.rev.jsonnet
 ---
 runtime error: bad utf8
-    issue187.rev.jsonnet:1:1-92: function <builtin_decode_utf8> call
+    issue187.rev.jsonnet:1:15-92: function <builtin_decode_utf8> call
modifiedtests/tests/snapshots/golden__golden@issue23.jsonnet.snapdiffbeforeafterboth
--- a/tests/tests/snapshots/golden__golden@issue23.jsonnet.snap
+++ b/tests/tests/snapshots/golden__golden@issue23.jsonnet.snap
@@ -4,4 +4,4 @@
 input_file: tests/golden/issue23.jsonnet
 ---
 infinite recursion detected
-    issue23.jsonnet:1:1-26: import "issue23.jsonnet"
+    issue23.jsonnet:1:1-8: import "issue23.jsonnet"
modifiedtests/tests/snapshots/golden__golden@issue40.jsonnet.snapdiffbeforeafterboth
--- a/tests/tests/snapshots/golden__golden@issue40.jsonnet.snap
+++ b/tests/tests/snapshots/golden__golden@issue40.jsonnet.snap
@@ -5,4 +5,4 @@
 ---
 assert failed: is number
     issue40.jsonnet:6:10-31: assertion failure
-    issue40.jsonnet:9:1-32:  function <builtin_manifest_json_ex> call
+    issue40.jsonnet:9:19-32: function <builtin_manifest_json_ex> call
modifiedtests/tests/snapshots/golden__golden@test_assertThrow.jsonnet.snapdiffbeforeafterboth
--- a/tests/tests/snapshots/golden__golden@test_assertThrow.jsonnet.snap
+++ b/tests/tests/snapshots/golden__golden@test_assertThrow.jsonnet.snap
@@ -4,4 +4,4 @@
 input_file: tests/golden/test_assertThrow.jsonnet
 ---
 runtime error: expected argument to throw on evaluation, but it returned instead
-    test_assertThrow.jsonnet:2:1-26: function <assert_throw> call
+    test_assertThrow.jsonnet:2:17-26: function <assert_throw> call