difftreelog
fix parser should parse import argument as an expression
in: master
4 files changed
crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/evaluate/mod.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/mod.rs
@@ -17,8 +17,8 @@
tb, throw,
typed::Typed,
val::{ArrValue, CachedUnbound, IndexableVal, Thunk, ThunkValue},
- Context, GcHashMap, ObjValue, ObjValueBuilder, ObjectAssertion, Pending, Result, State,
- Unbound, Val,
+ Context, GcHashMap, LocError, ObjValue, ObjValueBuilder, ObjectAssertion, Pending, Result,
+ ResultExt, State, Unbound, Val,
};
pub mod destructure;
pub mod operator;
@@ -591,6 +591,9 @@
IndexableVal::into_untyped(indexable.into_indexable()?.slice(start, end, step)?)?
}
i @ (Import(path) | ImportStr(path) | ImportBin(path)) => {
+ let Expr::Str(path) = &*path.0 else {
+ throw!("computed imports are not supported")
+ };
let tmp = loc.clone().0;
let s = ctx.state();
let resolved_path = s.resolve_from(tmp.source_path(), path as &str)?;
crates/jrsonnet-evaluator/src/tla.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/tla.rs
+++ b/crates/jrsonnet-evaluator/src/tla.rs
@@ -12,7 +12,10 @@
|| "during TLA call".to_owned(),
|| {
func.evaluate(
- s.create_default_context(Source::new_virtual("<top-level-arg>".into(), IStr::empty())),
+ s.create_default_context(Source::new_virtual(
+ "<top-level-arg>".into(),
+ IStr::empty(),
+ )),
CallLocation::native(),
args,
false,
crates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth1use std::{2 fmt::{self, Debug, Display},3 ops::Deref,4 rc::Rc,5};67use jrsonnet_gcmodule::Trace;8use jrsonnet_interner::IStr;9#[cfg(feature = "serde")]10use serde::{Deserialize, Serialize};11#[cfg(feature = "structdump")]12use structdump::Codegen;1314use crate::source::Source;1516#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]17#[cfg_attr(feature = "structdump", derive(Codegen))]18#[derive(Debug, PartialEq, Trace)]19pub enum FieldName {20 /// {fixed: 2}21 Fixed(IStr),22 /// {["dyn"+"amic"]: 3}23 Dyn(LocExpr),24}2526#[cfg_attr(feature = "structdump", derive(Codegen))]27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]28#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]29pub enum Visibility {30 /// :31 Normal,32 /// ::33 Hidden,34 /// :::35 Unhide,36}3738impl Visibility {39 pub fn is_visible(&self) -> bool {40 matches!(self, Self::Normal | Self::Unhide)41 }42}4344#[cfg_attr(feature = "structdump", derive(Codegen))]45#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]46#[derive(Clone, Debug, PartialEq, Trace)]47pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4849#[cfg_attr(feature = "structdump", derive(Codegen))]50#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]51#[derive(Debug, PartialEq, Trace)]52pub struct FieldMember {53 pub name: FieldName,54 pub plus: bool,55 pub params: Option<ParamsDesc>,56 pub visibility: Visibility,57 pub value: LocExpr,58}5960#[cfg_attr(feature = "structdump", derive(Codegen))]61#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]62#[derive(Debug, PartialEq, Trace)]63pub enum Member {64 Field(FieldMember),65 BindStmt(BindSpec),66 AssertStmt(AssertStmt),67}6869#[cfg_attr(feature = "structdump", derive(Codegen))]70#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]71#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]72pub enum UnaryOpType {73 Plus,74 Minus,75 BitNot,76 Not,77}7879impl Display for UnaryOpType {80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {81 use UnaryOpType::*;82 write!(83 f,84 "{}",85 match self {86 Plus => "+",87 Minus => "-",88 BitNot => "~",89 Not => "!",90 }91 )92 }93}9495#[cfg_attr(feature = "structdump", derive(Codegen))]96#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]97#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]98pub enum BinaryOpType {99 Mul,100 Div,101102 /// Implemented as intrinsic, put here for completeness103 Mod,104105 Add,106 Sub,107108 Lhs,109 Rhs,110111 Lt,112 Gt,113 Lte,114 Gte,115116 BitAnd,117 BitOr,118 BitXor,119120 Eq,121 Neq,122123 And,124 Or,125126 // Equialent to std.objectHasEx(a, b, true)127 In,128}129130impl Display for BinaryOpType {131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {132 use BinaryOpType::*;133 write!(134 f,135 "{}",136 match self {137 Mul => "*",138 Div => "/",139 Mod => "%",140 Add => "+",141 Sub => "-",142 Lhs => "<<",143 Rhs => ">>",144 Lt => "<",145 Gt => ">",146 Lte => "<=",147 Gte => ">=",148 BitAnd => "&",149 BitOr => "|",150 BitXor => "^",151 Eq => "==",152 Neq => "!=",153 And => "&&",154 Or => "||",155 In => "in",156 }157 )158 }159}160161/// name, default value162#[cfg_attr(feature = "structdump", derive(Codegen))]163#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]164#[derive(Debug, PartialEq, Trace)]165pub struct Param(pub Destruct, pub Option<LocExpr>);166167/// Defined function parameters168#[cfg_attr(feature = "structdump", derive(Codegen))]169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]170#[derive(Debug, Clone, PartialEq, Trace)]171pub struct ParamsDesc(pub Rc<Vec<Param>>);172173impl Deref for ParamsDesc {174 type Target = Vec<Param>;175 fn deref(&self) -> &Self::Target {176 &self.0177 }178}179180#[cfg_attr(feature = "structdump", derive(Codegen))]181#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]182#[derive(Debug, PartialEq, Trace)]183pub struct ArgsDesc {184 pub unnamed: Vec<LocExpr>,185 pub named: Vec<(IStr, LocExpr)>,186}187impl ArgsDesc {188 pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {189 Self { unnamed, named }190 }191}192193#[cfg_attr(feature = "structdump", derive(Codegen))]194#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]195#[derive(Debug, Clone, PartialEq, Eq, Trace)]196pub enum DestructRest {197 /// ...rest198 Keep(IStr),199 /// ...200 Drop,201}202203#[cfg_attr(feature = "structdump", derive(Codegen))]204#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]205#[derive(Debug, Clone, PartialEq, Trace)]206pub enum Destruct {207 Full(IStr),208 #[cfg(feature = "exp-destruct")]209 Skip,210 #[cfg(feature = "exp-destruct")]211 Array {212 start: Vec<Destruct>,213 rest: Option<DestructRest>,214 end: Vec<Destruct>,215 },216 #[cfg(feature = "exp-destruct")]217 Object {218 fields: Vec<(IStr, Option<Destruct>, Option<LocExpr>)>,219 rest: Option<DestructRest>,220 },221}222impl Destruct {223 /// Name of destructure, used for function parameter names224 pub fn name(&self) -> Option<IStr> {225 match self {226 Self::Full(name) => Some(name.clone()),227 #[cfg(feature = "exp-destruct")]228 _ => None,229 }230 }231 pub fn capacity_hint(&self) -> usize {232 #[cfg(feature = "exp-destruct")]233 fn cap_rest(rest: &Option<DestructRest>) -> usize {234 match rest {235 Some(DestructRest::Keep(_)) => 1,236 Some(DestructRest::Drop) => 0,237 None => 0,238 }239 }240 match self {241 Self::Full(_) => 1,242 #[cfg(feature = "exp-destruct")]243 Self::Skip => 0,244 #[cfg(feature = "exp-destruct")]245 Self::Array { start, rest, end } => {246 start.iter().map(Destruct::capacity_hint).sum::<usize>()247 + end.iter().map(Destruct::capacity_hint).sum::<usize>()248 + cap_rest(rest)249 }250 #[cfg(feature = "exp-destruct")]251 Self::Object { fields, rest } => {252 let mut out = 0;253 for (_, into, _) in fields {254 match into {255 Some(v) => out += v.capacity_hint(),256 // Field is destructured to default name257 None => out += 1,258 }259 }260 out + cap_rest(rest)261 }262 }263 }264}265266#[cfg_attr(feature = "structdump", derive(Codegen))]267#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]268#[derive(Debug, Clone, PartialEq, Trace)]269pub enum BindSpec {270 Field {271 into: Destruct,272 value: LocExpr,273 },274 Function {275 name: IStr,276 params: ParamsDesc,277 value: LocExpr,278 },279}280impl BindSpec {281 pub fn capacity_hint(&self) -> usize {282 match self {283 BindSpec::Field { into, .. } => into.capacity_hint(),284 BindSpec::Function { .. } => 1,285 }286 }287}288289#[cfg_attr(feature = "structdump", derive(Codegen))]290#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]291#[derive(Debug, PartialEq, Trace)]292pub struct IfSpecData(pub LocExpr);293294#[cfg_attr(feature = "structdump", derive(Codegen))]295#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]296#[derive(Debug, PartialEq, Trace)]297pub struct ForSpecData(pub Destruct, pub LocExpr);298299#[cfg_attr(feature = "structdump", derive(Codegen))]300#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]301#[derive(Debug, PartialEq, Trace)]302pub enum CompSpec {303 IfSpec(IfSpecData),304 ForSpec(ForSpecData),305}306307#[cfg_attr(feature = "structdump", derive(Codegen))]308#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]309#[derive(Debug, PartialEq, Trace)]310pub struct ObjComp {311 pub pre_locals: Vec<BindSpec>,312 pub field: FieldMember,313 pub post_locals: Vec<BindSpec>,314 pub compspecs: Vec<CompSpec>,315}316317#[cfg_attr(feature = "structdump", derive(Codegen))]318#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]319#[derive(Debug, PartialEq, Trace)]320pub enum ObjBody {321 MemberList(Vec<Member>),322 ObjComp(ObjComp),323}324325#[cfg_attr(feature = "structdump", derive(Codegen))]326#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]327#[derive(Debug, PartialEq, Eq, Clone, Copy, Trace)]328pub enum LiteralType {329 This,330 Super,331 Dollar,332 Null,333 True,334 False,335}336337#[cfg_attr(feature = "structdump", derive(Codegen))]338#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]339#[derive(Debug, PartialEq, Trace)]340pub struct SliceDesc {341 pub start: Option<LocExpr>,342 pub end: Option<LocExpr>,343 pub step: Option<LocExpr>,344}345346/// Syntax base347#[cfg_attr(feature = "structdump", derive(Codegen))]348#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]349#[derive(Debug, PartialEq, Trace)]350pub enum Expr {351 Literal(LiteralType),352353 /// String value: "hello"354 Str(IStr),355 /// Number: 1, 2.0, 2e+20356 Num(f64),357 /// Variable name: test358 Var(IStr),359360 /// Array of expressions: [1, 2, "Hello"]361 Arr(Vec<LocExpr>),362 /// Array comprehension:363 /// ```jsonnet364 /// ingredients: [365 /// { kind: kind, qty: 4 / 3 }366 /// for kind in [367 /// 'Honey Syrup',368 /// 'Lemon Juice',369 /// 'Farmers Gin',370 /// ]371 /// ],372 /// ```373 ArrComp(LocExpr, Vec<CompSpec>),374375 /// Object: {a: 2}376 Obj(ObjBody),377 /// Object extension: var1 {b: 2}378 ObjExtend(LocExpr, ObjBody),379380 /// (obj)381 Parened(LocExpr),382383 /// -2384 UnaryOp(UnaryOpType, LocExpr),385 /// 2 - 2386 BinaryOp(LocExpr, BinaryOpType, LocExpr),387 /// assert 2 == 2 : "Math is broken"388 AssertExpr(AssertStmt, LocExpr),389 /// local a = 2; { b: a }390 LocalExpr(Vec<BindSpec>, LocExpr),391392 /// import "hello"393 Import(IStr),394 /// importStr "file.txt"395 ImportStr(IStr),396 /// importBin "file.txt"397 ImportBin(IStr),398 /// error "I'm broken"399 ErrorStmt(LocExpr),400 /// a(b, c)401 Apply(LocExpr, ArgsDesc, bool),402 /// a[b]403 Index(LocExpr, LocExpr),404 /// function(x) x405 Function(ParamsDesc, LocExpr),406 /// if true == false then 1 else 2407 IfElse {408 cond: IfSpecData,409 cond_then: LocExpr,410 cond_else: Option<LocExpr>,411 },412 Slice(LocExpr, SliceDesc),413}414415/// file, begin offset, end offset416#[cfg_attr(feature = "structdump", derive(Codegen))]417#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]418#[derive(Clone, PartialEq, Eq, Trace)]419#[trace(skip)]420#[repr(C)]421pub struct ExprLocation(pub Source, pub u32, pub u32);422impl ExprLocation {423 pub fn belongs_to(&self, other: &ExprLocation) -> bool {424 other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2425 }426}427428#[cfg(target_pointer_width = "64")]429static_assertions::assert_eq_size!(ExprLocation, [u8; 16]);430431impl Debug for ExprLocation {432 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {433 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)434 }435}436437/// Holds AST expression and its location in source file438#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]439#[cfg_attr(feature = "structdump", derive(Codegen))]440#[derive(Clone, PartialEq, Trace)]441pub struct LocExpr(pub Rc<Expr>, pub ExprLocation);442443#[cfg(target_pointer_width = "64")]444static_assertions::assert_eq_size!(LocExpr, [u8; 24]);445446impl Debug for LocExpr {447 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {448 if f.alternate() {449 write!(f, "{:#?}", self.0)?;450 } else {451 write!(f, "{:?}", self.0)?;452 }453 write!(f, " from {:?}", self.1)?;454 Ok(())455 }456}1use std::{2 fmt::{self, Debug, Display},3 ops::Deref,4 rc::Rc,5};67use jrsonnet_gcmodule::Trace;8use jrsonnet_interner::IStr;9#[cfg(feature = "serde")]10use serde::{Deserialize, Serialize};11#[cfg(feature = "structdump")]12use structdump::Codegen;1314use crate::source::Source;1516#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]17#[cfg_attr(feature = "structdump", derive(Codegen))]18#[derive(Debug, PartialEq, Trace)]19pub enum FieldName {20 /// {fixed: 2}21 Fixed(IStr),22 /// {["dyn"+"amic"]: 3}23 Dyn(LocExpr),24}2526#[cfg_attr(feature = "structdump", derive(Codegen))]27#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]28#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]29pub enum Visibility {30 /// :31 Normal,32 /// ::33 Hidden,34 /// :::35 Unhide,36}3738impl Visibility {39 pub fn is_visible(&self) -> bool {40 matches!(self, Self::Normal | Self::Unhide)41 }42}4344#[cfg_attr(feature = "structdump", derive(Codegen))]45#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]46#[derive(Clone, Debug, PartialEq, Trace)]47pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4849#[cfg_attr(feature = "structdump", derive(Codegen))]50#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]51#[derive(Debug, PartialEq, Trace)]52pub struct FieldMember {53 pub name: FieldName,54 pub plus: bool,55 pub params: Option<ParamsDesc>,56 pub visibility: Visibility,57 pub value: LocExpr,58}5960#[cfg_attr(feature = "structdump", derive(Codegen))]61#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]62#[derive(Debug, PartialEq, Trace)]63pub enum Member {64 Field(FieldMember),65 BindStmt(BindSpec),66 AssertStmt(AssertStmt),67}6869#[cfg_attr(feature = "structdump", derive(Codegen))]70#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]71#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]72pub enum UnaryOpType {73 Plus,74 Minus,75 BitNot,76 Not,77}7879impl Display for UnaryOpType {80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {81 use UnaryOpType::*;82 write!(83 f,84 "{}",85 match self {86 Plus => "+",87 Minus => "-",88 BitNot => "~",89 Not => "!",90 }91 )92 }93}9495#[cfg_attr(feature = "structdump", derive(Codegen))]96#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]97#[derive(Debug, Clone, Copy, PartialEq, Eq, Trace)]98pub enum BinaryOpType {99 Mul,100 Div,101102 /// Implemented as intrinsic, put here for completeness103 Mod,104105 Add,106 Sub,107108 Lhs,109 Rhs,110111 Lt,112 Gt,113 Lte,114 Gte,115116 BitAnd,117 BitOr,118 BitXor,119120 Eq,121 Neq,122123 And,124 Or,125126 // Equialent to std.objectHasEx(a, b, true)127 In,128}129130impl Display for BinaryOpType {131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {132 use BinaryOpType::*;133 write!(134 f,135 "{}",136 match self {137 Mul => "*",138 Div => "/",139 Mod => "%",140 Add => "+",141 Sub => "-",142 Lhs => "<<",143 Rhs => ">>",144 Lt => "<",145 Gt => ">",146 Lte => "<=",147 Gte => ">=",148 BitAnd => "&",149 BitOr => "|",150 BitXor => "^",151 Eq => "==",152 Neq => "!=",153 And => "&&",154 Or => "||",155 In => "in",156 }157 )158 }159}160161/// name, default value162#[cfg_attr(feature = "structdump", derive(Codegen))]163#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]164#[derive(Debug, PartialEq, Trace)]165pub struct Param(pub Destruct, pub Option<LocExpr>);166167/// Defined function parameters168#[cfg_attr(feature = "structdump", derive(Codegen))]169#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]170#[derive(Debug, Clone, PartialEq, Trace)]171pub struct ParamsDesc(pub Rc<Vec<Param>>);172173impl Deref for ParamsDesc {174 type Target = Vec<Param>;175 fn deref(&self) -> &Self::Target {176 &self.0177 }178}179180#[cfg_attr(feature = "structdump", derive(Codegen))]181#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]182#[derive(Debug, PartialEq, Trace)]183pub struct ArgsDesc {184 pub unnamed: Vec<LocExpr>,185 pub named: Vec<(IStr, LocExpr)>,186}187impl ArgsDesc {188 pub fn new(unnamed: Vec<LocExpr>, named: Vec<(IStr, LocExpr)>) -> Self {189 Self { unnamed, named }190 }191}192193#[cfg_attr(feature = "structdump", derive(Codegen))]194#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]195#[derive(Debug, Clone, PartialEq, Eq, Trace)]196pub enum DestructRest {197 /// ...rest198 Keep(IStr),199 /// ...200 Drop,201}202203#[cfg_attr(feature = "structdump", derive(Codegen))]204#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]205#[derive(Debug, Clone, PartialEq, Trace)]206pub enum Destruct {207 Full(IStr),208 #[cfg(feature = "exp-destruct")]209 Skip,210 #[cfg(feature = "exp-destruct")]211 Array {212 start: Vec<Destruct>,213 rest: Option<DestructRest>,214 end: Vec<Destruct>,215 },216 #[cfg(feature = "exp-destruct")]217 Object {218 fields: Vec<(IStr, Option<Destruct>, Option<LocExpr>)>,219 rest: Option<DestructRest>,220 },221}222impl Destruct {223 /// Name of destructure, used for function parameter names224 pub fn name(&self) -> Option<IStr> {225 match self {226 Self::Full(name) => Some(name.clone()),227 #[cfg(feature = "exp-destruct")]228 _ => None,229 }230 }231 pub fn capacity_hint(&self) -> usize {232 #[cfg(feature = "exp-destruct")]233 fn cap_rest(rest: &Option<DestructRest>) -> usize {234 match rest {235 Some(DestructRest::Keep(_)) => 1,236 Some(DestructRest::Drop) => 0,237 None => 0,238 }239 }240 match self {241 Self::Full(_) => 1,242 #[cfg(feature = "exp-destruct")]243 Self::Skip => 0,244 #[cfg(feature = "exp-destruct")]245 Self::Array { start, rest, end } => {246 start.iter().map(Destruct::capacity_hint).sum::<usize>()247 + end.iter().map(Destruct::capacity_hint).sum::<usize>()248 + cap_rest(rest)249 }250 #[cfg(feature = "exp-destruct")]251 Self::Object { fields, rest } => {252 let mut out = 0;253 for (_, into, _) in fields {254 match into {255 Some(v) => out += v.capacity_hint(),256 // Field is destructured to default name257 None => out += 1,258 }259 }260 out + cap_rest(rest)261 }262 }263 }264}265266#[cfg_attr(feature = "structdump", derive(Codegen))]267#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]268#[derive(Debug, Clone, PartialEq, Trace)]269pub enum BindSpec {270 Field {271 into: Destruct,272 value: LocExpr,273 },274 Function {275 name: IStr,276 params: ParamsDesc,277 value: LocExpr,278 },279}280impl BindSpec {281 pub fn capacity_hint(&self) -> usize {282 match self {283 BindSpec::Field { into, .. } => into.capacity_hint(),284 BindSpec::Function { .. } => 1,285 }286 }287}288289#[cfg_attr(feature = "structdump", derive(Codegen))]290#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]291#[derive(Debug, PartialEq, Trace)]292pub struct IfSpecData(pub LocExpr);293294#[cfg_attr(feature = "structdump", derive(Codegen))]295#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]296#[derive(Debug, PartialEq, Trace)]297pub struct ForSpecData(pub Destruct, pub LocExpr);298299#[cfg_attr(feature = "structdump", derive(Codegen))]300#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]301#[derive(Debug, PartialEq, Trace)]302pub enum CompSpec {303 IfSpec(IfSpecData),304 ForSpec(ForSpecData),305}306307#[cfg_attr(feature = "structdump", derive(Codegen))]308#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]309#[derive(Debug, PartialEq, Trace)]310pub struct ObjComp {311 pub pre_locals: Vec<BindSpec>,312 pub field: FieldMember,313 pub post_locals: Vec<BindSpec>,314 pub compspecs: Vec<CompSpec>,315}316317#[cfg_attr(feature = "structdump", derive(Codegen))]318#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]319#[derive(Debug, PartialEq, Trace)]320pub enum ObjBody {321 MemberList(Vec<Member>),322 ObjComp(ObjComp),323}324325#[cfg_attr(feature = "structdump", derive(Codegen))]326#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]327#[derive(Debug, PartialEq, Eq, Clone, Copy, Trace)]328pub enum LiteralType {329 This,330 Super,331 Dollar,332 Null,333 True,334 False,335}336337#[cfg_attr(feature = "structdump", derive(Codegen))]338#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]339#[derive(Debug, PartialEq, Trace)]340pub struct SliceDesc {341 pub start: Option<LocExpr>,342 pub end: Option<LocExpr>,343 pub step: Option<LocExpr>,344}345346/// Syntax base347#[cfg_attr(feature = "structdump", derive(Codegen))]348#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]349#[derive(Debug, PartialEq, Trace)]350pub enum Expr {351 Literal(LiteralType),352353 /// String value: "hello"354 Str(IStr),355 /// Number: 1, 2.0, 2e+20356 Num(f64),357 /// Variable name: test358 Var(IStr),359360 /// Array of expressions: [1, 2, "Hello"]361 Arr(Vec<LocExpr>),362 /// Array comprehension:363 /// ```jsonnet364 /// ingredients: [365 /// { kind: kind, qty: 4 / 3 }366 /// for kind in [367 /// 'Honey Syrup',368 /// 'Lemon Juice',369 /// 'Farmers Gin',370 /// ]371 /// ],372 /// ```373 ArrComp(LocExpr, Vec<CompSpec>),374375 /// Object: {a: 2}376 Obj(ObjBody),377 /// Object extension: var1 {b: 2}378 ObjExtend(LocExpr, ObjBody),379380 /// (obj)381 Parened(LocExpr),382383 /// -2384 UnaryOp(UnaryOpType, LocExpr),385 /// 2 - 2386 BinaryOp(LocExpr, BinaryOpType, LocExpr),387 /// assert 2 == 2 : "Math is broken"388 AssertExpr(AssertStmt, LocExpr),389 /// local a = 2; { b: a }390 LocalExpr(Vec<BindSpec>, LocExpr),391392 /// import "hello"393 Import(LocExpr),394 /// importStr "file.txt"395 ImportStr(LocExpr),396 /// importBin "file.txt"397 ImportBin(LocExpr),398 /// error "I'm broken"399 ErrorStmt(LocExpr),400 /// a(b, c)401 Apply(LocExpr, ArgsDesc, bool),402 /// a[b]403 Index(LocExpr, LocExpr),404 /// function(x) x405 Function(ParamsDesc, LocExpr),406 /// if true == false then 1 else 2407 IfElse {408 cond: IfSpecData,409 cond_then: LocExpr,410 cond_else: Option<LocExpr>,411 },412 Slice(LocExpr, SliceDesc),413}414415/// file, begin offset, end offset416#[cfg_attr(feature = "structdump", derive(Codegen))]417#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]418#[derive(Clone, PartialEq, Eq, Trace)]419#[trace(skip)]420#[repr(C)]421pub struct ExprLocation(pub Source, pub u32, pub u32);422impl ExprLocation {423 pub fn belongs_to(&self, other: &ExprLocation) -> bool {424 other.0 == self.0 && other.1 <= self.1 && other.2 >= self.2425 }426}427428#[cfg(target_pointer_width = "64")]429static_assertions::assert_eq_size!(ExprLocation, [u8; 16]);430431impl Debug for ExprLocation {432 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {433 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)434 }435}436437/// Holds AST expression and its location in source file438#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]439#[cfg_attr(feature = "structdump", derive(Codegen))]440#[derive(Clone, PartialEq, Trace)]441pub struct LocExpr(pub Rc<Expr>, pub ExprLocation);442443#[cfg(target_pointer_width = "64")]444static_assertions::assert_eq_size!(LocExpr, [u8; 24]);445446impl Debug for LocExpr {447 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {448 if f.alternate() {449 write!(f, "{:#?}", self.0)?;450 } else {451 write!(f, "{:?}", self.0)?;452 }453 write!(f, " from {:?}", self.1)?;454 Ok(())455 }456}crates/jrsonnet-parser/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-parser/src/lib.rs
+++ b/crates/jrsonnet-parser/src/lib.rs
@@ -257,9 +257,9 @@
/ array_expr(s)
/ array_comp_expr(s)
- / keyword("importstr") _ path:string() {Expr::ImportStr(path.into())}
- / keyword("importbin") _ path:string() {Expr::ImportBin(path.into())}
- / keyword("import") _ path:string() {Expr::Import(path.into())}
+ / keyword("importstr") _ path:expr(s) {Expr::ImportStr(path)}
+ / keyword("importbin") _ path:expr(s) {Expr::ImportBin(path)}
+ / keyword("import") _ path:expr(s) {Expr::Import(path)}
/ var_expr(s)
/ local_expr(s)