1use ropey::Rope;
2
3use crate::range_from_span::RangeFromSpan;
4use crate::types::{Diagnostic, LanguageMode, Range};
5
6use crate::lexer::{SpannedToken, Token};
7use crate::parser::RsmlParser;
8use crate::parser::parse_error::ParseError;
9
10#[derive(Debug, Default, Clone, Copy)]
11pub struct Directives {
12 pub nobuiltins: bool,
13 pub language_mode: Option<LanguageMode>,
14}
15
16pub struct ParsedRsml<'a> {
17 pub ast: Vec<Construct<'a>>,
18 pub ast_errors: AstErrors,
19 pub directives: Directives,
20 pub rope: Rope,
21}
22
23impl<'a> ParsedRsml<'a> {
24 pub fn range_from_span(&self, span: (usize, usize)) -> Range {
25 Range::from_span(&self.rope, span)
26 }
27}
28
29pub(crate) type Trivia<'a> = Vec<SpannedToken<'a>>;
30
31#[derive(Debug)]
32pub struct Node<'a> {
33 pub token: SpannedToken<'a>,
34 pub leading_trivia: Option<Trivia<'a>>,
35}
36
37pub(crate) trait UpdateLastTokenEnd {
38 fn update_last_token_end(self, parser: &mut RsmlParser) -> Self;
39}
40
41impl<'a> UpdateLastTokenEnd for Option<Node<'a>> {
42 fn update_last_token_end(self, parser: &mut RsmlParser) -> Self {
43 if let Some(Node {
44 token: SpannedToken(_, _, end),
45 ..
46 }) = self
47 {
48 parser.last_token_end = end
49 };
50
51 self
52 }
53}
54
55pub(crate) trait ToStatus<'a> {
56 fn to_status(self) -> NodeStatus<'a>;
57}
58
59impl<'a> ToStatus<'a> for Option<Node<'a>> {
60 fn to_status(self) -> NodeStatus<'a> {
61 match self {
62 Some(node) => NodeStatus::Err(node),
63 None => NodeStatus::None,
64 }
65 }
66}
67
68impl<'a> ToStatus<'a> for Node<'a> {
69 fn to_status(self) -> NodeStatus<'a> {
70 NodeStatus::Err(self)
71 }
72}
73
74pub(crate) struct Parsed<'a, T = Construct<'a>>(pub Option<Node<'a>>, pub Option<T>);
75
76impl<'a> Parsed<'a> {
77 pub(crate) fn handle_construct(self, ast: &mut Vec<Construct<'a>>) -> Option<Node<'a>> {
78 if let Some(construct) = self.1 {
79 ast.push(construct)
80 };
81 self.0
82 }
83}
84
85pub trait SpanEnd {
86 fn end(&self) -> usize;
87}
88
89#[derive(Debug)]
90pub enum SelectorNode<'a> {
91 Token(Node<'a>),
92 MacroCall {
93 name: Node<'a>,
94 body: Option<Delimited<'a>>,
95 },
96}
97
98impl<'a> SelectorNode<'a> {
99 pub fn start(&self) -> usize {
100 match self {
101 Self::Token(node) => node.token.start(),
102 Self::MacroCall { name, .. } => name.token.start(),
103 }
104 }
105}
106
107impl<'a> SpanEnd for SelectorNode<'a> {
108 fn end(&self) -> usize {
109 match self {
110 Self::Token(node) => node.token.end(),
111 Self::MacroCall { name, body } => {
112 if let Some(body) = body {
113 return body.end();
114 }
115 name.token.end()
116 }
117 }
118 }
119}
120
121#[derive(Debug)]
122pub enum MacroBodyContent<'a> {
123 Construct(Option<Vec<Construct<'a>>>),
124 Datatype(Option<Box<Construct<'a>>>),
125 Selector(Option<Vec<SelectorNode<'a>>>),
126}
127
128#[derive(Debug)]
129pub struct MacroBody<'a> {
130 pub open: Node<'a>,
131 pub content: MacroBodyContent<'a>,
132 pub close: Option<Node<'a>>,
133}
134
135impl<'a> SpanEnd for MacroBody<'a> {
136 fn end(&self) -> usize {
137 if let Some(close) = &self.close {
138 return close.token.end();
139 }
140 match &self.content {
141 MacroBodyContent::Construct(Some(items)) => {
142 if let Some(last) = items.last() {
143 return last.end();
144 }
145 }
146
147 MacroBodyContent::Datatype(Some(item)) => return item.end(),
148
149 MacroBodyContent::Selector(Some(items)) => {
150 if let Some(last) = items.last() {
151 return last.end();
152 }
153 }
154
155 _ => {}
156 }
157
158 self.open.token.end()
159 }
160}
161
162#[derive(Debug)]
163pub enum Construct<'a> {
164 Macro {
165 declaration: Node<'a>,
166 name: Option<Node<'a>>,
167 args: Option<Delimited<'a>>,
168 return_type: Option<(Node<'a>, Option<Node<'a>>)>,
169 body: Option<MacroBody<'a>>,
170 },
171
172 MacroCall {
173 name: Node<'a>,
174 body: Option<Delimited<'a>>,
175 terminator: Option<Node<'a>>,
176 },
177
178 Derive {
179 declaration: Node<'a>,
180 body: Option<Box<Construct<'a>>>,
181 terminator: Option<Node<'a>>,
182 },
183
184 Priority {
185 declaration: Node<'a>,
186 body: Option<Box<Construct<'a>>>,
187 terminator: Option<Node<'a>>,
188 },
189
190 Tween {
191 declaration: Node<'a>,
192 name: Option<Node<'a>>,
193 body: Option<Box<Construct<'a>>>,
194 terminator: Option<Node<'a>>,
195 },
196
197 Rule {
198 selectors: Option<Vec<SelectorNode<'a>>>,
199 body: Option<Delimited<'a>>,
200 },
201
202 Assignment {
203 left: Node<'a>,
204 middle: Option<Node<'a>>,
205 right: Option<Box<Construct<'a>>>,
206 terminator: Option<Node<'a>>,
207 },
208
209 MathOperation {
210 left: Box<Construct<'a>>,
211 operators: Vec<Node<'a>>,
212 right: Option<Box<Construct<'a>>>,
213 },
214
215 UnaryMinus {
216 operator: Node<'a>,
217 operand: Box<Construct<'a>>,
218 },
219
220 AnnotatedTable {
221 annotation: Node<'a>,
222 body: Option<Delimited<'a>>,
223 },
224
225 Table {
226 body: Delimited<'a>,
227 },
228
229 Enum {
230 keyword: Node<'a>,
231 name: Option<Node<'a>>,
232 variant: Option<Node<'a>>,
233 },
234
235 Node {
236 node: Node<'a>,
237 },
238
239 None {
240 node: Node<'a>,
241 },
242}
243
244impl<'a> Construct<'a> {
245 pub fn rule(selectors: Option<Vec<SelectorNode<'a>>>, body: Delimited<'a>) -> Self {
246 Self::Rule {
247 selectors,
248 body: Some(body),
249 }
250 }
251
252 pub fn name_plural(&self) -> &str {
253 match self {
254 Self::Macro { .. } => "Macros",
255 Self::MacroCall { .. } => "Macro calls",
256 Self::Derive { .. } => "Derives",
257 Self::Priority { .. } => "Priorities",
258 Self::Tween { .. } => "Tweens",
259 Self::Rule { .. } => "Rules",
260 Self::Assignment { left, .. } => match left.token.value() {
261 Token::Identifier(_) => "Property assignments",
262 Token::StaticTokenIdentifier(_) => "Static token assignments",
263 Token::TokenIdentifier(_) => "Token assignments",
264 _ => "Assignments",
265 },
266 Self::MathOperation { .. } | Self::UnaryMinus { .. } => "Math Operations",
267 Self::Table { .. } | Self::AnnotatedTable { .. } => "Tables",
268 Self::Enum { .. } => "Enums",
269 Self::Node { .. } | Self::None { .. } => "These",
270 }
271 }
272
273 pub fn start(&self) -> usize {
274 match self {
275 Self::Macro { declaration, .. } => declaration.token.start(),
276 Self::MacroCall { name, .. } => name.token.start(),
277
278 Self::Derive { declaration, .. }
279 | Self::Priority { declaration, .. }
280 | Self::Tween { declaration, .. } => declaration.token.start(),
281
282 Self::Rule { selectors, body } => {
283 if let Some(first) = selectors.as_ref().and_then(|s| s.first()) {
284 return first.start();
285 }
286
287 if let Some(body) = body {
288 return body.start();
289 }
290
291 0
292 }
293
294 Self::Assignment { left, .. } => left.token.start(),
295 Self::MathOperation { left, .. } => left.start(),
296 Self::UnaryMinus { operator, .. } => operator.token.start(),
297 Self::AnnotatedTable { annotation, .. } => annotation.token.start(),
298 Self::Table { body } => body.start(),
299 Self::Enum { keyword, .. } => keyword.token.start(),
300 Self::Node { node } | Self::None { node } => node.token.start(),
301 }
302 }
303
304 pub fn span(&self) -> (usize, usize) {
305 (self.start(), self.end())
306 }
307}
308
309impl<'a> SpanEnd for Construct<'a> {
310 fn end(&self) -> usize {
311 match self {
312 Self::Macro {
313 declaration,
314 name,
315 args,
316 return_type,
317 body,
318 } => {
319 if let Some(body) = body {
320 return body.end();
321 }
322
323 if let Some((arrow, ident)) = return_type {
324 if let Some(ident) = ident {
325 return ident.token.end();
326 }
327
328 return arrow.token.end();
329 }
330
331 if let Some(args) = args {
332 return args.end();
333 }
334
335 if let Some(name) = name {
336 return name.token.end();
337 }
338
339 declaration.token.end()
340 }
341
342 Self::MacroCall {
343 name,
344 body,
345 terminator,
346 } => {
347 if let Some(terminator) = terminator {
348 return terminator.token.end();
349 }
350
351 if let Some(body) = body {
352 return body.end();
353 }
354
355 name.token.end()
356 }
357
358 Self::Derive {
359 declaration,
360 body,
361 terminator,
362 }
363 | Self::Priority {
364 declaration,
365 body,
366 terminator,
367 }
368 => {
369 if let Some(terminator) = terminator {
370 return terminator.token.end();
371 }
372
373 if let Some(body) = body {
374 return body.end();
375 }
376
377 declaration.token.end()
378 }
379
380 Self::Tween {
381 declaration,
382 name,
383 body,
384 terminator,
385 } => {
386 if let Some(terminator) = terminator {
387 return terminator.token.end();
388 }
389
390 if let Some(body) = body {
391 return body.end();
392 }
393
394 if let Some(name) = name {
395 return name.token.end();
396 }
397
398 declaration.token.end()
399 }
400
401 Self::Rule { body, .. } => {
402 if let Some(body) = body {
403 return body.end();
404 }
405
406 0
407 }
408
409 Self::Assignment {
410 left,
411 middle,
412 right,
413 terminator,
414 } => {
415 if let Some(terminator) = terminator {
416 return terminator.token.end();
417 }
418
419 if let Some(right) = right {
420 return right.end();
421 }
422
423 if let Some(middle) = middle {
424 return middle.token.end();
425 }
426
427 left.token.end()
428 }
429
430 Self::MathOperation {
431 left,
432 operators,
433 right,
434 ..
435 } => {
436 if let Some(right) = right {
437 return right.end();
438 }
439
440 if let Some(last_op) = operators.last() {
441 return last_op.token.end();
442 }
443
444 left.end()
445 }
446
447 Self::UnaryMinus { operand, .. } => operand.end(),
448
449 Self::AnnotatedTable { annotation, body } => {
450 if let Some(body) = body {
451 return body.end();
452 }
453
454 annotation.token.end()
455 }
456
457 Self::Table { body } => body.end(),
458
459 Self::Enum {
460 keyword,
461 name,
462 variant,
463 } => {
464 if let Some(variant) = variant {
465 return variant.token.end();
466 }
467
468 if let Some(name) = name {
469 return name.token.end();
470 }
471
472 keyword.token.end()
473 }
474
475 Self::Node { node } | Self::None { node } => node.token.end(),
476 }
477 }
478}
479
480pub(crate) enum ParseEndedReason {
481 Eof,
482 Manual,
483}
484
485#[derive(Debug)]
486pub struct Delimited<'a, T: SpanEnd = Construct<'a>> {
487 pub left: Node<'a>,
488 pub content: Option<Vec<T>>,
489 pub right: Option<Node<'a>>,
490}
491
492impl<'a, T: SpanEnd> Delimited<'a, T> {
493 pub(crate) fn new(left: Node<'a>, content: Option<Vec<T>>, right: Option<Node<'a>>) -> Self {
494 Self {
495 left,
496 content,
497 right,
498 }
499 }
500
501 #[inline(always)]
502 pub(crate) fn start(&self) -> usize {
503 self.left.token.start()
504 }
505
506 pub(crate) fn end(&self) -> usize {
507 if let Some(right) = &self.right {
508 return right.token.2;
509 }
510
511 if let Some(content) = &self.content {
512 if let Some(last) = content.last() {
513 return last.end();
514 }
515 }
516
517 self.left.token.end()
518 }
519}
520
521impl<'a, T: SpanEnd> SpanEnd for Delimited<'a, T> {
522 fn end(&self) -> usize {
523 Delimited::end(self)
524 }
525}
526
527#[derive(Debug)]
528pub struct AstErrors(pub Vec<Diagnostic>);
529
530impl AstErrors {
531 pub fn new() -> Self {
532 Self(Vec::new())
533 }
534}
535
536pub(crate) trait PushParseError {
537 fn push(&mut self, error: ParseError, range: Range);
538}
539
540impl PushParseError for AstErrors {
541 fn push(&mut self, error: ParseError, range: Range) {
542 self.0.push(Diagnostic {
543 range,
544 severity: error.severity(),
545 code: error.to_string(),
546 message: error.message(),
547 data: error.data(),
548 });
549 }
550}
551
552#[inline(always)]
553pub(crate) fn clamp_span_to_end(span_end: usize) -> (usize, usize) {
554 (span_end - 1, span_end)
555}
556
557#[derive(Debug)]
558pub enum NodeStatus<'a> {
559 Exists,
560
561 None,
562
563 Err(Node<'a>),
565}
566
567impl<'a> NodeStatus<'a> {
568 pub(crate) fn consume_err_or_advance(self, parser: &mut RsmlParser<'a>) -> Option<Node<'a>> {
569 match self {
570 Self::Err(node) => Some(node),
571 Self::Exists => parser.advance(),
572 Self::None => None,
573 }
574 }
575}