Skip to main content

m2_syn/
nodes.rs

1macro_rules! syntax_schema {
2    ($($tokens:tt)*) => {};
3}
4
5// This inert invocation is the single source of truth consumed by the
6// generator. The checked-in expansion is included below.
7syntax_schema! {
8    // Structural precedences with no single owning operator token; consumed
9    // directly by the native parser. Operator tokens below carry their own
10    // precedence numbers inline instead of naming a shared table entry.
11    precedence: {
12        PREC_CLOSER = 6,
13        PREC_SEMICOLON = 8,
14        PREC_COMMA = 10,
15        PREC_CONTROL = 12,
16        PREC_LOOP_CLAUSE = 16,
17        PREC_COLLECTION = 56,
18        PREC_APPLICATION_RIGHT = 61,
19        PREC_APPLICATION = 62,
20        PREC_QUOTE = 74,
21    }
22
23    augmented: (14, 13)
24
25    // Each row carries (precedence, binary_strength, unary_strength); `_`
26    // marks a slot the row's flags don't use.
27    tokens {
28        [!=]       { bin }             (36, 35, _)
29        [#]        { bin, pref }       (70, 70, 61)
30        [#?]       { bin }             (70, 70, _)
31        [%]        { bin, aug }        (58, 58, _)
32        [&]        { bin, aug }        (46, 46, _)
33        [*]        { bin, pref, aug }  (58, 58, 58)
34        [**]       { bin, aug }        (54, 54, _)
35        [+]        { bin, pref, aug }  (50, 50, 50)
36        [++]       { bin, aug }        (50, 50, _)
37        [-]        { bin, pref, aug }  (50, 50, 50)
38        [->]       { infix }           (14, 13, _)
39        [.]        { bin }             (70, 70, _)
40        [..]       { bin, aug }        (48, 48, _)
41        [..<]      { bin, aug }        (48, 48, _)
42        [.?]       { bin }             (70, 70, _)
43        [/]        { bin, aug }        (58, 58, _)
44        [/ /]      { bin, aug }        (58, 58, _)
45        [:]        { bin, aug }        (40, 39, _)
46        [<]        { bin, pref }       (36, 35, 36)
47        [<-]       { infix }           (14, 13, _)
48        [<<]       { bin, pref, aug }  (18, 18, 18)
49        [<=]       { bin, pref }       (36, 35, 36)
50        [<==]      { bin, pref }       (26, 25, 26)
51        [<===]     { bin, pref }       (22, 21, 22)
52        [<==>]     { bin, aug }        (24, 23, _)
53        [=]        { infix }           (14, 13, _)
54        [=!=]      { bin }             (36, 35, _)
55        [==]       { bin }             (36, 35, _)
56        [===]      { bin }             (36, 35, _)
57        [===>]     { bin, aug }        (22, 21, _)
58        [==>]      { bin, aug }        (26, 25, _)
59        [=>]       { infix }           (14, 13, _)
60        [>]        { bin, pref }       (36, 35, 36)
61        [>=]       { bin, pref }       (36, 35, 36)
62        [>>]       { bin, aug }        (14, 13, _)
63        [?]        { bin, pref }       (36, 35, 36)
64        [??]       { bin, pref, aug }  (28, 27, 28)
65        [@]        { bin, aug }        (60, 59, _)
66        [@@]       { bin, aug }        (66, 66, _)
67        [@@?]      { bin, aug }        (66, 66, _)
68        ["\\"]     { bin, aug }        (58, 57, _)
69        ["\\\\"]   { bin, aug }        (58, 57, _)
70        [^]        { bin, aug }        (70, 70, _)
71        [^**]      { bin, aug }        (70, 70, _)
72        [^<]       { bin }             (70, 70, _)
73        [^<=]      { bin }             (70, 70, _)
74        [^>]       { bin }             (70, 70, _)
75        [^>=]      { bin }             (70, 70, _)
76        [^^]       { bin, aug }        (44, 44, _)
77        [_]        { bin, aug }        (70, 70, _)
78        [_<]       { bin }             (70, 70, _)
79        [_<=]      { bin }             (70, 70, _)
80        [_>]       { bin }             (70, 70, _)
81        [_>=]      { bin }             (70, 70, _)
82        [|]        { bin, aug }        (42, 42, _)
83        [|-]       { bin, pref, aug }  (20, 20, 20)
84        [|_]       { bin, aug }        (70, 70, _)
85        [||]       { bin, aug }        (38, 38, _)
86        [~]        { bin, pref, aug }  (36, 35, 36)
87        ["·"]      { bin, aug }        (52, 52, _)
88        ["⊠"]      { bin, aug }        (54, 54, _)
89        ["⧢"]      { bin, aug }        (54, 54, _)
90        [and]      { bin }             (32, 31, _)
91        [or]       { bin }             (28, 27, _)
92        [SPACE]    { bin }             (62, 61, _)
93        [xor]      { bin }             (30, 29, _)
94        [!]        { post }            (72, _, _)
95        [(*)]      { post }            (64, _, _)
96        [^!]       { post }            (72, _, _)
97        [^*]       { post }            (68, _, _)
98        [^~]       { post }            (68, _, _)
99        [_!]       { post }            (72, _, _)
100        [_*]       { post }            (68, _, _)
101        [_~]       { post }            (68, _, _)
102        [not]      { pref }            (34, _, 34)
103    }
104
105    keywords {
106        [break] [breakpoint] [catch] [continue]
107        [do] [elapsedTime] [elapsedTiming] [else] [except] [finish]
108        [for] [from] [global] [if] [in] [list] [local]
109        [new] [of] [profile] [return] [shield]
110        [step] [symbol] [TEST] [then] [threadLocal]
111        [threadVariable] [throw] [time] [timing] [to] [trap]
112        [try] [when] [while]
113    }
114
115    markers {}
116
117    punct {
118        [;], [,]
119    }
120    // Leaf nodes retain their source text. Their concrete names are obtained by
121    // converting the Rust name to snake_case, matching grammar.js.
122    struct Symbol;
123    struct BlockComment;
124    struct LineComment;
125    struct EmptyComponent;
126    struct EscapeSequence;
127    struct FloatLiteral;
128    struct IntegerLiteral;
129    struct RawStringContent;
130    struct StringContent;
131
132    // `(_)` marks a field addressed positionally rather than by a CST field
133    // name. The generator may still give it an artificial Rust name, but
134    // that name is not a CST field.
135    struct SourceFile {
136        elements: (_ lines) Vec<AnyCell>
137    }
138
139    #[cst(kind = cell)]
140    struct ExpressionCell {
141        value: (_) Expr
142    }
143
144    #[cst(kind = cell)]
145    struct SequenceCell {
146        value: (_) NakedSequence
147    }
148
149    struct NakedSequence {
150        elements: (_) Punctuated<Component>
151    }
152
153    #[cst(kind = muted)]
154    struct MutedCell {
155        elements: (_) Punctuated<Component>,
156        semicolon: (_) Token![;],
157    }
158
159    #[cst(kind = muted)]
160    struct MutedGroup {
161        elements: (_) Punctuated<Component>,
162        semicolon: (_) Token![;],
163    }
164
165    #[delimiter(bracket)]
166    struct Array {
167        muted: (_) Vec<MutedGroup>,
168        elements: (_) Punctuated<Component>,
169    }
170
171    #[delimiter(brace)]
172    struct List {
173        muted: (_) Vec<MutedGroup>,
174        elements: (_) Punctuated<Component>,
175    }
176
177    #[delimiter(angle_bar)]
178    struct AngleBarList {
179        muted: (_) Vec<MutedGroup>,
180        elements: (_) Punctuated<Component>,
181    }
182
183    #[delimiter(parenthesis)]
184    struct Sequence {
185        muted: (_) Vec<MutedGroup>,
186        elements: (_) Punctuated<Component>,
187    }
188
189    #[delimiter(parenthesis)]
190    struct ParenthesizedExpression {
191        muted: (_) Vec<MutedGroup>,
192        value: (_) Expr?,
193    }
194
195    #[delimiter(string)]
196    struct StringLiteral {
197        elements: (_) Vec<StringElement>,
198    }
199
200    #[delimiter(raw_string)]
201    struct RawStringLiteral {
202        elements: (_) Vec<RawStringElement>,
203    }
204
205    struct BinaryExpression {
206        left: Expr,
207        operator: BinaryOperator,
208        right: Expr,
209    }
210
211    #[cst(kind = adjacent_expression)]
212    struct AdjacentExpression {
213        left: Expr,
214        right: Expr,
215    }
216
217    struct PrefixExpression {
218        operator: PrefixOperator,
219        operand: Expr,
220    }
221
222    struct PostfixExpression {
223        operand: Expr,
224        operator: PostfixOperator,
225    }
226
227    struct LambdaExpression {
228        parameters: LambdaParameters,
229        operator: Token![->],
230        body: Expr,
231    }
232
233    #[cst(kind = assignment)]
234    struct Assignment {
235        left: Symbol,
236        operator: Token![=],
237        right: Expr,
238    }
239
240    #[cst(kind = local_assignment)]
241    struct LocalAssignment {
242        left: Symbol,
243        operator: Token![:=],
244        right: Expr,
245    }
246
247    struct BinaryAssignment {
248        left: BinaryExpression,
249        operator: Token![=],
250        right: Expr,
251    }
252
253    struct BinaryInstallation {
254        left: BinaryExpression,
255        operator: Token![:=],
256        right: Expr,
257    }
258
259    struct PrefixAssignment {
260        left: PrefixExpression,
261        operator: Token![=],
262        right: Expr,
263    }
264
265    struct PrefixInstallation {
266        left: PrefixExpression,
267        operator: Token![:=],
268        right: Expr,
269    }
270
271    struct PostfixAssignment {
272        left: PostfixExpression,
273        operator: Token![=],
274        right: Expr,
275    }
276
277    struct PostfixInstallation {
278        left: PostfixExpression,
279        operator: Token![:=],
280        right: Expr,
281    }
282
283    // grammar.js gives the binding pack its own CST field name,
284    // `binding_pack`, instead of the `left` used by every other assignment
285    // form.
286    struct StructuredBinding {
287        binding_pack: BindingPack,
288        operator: Token![=],
289        right: Expr,
290    }
291
292    struct LocalStructuredBinding {
293        binding_pack: BindingPack,
294        operator: Token![:=],
295        right: Expr,
296    }
297
298    struct EvaluatedAssignment {
299        left: Expr,
300        operator: Token![<-],
301        right: Expr,
302    }
303
304    #[cst(kind = option)]
305    struct OptionExpression {
306        left: Expr,
307        operator: Token![=>],
308        right: Expr,
309    }
310
311    struct ThenClause {
312        keyword: (_) Token![then],
313        value: (_) Expr,
314    }
315
316    struct ElseClause {
317        keyword: (_) Token![else],
318        value: (_) Expr,
319    }
320
321    struct IfStatement {
322        keyword: (_) Token![if],
323        condition: Expr,
324        then_clause: (_) ThenClause,
325        else_clause: (_) ElseClause?,
326    }
327
328    struct LoopBody {
329        list_keyword: (_) Token![list]?,
330        listed_value: Expr?,
331        do_keyword: (_) Token![do]?,
332        ignored_value: Expr?,
333    }
334
335    struct IterationRange {
336        in_keyword: (_) Token![in]?,
337        iterated_collection: Expr?,
338        from_keyword: (_) Token![from]?,
339        range_start: Expr?,
340        to_keyword: (_) Token![to]?,
341        range_end: Expr?,
342    }
343
344    struct ForLoop {
345        keyword: (_) Token![for],
346        variable: Symbol,
347        range: (_) IterationRange?,
348        when_keyword: (_) Token![when]?,
349        filter: Expr?,
350        body: (_) LoopBody,
351    }
352
353    struct WhileLoop {
354        keyword: (_) Token![while],
355        condition: Expr,
356        body: (_) LoopBody,
357    }
358
359    struct NewStatement {
360        keyword: (_) Token![new],
361        class: Expr,
362        of_keyword: (_) Token![of]?,
363        parent: Expr?,
364        from_keyword: (_) Token![from]?,
365        instance: Expr?,
366    }
367
368    enum DebugKeyword {
369        Token![step],
370        Token![finish],
371        Token![shield],
372        Token![TEST],
373        Token![time],
374        Token![timing],
375        Token![breakpoint],
376        Token![elapsedTime],
377        Token![elapsedTiming],
378        Token![profile],
379    }
380
381    struct DebugClause {
382        keyword: DebugKeyword,
383        value: (_) Expr?,
384    }
385
386    struct BreakStatement {
387        keyword: (_) Token![break],
388        value: (_) Expr?,
389    }
390
391    struct ContinueStatement {
392        keyword: (_) Token![continue],
393        value: (_) Expr?,
394    }
395
396    struct ReturnStatement {
397        keyword: (_) Token![return],
398        value: (_) Expr?,
399    }
400
401    struct CatchStatement {
402        keyword: (_) Token![catch],
403        value: (_) Expr,
404    }
405
406    struct ThrowStatement {
407        keyword: (_) Token![throw],
408        value: (_) Expr,
409    }
410
411    struct TrapStatement {
412        keyword: (_) Token![trap],
413        value: (_) Expr,
414    }
415
416    struct ExceptClause {
417        keyword: (_) Token![except],
418        exception: Symbol,
419        do_keyword: (_) Token![do],
420        value: (_) Expr,
421    }
422
423    enum TryFallback {
424        ExceptClause,
425        ElseClause,
426    }
427
428    struct TryStatement {
429        keyword: (_) Token![try],
430        value: (_) Expr,
431        then_clause: (_) ThenClause?,
432        fallback: TryFallback?,
433    }
434
435    enum QuoteSpecifier {
436        Token![symbol],
437        Token![local],
438        Token![global],
439        Token![threadVariable],
440        Token![threadLocal],
441    }
442
443    struct QuoteExpression {
444        specifier: (_) QuoteSpecifier,
445        token: Symbol,
446    }
447
448    enum AnyCell {
449        ExpressionCell,
450        SequenceCell,
451        MutedCell,
452    }
453
454    enum Component {
455        EmptyComponent,
456        Expr,
457    }
458
459    enum SequenceElement {
460        Component,
461        MutedGroup,
462    }
463
464    enum StringElement {
465        EscapeSequence,
466        StringContent,
467    }
468
469    enum RawStringElement {
470        EscapeSequence,
471        RawStringContent,
472    }
473
474    enum Collection {
475        ParenthesizedExpression,
476        Sequence,
477        List,
478        Array,
479        AngleBarList,
480    }
481
482    enum BindingPack {
483        ParenthesizedExpression,
484        Sequence,
485        List,
486        Array,
487        AngleBarList,
488    }
489
490    enum LambdaParameters {
491        Symbol,
492        ParenthesizedExpression,
493        Sequence,
494        List,
495        Array,
496        AngleBarList,
497    }
498
499    enum OperatorExpr {
500        AdjacentExpression,
501        BinaryExpression,
502        PrefixExpression,
503        PostfixExpression,
504    }
505
506    enum AssignmentExpr {
507        Assignment,
508        LocalAssignment,
509        BinaryAssignment,
510        BinaryInstallation,
511        PrefixAssignment,
512        PrefixInstallation,
513        PostfixAssignment,
514        PostfixInstallation,
515        StructuredBinding,
516        LocalStructuredBinding,
517        EvaluatedAssignment,
518    }
519
520    enum Expr {
521        Collection,
522        OperatorExpr,
523        AssignmentExpr,
524        OptionExpression,
525        LambdaExpression,
526        IfStatement,
527        ForLoop,
528        WhileLoop,
529        TryStatement,
530        QuoteExpression,
531        NewStatement,
532        BreakStatement,
533        ContinueStatement,
534        ReturnStatement,
535        CatchStatement,
536        ThrowStatement,
537        TrapStatement,
538        DebugClause,
539        FloatLiteral,
540        IntegerLiteral,
541        RawStringLiteral,
542        StringLiteral,
543        Symbol,
544    }
545
546    enum SyntaxNode {
547        SourceFile,
548        AnyCell,
549        Expr,
550    }
551}
552
553include!("gen/tokens.rs");
554include!("gen/nodes.rs");
555include!("gen/visit.rs");
556include!("gen/visit_mut.rs");
557include!("gen/fold.rs");
558
559/// An expression evaluated in global scope.
560///
561/// Rust Analyzer presents the implementations below as the concrete type
562/// hierarchy for cells.
563pub trait CellNode: ::m2_syn::Spanned + ::m2_syn::ToTokens {
564    /// Returns the global cell delimiter represented by this typed node.
565    fn cell_delimiter(&self) -> ::m2_syn::DelimiterKind;
566}
567
568impl CellNode for AnyCell {
569    fn cell_delimiter(&self) -> ::m2_syn::DelimiterKind {
570        match self {
571            Self::ExpressionCell(_) | Self::SequenceCell(_) => ::m2_syn::DelimiterKind::Empty,
572            Self::MutedCell(_) => ::m2_syn::DelimiterKind::Semicolon,
573        }
574    }
575}
576
577impl CellNode for ExpressionCell {
578    fn cell_delimiter(&self) -> ::m2_syn::DelimiterKind {
579        ::m2_syn::DelimiterKind::Empty
580    }
581}
582
583impl CellNode for SequenceCell {
584    fn cell_delimiter(&self) -> ::m2_syn::DelimiterKind {
585        ::m2_syn::DelimiterKind::Empty
586    }
587}
588
589impl CellNode for MutedCell {
590    fn cell_delimiter(&self) -> ::m2_syn::DelimiterKind {
591        ::m2_syn::DelimiterKind::Semicolon
592    }
593}
594
595fn append_cell_node<T: CellNode>(node: &T, output: &mut ::m2_syn::CellStream) {
596    let kind = node.cell_delimiter();
597    let mut stream = ::m2_syn::ToTokens::to_token_stream(node);
598    if kind == ::m2_syn::DelimiterKind::Semicolon {
599        stream.pop().expect("a muted cell emits its semicolon last");
600    }
601    output.push(::m2_syn::CellBlock::new(
602        ::m2_syn::Delimiter::new(kind, ::m2_syn::Spanned::span(node)),
603        stream,
604    ));
605}
606
607macro_rules! impl_to_cells_for_cell_node {
608    ($($ty:ty),* $(,)?) => {
609        $(
610            impl ::m2_syn::ToCells for $ty {
611                fn to_cells(&self, output: &mut ::m2_syn::CellStream) {
612                    append_cell_node(self, output);
613                }
614            }
615        )*
616    }
617}
618
619impl_to_cells_for_cell_node!(AnyCell, ExpressionCell, SequenceCell, MutedCell);
620
621impl ::m2_syn::ToCells for SourceFile {
622    fn to_cells(&self, output: &mut ::m2_syn::CellStream) {
623        ::m2_syn::ToCells::to_cells(&self.elements, output);
624    }
625}
626
627impl ::m2_syn::ToCells for Expr {
628    fn to_cells(&self, output: &mut ::m2_syn::CellStream) {
629        ::m2_syn::ToCells::to_cells(&::m2_syn::ToTokens::to_token_stream(self), output);
630    }
631}
632
633macro_rules! impl_to_cells_for_expr_node {
634    ($($ty:ty),* $(,)?) => {
635        $(
636            impl ::m2_syn::ToCells for $ty {
637                fn to_cells(&self, output: &mut ::m2_syn::CellStream) {
638                    ::m2_syn::ToCells::to_cells(
639                        &::m2_syn::ToTokens::to_token_stream(self),
640                        output,
641                    );
642                }
643            }
644        )*
645    };
646}
647
648impl_to_cells_for_expr_node!(
649    Collection,
650    OperatorExpr,
651    AssignmentExpr,
652    OptionExpression,
653    LambdaExpression,
654    IfStatement,
655    ForLoop,
656    WhileLoop,
657    TryStatement,
658    QuoteExpression,
659    NewStatement,
660    BreakStatement,
661    ContinueStatement,
662    ReturnStatement,
663    CatchStatement,
664    ThrowStatement,
665    TrapStatement,
666    DebugClause,
667    FloatLiteral,
668    IntegerLiteral,
669    RawStringLiteral,
670    StringLiteral,
671    Symbol,
672);
673
674impl ::m2_syn::ToCells for SyntaxNode {
675    fn to_cells(&self, output: &mut ::m2_syn::CellStream) {
676        match self {
677            Self::SourceFile(node) => ::m2_syn::ToCells::to_cells(node, output),
678            Self::AnyCell(node) => ::m2_syn::ToCells::to_cells(node, output),
679            Self::Expr(node) => ::m2_syn::ToCells::to_cells(node, output),
680        }
681    }
682}