--- a/crates/jrsonnet-evaluator/src/error.rs +++ b/crates/jrsonnet-evaluator/src/error.rs @@ -24,8 +24,8 @@ NoTopLevelObjectFound, #[error("self is only usable inside objects")] CantUseSelfOutsideOfObject, - #[error("super is only usable inside objects")] - CantUseSuperOutsideOfObject, + #[error("no super found")] + NoSuperFound, #[error("for loop can only iterate over arrays")] InComprehensionCanOnlyIterateOverArray, --- a/crates/jrsonnet-evaluator/src/evaluate.rs +++ b/crates/jrsonnet-evaluator/src/evaluate.rs @@ -418,6 +418,13 @@ Literal(LiteralType::This) => { Val::Obj(context.this().clone().ok_or(CantUseSelfOutsideOfObject)?) } + Literal(LiteralType::Super) => Val::Obj( + context + .super_obj() + .clone() + .ok_or(NoSuperFound)? + .with_this(context.this().clone().unwrap()), + ), Literal(LiteralType::Dollar) => { Val::Obj(context.dollar().clone().ok_or(NoTopLevelObjectFound)?) } @@ -434,15 +441,6 @@ || format!("variable <{}>", name), || Ok(context.binding(name.clone())?.evaluate()?), )?, - Index(LocExpr(v, _), index) if matches!(&**v, Expr::Literal(LiteralType::Super)) => { - let name = evaluate(context.clone(), index)?.try_cast_str("object index")?; - context - .super_obj() - .clone() - .expect("no super found") - .get_raw(name, Some(&context.this().clone().expect("no this found")))? - .expect("value not found") - } Index(value, index) => { match (evaluate(context.clone(), value)?, evaluate(context, index)?) { (Val::Obj(v), Val::Str(s)) => { @@ -620,6 +618,5 @@ import_location.pop(); Val::Str(with_state(|s| s.import_file_str(import_location, path))?) } - Literal(LiteralType::Super) => throw!(StandaloneSuper), }) } --- a/crates/jrsonnet-evaluator/src/lib.rs +++ b/crates/jrsonnet-evaluator/src/lib.rs @@ -931,6 +931,25 @@ Ok(()) } + #[test] + fn standalone_super() -> crate::error::Result<()> { + assert_eval!( + r#" + local obj = { + a: 1, + b: 2, + c: 3, + }; + local test = obj + { + fields: std.objectFields(super), + d: 5, + }; + test.fields == ['a', 'b', 'c'] + "# + ); + Ok(()) + } + struct TestImportResolver(IStr); impl crate::import::ImportResolver for TestImportResolver { fn resolve_file(&self, _: &PathBuf, _: &PathBuf) -> crate::error::Result> {