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

difftreelog

fix field in super should not be interpreted with standalone-super concept.

Yaroslav Bolyukin2024-03-20parent: #a7b20f9.patch.diff
in: master
Jsonnet spec defines special behavior for `super.field` and
`field in super` expressions, while in jrsonnet it is implemented by
standalone-super concept, with optimizations in case of `super.field`.

However, standalone-super is conflicting with `field in super` behavior,
so special handling is needed for this expression.

3 files changed

modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
3use jrsonnet_gcmodule::{Cc, Trace};3use jrsonnet_gcmodule::{Cc, Trace};
4use jrsonnet_interner::IStr;4use jrsonnet_interner::IStr;
5use jrsonnet_parser::{5use jrsonnet_parser::{
6 ArgsDesc, AssertStmt, BindSpec, CompSpec, Expr, FieldMember, FieldName, ForSpecData,6 ArgsDesc, AssertStmt, BinaryOpType, BindSpec, CompSpec, Expr, FieldMember, FieldName,
7 IfSpecData, LiteralType, LocExpr, Member, ObjBody, ParamsDesc,7 ForSpecData, IfSpecData, LiteralType, LocExpr, Member, ObjBody, ParamsDesc,
8};8};
9use jrsonnet_types::ValType;9use jrsonnet_types::ValType;
439 Parened(e) => evaluate(ctx, e)?,439 Parened(e) => evaluate(ctx, e)?,
440 Str(v) => Val::string(v.clone()),440 Str(v) => Val::string(v.clone()),
441 Num(v) => Val::new_checked_num(*v)?,441 Num(v) => Val::new_checked_num(*v)?,
442 // I have tried to remove special behavior from super by implementing standalone-super
443 // expresion, but looks like this case still needs special treatment.
444 //
445 // Note that other jsonnet implementations will fail on `if value in (super)` expression,
446 // because the standalone super literal is not supported, that is because in other
447 // implementations `in super` treated differently from in `smth_else`.
448 BinaryOp(field, BinaryOpType::In, e)
449 if matches!(&*e.0, Expr::Literal(LiteralType::Super)) =>
450 {
451 let Some(super_obj) = ctx.super_obj() else {
452 return Ok(Val::Bool(false));
453 };
454 let field = evaluate(ctx.clone(), field)?;
455 Val::Bool(super_obj.has_field_ex(field.to_string()?, true))
456 }
442 BinaryOp(v1, o, v2) => evaluate_binary_op_special(ctx, v1, *o, v2)?,457 BinaryOp(v1, o, v2) => evaluate_binary_op_special(ctx, v1, *o, v2)?,
443 UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(ctx, v)?)?,458 UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(ctx, v)?)?,
444 Var(name) => State::push(459 Var(name) => State::push(
addedtests/golden/issue153.jsonnetdiffbeforeafterboth

no changes

addedtests/golden/issue153.jsonnet.goldendiffbeforeafterboth

no changes