Skip to main content

yog_script_analyze/ast/
decl.rs

1//! Declarations (`ys-grammar.md` §2): the mod, types, members, content,
2//! components and systems, events.
3
4use super::{Block, Expr, Generic, Name, Patch, Type, Where};
5use crate::source::token::Span;
6
7/// What a declaration is marked with.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum Modifier {
10    Public,
11    Private,
12    Internal,
13    Static,
14    Const,
15    Readonly,
16    Async,
17    Server,
18    Client,
19    Shared,
20    Saved,
21    Synced,
22    Tune,
23    Protected,
24    Abstract,
25    Virtual,
26    Override,
27    Sealed,
28    /// `ref struct`: holds borrows, never on the heap.
29    Ref,
30    /// Its body is elsewhere: a `[Service]` method's, on the bus.
31    Extern,
32}
33
34/// `[Obsolete("…")]`.
35#[derive(Debug, Clone, PartialEq)]
36pub struct Attribute {
37    pub path: Vec<Name>,
38    pub args: Vec<super::Arg>,
39}
40
41/// A declaration, its attributes, documentation and modifiers.
42#[derive(Debug, Clone, PartialEq)]
43pub struct Decl {
44    pub attributes: Vec<Attribute>,
45    pub doc: Vec<String>,
46    pub modifiers: Vec<Modifier>,
47    pub kind: DeclKind,
48    pub span: Span,
49}
50
51impl Decl {
52    pub fn has(&self, m: Modifier) -> bool {
53        self.modifiers.contains(&m)
54    }
55}
56
57/// A type's name and what follows it: generics, its primary constructor,
58/// what it implements, the constraints, the components it has.
59#[derive(Debug, Clone, PartialEq, Default)]
60pub struct TypeHeader {
61    pub generics: Vec<Generic>,
62    pub ctor: Option<Vec<Param>>,
63    pub bases: Vec<Type>,
64    pub constraints: Vec<Where>,
65    pub has: Vec<Expr>,
66}
67
68#[derive(Debug, Clone, PartialEq)]
69pub enum DeclKind {
70    /// `using Yog.Ui;`, `using static Yog.Chat;`, `global using …;`.
71    Using {
72        path: Vec<Name>,
73        global: bool,
74        statics: bool,
75    },
76    /// `namespace A.B;` (the rest of the file: `body` None) or `namespace A.B { … }`.
77    Namespace {
78        path: Vec<Name>,
79        body: Option<Vec<Decl>>,
80    },
81    /// `using Grid = Dictionary<Pos, i32>;`.
82    Alias {
83        name: Name,
84        ty: Type,
85    },
86    /// `mod Charge { Version = "1.0.0"; … }`: its properties, and members —
87    /// its constructor runs when the mod loads.
88    Mod {
89        name: Name,
90        body: Vec<Decl>,
91    },
92    /// `public event Action<Player> Joined;`.
93    Event {
94        ty: Type,
95        name: Name,
96    },
97    Method(Method),
98    Field(Field),
99    /// `Ticks Left { get; set; }`, `Energy Room => …;`.
100    Property {
101        ty: Type,
102        name: Name,
103        accessors: Vec<Accessor>,
104        value: Option<Expr>,
105    },
106    Ctor(Ctor),
107    /// `class`, `struct`, `record`, `interface`: which is `word`;
108    /// `value`: copied by value (a struct, a `record struct`).
109    Type {
110        word: Name,
111        name: Name,
112        value: bool,
113        header: TypeHeader,
114        body: Vec<Decl>,
115    },
116    /// `enum Mode { Idle, Charging(i32 Rate) }`, `enum Tier : u8 { Wood = 1 }`.
117    Enum {
118        name: Name,
119        generics: Vec<Generic>,
120        base: Option<Type>,
121        variants: Vec<Variant>,
122        body: Vec<Decl>,
123    },
124    /// `unit Energy;` / `unit FE = Energy * 1;`.
125    Unit {
126        name: Name,
127        value: Option<Expr>,
128    },
129    /// `block Charger has Charge(1000) { … }`, `recipe Battery : Shaped { … }`,
130    /// a mod's own kinds.
131    Content {
132        kind: Name,
133        name: Name,
134        header: TypeHeader,
135        body: Vec<Decl>,
136    },
137    Component {
138        name: Name,
139        header: TypeHeader,
140        body: Vec<Decl>,
141    },
142    /// `server system Solar(Charge charge, Block block) every 1t { … }`.
143    System {
144        name: Name,
145        params: Vec<Param>,
146        every: Option<Expr>,
147        body: Block,
148    },
149    Extend {
150        ty: Type,
151        header: TypeHeader,
152        body: Vec<Decl>,
153    },
154    /// `Hardness = 2.0f;` in a content or mod body.
155    Prop(Prop),
156    Screen {
157        name: Name,
158        header: TypeHeader,
159        ui: String,
160        body: Vec<Decl>,
161    },
162    Command {
163        name: String,
164        body: Vec<Decl>,
165    },
166    Test {
167        name: String,
168        body: Block,
169    },
170    Patch(Patch),
171    /// `targets mc 1.20.1..26.2;`: the game versions a `.yns` is for.
172    Targets(VersionCond),
173}
174
175/// `Name = value;`.
176#[derive(Debug, Clone, PartialEq)]
177pub struct Prop {
178    pub name: Name,
179    pub value: Expr,
180}
181
182/// `i32 Area(i32 w, i32 h) => w * h;`; `ret` None: `void`.
183#[derive(Debug, Clone, PartialEq)]
184pub struct Method {
185    pub ret: Option<Type>,
186    pub name: Name,
187    pub generics: Vec<Generic>,
188    pub params: Vec<Param>,
189    pub constraints: Vec<Where>,
190    pub requires: Option<Expr>,
191    /// None: a signature only (`native`, an interface's).
192    pub body: Option<MethodBody>,
193}
194
195#[derive(Debug, Clone, PartialEq)]
196pub enum MethodBody {
197    Block(Block),
198    Expr(Expr),
199}
200
201/// `saved synced Energy Energy in 0..capacity = 0 was Power: i32;`.
202#[derive(Debug, Clone, PartialEq)]
203pub struct Field {
204    pub ty: Type,
205    pub name: Name,
206    pub bound: Option<Expr>,
207    pub value: Option<Expr>,
208    /// What an old save calls it.
209    pub was: Option<(Name, Option<Type>)>,
210}
211
212/// `get;`, `set { … }`, `init;`.
213#[derive(Debug, Clone, PartialEq)]
214pub struct Accessor {
215    pub name: Name,
216    pub body: Option<MethodBody>,
217}
218
219/// `public Timer() : this(20t) { … }`.
220#[derive(Debug, Clone, PartialEq)]
221pub struct Ctor {
222    pub name: Name,
223    pub params: Vec<Param>,
224    /// `: this(…)` / `: base(…)`: the constructor run first.
225    pub chain: Option<(Chain, Vec<super::Arg>)>,
226    pub body: Block,
227}
228
229/// Which constructor a constructor runs first.
230#[derive(Debug, Clone, Copy, PartialEq, Eq)]
231pub enum Chain {
232    This,
233    Base,
234}
235
236/// `Player target = source.Player`.
237#[derive(Debug, Clone, PartialEq)]
238pub struct Param {
239    pub pass: Option<super::Pass>,
240    /// `in 'a T x`: the borrow's lifetime.
241    pub lifetime: Option<Name>,
242    pub ty: Type,
243    pub name: Name,
244    pub default: Option<Expr>,
245}
246
247#[derive(Debug, Clone, PartialEq)]
248pub struct Variant {
249    pub name: Name,
250    pub fields: Vec<Param>,
251    /// `Wood = 1`: its number.
252    pub value: Option<Expr>,
253}
254
255/// `mc >= 1.21`, `mc 1.20.1..1.21.4`.
256#[derive(Debug, Clone, PartialEq)]
257pub enum VersionCond {
258    Compare { op: super::BinOp, version: String },
259    Range { from: String, to: String },
260}