1use toolshed::list::{ListBuilder, GrowableList};
2use crate::parser::{Parser, Parse, ANY, B0};
3use crate::lexer::Token::*;
4use crate::lexer::Asi;
5use crate::ast::{Node, NodeList, Declarator, DeclarationKind};
6use crate::ast::{Statement, StatementNode, Expression, ExpressionNode, Class, Function, Pattern};
7use crate::ast::expression::BinaryExpression;
8use crate::ast::statement::{ThrowStatement, ContinueStatement, BreakStatement, ReturnStatement};
9use crate::ast::statement::{TryStatement, CatchClause, IfStatement, WhileStatement, DoStatement};
10use crate::ast::statement::{DeclarationStatement, ForStatement, ForInStatement, ForOfStatement};
11use crate::ast::statement::{SwitchStatement, SwitchCase, LabeledStatement, ForInit};
12use crate::ast::OperatorKind::*;
13
14
15type StatementHandler = for<'ast> fn(&mut Parser<'ast>) -> StatementNode<'ast>;
16
17static STMT_HANDLERS: [StatementHandler; 108] = [
18 ____, EMPT, ____, ____, PRN, ____, ARR, ____, BLCK, ____, ____, NEW,
19OP, OP, OP, OP, OP, OP, OP, ____, REG, ____, ____, OP,
22OP, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
25____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
28____, ____, ____, ____, ____, ____, ____, ____, ____, ____, VAR, LET,
31CONS, BRK, DO, ____, ____, ____, ____, CLAS, ____, RET, WHL, ____,
34____, ____, CONT, FOR, SWCH, ____, ____, FUNC, THIS, ____, IF, THRW,
37____, TRY, ____, TRUE, FALS, NULL, UNDE, STR, NUM, BIN, ____, ____,
40____, ____, ____, ____, ____, ____, LABL, ____, TPLE, TPLS, ____, ____,
43];
45
46
47macro_rules! create_handlers {
48 ($( const $name:ident = |$par:ident| $code:expr; )*) => {
49 $(
50 #[allow(non_snake_case)]
51 fn $name<'ast>($par: &mut Parser<'ast>) -> StatementNode<'ast> {
52 $code
53 }
54 )*
55 };
56}
57
58use crate::parser::expression::handlers::{
60 PRN, ARR, OP, NEW, REG, THIS, TRUE, FALS, NULL, UNDE, STR, NUM, BIN, TPLS, TPLE
61};
62
63create_handlers! {
64 const ____ = |par| {
65 let loc = par.lexer.start();
66 par.error::<()>();
67 par.alloc_at_loc(loc, loc, Statement::Empty)
68 };
69 const EMPT = |par| {
70 let stmt = par.alloc_in_loc(Statement::Empty);
71 par.lexer.consume();
72
73 stmt
74 };
75 const BLCK = |par| par.block_statement();
76 const VAR = |par| par.variable_declaration_statement(DeclarationKind::Var);
77 const LET = |par| par.variable_declaration_statement(DeclarationKind::Let);
78 const CONS = |par| par.variable_declaration_statement(DeclarationKind::Const);
79 const RET = |par| par.return_statement();
80 const BRK = |par| par.break_statement();
81 const THRW = |par| par.throw_statement();
82 const CONT = |par| par.continue_statement();
83 const FUNC = |par| par.function_statement();
84 const CLAS = |par| par.class_statement();
85 const IF = |par| par.if_statement();
86 const WHL = |par| par.while_statement();
87 const DO = |par| par.do_statement();
88 const FOR = |par| par.for_statement();
89 const TRY = |par| par.try_statement();
90 const SWCH = |par| par.switch_statement();
91 const LABL = |par| par.labeled_or_expression_statement();
92}
93
94impl<'ast> Parse<'ast> for Statement<'ast> {
95 type Output = Node<'ast, Self>;
96
97 #[inline]
98 fn parse(par: &mut Parser<'ast>) -> Self::Output {
99 par.statement()
100 }
101}
102
103impl<'ast> Parse<'ast> for SwitchCase<'ast> {
104 type Output = Node<'ast, Self>;
105
106 #[inline]
107 fn parse(par: &mut Parser<'ast>) -> Self::Output {
108 let start = par.lexer.start();
109 let test = match par.lexer.token {
110 Case => {
111 par.lexer.consume();
112
113 Some(par.expression::<ANY>())
114 },
115 Default => {
116 par.lexer.consume();
117
118 None
119 },
120 _ => {
121 par.error::<()>();
122
123 None
124 }
125 };
126
127 let mut end = par.lexer.end();
128 expect!(par, Colon);
129
130 let builder = GrowableList::new();
131
132 loop {
133 match par.lexer.token {
134 Case | Default | BraceClose => break,
135 _ => {
136 let statement = par.statement();
137 end = statement.end;
138 builder.push(par.arena, statement);
139 }
140 }
141 }
142
143 par.alloc_at_loc(start, end, SwitchCase {
144 test,
145 consequent: builder.as_list()
146 })
147 }
148}
149
150impl<'ast> Parser<'ast> {
151 #[inline]
152 pub fn statement(&mut self) -> StatementNode<'ast> {
153 unsafe { (*(&STMT_HANDLERS as *const StatementHandler).offset(self.lexer.token as isize))(self) }
154 }
155
156 #[inline]
159 fn expect_semicolon(&mut self) {
160 match self.asi() {
161 Asi::ExplicitSemicolon => self.lexer.consume(),
162 Asi::ImplicitSemicolon => {},
163 Asi::NoSemicolon => self.error(),
164 }
165 }
166
167 #[inline]
168 pub fn block_statement(&mut self) -> StatementNode<'ast> {
169 let start = self.lexer.start_then_consume();
170 let block = self.raw_block();
171 let end = self.lexer.end_then_consume();
172
173 self.alloc_at_loc(start, end, block)
174 }
175
176 #[inline]
177 pub fn expression_statement(&mut self, expression: ExpressionNode<'ast>) -> StatementNode<'ast> {
178 let expression = self.nested_expression::<ANY>(expression);
179
180 self.wrap_expression(expression)
181 }
182
183 #[inline]
184 pub fn wrap_expression(&mut self, expression: ExpressionNode<'ast>) -> StatementNode<'ast> {
185 self.expect_semicolon();
186 self.alloc_at_loc(expression.start, expression.end, expression)
187 }
188
189 #[inline]
190 pub fn labeled_or_expression_statement(&mut self) -> StatementNode<'ast> {
191 let label = self.lexer.token_as_str();
192 let (start, end) = self.lexer.loc();
193
194 self.lexer.consume();
195
196 if self.lexer.token == Colon {
197 self.lexer.consume();
198
199 let body = self.statement();
200
201 return self.alloc_at_loc(start, body.end, LabeledStatement {
202 label,
203 body,
204 });
205 }
206
207 let expression = self.alloc_at_loc(start, end, label);
208 let expression = self.nested_expression::<ANY>(expression);
209
210 self.expect_semicolon();
211
212 self.alloc_at_loc(start, expression.end, expression)
213 }
214
215 #[inline]
216 pub fn function_statement(&mut self) -> StatementNode<'ast> {
217 let start = self.lexer.start_then_consume();
218 let function = Function::parse(self);
219
220 self.alloc_at_loc(start, function.body.end, function)
221 }
222
223 #[inline]
224 fn class_statement(&mut self) -> StatementNode<'ast> {
225 let start = self.lexer.start_then_consume();
226 let class = Class::parse(self);
227
228 self.alloc_at_loc(start, class.body.end, class)
229 }
230
231 #[inline]
232 pub fn variable_declaration_statement(&mut self, kind: DeclarationKind) -> StatementNode<'ast> {
233 let start = self.lexer.start_then_consume();
234 let declarators = self.variable_declarators();
235 let end = self.lexer.end();
236 let declaration = self.alloc_at_loc(start, end, DeclarationStatement {
237 kind,
238 declarators
239 });
240
241 self.expect_semicolon();
242
243 declaration
244 }
245
246 #[inline]
247 pub fn variable_declarator(&mut self) -> Node<'ast, Declarator<'ast>> {
248 let id = Pattern::parse(self);
249
250 let (init, end) = match self.lexer.token {
251 OperatorAssign => {
252 self.lexer.consume();
253 let init = self.expression::<B0>();
254
255 (Some(init), init.end)
256 },
257 _ => (None, id.end)
258 };
259
260 self.alloc_at_loc(id.start, end, Declarator {
261 id,
262 init,
263 })
264 }
265
266 #[inline]
267 pub fn variable_declarators(&mut self) -> NodeList<'ast, Declarator<'ast>> {
268 let builder = ListBuilder::new(self.arena, self.variable_declarator());
269
270 match self.lexer.token {
271 Comma => self.lexer.consume(),
272 _ => return builder.as_list(),
273 }
274
275 loop {
276 builder.push(self.arena, self.variable_declarator());
277
278 match self.lexer.token {
279 Comma => self.lexer.consume(),
280 _ => return builder.as_list(),
281 }
282 }
283 }
284
285 #[inline]
286 pub fn return_statement(&mut self) -> StatementNode<'ast> {
287 let (start, mut end) = self.lexer.loc();
288 self.lexer.consume();
289
290 let value = match self.asi() {
291 Asi::NoSemicolon => {
292 let expression = self.expression::<ANY>();
293 end = expression.end;
294
295 self.expect_semicolon();
296
297 Some(expression)
298 }
299
300 Asi::ImplicitSemicolon => None,
301 Asi::ExplicitSemicolon => {
302 self.lexer.consume();
303
304 None
305 }
306 };
307
308 self.alloc_at_loc(start, end, ReturnStatement { value })
309 }
310
311 #[inline]
312 pub fn break_statement(&mut self) -> StatementNode<'ast> {
313 let (start, mut end) = self.lexer.loc();
314 self.lexer.consume();
315
316 let label = match self.asi() {
317 Asi::ExplicitSemicolon => {
318 self.lexer.consume();
319 None
320 },
321 Asi::ImplicitSemicolon => None,
322 Asi::NoSemicolon => {
323 let label = self.identifier();
324 end = label.end;
325
326 self.expect_semicolon();
327
328 Some(label)
329 }
330 };
331
332 self.alloc_at_loc(start, end, BreakStatement { label })
333 }
334
335 #[inline]
336 pub fn continue_statement(&mut self) -> StatementNode<'ast> {
337 let (start, mut end) = self.lexer.loc();
338 self.lexer.consume();
339
340 let label = match self.asi() {
341 Asi::ExplicitSemicolon => {
342 self.lexer.consume();
343 None
344 },
345 Asi::ImplicitSemicolon => None,
346 Asi::NoSemicolon => {
347 let label = self.identifier();
348 end = label.end;
349
350 self.expect_semicolon();
351
352 Some(label)
353 }
354 };
355
356 self.alloc_at_loc(start, end, ContinueStatement { label })
357 }
358
359 #[inline]
360 pub fn throw_statement(&mut self) -> StatementNode<'ast> {
361 let start = self.lexer.start_then_consume();
362 let value = self.expression::<ANY>();
363
364 self.expect_semicolon();
365
366 self.alloc_at_loc(start, value.end, ThrowStatement { value })
367 }
368
369 #[inline]
370 pub fn try_statement(&mut self) -> StatementNode<'ast> {
371 let start = self.lexer.start_then_consume();
372 let block = self.block();
373
374 let (handler, finalizer, end) = match self.lexer.token {
375 Catch => {
376 let start = self.lexer.start_then_consume();
377 expect!(self, ParenOpen);
378 let param = Pattern::parse(self);
379 expect!(self, ParenClose);
380 let body = self.block();
381
382 let handler = self.alloc_at_loc(start, body.end, CatchClause {
383 param,
384 body,
385 });
386
387 match self.lexer.token {
388 Finally => {
389 self.lexer.consume();
390 let block = self.block();
391
392 (Some(handler), Some(block), block.end)
393 },
394 _ => (Some(handler), None, handler.end)
395 }
396 },
397 Finally => {
398 self.lexer.consume();
399 let block = self.block();
400
401 (None, Some(block), block.end)
402 },
403 _ => {
404 self.error::<()>();
405
406 (None, None, block.end)
407 }
408 };
409
410 self.alloc_at_loc(start, end, TryStatement {
411 block,
412 handler,
413 finalizer,
414 })
415 }
416
417 #[inline]
418 pub fn if_statement(&mut self) -> StatementNode<'ast> {
419 let start = self.lexer.start_then_consume();
420 expect!(self, ParenOpen);
421 let test = self.expression::<ANY>();
422 expect!(self, ParenClose);
423
424 let consequent = self.statement();
425
426 let (alternate, end) = match self.lexer.token {
427 Else => {
428 self.lexer.consume();
429 let alternate = self.statement();
430 (Some(alternate), alternate.end)
431 },
432 _ => (None, consequent.end)
433 };
434
435 self.alloc_at_loc(start, end, IfStatement {
436 test,
437 consequent,
438 alternate,
439 })
440 }
441
442 #[inline]
443 pub fn while_statement(&mut self) -> StatementNode<'ast> {
444 let start = self.lexer.start_then_consume();
445 expect!(self, ParenOpen);
446 let test = self.expression::<ANY>();
447 expect!(self, ParenClose);
448
449 let body = self.statement();
450
451 self.alloc_at_loc(start, body.end, WhileStatement {
452 test,
453 body,
454 })
455 }
456
457 #[inline]
458 pub fn do_statement(&mut self) -> StatementNode<'ast> {
459 let start = self.lexer.start_then_consume();
460 let body = self.statement();
461 expect!(self, While);
462 expect!(self, ParenOpen);
463 let test = self.expression::<ANY>();
464 let end = self.lexer.end();
465 expect!(self, ParenClose);
466
467 self.alloc_at_loc(start, end, DoStatement {
468 body,
469 test,
470 })
471 }
472
473 #[inline]
474 fn for_init(&mut self, kind: DeclarationKind) -> Node<'ast, ForInit<'ast>> {
475 let start = self.lexer.start_then_consume();
476 let declarators = self.variable_declarators();
477 let end = self.lexer.end();
478
479 self.alloc_at_loc(start, end, DeclarationStatement {
480 kind,
481 declarators
482 })
483 }
484
485 #[inline]
486 fn for_statement(&mut self) -> StatementNode<'ast> {
487 let start = self.lexer.start_then_consume();
488 expect!(self, ParenOpen);
489
490 let init = match self.lexer.token {
491 Semicolon => {
492 self.lexer.consume();
493 None
494 },
495 DeclarationVar => Some(self.for_init(DeclarationKind::Var)),
496 DeclarationLet => Some(self.for_init(DeclarationKind::Let)),
497 DeclarationConst => Some(self.for_init(DeclarationKind::Const)),
498 _ => {
499 let init = self.expression::<ANY>();
500
501 if let Expression::Binary(BinaryExpression {
502 operator: In,
503 left,
504 right,
505 ..
506 }) = init.item {
507 let left = self.alloc_at_loc(left.start, left.end, left);
508
509 return self.for_in_statement_from_parts(start, left, right);
510 }
511
512 Some(self.alloc_at_loc(init.start, init.end, init))
513 },
514 };
515
516 if let Some(ref init) = init {
517 match self.lexer.token {
518 OperatorIn => {
519 self.lexer.consume();
520 return self.for_in_statement(start, *init);
521 },
522 Identifier if self.lexer.token_as_str() == "of" => {
523 self.lexer.consume();
524 return self.for_of_statement(start, *init);
525 },
526 _ => expect!(self, Semicolon)
527 }
528 }
529
530 let test = match self.lexer.token {
531 Semicolon => {
532 self.lexer.consume();
533 None
534 },
535 _ => {
536 let test = self.expression::<ANY>();
537 expect!(self, Semicolon);
538
539 Some(test)
540 }
541 };
542
543 let update = match self.lexer.token {
544 ParenClose => {
545 self.lexer.consume();
546 None
547 },
548 _ => {
549 let update = self.expression::<ANY>();
550 expect!(self, ParenClose);
551
552 Some(update)
553 }
554 };
555
556 let body = self.statement();
557
558 self.alloc_at_loc(start, body.end, ForStatement {
559 init,
560 test,
561 update,
562 body,
563 })
564 }
565
566 fn for_in_statement_from_parts(&mut self, start: u32, left: Node<'ast, ForInit<'ast>>, right: ExpressionNode<'ast>) -> StatementNode<'ast> {
567 expect!(self, ParenClose);
568
569 let body = self.statement();
570
571 self.alloc_at_loc(start, body.end, ForInStatement {
572 left,
573 right,
574 body,
575 })
576 }
577
578 fn for_in_statement(&mut self, start: u32, left: Node<'ast, ForInit<'ast>>) -> StatementNode<'ast> {
579 let right = self.expression::<ANY>();
580
581 expect!(self, ParenClose);
582
583 let body = self.statement();
584
585 self.alloc_at_loc(start, body.end, ForInStatement {
586 left,
587 right,
588 body,
589 })
590 }
591
592 fn for_of_statement(&mut self, start: u32, left: Node<'ast, ForInit<'ast>>) -> StatementNode<'ast> {
593 let right = self.expression::<ANY>();
594
595 expect!(self, ParenClose);
596
597 let body = self.statement();
598
599 self.alloc_at_loc(start, body.end, ForOfStatement {
600 left,
601 right,
602 body,
603 })
604 }
605
606 fn switch_statement(&mut self) -> StatementNode<'ast> {
607 let start = self.lexer.start_then_consume();
608 expect!(self, ParenOpen);
609
610 let discriminant = self.expression::<ANY>();
611
612 expect!(self, ParenClose);
613
614 let cases = self.block();
615
616 self.alloc_at_loc(start, cases.end, SwitchStatement {
617 discriminant,
618 cases
619 })
620 }
621}
622
623#[cfg(test)]
624mod test {
625 use super::*;
626 use crate::parser::parse;
627 use crate::parser::mock::Mock;
628 use crate::ast::{NodeList, Literal, Function, Class, OperatorKind, BlockStatement};
629 use crate::ast::expression::*;
630
631 #[test]
632 fn block_statement() {
633 let src = "{ true }";
634 let mock = Mock::new();
635
636 let expected = mock.list([
637 BlockStatement {
638 body: mock.list([
639 mock.ptr(Literal::True)
640 ])
641 }
642 ]);
643
644 assert_eq!(parse(src).unwrap().body(), expected);
645 }
646
647 #[test]
648 fn labeled_block_statement() {
649 let src = "foobar: { true }";
650 let mock = Mock::new();
651
652 let expected = mock.list([
653 LabeledStatement {
654 label: "foobar",
655 body: mock.ptr(BlockStatement {
656 body: mock.list([
657 mock.ptr(Literal::True)
658 ])
659 })
660 }
661 ]);
662
663 assert_eq!(parse(src).unwrap().body(), expected);
664 }
665
666 #[test]
667 fn if_statement() {
668 let src = "if (true) foo;";
669 let mock = Mock::new();
670
671 let expected = mock.list([
672 IfStatement {
673 test: mock.ptr(Literal::True),
674 consequent: mock.ptr(mock.ptr("foo")),
675 alternate: None
676 }
677 ]);
678
679 assert_eq!(parse(src).unwrap().body(), expected);
680 }
681
682 #[test]
683 fn if_else_statement() {
684 let src = "if (true) foo; else { bar; }";
685 let mock = Mock::new();
686
687 let expected = mock.list([
688 IfStatement {
689 test: mock.ptr(Literal::True),
690 consequent: mock.ptr(mock.ptr("foo")),
691 alternate: Some(mock.ptr(BlockStatement {
692 body: mock.list([
693 mock.ptr("bar")
694 ])
695 }))
696 }
697 ]);
698
699 assert_eq!(parse(src).unwrap().body(), expected);
700 }
701
702 #[test]
703 fn while_statement() {
704 let src = "while (true) foo;";
705 let mock = Mock::new();
706
707 let expected = mock.list([
708 WhileStatement {
709 test: mock.ptr(Literal::True),
710 body: mock.ptr(mock.ptr("foo"))
711 }
712 ]);
713
714 assert_eq!(parse(src).unwrap().body(), expected);
715 }
716
717 #[test]
718 fn while_statement_block() {
719 let src = "while (true) { foo; }";
720 let mock = Mock::new();
721
722 let expected = mock.list([
723 WhileStatement {
724 test: mock.ptr(Literal::True),
725 body: mock.ptr(BlockStatement {
726 body: mock.list([
727 mock.ptr("foo")
728 ])
729 })
730 }
731 ]);
732
733 assert_eq!(parse(src).unwrap().body(), expected);
734 }
735
736 #[test]
737 fn do_statement() {
738 let src = "do foo; while (true)";
739 let mock = Mock::new();
740
741 let expected = mock.list([
742 DoStatement {
743 body: mock.ptr(mock.ptr("foo")),
744 test: mock.ptr(Literal::True)
745 }
746 ]);
747
748 assert_eq!(parse(src).unwrap().body(), expected);
749 }
750
751 #[test]
752 fn break_statement() {
753 let src = "break;";
754 let mock = Mock::new();
755
756 let expected = mock.list([
757 BreakStatement {
758 label: None,
759 }
760 ]);
761
762 assert_eq!(parse(src).unwrap().body(), expected);
763 }
764
765 #[test]
766 fn break_statement_label() {
767 let src = "break foo;";
768 let mock = Mock::new();
769
770 let expected = mock.list([
771 BreakStatement {
772 label: Some(mock.ptr("foo")),
773 }
774 ]);
775
776 assert_eq!(parse(src).unwrap().body(), expected);
777 }
778
779 #[test]
780 fn throw_statement() {
781 let src = "throw '3'";
782 let mock = Mock::new();
783
784 let expected = mock.list([
785 ThrowStatement {
786 value: mock.ptr(Literal::String("'3'")),
787 }
788 ]);
789
790 assert_eq!(parse(src).unwrap().body(), expected);
791 }
792
793 #[test]
794 fn try_statement() {
795 let src = "try {} catch (err) {}";
796 let mock = Mock::new();
797
798 let expected = mock.list([
799 TryStatement {
800 block: mock.empty_block(),
801 handler: Some(mock.ptr(CatchClause {
802 param: mock.ptr(Pattern::Identifier("err")),
803 body: mock.empty_block()
804 })),
805 finalizer: None
806 }
807 ]);
808
809 assert_eq!(parse(src).unwrap().body(), expected);
810 }
811
812 #[test]
813 fn try_statement_finally() {
814 let src = "try { foo; } finally { bar; }";
815 let mock = Mock::new();
816
817 let expected = mock.list([
818 TryStatement {
819 block: mock.block([
820 mock.ptr("foo")
821 ]),
822 handler: None,
823 finalizer: Some(mock.block([
824 mock.ptr("bar")
825 ])),
826 }
827 ]);
828
829 assert_eq!(parse(src).unwrap().body(), expected);
830 }
831
832 #[test]
833 fn try_statement_full() {
834 let src = "try { foo; } catch (err) { bar; } finally { qux; }";
835 let mock = Mock::new();
836
837 let expected = mock.list([
838 TryStatement {
839 block: mock.block([
840 mock.ptr("foo")
841 ]),
842 handler: Some(mock.ptr(CatchClause {
843 param: mock.ptr(Pattern::Identifier("err")),
844 body: mock.block([
845 mock.ptr("bar")
846 ])
847 })),
848 finalizer: Some(mock.block([
849 mock.ptr("qux")
850 ])),
851 }
852 ]);
853
854 assert_eq!(parse(src).unwrap().body(), expected);
855 }
856
857 #[test]
858 fn try_statement_no_tail() {
859 assert!(parse("try {}").is_err())
860 }
861
862 #[test]
863 fn variable_declaration_statement() {
864 let src = "var x, y, z = 42;";
865 let mock = Mock::new();
866
867 let expected = mock.list([
868 DeclarationStatement {
869 kind: DeclarationKind::Var,
870 declarators: mock.list([
871 Declarator {
872 id: mock.ptr(Pattern::Identifier("x")),
873 init: None,
874 },
875 Declarator {
876 id: mock.ptr(Pattern::Identifier("y")),
877 init: None,
878 },
879 Declarator {
880 id: mock.ptr(Pattern::Identifier("z")),
881 init: Some(mock.number("42"))
882 }
883 ])
884 }
885 ]);
886
887 assert_eq!(parse(src).unwrap().body(), expected);
888 }
889
890 #[test]
891 fn variable_declaration_statement_spread() {
892 let src = "const a = {...foo}";
893 let mock = Mock::new();
894
895 let expected = mock.list([
896 DeclarationStatement {
897 kind: DeclarationKind::Const,
898 declarators: mock.list([
899 Declarator {
900 id: mock.ptr(Pattern::Identifier("a")),
901 init: Some(mock.ptr(ObjectExpression {
902 body: mock.list([
903 Property::Spread {
904 argument: mock.ptr("foo")
905 },
906 ])
907 }))
908 }
909 ])
910 }
911 ]);
912
913 assert_eq!(parse(src).unwrap().body(), expected);
914 }
915
916 #[test]
917 fn variable_declaration_statement_destructuring_array() {
918 let src = "let [x, y] = [1, 2];";
919 let mock = Mock::new();
920
921 let expected = mock.list([
922 DeclarationStatement {
923 kind: DeclarationKind::Let,
924 declarators: mock.list([
925 Declarator {
926 id: mock.ptr(Pattern::ArrayPattern {
927 elements: mock.list([
928 Pattern::Identifier("x"),
929 Pattern::Identifier("y")
930 ])
931 }),
932 init: Some(mock.ptr(ArrayExpression {
933 body: mock.list([
934 Expression::Literal(Literal::Number("1")),
935 Expression::Literal(Literal::Number("2")),
936 ])
937 })),
938 },
939 ])
940 }
941 ]);
942
943 assert_eq!(parse(src).unwrap().body(), expected);
944 }
945
946 #[test]
947 fn variable_declaration_statement_destructuring_array_sparse() {
948 let src = "let [, foo] = bar;";
949 let mock = Mock::new();
950
951 let expected = mock.list([
952 DeclarationStatement {
953 kind: DeclarationKind::Let,
954 declarators: mock.list([
955 Declarator {
956 id: mock.ptr(Pattern::ArrayPattern {
957 elements: mock.list([
958 Pattern::Void,
959 Pattern::Identifier("foo")
960 ])
961 }),
962 init: Some(mock.ptr("bar")),
963 },
964 ])
965 }
966 ]);
967
968 assert_eq!(parse(src).unwrap().body(), expected);
969 }
970
971 #[test]
972 fn variable_declaration_statement_destructuring_object() {
973 let src = "const { x, y } = { a, b };";
974 let mock = Mock::new();
975
976 let expected = mock.list([
977 DeclarationStatement {
978 kind: DeclarationKind::Const,
979 declarators: mock.list([
980 Declarator {
981 id: mock.ptr(Pattern::ObjectPattern {
982 properties: mock.list([
983 Property::Shorthand("x"),
984 Property::Shorthand("y"),
985 ])
986 }),
987 init: Some(mock.ptr(ObjectExpression {
988 body: mock.list([
989 Property::Shorthand("a"),
990 Property::Shorthand("b"),
991 ])
992 })),
993 },
994 ])
995 }
996 ]);
997
998 assert_eq!(parse(src).unwrap().body(), expected);
999 }
1000
1001 #[test]
1002 fn for_statement() {
1003 let src = "for (let i = 0; i < 10; i++) {}";
1004 let mock = Mock::new();
1005
1006 let expected = mock.list([
1007 ForStatement {
1008 init: Some(mock.ptr(DeclarationStatement {
1009 kind: DeclarationKind::Let,
1010 declarators: mock.list([
1011 Declarator {
1012 id: mock.ptr(Pattern::Identifier("i")),
1013 init: Some(mock.number("0")),
1014 }
1015 ]),
1016 })),
1017 test: Some(mock.ptr(BinaryExpression {
1018 operator: OperatorKind::Lesser,
1019 left: mock.ptr("i"),
1020 right: mock.number("10"),
1021 })),
1022 update: Some(mock.ptr(PostfixExpression {
1023 operator: OperatorKind::Increment,
1024 operand: mock.ptr("i")
1025 })),
1026 body: mock.ptr(BlockStatement {
1027 body: NodeList::empty()
1028 })
1029 }
1030 ]);
1031
1032 assert_eq!(parse(src).unwrap().body(), expected);
1033 }
1034
1035 #[test]
1036 fn empty_for_statement() {
1037 let src = "for (;;) {}";
1038 let mock = Mock::new();
1039
1040 let expected = mock.list([
1041 ForStatement {
1042 init: None,
1043 test: None,
1044 update: None,
1045 body: mock.ptr(BlockStatement {
1046 body: NodeList::empty()
1047 })
1048 }
1049 ]);
1050
1051 assert_eq!(parse(src).unwrap().body(), expected);
1052 }
1053
1054
1055 #[test]
1056 fn for_statement_continue() {
1057 let src = "for (let i = 0, j = 10; i < 10; i++, j--) { continue; }";
1058 let mock = Mock::new();
1059
1060 let expected = mock.list([
1061 ForStatement {
1062 init: Some(mock.ptr(DeclarationStatement {
1063 kind: DeclarationKind::Let,
1064 declarators: mock.list([
1065 Declarator {
1066 id: mock.ptr(Pattern::Identifier("i")),
1067 init: Some(mock.number("0")),
1068 },
1069 Declarator {
1070 id: mock.ptr(Pattern::Identifier("j")),
1071 init: Some(mock.number("10")),
1072 }
1073 ]),
1074 })),
1075 test: Some(mock.ptr(BinaryExpression {
1076 operator: OperatorKind::Lesser,
1077 left: mock.ptr("i"),
1078 right: mock.number("10"),
1079 })),
1080 update: Some(mock.ptr(SequenceExpression {
1081 body: mock.list([
1082 Expression::Postfix(PostfixExpression {
1083 operator: OperatorKind::Increment,
1084 operand: mock.ptr("i")
1085 }),
1086 Expression::Postfix(PostfixExpression {
1087 operator: OperatorKind::Decrement,
1088 operand: mock.ptr("j")
1089 })
1090 ])
1091 })),
1092 body: mock.ptr(BlockStatement {
1093 body: mock.list([
1094 ContinueStatement {
1095 label: None
1096 }
1097 ]),
1098 })
1099 }
1100 ]);
1101
1102 assert_eq!(parse(src).unwrap().body(), expected);
1103 }
1104
1105
1106 #[test]
1107 fn for_statement_sequences() {
1108 let src = "for (let i = 0, j = 10; i < 10; i++, j--) {}";
1109 let mock = Mock::new();
1110
1111 let expected = mock.list([
1112 ForStatement {
1113 init: Some(mock.ptr(DeclarationStatement {
1114 kind: DeclarationKind::Let,
1115 declarators: mock.list([
1116 Declarator {
1117 id: mock.ptr(Pattern::Identifier("i")),
1118 init: Some(mock.number("0")),
1119 },
1120 Declarator {
1121 id: mock.ptr(Pattern::Identifier("j")),
1122 init: Some(mock.number("10")),
1123 }
1124 ]),
1125 })),
1126 test: Some(mock.ptr(BinaryExpression {
1127 operator: OperatorKind::Lesser,
1128 left: mock.ptr("i"),
1129 right: mock.number("10"),
1130 })),
1131 update: Some(mock.ptr(SequenceExpression {
1132 body: mock.list([
1133 Expression::Postfix(PostfixExpression {
1134 operator: OperatorKind::Increment,
1135 operand: mock.ptr("i")
1136 }),
1137 Expression::Postfix(PostfixExpression {
1138 operator: OperatorKind::Decrement,
1139 operand: mock.ptr("j")
1140 })
1141 ])
1142 })),
1143 body: mock.ptr(BlockStatement {
1144 body: NodeList::empty()
1145 })
1146 }
1147 ]);
1148
1149 assert_eq!(parse(src).unwrap().body(), expected);
1150 }
1151
1152 #[test]
1153 fn function_statement() {
1154 let src = "function foo() {}";
1155 let mock = Mock::new();
1156
1157 let expected = mock.list([
1158 Function {
1159 name: mock.name("foo"),
1160 generator: false,
1161 params: NodeList::empty(),
1162 body: mock.empty_block(),
1163 }
1164 ]);
1165
1166 assert_eq!(parse(src).unwrap().body(), expected);
1167 }
1168
1169 #[test]
1170 fn function_statement_must_have_name() {
1171 assert!(parse("function() {}").is_err());
1172 }
1173
1174 #[test]
1175 fn class_statement() {
1176 let src = "class Foo {}";
1177 let mock = Mock::new();
1178
1179 let expected = mock.list([
1180 Class {
1181 name: mock.name("Foo"),
1182 extends: None,
1183 body: mock.empty_block(),
1184 }
1185 ]);
1186
1187 assert_eq!(parse(src).unwrap().body(), expected);
1188 }
1189
1190 #[test]
1191 #[should_panic]
1192 fn class_statement_must_have_name() {
1193 parse("class {}").unwrap();
1194 }
1195
1196 #[test]
1197 fn switch_statement() {
1198 let src = r#"
1199 switch (times) {
1200 case 3:
1201 break;
1202 case 2:
1203 return b;
1204 case "1":
1205 default:
1206 return false;
1207 }
1208 "#;
1209 let mock = Mock::new();
1210
1211 let expected = mock.list([
1212 SwitchStatement {
1213 discriminant: mock.ptr("times"),
1214 cases: mock.block([
1215 SwitchCase {
1216 test: Some(mock.number("3")),
1217 consequent: mock.list([
1218 BreakStatement { label: None }
1219 ])
1220 },
1221 SwitchCase {
1222 test: Some(mock.number("2")),
1223 consequent: mock.list([
1224 ReturnStatement { value: Some(mock.ptr("b")) }
1225 ])
1226 },
1227 SwitchCase {
1228 test: Some(mock.ptr(Expression::Literal(Literal::String("\"1\"")))),
1229 consequent: NodeList::empty()
1230 },
1231 SwitchCase {
1232 test: None,
1233 consequent: mock.list([
1234 ReturnStatement { value: Some(mock.ptr(Expression::Literal(Literal::False))) }
1235 ])
1236 },
1237 ])
1238 }
1239 ]);
1240 assert_eq!(parse(src).unwrap().body(), expected);
1241 }
1242}