1use std::{cell::{Cell, RefCell}, mem::{forget, take}};
2
3use rowan::{GreenNode, GreenNodeBuilder, SyntaxKind};
4
5#[derive(Debug)]
6pub struct QuietGuard<'b, 'a>(&'b ParseState<'a>);
7
8impl<'b, 'a> std::ops::Deref for QuietGuard<'b, 'a> {
9 type Target = &'b ParseState<'a>;
10
11 fn deref(&self) -> &Self::Target {
12 &self.0
13 }
14}
15
16impl<'b, 'a> Drop for QuietGuard<'b, 'a> {
17 fn drop(&mut self) {
18 self.0.quiet.update(|n| n+1);
19 }
20}
21
22#[derive(Debug)]
23pub struct RuleGuard<'b, 'a> {
24 state: &'b ParseState<'a>,
25 len: usize,
26 quiet: u32,
27 kind: SyntaxKind,
28}
29
30impl<'b, 'a> RuleGuard<'b, 'a> {
31 fn end_set(&self) {
32 self.state.quiet.set(self.quiet);
33 }
34
35 pub fn accept_token(self, text: &'a str) {
36 self.end_set();
37 self.state.action(Action::Token(self.kind, text));
38 forget(self);
39 }
40
41 pub fn accept_none(self) {
42 self.end_set();
43 forget(self);
44 }
45
46 pub fn accept(self) {
47 self.end_set();
48 self.state.action(Action::Finish);
49 forget(self);
50 }
51}
52
53impl<'b, 'a> Drop for RuleGuard<'b, 'a> {
54 fn drop(&mut self) {
55 let RuleGuard { state, len, quiet, kind: _ } = *self;
56 state.actions.borrow_mut().truncate(len);
57 state.quiet.set(quiet);
58 }
59}
60
61#[derive(Debug, Clone)]
62pub enum Action<'a> {
63 Token(SyntaxKind, &'a str),
64 Start(SyntaxKind),
65 Finish,
66}
67
68#[derive(Debug, Default)]
69pub struct ParseState<'a> {
70 actions: RefCell<Vec<Action<'a>>>,
71 quiet: Cell<u32>,
72 builder: GreenNodeBuilder<'static>,
73 exclude_empty: bool,
74}
75
76impl<'a> ParseState<'a> {
77 pub fn clear(&mut self) {
78 let mut actions = take(&mut self.actions);
79 actions.get_mut().clear();
80 *self = Self {
81 actions,
82 quiet: 0.into(),
83 ..Default::default()
84 }
85 }
86
87 pub fn action(&self, action: Action<'a>) {
88 if self.quiet.get() == 0 {
89 self.actions.borrow_mut().push(action);
90 }
91 }
92
93 pub fn quiet(&self) -> QuietGuard<'_, 'a> {
94 QuietGuard(self)
95 }
96
97 pub fn guard(&self, kind: impl Into<SyntaxKind>) -> RuleGuard<'_, 'a> {
98 let kind = kind.into();
99 let guard = self.guard_token(kind);
100 self.action(Action::Start(kind.into()));
101 guard
102 }
103
104 pub fn guard_token(&self, kind: impl Into<SyntaxKind>) -> RuleGuard<'_, 'a> {
105 let len = self.actions.borrow().len();
106 RuleGuard { state: self, len, quiet: self.quiet.get(), kind: kind.into() }
107 }
108
109 pub fn guard_none(&self) -> RuleGuard<'_, 'a> {
110 let kind = SyntaxKind(0);
111 self.guard_token(kind)
112 }
113
114 pub fn finish(&mut self) -> GreenNode {
115 for action in self.actions.get_mut().drain(..) {
116 match action {
117 Action::Token(kind, text) => {
118 if !text.is_empty() || !self.exclude_empty {
119 self.builder.token(kind, text)
120 }
121 }
122 Action::Start(kind) => self.builder.start_node(kind),
123 Action::Finish => self.builder.finish_node(),
124 }
125 }
126 take(&mut self.builder).finish()
127 }
128
129 pub fn set_exclude_empty(&mut self, exclude_empty: bool) {
130 self.exclude_empty = exclude_empty;
131 }
132}