difftreelog
feat prettier AST printing
in: master
1 file changed
crates/jrsonnet-parser/src/expr.rsdiffbeforeafterboth1use jrsonnet_interner::IStr;2#[cfg(feature = "deserialize")]3use serde::Deserialize;4#[cfg(feature = "serialize")]5use serde::Serialize;6use std::{7 fmt::{Debug, Display},8 ops::Deref,9 path::PathBuf,10 rc::Rc,11};1213#[cfg_attr(feature = "serialize", derive(Serialize))]14#[cfg_attr(feature = "deserialize", derive(Deserialize))]15#[derive(Debug, PartialEq)]16pub enum FieldName {17 /// {fixed: 2}18 Fixed(IStr),19 /// {["dyn"+"amic"]: 3}20 Dyn(LocExpr),21}2223#[cfg_attr(feature = "serialize", derive(Serialize))]24#[cfg_attr(feature = "deserialize", derive(Deserialize))]25#[derive(Debug, Clone, Copy, PartialEq)]26pub enum Visibility {27 /// :28 Normal,29 /// ::30 Hidden,31 /// :::32 Unhide,33}3435impl Visibility {36 pub fn is_visible(&self) -> bool {37 matches!(self, Self::Normal | Self::Unhide)38 }39}4041#[cfg_attr(feature = "serialize", derive(Serialize))]42#[cfg_attr(feature = "deserialize", derive(Deserialize))]43#[derive(Debug, PartialEq)]44pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);4546#[cfg_attr(feature = "serialize", derive(Serialize))]47#[cfg_attr(feature = "deserialize", derive(Deserialize))]48#[derive(Debug, PartialEq)]49pub struct FieldMember {50 pub name: FieldName,51 pub plus: bool,52 pub params: Option<ParamsDesc>,53 pub visibility: Visibility,54 pub value: LocExpr,55}5657#[cfg_attr(feature = "serialize", derive(Serialize))]58#[cfg_attr(feature = "deserialize", derive(Deserialize))]59#[derive(Debug, PartialEq)]60pub enum Member {61 Field(FieldMember),62 BindStmt(BindSpec),63 AssertStmt(AssertStmt),64}6566#[cfg_attr(feature = "serialize", derive(Serialize))]67#[cfg_attr(feature = "deserialize", derive(Deserialize))]68#[derive(Debug, Clone, Copy, PartialEq)]69pub enum UnaryOpType {70 Plus,71 Minus,72 BitNot,73 Not,74}75impl Display for UnaryOpType {76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {77 use UnaryOpType::*;78 write!(79 f,80 "{}",81 match self {82 Plus => "+",83 Minus => "-",84 BitNot => "~",85 Not => "!",86 }87 )88 }89}9091#[cfg_attr(feature = "serialize", derive(Serialize))]92#[cfg_attr(feature = "deserialize", derive(Deserialize))]93#[derive(Debug, Clone, Copy, PartialEq)]94pub enum BinaryOpType {95 Mul,96 Div,9798 /// Implemented as intrinsic, put here for completeness99 Mod,100101 Add,102 Sub,103104 Lhs,105 Rhs,106107 Lt,108 Gt,109 Lte,110 Gte,111112 BitAnd,113 BitOr,114 BitXor,115116 And,117 Or,118}119impl Display for BinaryOpType {120 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {121 use BinaryOpType::*;122 write!(123 f,124 "{}",125 match self {126 Mul => "*",127 Div => "/",128 Mod => "%",129 Add => "+",130 Sub => "-",131 Lhs => "<<",132 Rhs => ">>",133 Lt => "<",134 Gt => ">",135 Lte => "<=",136 Gte => ">=",137 BitAnd => "&",138 BitOr => "|",139 BitXor => "^",140 And => "&&",141 Or => "||",142 }143 )144 }145}146147/// name, default value148#[cfg_attr(feature = "serialize", derive(Serialize))]149#[cfg_attr(feature = "deserialize", derive(Deserialize))]150#[derive(Debug, PartialEq)]151pub struct Param(pub IStr, pub Option<LocExpr>);152153/// Defined function parameters154#[cfg_attr(feature = "serialize", derive(Serialize))]155#[cfg_attr(feature = "deserialize", derive(Deserialize))]156#[derive(Debug, Clone, PartialEq)]157pub struct ParamsDesc(pub Rc<Vec<Param>>);158impl Deref for ParamsDesc {159 type Target = Vec<Param>;160 fn deref(&self) -> &Self::Target {161 &self.0162 }163}164165#[cfg_attr(feature = "serialize", derive(Serialize))]166#[cfg_attr(feature = "deserialize", derive(Deserialize))]167#[derive(Debug, PartialEq)]168pub struct Arg(pub Option<String>, pub LocExpr);169170#[cfg_attr(feature = "serialize", derive(Serialize))]171#[cfg_attr(feature = "deserialize", derive(Deserialize))]172#[derive(Debug, PartialEq)]173pub struct ArgsDesc(pub Vec<Arg>);174impl Deref for ArgsDesc {175 type Target = Vec<Arg>;176 fn deref(&self) -> &Self::Target {177 &self.0178 }179}180181#[cfg_attr(feature = "serialize", derive(Serialize))]182#[cfg_attr(feature = "deserialize", derive(Deserialize))]183#[derive(Debug, Clone, PartialEq)]184pub struct BindSpec {185 pub name: IStr,186 pub params: Option<ParamsDesc>,187 pub value: LocExpr,188}189190#[cfg_attr(feature = "serialize", derive(Serialize))]191#[cfg_attr(feature = "deserialize", derive(Deserialize))]192#[derive(Debug, PartialEq)]193pub struct IfSpecData(pub LocExpr);194195#[cfg_attr(feature = "serialize", derive(Serialize))]196#[cfg_attr(feature = "deserialize", derive(Deserialize))]197#[derive(Debug, PartialEq)]198pub struct ForSpecData(pub IStr, pub LocExpr);199200#[cfg_attr(feature = "serialize", derive(Serialize))]201#[cfg_attr(feature = "deserialize", derive(Deserialize))]202#[derive(Debug, PartialEq)]203pub enum CompSpec {204 IfSpec(IfSpecData),205 ForSpec(ForSpecData),206}207208#[cfg_attr(feature = "serialize", derive(Serialize))]209#[cfg_attr(feature = "deserialize", derive(Deserialize))]210#[derive(Debug, PartialEq)]211pub struct ObjComp {212 pub pre_locals: Vec<BindSpec>,213 pub key: LocExpr,214 pub value: LocExpr,215 pub post_locals: Vec<BindSpec>,216 pub compspecs: Vec<CompSpec>,217}218219#[cfg_attr(feature = "serialize", derive(Serialize))]220#[cfg_attr(feature = "deserialize", derive(Deserialize))]221#[derive(Debug, PartialEq)]222pub enum ObjBody {223 MemberList(Vec<Member>),224 ObjComp(ObjComp),225}226227#[cfg_attr(feature = "serialize", derive(Serialize))]228#[cfg_attr(feature = "deserialize", derive(Deserialize))]229#[derive(Debug, PartialEq, Clone, Copy)]230pub enum LiteralType {231 This,232 Super,233 Dollar,234 Null,235 True,236 False,237}238239#[derive(Debug, PartialEq)]240pub struct SliceDesc {241 pub start: Option<LocExpr>,242 pub end: Option<LocExpr>,243 pub step: Option<LocExpr>,244}245246/// Syntax base247#[cfg_attr(feature = "serialize", derive(Serialize))]248#[cfg_attr(feature = "deserialize", derive(Deserialize))]249#[derive(Debug, PartialEq)]250pub enum Expr {251 Literal(LiteralType),252253 /// String value: "hello"254 Str(IStr),255 /// Number: 1, 2.0, 2e+20256 Num(f64),257 /// Variable name: test258 Var(IStr),259260 /// Array of expressions: [1, 2, "Hello"]261 Arr(Vec<LocExpr>),262 /// Array comprehension:263 /// ```jsonnet264 /// ingredients: [265 /// { kind: kind, qty: 4 / 3 }266 /// for kind in [267 /// 'Honey Syrup',268 /// 'Lemon Juice',269 /// 'Farmers Gin',270 /// ]271 /// ],272 /// ```273 ArrComp(LocExpr, Vec<CompSpec>),274275 /// Object: {a: 2}276 Obj(ObjBody),277 /// Object extension: var1 {b: 2}278 ObjExtend(LocExpr, ObjBody),279280 /// (obj)281 Parened(LocExpr),282283 /// -2284 UnaryOp(UnaryOpType, LocExpr),285 /// 2 - 2286 BinaryOp(LocExpr, BinaryOpType, LocExpr),287 /// assert 2 == 2 : "Math is broken"288 AssertExpr(AssertStmt, LocExpr),289 /// local a = 2; { b: a }290 LocalExpr(Vec<BindSpec>, LocExpr),291292 /// import "hello"293 Import(PathBuf),294 /// importStr "file.txt"295 ImportStr(PathBuf),296 /// error "I'm broken"297 ErrorStmt(LocExpr),298 /// a(b, c)299 Apply(LocExpr, ArgsDesc, bool),300 /// a[b]301 Index(LocExpr, LocExpr),302 /// function(x) x303 Function(ParamsDesc, LocExpr),304 /// std.primitiveEquals305 Intrinsic(IStr),306 /// if true == false then 1 else 2307 IfElse {308 cond: IfSpecData,309 cond_then: LocExpr,310 cond_else: Option<LocExpr>,311 },312}313314/// file, begin offset, end offset315#[cfg_attr(feature = "serialize", derive(Serialize))]316#[cfg_attr(feature = "deserialize", derive(Deserialize))]317#[derive(Clone, PartialEq)]318pub struct ExprLocation(pub Rc<PathBuf>, pub usize, pub usize);319impl Debug for ExprLocation {320 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {321 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)322 }323}324325/// Holds AST expression and its location in source file326#[cfg_attr(feature = "serialize", derive(Serialize))]327#[cfg_attr(feature = "deserialize", derive(Deserialize))]328#[derive(Clone, PartialEq)]329pub struct LocExpr(pub Rc<Expr>, pub Option<ExprLocation>);330impl Debug for LocExpr {331 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {332 if f.alternate() {333 write!(f, "{:#?}", self.0)?;334 } else {335 write!(f, "{:?}", self.0)?;336 }337 if let Some(loc) = &self.1 {338 write!(f, " from {:?}", loc)?;339 }340 Ok(())341 }342}343344/// Creates LocExpr from Expr and ExprLocation components345#[macro_export]346macro_rules! loc_expr {347 ($expr:expr, $need_loc:expr,($name:expr, $start:expr, $end:expr)) => {348 LocExpr(349 std::rc::Rc::new($expr),350 if $need_loc {351 Some(ExprLocation($name, $start, $end))352 } else {353 None354 },355 )356 };357}358359/// Creates LocExpr without location info360#[macro_export]361macro_rules! loc_expr_todo {362 ($expr:expr) => {363 LocExpr(Rc::new($expr), None)364 };365}