From c3b4574a459ad4c97c82af92f5550e7631962257 Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Wed, 09 Nov 2022 18:54:18 +0000 Subject: [PATCH] fix: unify handling of field in obj and objcomp --- --- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs +++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs @@ -113,6 +113,97 @@ UnboundLocals { fctx, locals } } +pub fn evaluate_field_member + Clone>( + builder: &mut ObjValueBuilder, + ctx: Context, + uctx: B, + member: &FieldMember, +) -> Result<()> { + match member { + FieldMember { + name, + plus, + params: None, + visibility, + value, + } => { + #[derive(Trace)] + struct UnboundValue { + uctx: B, + value: LocExpr, + name: IStr, + } + impl> Unbound for UnboundValue { + type Bound = Val; + fn bind(&self, sup: Option, this: Option) -> Result { + Ok(evaluate_named( + self.uctx.bind(sup, this)?, + &self.value, + self.name.clone(), + )?) + } + } + + let name = evaluate_field_name(ctx.clone(), name)?; + let Some(name) = name else { + return Ok(()); + }; + + builder + .member(name.clone()) + .with_add(*plus) + .with_visibility(*visibility) + .with_location(value.1.clone()) + .bindable(tb!(UnboundValue { + uctx: uctx.clone(), + value: value.clone(), + name: name.clone() + }))?; + } + FieldMember { + name, + params: Some(params), + value, + .. + } => { + #[derive(Trace)] + struct UnboundMethod { + uctx: B, + value: LocExpr, + params: ParamsDesc, + name: IStr, + } + impl> Unbound for UnboundMethod { + type Bound = Val; + fn bind(&self, sup: Option, this: Option) -> Result { + Ok(evaluate_method( + self.uctx.bind(sup, this)?, + self.name.clone(), + self.params.clone(), + self.value.clone(), + )) + } + } + + let Some(name) = evaluate_field_name(ctx.clone(), name)? else { + return Ok(()); + }; + + builder + .member(name.clone()) + .hide() + .with_location(value.1.clone()) + .bindable(tb!(UnboundMethod { + uctx: uctx.clone(), + value: value.clone(), + params: params.clone(), + name: name.clone() + }))?; + } + } + Ok(()) +} + #[allow(clippy::too_many_lines)] pub fn evaluate_member_list_object(ctx: Context, members: &[Member]) -> Result { let mut builder = ObjValueBuilder::new(); @@ -133,87 +224,12 @@ for member in members.iter() { match member { - Member::Field(FieldMember { - name, - plus, - params: None, - visibility, - value, - }) => { - #[derive(Trace)] - struct UnboundValue { - uctx: B, - value: LocExpr, - name: IStr, - } - impl> Unbound for UnboundValue { - type Bound = Val; - fn bind(&self, sup: Option, this: Option) -> Result { - Ok(evaluate_named( - self.uctx.bind(sup, this)?, - &self.value, - self.name.clone(), - )?) - } - } - - let name = evaluate_field_name(ctx.clone(), name)?; - let Some(name) = name else { - continue; - }; - - builder - .member(name.clone()) - .with_add(*plus) - .with_visibility(*visibility) - .with_location(value.1.clone()) - .bindable(tb!(UnboundValue { - uctx: uctx.clone(), - value: value.clone(), - name: name.clone() - }))?; + Member::Field(field) => { + evaluate_field_member(&mut builder, ctx.clone(), uctx.clone(), &field)? } - Member::Field(FieldMember { - name, - params: Some(params), - value, - .. - }) => { - #[derive(Trace)] - struct UnboundMethod { - uctx: B, - value: LocExpr, - params: ParamsDesc, - name: IStr, - } - impl> Unbound for UnboundMethod { - type Bound = Val; - fn bind(&self, sup: Option, this: Option) -> Result { - Ok(evaluate_method( - self.uctx.bind(sup, this)?, - self.name.clone(), - self.params.clone(), - self.value.clone(), - )) - } - } - - let Some(name) = evaluate_field_name(ctx.clone(), name)? else { - continue; - }; - - builder - .member(name.clone()) - .hide() - .with_location(value.1.clone()) - .bindable(tb!(UnboundMethod { - uctx: uctx.clone(), - value: value.clone(), - params: params.clone(), - name: name.clone() - }))?; + Member::BindStmt(_) => { + // Already handled } - Member::BindStmt(_) => {} Member::AssertStmt(stmt) => { #[derive(Trace)] struct ObjectAssert { @@ -252,50 +268,11 @@ ); let mut ctxs = vec![]; evaluate_comp(ctx, &obj.compspecs, &mut |ctx| { - let key = evaluate(ctx.clone(), &obj.key)?; let fctx = Context::new_future(); - ctxs.push((ctx, fctx.clone())); + ctxs.push((ctx.clone(), fctx.clone())); let uctx = evaluate_object_locals(fctx, locals.clone()); - match key { - Val::Null => {} - Val::Str(n) => { - #[derive(Trace)] - struct UnboundValue { - uctx: B, - value: LocExpr, - } - impl> Unbound for UnboundValue { - type Bound = Val; - fn bind( - &self, - sup: Option, - this: Option, - ) -> Result { - Ok(evaluate( - self.uctx.bind(sup, this.clone())?.extend( - GcHashMap::new(), - None, - None, - this, - ), - &self.value, - )?) - } - } - builder - .member(n) - .with_location(obj.value.1.clone()) - .with_add(obj.plus) - .bindable(tb!(UnboundValue { - uctx, - value: obj.value.clone(), - }))?; - } - v => throw!(FieldMustBeStringGot(v.value_type())), - } - - Ok(()) + evaluate_field_member(&mut builder, ctx, uctx, &obj.field) })?; let this = builder.build(); --- a/crates/jrsonnet-parser/src/expr.rs +++ b/crates/jrsonnet-parser/src/expr.rs @@ -268,9 +268,7 @@ #[derive(Debug, PartialEq, Trace)] pub struct ObjComp { pub pre_locals: Vec, - pub key: LocExpr, - pub plus: bool, - pub value: LocExpr, + pub field: FieldMember, pub post_locals: Vec, pub compspecs: Vec, } --- a/crates/jrsonnet-parser/src/lib.rs +++ b/crates/jrsonnet-parser/src/lib.rs @@ -194,14 +194,12 @@ / assertion:assertion(s) {expr::Member::AssertStmt(assertion)} / field:field(s) {expr::Member::Field(field)} pub rule objinside(s: &ParserSettings) -> expr::ObjBody - = pre_locals:(b: obj_local(s) comma() {b})* "[" _ key:expr(s) _ "]" _ plus:"+"? _ ":" _ value:expr(s) post_locals:(comma() b:obj_local(s) {b})* _ ("," _)? forspec:forspec(s) others:(_ rest:compspec(s) {rest})? { + = pre_locals:(b: obj_local(s) comma() {b})* field:field(s) post_locals:(comma() b:obj_local(s) {b})* _ ("," _)? forspec:forspec(s) others:(_ rest:compspec(s) {rest})? { let mut compspecs = vec![CompSpec::ForSpec(forspec)]; compspecs.extend(others.unwrap_or_default()); expr::ObjBody::ObjComp(expr::ObjComp{ pre_locals, - key, - plus: plus.is_some(), - value, + field, post_locals, compspecs, }) -- gitstuff