difftreelog
Add location info to all sub-expressions
in: master
2 files changed
crates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth404 };404 };405}405}406407/// Creates LocExpr without location info408#[macro_export]409macro_rules! loc_expr_todo {410 ($expr:expr) => {411 LocExpr(Rc::new($expr), None)412 };413}414406crates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth171718macro_rules! expr_bin {18macro_rules! expr_bin {19 ($a:ident $op:ident $b:ident) => {19 ($a:ident $op:ident $b:ident) => {20 loc_expr_todo!(Expr::BinaryOp($a, $op, $b))20 Expr::BinaryOp($a, $op, $b)21 };21 };22}22}23macro_rules! expr_un {23macro_rules! expr_un {24 ($op:ident $a:ident) => {24 ($op:ident $a:ident) => {25 loc_expr_todo!(Expr::UnaryOp($op, $a))25 Expr::UnaryOp($op, $a)26 };26 };27}27}2828555556 rule keyword(id: &'static str) -> ()56 rule keyword(id: &'static str) -> ()57 = ##parse_string_literal(id) end_of_ident()57 = ##parse_string_literal(id) end_of_ident()58 // Adds location data information to existing expression59 rule l(s: &ParserSettings, x: rule<Expr>) -> LocExpr60 = start:position!() v:x() end:position!() {loc_expr!(v, s.loc_data, (s.file_name.clone(), start, end))}615862 pub rule param(s: &ParserSettings) -> expr::Param = name:$(id()) expr:(_ "=" _ expr:expr(s){expr})? { expr::Param(name.into(), expr) }59 pub rule param(s: &ParserSettings) -> expr::Param = name:$(id()) expr:(_ "=" _ expr:expr(s){expr})? { expr::Param(name.into(), expr) }63 pub rule params(s: &ParserSettings) -> expr::ParamsDesc60 pub rule params(s: &ParserSettings) -> expr::ParamsDesc166 = keyword("for") _ id:$(id()) _ keyword("in") _ cond:expr(s) {ForSpecData(id.into(), cond)}163 = keyword("for") _ id:$(id()) _ keyword("in") _ cond:expr(s) {ForSpecData(id.into(), cond)}167 pub rule compspec(s: &ParserSettings) -> Vec<expr::CompSpec>164 pub rule compspec(s: &ParserSettings) -> Vec<expr::CompSpec>168 = s:(i:ifspec(s) { expr::CompSpec::IfSpec(i) } / f:forspec(s) {expr::CompSpec::ForSpec(f)} ) ** _ {s}165 = s:(i:ifspec(s) { expr::CompSpec::IfSpec(i) } / f:forspec(s) {expr::CompSpec::ForSpec(f)} ) ** _ {s}169 pub rule local_expr(s: &ParserSettings) -> LocExpr166 pub rule local_expr(s: &ParserSettings) -> Expr170 = l(s,<keyword("local") _ binds:bind(s) ** comma() _ ";" _ expr:expr(s) { Expr::LocalExpr(binds, expr) }>)167 = keyword("local") _ binds:bind(s) ** comma() _ ";" _ expr:expr(s) { Expr::LocalExpr(binds, expr) }171 pub rule string_expr(s: &ParserSettings) -> LocExpr168 pub rule string_expr(s: &ParserSettings) -> Expr172 = l(s, <s:string() {Expr::Str(s.into())}>)169 = s:string() {Expr::Str(s.into())}173 pub rule obj_expr(s: &ParserSettings) -> LocExpr170 pub rule obj_expr(s: &ParserSettings) -> Expr174 = l(s,<"{" _ body:objinside(s) _ "}" {Expr::Obj(body)}>)171 = "{" _ body:objinside(s) _ "}" {Expr::Obj(body)}175 pub rule array_expr(s: &ParserSettings) -> LocExpr172 pub rule array_expr(s: &ParserSettings) -> Expr176 = l(s,<"[" _ elems:(expr(s) ** comma()) _ comma()? "]" {Expr::Arr(elems)}>)173 = "[" _ elems:(expr(s) ** comma()) _ comma()? "]" {Expr::Arr(elems)}177 pub rule array_comp_expr(s: &ParserSettings) -> LocExpr174 pub rule array_comp_expr(s: &ParserSettings) -> Expr178 = l(s,<"[" _ expr:expr(s) _ comma()? _ forspec:forspec(s) _ others:(others: compspec(s) _ {others})? "]" {175 = "[" _ expr:expr(s) _ comma()? _ forspec:forspec(s) _ others:(others: compspec(s) _ {others})? "]" {179 let mut specs = vec![CompSpec::ForSpec(forspec)];176 let mut specs = vec![CompSpec::ForSpec(forspec)];180 specs.extend(others.unwrap_or_default());177 specs.extend(others.unwrap_or_default());181 Expr::ArrComp(expr, specs)178 Expr::ArrComp(expr, specs)182 }>)179 }183 pub rule number_expr(s: &ParserSettings) -> LocExpr180 pub rule number_expr(s: &ParserSettings) -> Expr184 = l(s,<n:number() { expr::Expr::Num(n) }>)181 = n:number() { expr::Expr::Num(n) }185 pub rule var_expr(s: &ParserSettings) -> LocExpr182 pub rule var_expr(s: &ParserSettings) -> Expr186 = l(s,<n:$(id()) { expr::Expr::Var(n.into()) }>)183 = n:$(id()) { expr::Expr::Var(n.into()) }187 pub rule if_then_else_expr(s: &ParserSettings) -> LocExpr184 pub rule if_then_else_expr(s: &ParserSettings) -> Expr188 = l(s,<cond:ifspec(s) _ keyword("then") _ cond_then:expr(s) cond_else:(_ keyword("else") _ e:expr(s) {e})? {Expr::IfElse{185 = cond:ifspec(s) _ keyword("then") _ cond_then:expr(s) cond_else:(_ keyword("else") _ e:expr(s) {e})? {Expr::IfElse{189 cond,186 cond,190 cond_then,187 cond_then,191 cond_else,188 cond_else,192 }}>)189 }}193190194 pub rule literal(s: &ParserSettings) -> LocExpr191 pub rule literal(s: &ParserSettings) -> Expr195 = l(s,<v:(192 = v:(196 keyword("null") {LiteralType::Null}193 keyword("null") {LiteralType::Null}197 / keyword("true") {LiteralType::True}194 / keyword("true") {LiteralType::True}198 / keyword("false") {LiteralType::False}195 / keyword("false") {LiteralType::False}199 / keyword("self") {LiteralType::This}196 / keyword("self") {LiteralType::This}200 / keyword("$") {LiteralType::Dollar}197 / keyword("$") {LiteralType::Dollar}201 / keyword("super") {LiteralType::Super}198 / keyword("super") {LiteralType::Super}202 ) {Expr::Literal(v)}>)199 ) {Expr::Literal(v)}203200204 pub rule expr_basic(s: &ParserSettings) -> LocExpr201 pub rule expr_basic(s: &ParserSettings) -> Expr205 = literal(s)202 = literal(s)206203207 / quiet!{l(s,<"$intrinsic(" name:$(id()) ")" {Expr::Intrinsic(name.into())}>)}204 / quiet!{"$intrinsic(" name:$(id()) ")" {Expr::Intrinsic(name.into())}}208205209 / string_expr(s) / number_expr(s)206 / string_expr(s) / number_expr(s)210 / array_expr(s)207 / array_expr(s)211 / obj_expr(s)208 / obj_expr(s)212 / array_expr(s)209 / array_expr(s)213 / array_comp_expr(s)210 / array_comp_expr(s)214211215 / l(s,<keyword("importstr") _ path:string() {Expr::ImportStr(PathBuf::from(path))}>)212 / keyword("importstr") _ path:string() {Expr::ImportStr(PathBuf::from(path))}216 / l(s,<keyword("import") _ path:string() {Expr::Import(PathBuf::from(path))}>)213 / keyword("import") _ path:string() {Expr::Import(PathBuf::from(path))}217214218 / var_expr(s)215 / var_expr(s)219 / local_expr(s)216 / local_expr(s)220 / if_then_else_expr(s)217 / if_then_else_expr(s)221218222 / l(s,<keyword("function") _ "(" _ params:params(s) _ ")" _ expr:expr(s) {Expr::Function(params, expr)}>)219 / keyword("function") _ "(" _ params:params(s) _ ")" _ expr:expr(s) {Expr::Function(params, expr)}223 / l(s,<assertion:assertion(s) _ ";" _ expr:expr(s) { Expr::AssertExpr(assertion, expr) }>)220 / assertion:assertion(s) _ ";" _ expr:expr(s) { Expr::AssertExpr(assertion, expr) }224221225 / l(s,<keyword("error") _ expr:expr(s) { Expr::ErrorStmt(expr) }>)222 / keyword("error") _ expr:expr(s) { Expr::ErrorStmt(expr) }226223227 rule slice_part(s: &ParserSettings) -> Option<LocExpr>224 rule slice_part(s: &ParserSettings) -> Option<LocExpr>228 = e:(_ e:expr(s) _{e})? {e}225 = e:(_ e:expr(s) _{e})? {e}246 use BinaryOpType::*;243 use BinaryOpType::*;247 use UnaryOpType::*;244 use UnaryOpType::*;248 rule expr(s: &ParserSettings) -> LocExpr245 rule expr(s: &ParserSettings) -> LocExpr249 = start:position!() a:precedence! {246 = precedence! {247 start:position!() v:@ end:position!() { loc_expr!(v, s.loc_data, (s.file_name.clone(), start, end)) }248 --250 a:(@) _ binop(<"||">) _ b:@ {expr_bin!(a Or b)}249 a:(@) _ binop(<"||">) _ b:@ {expr_bin!(a Or b)}251 --250 --252 a:(@) _ binop(<"&&">) _ b:@ {expr_bin!(a And b)}251 a:(@) _ binop(<"&&">) _ b:@ {expr_bin!(a And b)}280 unaryop(<"!">) _ b:@ {expr_un!(Not b)}279 unaryop(<"!">) _ b:@ {expr_un!(Not b)}281 unaryop(<"~">) _ b:@ {expr_un!(BitNot b)}280 unaryop(<"~">) _ b:@ {expr_un!(BitNot b)}282 --281 --283 a:(@) _ "[" _ s:slice_desc(s) _ "]" {loc_expr_todo!(Expr::Slice(a, s))}282 a:(@) _ "[" _ e:slice_desc(s) _ "]" {Expr::Slice(a, e)}284 a:(@) _ "." _ s:$(id()) {loc_expr_todo!(Expr::Index(a, el!(Expr::Str(s.into()))))}283 a:(@) _ "." _ e:$(id()) {Expr::Index(a, el!(Expr::Str(e.into())))}285 a:(@) _ "[" _ s:expr(s) _ "]" {loc_expr_todo!(Expr::Index(a, s))}284 a:(@) _ "[" _ e:expr(s) _ "]" {Expr::Index(a, e)}286 a:(@) _ "(" _ args:args(s) _ ")" ts:(_ keyword("tailstrict"))? {loc_expr_todo!(Expr::Apply(a, args, ts.is_some()))}285 a:(@) _ "(" _ args:args(s) _ ")" ts:(_ keyword("tailstrict"))? {Expr::Apply(a, args, ts.is_some())}287 a:(@) _ "{" _ body:objinside(s) _ "}" {loc_expr_todo!(Expr::ObjExtend(a, body))}286 a:(@) _ "{" _ body:objinside(s) _ "}" {Expr::ObjExtend(a, body)}288 --287 --289 e:expr_basic(s) {e}288 e:expr_basic(s) {e}290 "(" _ e:expr(s) _ ")" {loc_expr_todo!(Expr::Parened(e))}289 "(" _ e:expr(s) _ ")" {Expr::Parened(e)}291 } end:position!() {290 }292 let LocExpr(e, _) = a;293 LocExpr(e, if s.loc_data {294 Some(ExprLocation(s.file_name.clone(), start, end))295 } else {296 None297 })298 }299 / e:expr_basic(s) {e}300291301 pub rule jsonnet(s: &ParserSettings) -> LocExpr = _ e:expr(s) _ {e}292 pub rule jsonnet(s: &ParserSettings) -> LocExpr = _ e:expr(s) _ {e}302 }293 }334 };325 };335 }326 }327328 macro_rules! el_loc {329 ($expr:expr, $loc:expr$(,)?) => {330 LocExpr(std::rc::Rc::new($expr), Some($loc))331 };332 }336333337 mod expressions {334 mod expressions {338 use super::*;335 use super::*;576 parse!(jrsonnet_stdlib::STDLIB_STR);573 parse!(jrsonnet_stdlib::STDLIB_STR);577 }574 }578575576 #[test]577 fn add_location_info_to_all_sub_expressions() {578 use Expr::*;579580 let file_name: std::rc::Rc<std::path::Path> = PathBuf::from("/test.jsonnet").into();581 let expr = parse(582 "{} { local x = 1, x: x } + {}",583 &ParserSettings {584 loc_data: true,585 file_name: file_name.clone(),586 },587 )588 .unwrap();589 assert_eq!(590 expr,591 el_loc!(592 BinaryOp(593 el_loc!(594 ObjExtend(595 el_loc!(596 Obj(ObjBody::MemberList(vec![])),597 ExprLocation(file_name.clone(), 0, 2)598 ),599 ObjBody::MemberList(vec![600 Member::BindStmt(BindSpec {601 name: "x".into(),602 params: None,603 value: el_loc!(604 Num(1.0),605 ExprLocation(file_name.clone(), 15, 16)606 )607 }),608 Member::Field(FieldMember {609 name: FieldName::Fixed("x".into()),610 plus: false,611 params: None,612 visibility: Visibility::Normal,613 value: el_loc!(614 Var("x".into()),615 ExprLocation(file_name.clone(), 21, 22)616 ),617 })618 ])619 ),620 ExprLocation(file_name.clone(), 0, 24)621 ),622 BinaryOpType::Add,623 el_loc!(624 Obj(ObjBody::MemberList(vec![])),625 ExprLocation(file_name.clone(), 27, 29)626 ),627 ),628 ExprLocation(file_name.clone(), 0, 29),629 ),630 );631 }579 // From source code632 // From source code580 /*633 /*581 #[bench]634 #[bench]