difftreelog
refactor(ir) flatten obj member
in: master
7 files changed
crates/jrsonnet-evaluator/src/async_import.rsdiffbeforeafterboth4use jrsonnet_gcmodule::Acyclic;4use jrsonnet_gcmodule::Acyclic;5use jrsonnet_parser::{5use jrsonnet_parser::{6 ArgsDesc, AssertExpr, AssertStmt, BindSpec, CompSpec, Destruct, Expr, FieldMember, FieldName,6 ArgsDesc, AssertExpr, AssertStmt, BindSpec, CompSpec, Destruct, Expr, FieldMember, FieldName,7 ForSpecData, IfElse, IfSpecData, ImportKind, Member, ObjBody, Param, ParamsDesc,7 ForSpecData, IfElse, IfSpecData, ImportKind, ObjBody, Param, ParamsDesc,8 ParserSettings, Slice, SliceDesc, Source, SourcePath, Spanned,8 ParserSettings, Slice, SliceDesc, Source, SourcePath, Spanned,9};9};10use rustc_hash::FxHashMap;10use rustc_hash::FxHashMap;102 }102 }103 fn in_obj(obj: &ObjBody, out: &mut FoundImports) {103 fn in_obj(obj: &ObjBody, out: &mut FoundImports) {104 match obj {104 match obj {105 ObjBody::MemberList(v) => {105 ObjBody::MemberList(obj) => {106 for member in v {106 for FieldMember {107 match member {108 Member::Field(FieldMember {109 name,107 name,110 params,108 params,111 value,109 value,112 ..110 ..113 }) => {111 } in &obj.fields112 {114 match name {113 match name {115 FieldName::Fixed(_) => {}114 FieldName::Fixed(_) => {}120 }119 }121 find_imports(value, out);120 find_imports(value, out);122 }121 }123 Member::BindStmt(_) => todo!(),122 for _ in &*obj.locals {124 Member::AssertStmt(assert) => {123 todo!()125 find_imports(&assert.0, out);124 }126 if let Some(expr) = &assert.1 {125 for assert in &*obj.asserts {127 find_imports(expr, out);126 find_imports(&assert.0, out);128 }127 if let Some(expr) = &assert.1 {129 }128 find_imports(expr, out);130 }129 }131 }130 }132 }131 }133 ObjBody::ObjComp(_) => todo!(),132 ObjBody::ObjComp(_) => todo!(),134 }133 }crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth4use jrsonnet_interner::IStr;4use jrsonnet_interner::IStr;5use jrsonnet_parser::{5use jrsonnet_parser::{6 ArgsDesc, AssertStmt, BinaryOpType, BindSpec, CompSpec, Expr, FieldMember, FieldName,6 ArgsDesc, AssertStmt, BinaryOpType, BindSpec, CompSpec, Expr, FieldMember, FieldName,7 ForSpecData, IfSpecData, ImportKind, LiteralType, Member, ObjBody, ParamsDesc, Spanned,7 ForSpecData, IfSpecData, ImportKind, LiteralType, ObjBody, ObjMembers, ParamsDesc, Spanned,8};8};9use jrsonnet_types::ValType;9use jrsonnet_types::ValType;10use rustc_hash::FxHashMap;10use rustc_hash::FxHashMap;282}282}283283284#[allow(clippy::too_many_lines)]284#[allow(clippy::too_many_lines)]285pub fn evaluate_member_list_object(ctx: Context, members: &[Member]) -> Result<ObjValue> {285pub fn evaluate_member_list_object(ctx: Context, members: &ObjMembers) -> Result<ObjValue> {286 let mut builder = ObjValueBuilder::new();286 let mut builder = ObjValueBuilder::new();287 let locals = Rc::new(287 let locals = members.locals.clone();288 members289 .iter()290 .filter_map(|m| match m {291 Member::BindStmt(bind) => Some(bind.clone()),292 _ => None,293 })294 .collect::<Vec<_>>(),295 );296288297 // We have single context for all fields, so we can cache binds289 // We have single context for all fields, so we can cache binds298 let uctx = CachedUnbound::new(evaluate_object_locals(ctx.clone(), locals));290 let uctx = CachedUnbound::new(evaluate_object_locals(ctx.clone(), locals));299291300 for member in members {292 for field in &members.fields {301 match member {293 evaluate_field_member(&mut builder, ctx.clone(), uctx.clone(), &field)?;302 Member::Field(field) => {294 }295303 evaluate_field_member(&mut builder, ctx.clone(), uctx.clone(), field)?;296 if !members.asserts.is_empty() {304 }305 Member::AssertStmt(stmt) => {306 #[derive(Trace)]297 #[derive(Trace)]307 struct ObjectAssert<B: Trace> {298 struct ObjectAssert<B: Trace> {308 uctx: B,299 uctx: B,309 assert: Rc<AssertStmt>,300 asserts: Rc<Vec<AssertStmt>>,310 }301 }311 impl<B: Unbound<Bound = Context>> ObjectAssertion for ObjectAssert<B> {302 impl<B: Unbound<Bound = Context>> ObjectAssertion for ObjectAssert<B> {312 fn run(&self, sup_this: SupThis) -> Result<()> {303 fn run(&self, sup_this: SupThis) -> Result<()> {313 let ctx = self.uctx.bind(sup_this)?;304 let ctx = self.uctx.bind(sup_this)?;305 for assert in &*self.asserts {314 evaluate_assert(ctx, &self.assert)306 evaluate_assert(ctx.clone(), &assert)?;307 }308 Ok(())315 }309 }316 }310 }317 builder.assert(ObjectAssert {311 builder.assert(ObjectAssert {318 uctx: uctx.clone(),312 uctx: uctx.clone(),319 assert: stmt.clone(),313 asserts: members.asserts.clone(),320 });314 });321 }315 }322 Member::BindStmt(_) => {316323 // Already handled324 }325 }326 }327 Ok(builder.build())317 Ok(builder.build())328}318}329319332 ObjBody::MemberList(members) => evaluate_member_list_object(ctx, members)?,322 ObjBody::MemberList(members) => evaluate_member_list_object(ctx, members)?,333 ObjBody::ObjComp(obj) => {323 ObjBody::ObjComp(obj) => {334 let mut builder = ObjValueBuilder::new();324 let mut builder = ObjValueBuilder::new();335 let locals = Rc::new(325 let locals = obj.locals.clone();336 obj.pre_locals337 .iter()338 .chain(obj.post_locals.iter())339 .cloned()340 .collect::<Vec<_>>(),341 );342 evaluate_comp(ctx, &obj.compspecs, &mut |ctx| {326 evaluate_comp(ctx, &obj.compspecs, &mut |ctx| {343 let uctx = evaluate_object_locals(ctx.clone(), locals.clone());327 let uctx = evaluate_object_locals(ctx.clone(), locals.clone());344328crates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth47}47}484849#[derive(Debug, PartialEq, Acyclic)]49#[derive(Debug, PartialEq, Acyclic)]50pub enum Member {50pub(crate) enum Member {51 Field(FieldMember),51 Field(FieldMember),52 BindStmt(BindSpec),52 BindStmt(BindSpec),53 AssertStmt(Rc<AssertStmt>),53 AssertStmt(AssertStmt),54}54}555556#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)]56#[derive(Debug, Clone, Copy, PartialEq, Eq, Acyclic)]240 }240 }241}241}242242243#[derive(Debug, Clone, PartialEq, Acyclic)]243#[derive(Debug, PartialEq, Acyclic)]244pub enum BindSpec {244pub enum BindSpec {245 Field {245 Field {246 into: Destruct,246 into: Destruct,275275276#[derive(Debug, PartialEq, Acyclic)]276#[derive(Debug, PartialEq, Acyclic)]277pub struct ObjComp {277pub struct ObjComp {278 pub pre_locals: Vec<BindSpec>,278 pub locals: Rc<Vec<BindSpec>>,279 pub field: Rc<FieldMember>,279 pub field: Rc<FieldMember>,280 pub post_locals: Vec<BindSpec>,281 pub compspecs: Vec<CompSpec>,280 pub compspecs: Vec<CompSpec>,282}281}282283#[derive(Debug, PartialEq, Acyclic)]284pub struct ObjMembers {285 pub locals: Rc<Vec<BindSpec>>,286 pub asserts: Rc<Vec<AssertStmt>>,287 pub fields: Vec<FieldMember>,288}283289284#[derive(Debug, PartialEq, Acyclic)]290#[derive(Debug, PartialEq, Acyclic)]285pub enum ObjBody {291pub enum ObjBody {286 MemberList(Vec<Member>),292 MemberList(ObjMembers),287 ObjComp(ObjComp),293 ObjComp(ObjComp),288}294}289295crates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth139 / obj:destruct_object(s) {obj}139 / obj:destruct_object(s) {obj}140140141 pub rule bind(s: &ParserSettings) -> expr::BindSpec141 pub rule bind(s: &ParserSettings) -> expr::BindSpec142 = into:destruct(s) _ "=" _ expr:expr(s) {expr::BindSpec::Field{into, value: Rc::new(expr)}}142 = into:destruct(s) _ "=" _ value:expr(s) {expr::BindSpec::Field{into, value: Rc::new(value)}}143 / name:id() _ "(" _ params:params(s) _ ")" _ "=" _ expr:expr(s) {expr::BindSpec::Function{name, params, value: Rc::new(expr)}}143 / name:id() _ "(" _ params:params(s) _ ")" _ "=" _ value:expr(s) {expr::BindSpec::Function{name, params, value: Rc::new(value)}}144144145 pub rule assertion(s: &ParserSettings) -> expr::AssertStmt145 pub rule assertion(s: &ParserSettings) -> expr::AssertStmt146 = keyword("assert") _ cond:expr(s) msg:(_ ":" _ e:expr(s) {e})? { expr::AssertStmt(cond, msg) }146 = keyword("assert") _ cond:expr(s) msg:(_ ":" _ e:expr(s) {e})? { expr::AssertStmt(cond, msg) }207 = keyword("local") _ bind:bind(s) {bind}207 = keyword("local") _ bind:bind(s) {bind}208 pub rule member(s: &ParserSettings) -> expr::Member208 pub rule member(s: &ParserSettings) -> expr::Member209 = bind:obj_local(s) {expr::Member::BindStmt(bind)}209 = bind:obj_local(s) {expr::Member::BindStmt(bind)}210 / assertion:assertion(s) {expr::Member::AssertStmt(Rc::new(assertion))}210 / assertion:assertion(s) {expr::Member::AssertStmt(assertion)}211 / field:field(s) {expr::Member::Field(field)}211 / field:field(s) {expr::Member::Field(field)}212 pub rule objinside(s: &ParserSettings) -> expr::ObjBody212 pub rule objinside(s: &ParserSettings) -> expr::ObjBody213 = 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})? {213 = 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})? {214 let mut compspecs = vec![CompSpec::ForSpec(forspec)];214 let mut compspecs = vec![CompSpec::ForSpec(forspec)];215 compspecs.extend(others.unwrap_or_default());215 compspecs.extend(others.unwrap_or_default());216 let mut locals = pre_locals;217 locals.extend(post_locals);216 expr::ObjBody::ObjComp(expr::ObjComp{218 expr::ObjBody::ObjComp(expr::ObjComp{217 pre_locals,219 locals: Rc::new(locals),218 field: Rc::new(field),220 field: Rc::new(field),219 post_locals,220 compspecs,221 compspecs,221 })222 })222 }223 }223 / members:(member(s) ** comma()) comma()? {expr::ObjBody::MemberList(members)}224 / members:(member(s) ** comma()) comma()? {225 let mut locals = Vec::new();226 let mut asserts = Vec::new();227 let mut fields = Vec::new();228 for member in members {229 match member {230 Member::Field(field_member) => fields.push(field_member),231 Member::BindStmt(bind_spec) => locals.push(bind_spec),232 Member::AssertStmt(assert_stmt) => asserts.push(assert_stmt),233 }234 }235 expr::ObjBody::MemberList(ObjMembers {236 locals: Rc::new(locals), asserts: Rc::new(asserts), fields237 })238 }224 pub rule ifspec(s: &ParserSettings) -> IfSpecData239 pub rule ifspec(s: &ParserSettings) -> IfSpecData225 = keyword("if") _ expr:expr(s) {IfSpecData(expr)}240 = keyword("if") _ expr:expr(s) {IfSpecData(expr)}crates/jrsonnet-parser/src/snapshots/jrsonnet_parser__tests__add_location_info_to_all_sub_expressions.snapdiffbeforeafterboth7 lhs: ObjExtend(7 lhs: ObjExtend(8 Obj(8 Obj(9 MemberList(9 MemberList(10 [],10 ObjMembers {11 locals: [],12 asserts: [],13 fields: [],14 },11 ),15 ),12 ) from virtual:<test>:0-2,16 ) from virtual:<test>:0-2,13 MemberList(17 MemberList(14 [18 ObjMembers {15 BindStmt(19 locals: [16 Field {20 Field {17 into: Full(21 into: Full(18 "x",22 "x",21 1.0,25 1.0,22 ) from virtual:<test>:15-16,26 ) from virtual:<test>:15-16,23 },27 },24 ),28 ],25 Field(29 asserts: [],30 fields: [26 FieldMember {31 FieldMember {27 name: Fixed(32 name: Fixed(28 "x",33 "x",34 "x",39 "x",35 ) from virtual:<test>:21-22,40 ) from virtual:<test>:21-22,36 },41 },37 ),42 ],38 ],43 },39 ),44 ),40 ) from virtual:<test>:0-24,45 ) from virtual:<test>:0-24,41 op: Add,46 op: Add,42 rhs: Obj(47 rhs: Obj(43 MemberList(48 MemberList(44 [],49 ObjMembers {50 locals: [],51 asserts: [],52 fields: [],53 },45 ),54 ),46 ) from virtual:<test>:27-29,55 ) from virtual:<test>:27-29,47 },56 },crates/jrsonnet-parser/src/snapshots/jrsonnet_parser__tests__empty_object.snapdiffbeforeafterboth4---4---5Obj(5Obj(6 MemberList(6 MemberList(7 [],7 ObjMembers {8 locals: [],9 asserts: [],10 fields: [],11 },8 ),12 ),9) from virtual:<test>:0-213) from virtual:<test>:0-21014crates/jrsonnet-parser/src/snapshots/jrsonnet_parser__tests__missing_newline_between_comment_and_eof.snapdiffbeforeafterboth4---4---5Obj(5Obj(6 MemberList(6 MemberList(7 [7 ObjMembers {8 locals: [],8 Field(9 asserts: [],10 fields: [9 FieldMember {11 FieldMember {10 name: Fixed(12 name: Fixed(11 "a",13 "a",17 1.0,19 1.0,18 ) from virtual:<test>:3-4,20 ) from virtual:<test>:3-4,19 },21 },20 ),22 ],21 ],23 },22 ),24 ),23) from virtual:<test>:0-525) from virtual:<test>:0-52426