1use toolshed::list::ListBuilder;
2use crate::parser::{Parser, Parse, BindingPower, ANY, B0, B15};
3use crate::lexer::Token::*;
4use crate::ast::{Node, NodeList, Expression, ExpressionNode, IdentifierNode, ExpressionList};
5use crate::ast::{Property, PropertyKey, OperatorKind, Literal, Function, Class, StatementNode};
6use crate::ast::expression::*;
7
8
9type ExpressionHandler = for<'ast> fn(&mut Parser<'ast>) -> ExpressionNode<'ast>;
10
11pub type Context = &'static [ExpressionHandler; 108];
12
13static DEF_CONTEXT: Context = &[
14 ____, ____, ____, ____, PRN, ____, ARR, ____, OBJ, ____, ____, NEW,
15OP, OP, OP, OP, OP, OP, OP, ____, REG, ____, ____, OP,
18OP, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
21____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
24____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
27____, ____, ____, ____, ____, ____, ____, CLAS, ____, ____, ____, ____,
30____, ____, ____, ____, ____, ____, ____, FUNC, THIS, ____, ____, ____,
33____, ____, ____, TRUE, FALS, NULL, UNDE, STR, NUM, BIN, ____, ____,
36____, ____, ____, ____, ____, ____, IDEN, ____, TPLE, TPLS, ____, ____,
39];
41
42pub static ARRAY_CONTEXT: Context = &[
44 ____, ____, ____, VOID, PRN, ____, ARR, VOID, OBJ, ____, ____, NEW,
45 OP, OP, OP, OP, OP, OP, OP, ____, REG, ____, ____, OP,
46 OP, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
47 ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
48 ____, ____, ____, ____, ____, ____, ____, ____, ____, SPRD, ____, ____,
49 ____, ____, ____, ____, ____, ____, ____, CLAS, ____, ____, ____, ____,
50 ____, ____, ____, ____, ____, ____, ____, FUNC, THIS, ____, ____, ____,
51 ____, ____, ____, TRUE, FALS, NULL, UNDE, STR, NUM, BIN, ____, ____,
52 ____, ____, ____, ____, ____, ____, IDEN, ____, TPLE, TPLS, ____, ____,
53];
54
55pub static CALL_CONTEXT: Context = &[
57 ____, ____, ____, ____, PRN, ____, ARR, ____, OBJ, ____, ____, NEW,
58 OP, OP, OP, OP, OP, OP, OP, ____, REG, ____, ____, OP,
59 OP, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
60 ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
61 ____, ____, ____, ____, ____, ____, ____, ____, ____, SPRD, ____, ____,
62 ____, ____, ____, ____, ____, ____, ____, CLAS, ____, ____, ____, ____,
63 ____, ____, ____, ____, ____, ____, ____, FUNC, THIS, ____, ____, ____,
64 ____, ____, ____, TRUE, FALS, NULL, UNDE, STR, NUM, BIN, ____, ____,
65 ____, ____, ____, ____, ____, ____, IDEN, ____, TPLE, TPLS, ____, ____,
66];
67
68macro_rules! create_handlers {
69 ($( const $name:ident = |$par:ident| $code:expr; )* $( pub const $pname:ident = |$ppar:ident| $pcode:expr; )*) => {
70 $(
71 #[allow(non_snake_case)]
72 fn $name<'ast>($par: &mut Parser<'ast>) -> ExpressionNode<'ast> {
73 $code
74 }
75 )*
76
77 pub(crate) mod handlers {
78 use super::*;
79
80 $(
81 #[allow(non_snake_case)]
82 pub fn $pname<'ast>($ppar: &mut Parser<'ast>) -> StatementNode<'ast> {
83 let expression = $pcode;
84 $ppar.expression_statement(expression)
85 }
86 )*
87 }
88
89 $(
90 #[allow(non_snake_case)]
91 fn $pname<'ast>($ppar: &mut Parser<'ast>) -> ExpressionNode<'ast> {
92 $pcode
93 }
94 )*
95 };
96}
97
98create_handlers! {
99 const ____ = |par| {
100 let loc = par.lexer.start();
101 par.error::<()>();
102 par.alloc_at_loc(loc, loc, Expression::Void)
103 };
104
105 const VOID = |par| par.void_expression();
106
107 const OBJ = |par| par.object_expression();
108
109 const CLAS = |par| par.class_expression();
110
111 const FUNC = |par| par.function_expression();
112
113 const IDEN = |par| {
114 let ident = par.lexer.token_as_str();
115 let expr = par.alloc_in_loc(ident);
116
117 par.lexer.consume();
118 expr
119 };
120
121 const SPRD = |par| {
122 let start = par.lexer.start_then_consume();
123 let argument = par.expression::<B0>();
124
125 par.alloc_at_loc(start, argument.end, SpreadExpression { argument })
126 };
127
128 pub const THIS = |par| {
129 let expr = par.alloc_in_loc(ThisExpression);
130 par.lexer.consume();
131
132 expr
133 };
134
135 pub const OP = |par| {
136 let start = par.lexer.start();
137 let op = OperatorKind::from_token(par.lexer.token).expect("Must be a prefix operator");
138 par.lexer.consume();
139 let expression = par.prefix_expression(op);
140 let end = par.lexer.end();
141 par.alloc_at_loc(start, end, expression)
142 };
143
144 pub const NEW = |par| {
145 let (start, op_end) = par.lexer.loc();
146
147 par.lexer.consume();
148
149 if par.lexer.token == Accessor {
150 let meta = par.alloc_at_loc(start, op_end, "new");
151 let expression = par.meta_property_expression(meta);
152 let end = par.lexer.end();
153 par.lexer.consume();
154 par.alloc_at_loc(start, end, expression)
155 } else {
156 let expression = par.prefix_expression(OperatorKind::New);
157 let end = par.lexer.end();
158 par.alloc_at_loc(start, end, expression)
159 }
160 };
161
162 pub const PRN = |par| {
163 par.paren_expression()
164 };
165
166 pub const ARR = |par| par.array_expression();
167
168 pub const REG = |par| par.regular_expression();
169
170 pub const TRUE = |par| {
171 let expr = par.alloc_in_loc(Literal::True);
172 par.lexer.consume();
173
174 expr
175 };
176
177 pub const FALS = |par| {
178 let expr = par.alloc_in_loc(Literal::False);
179
180 par.lexer.consume();
181 expr
182 };
183
184 pub const NULL = |par| {
185 let expr = par.alloc_in_loc(Literal::Null);
186
187 par.lexer.consume();
188 expr
189 };
190
191 pub const UNDE = |par| {
192 let expr = par.alloc_in_loc(Literal::Undefined);
193
194 par.lexer.consume();
195 expr
196 };
197
198 pub const STR = |par| {
199 let value = par.lexer.token_as_str();
200 let expr = par.alloc_in_loc(Literal::String(value));
201
202 par.lexer.consume();
203 expr
204 };
205
206 pub const NUM = |par| {
207 let value = par.lexer.token_as_str();
208 let expr = par.alloc_in_loc(Literal::Number(value));
209
210 par.lexer.consume();
211 expr
212 };
213
214 pub const BIN = |par| {
215 let value = par.lexer.token_as_str();
216 let expr = par.alloc_in_loc(Literal::Binary(value));
217
218 par.lexer.consume();
219 expr
220 };
221
222 pub const TPLS = |par| {
223 let quasi = par.lexer.quasi;
224 let quasi = par.alloc_in_loc(quasi);
225
226 par.lexer.consume();
227
228 par.alloc_at_loc(quasi.start, quasi.end, TemplateLiteral {
229 expressions: NodeList::empty(),
230 quasis: NodeList::from(par.arena, quasi)
231 })
232 };
233
234 pub const TPLE = |par| par.template_expression();
235}
236
237impl<'ast> Parser<'ast> {
238 #[inline]
239 fn bound_expression(&mut self) -> ExpressionNode<'ast> {
240 unsafe { (*(DEF_CONTEXT as *const ExpressionHandler).offset(self.lexer.token as isize))(self) }
241 }
242
243 #[inline]
244 fn context_bound_expression(&mut self, context: Context) -> ExpressionNode<'ast> {
245 unsafe { (*(context as *const ExpressionHandler).offset(self.lexer.token as isize))(self) }
246 }
247
248 #[inline]
249 pub fn expression<B>(&mut self) -> ExpressionNode<'ast>
250 where
251 B: BindingPower
252 {
253 let left = self.bound_expression();
254
255 self.nested_expression::<B>(left)
256 }
257
258 #[inline]
259 pub fn expression_in_context<B>(&mut self, context: Context) -> ExpressionNode<'ast>
260 where
261 B: BindingPower
262 {
263 let left = self.context_bound_expression(context);
264
265 self.nested_expression::<B>(left)
266 }
267
268 #[inline]
269 pub fn arrow_function_expression(&mut self, params: ExpressionList<'ast>) -> ArrowExpression<'ast> {
270 let params = self.params_from_expressions(params);
271
272 let body = match self.lexer.token {
273 BraceOpen => ArrowBody::Block(self.unchecked_block()),
274 _ => ArrowBody::Expression(self.expression::<B0>()),
275 };
276
277 ArrowExpression {
278 params,
279 body,
280 }
281 }
282
283 #[inline]
284 pub fn call_arguments(&mut self) -> ExpressionList<'ast> {
285 if self.lexer.token == ParenClose {
286 return NodeList::empty();
287 }
288
289 let expression = self.expression_in_context::<B0>(CALL_CONTEXT);
290 let builder = ListBuilder::new(self.arena, expression);
291
292 loop {
293 let expression = match self.lexer.token {
294 ParenClose => break,
295 Comma => {
296 self.lexer.consume();
297
298 if self.lexer.token == ParenClose {
299 break
300 }
301
302 self.expression_in_context::<B0>(CALL_CONTEXT)
303 }
304 _ => {
305 self.error::<()>();
306 break;
307 }
308 };
309
310 builder.push(self.arena, expression);
311 }
312
313 builder.as_list()
314 }
315
316 #[inline]
317 pub fn paren_expression(&mut self) -> ExpressionNode<'ast> {
318 let start = self.lexer.start_then_consume();
319 match self.lexer.token {
320 ParenClose => {
321 self.lexer.consume();
322 expect!(self, OperatorFatArrow);
323 let expression = self.arrow_function_expression(NodeList::empty());
324 let end = self.lexer.end();
325 self.alloc_at_loc(start, end, expression)
326 },
327 _ => {
328 let expression = self.expression::<ANY>();
329
330 expect!(self, ParenClose);
331
332 expression
333 }
334 }
335 }
336
337 #[inline]
338 pub fn prefix_expression(&mut self, operator: OperatorKind) -> PrefixExpression<'ast> {
339 let operand = self.expression::<B15>();
340
341 PrefixExpression {
342 operator,
343 operand,
344 }
345 }
346
347 #[inline]
348 pub fn object_expression(&mut self) -> ExpressionNode<'ast> {
349 let start = self.lexer.start_then_consume();
350 let body = self.property_list();
351 let end = self.lexer.end_then_consume();
352
353 self.alloc_at_loc(start, end, ObjectExpression {
354 body
355 })
356 }
357
358 #[inline]
359 pub fn meta_property_expression(&mut self, meta: IdentifierNode<'ast>) -> MetaPropertyExpression<'ast> {
360 let property = self.lexer.accessor_as_str();
361
362 if property != "target" {
364 self.error::<()>();
365 }
366
367 let property = self.alloc_in_loc(property);
368
369 MetaPropertyExpression {
370 meta,
371 property,
372 }
373 }
374
375 #[inline]
376 pub fn property_list(&mut self) -> NodeList<'ast, Property<'ast>> {
377 if self.lexer.token == BraceClose {
378 return NodeList::empty();
379 }
380
381 let builder = ListBuilder::new(self.arena, self.property());
382 loop {
383 match self.lexer.token {
384 BraceClose => break,
385 Comma => self.lexer.consume(),
386 _ => {
387 self.error::<()>();
388 break;
389 }
390 }
391
392 match self.lexer.token {
393 BraceClose => break,
394 _ => builder.push(self.arena, self.property()),
395 }
396 }
397
398 builder.as_list()
399 }
400
401 #[inline]
402 pub fn property(&mut self) -> Node<'ast, Property<'ast>> {
403 let start = self.lexer.start();
404
405 let key = match self.lexer.token {
406 _ if self.lexer.token.is_word() => {
407 let (start, end) = self.lexer.loc();
408 let label = self.lexer.token_as_str();
409
410 self.lexer.consume();
411
412 match self.lexer.token {
413 Colon | ParenOpen => self.alloc_at_loc(start, end, PropertyKey::Literal(label)),
414
415 _ => return self.alloc_at_loc(start, end, Property::Shorthand(label)),
416 }
417 },
418 OperatorSpread => {
419 let start = self.lexer.start_then_consume();
420 let argument = self.expression::<B0>();
421 let end = self.lexer.end();
422 return self.alloc_at_loc(start, end, Property::Spread { argument });
423 },
424 LiteralString |
425 LiteralNumber => {
426 let num = self.lexer.token_as_str();
427 let key = self.alloc_in_loc(PropertyKey::Literal(num));
428
429 self.lexer.consume();
430
431 key
432 },
433 LiteralBinary => {
434 let num = self.lexer.token_as_str();
435 let key = self.alloc_in_loc(PropertyKey::Binary(num));
436
437 self.lexer.consume();
438
439 key
440 },
441 BracketOpen => {
442 let start = self.lexer.start_then_consume();
443 let expression = self.expression::<ANY>();
444 let end = self.lexer.end();
445
446 expect!(self, BracketClose);
447
448 self.alloc_at_loc(start, end, PropertyKey::Computed(expression))
449 },
450 _ => return self.error(),
451 };
452
453 match self.lexer.token {
454 Colon => {
455 self.lexer.consume();
456
457 let value = self.expression::<B0>();
458
459 self.alloc_at_loc(start, value.end, Property::Literal {
460 key,
461 value,
462 })
463 },
464 ParenOpen => {
465 let value = Node::parse(self);
466
467 self.alloc_at_loc(start, value.end, Property::Method {
468 key,
469 value,
470 })
471 },
472 _ => self.error()
473 }
474 }
475
476 #[inline]
477 pub fn array_expression(&mut self) -> ExpressionNode<'ast> {
478 let start = self.lexer.start_then_consume();
479 let body = self.array_elements(|par| par.expression_in_context::<B0>(ARRAY_CONTEXT));
480 let end = self.lexer.end_then_consume();
481
482 self.alloc_at_loc(start, end, ArrayExpression { body })
483 }
484
485 #[inline]
486 pub fn void_expression(&mut self) -> ExpressionNode<'ast> {
488 let loc = self.lexer.start();
489 self.alloc_at_loc(loc, loc, Expression::Void)
490 }
491
492 #[inline]
493 pub fn array_elements<F, I>(&mut self, get: F) -> NodeList<'ast, I> where
494 F: Fn(&mut Parser<'ast>) -> Node<'ast, I>,
495 I: 'ast + Copy,
496 {
497 let item = match self.lexer.token {
498 BracketClose => return NodeList::empty(),
499 _ => get(self),
500 };
501
502 let builder = ListBuilder::new(self.arena, item);
503
504 loop {
505 match self.lexer.token {
506 Comma => self.lexer.consume(),
507 BracketClose => break,
508 _ => {
509 self.error::<()>();
510 break;
511 }
512 }
513
514 builder.push(self.arena, get(self))
515 }
516
517 builder.as_list()
518 }
519
520 #[inline]
521 pub fn regular_expression(&mut self) -> ExpressionNode<'ast> {
522 let start = self.lexer.start();
523 let value = self.lexer.read_regular_expression();
524 let end = self.lexer.end();
525
526 expect!(self, LiteralRegEx);
527
528 self.alloc_at_loc(start, end, Literal::RegEx(value))
529 }
530
531 #[inline]
532 pub fn template_string<T>(&mut self) -> Node<'ast, T>
533 where
534 T: Copy + From<TemplateLiteral<'ast>>,
535 {
536 let quasi = self.lexer.quasi;
537 let quasi = self.alloc_in_loc(quasi);
538
539 self.lexer.consume();
540
541 self.alloc_at_loc(quasi.start, quasi.end, TemplateLiteral {
542 expressions: NodeList::empty(),
543 quasis: NodeList::from(self.arena, quasi)
544 })
545 }
546
547 #[inline]
548 pub fn template_literal<T>(&mut self) -> Node<'ast, T>
549 where
550 T: Copy + From<TemplateLiteral<'ast>>,
551 {
552 let quasi = self.lexer.quasi;
553 let quasi = self.alloc_in_loc(quasi);
554
555 let start = self.lexer.start_then_consume();
556 let end;
557
558 let expression = self.expression::<ANY>();
559
560 match self.lexer.token {
561 BraceClose => self.lexer.read_template_kind(),
562 _ => self.error(),
563 }
564
565 let quasis = ListBuilder::new(self.arena, quasi);
566 let expressions = ListBuilder::new(self.arena, expression);
567
568 loop {
569 match self.lexer.token {
570 TemplateOpen => {
571 let quasi = self.lexer.quasi;
572 quasis.push(self.arena, self.alloc_in_loc(quasi));
573 self.lexer.consume();
574 expressions.push(self.arena, self.expression::<ANY>());
575
576 match self.lexer.token {
577 BraceClose => self.lexer.read_template_kind(),
578 _ => {
579 end = self.lexer.end();
580 self.error::<()>();
581 break;
582 }
583 }
584 },
585 TemplateClosed => {
586 let quasi = self.lexer.quasi;
587 quasis.push(self.arena, self.alloc_in_loc(quasi));
588 end = self.lexer.end_then_consume();
589 break;
590 },
591 _ => {
592 end = self.lexer.end();
593 self.error::<()>();
594 break;
595 }
596 }
597 }
598
599 self.alloc_at_loc(start, end, TemplateLiteral {
600 expressions: expressions.as_list(),
601 quasis: quasis.as_list(),
602 })
603 }
604
605 #[inline]
606 pub fn template_expression(&mut self) -> ExpressionNode<'ast> {
607 self.template_literal()
608 }
609
610 #[inline]
611 pub fn tagged_template_expression(&mut self, tag: ExpressionNode<'ast>) -> ExpressionNode<'ast> {
612 let quasi = self.template_literal();
613
614 self.alloc_at_loc(tag.start, quasi.end, TaggedTemplateExpression {
615 tag,
616 quasi,
617 })
618 }
619
620 #[inline]
621 pub fn function_expression(&mut self) -> ExpressionNode<'ast> {
622 let start = self.lexer.start_then_consume();
623 let function = Function::parse(self);
624
625 self.alloc_at_loc(start, function.body.end, function)
626 }
627
628 #[inline]
629 pub fn class_expression(&mut self) -> ExpressionNode<'ast> {
630 let start = self.lexer.start_then_consume();
631 let class = Class::parse(self);
632
633 self.alloc_at_loc(start, class.body.end, class)
634 }
635}
636
637#[cfg(test)]
638mod test {
639 use super::*;
640 use crate::ast::{OperatorKind, Literal, Statement, Function, Pattern, Class};
641 use crate::ast::expression::*;
642 use crate::ast::statement::*;
643 use crate::parser::parse;
644 use crate::parser::mock::Mock;
645
646 #[test]
647 fn ident_expression() {
648 let expected = Expression::Identifier("foobar");
649
650 assert_expr!("foobar;", expected);
651 }
652
653 #[test]
654 fn value_expression() {
655 let expected_a = Literal::String(r#""foobar""#);
656 let expected_b = Literal::Number("100");
657 let expected_c = Literal::True;
658
659 assert_expr!(r#""foobar";"#, expected_a);
660 assert_expr!("100;", expected_b);
661 assert_expr!("true;", expected_c);
662 }
663
664 #[test]
665 fn template_expression() {
666 let src = "`foobar`;";
667 let mock = Mock::new();
668
669 let expected = TemplateLiteral {
670 expressions: NodeList::empty(),
671 quasis: mock.list(["foobar"]),
672 };
673
674 assert_expr!(src, expected);
675 }
676
677 #[test]
678 fn tagged_template_expression() {
679 let src = "foo`bar`;";
680 let mock = Mock::new();
681
682 let expected = TaggedTemplateExpression {
683 tag: mock.ptr("foo"),
684 quasi: mock.ptr(TemplateLiteral {
685 expressions: NodeList::empty(),
686 quasis: mock.list(["bar"]),
687 })
688 };
689
690 assert_expr!(src, expected);
691 }
692
693 #[test]
694 fn complex_template_expression() {
695 let src = "`foo${ 10 }bar${ 20 }baz`;";
696 let mock = Mock::new();
697
698 let expected = TemplateLiteral {
699 expressions: mock.list([
700 Literal::Number("10"),
701 Literal::Number("20"),
702 ]),
703 quasis: mock.list(["foo", "bar", "baz" ]),
704 };
705
706 assert_expr!(src, expected);
707 }
708
709 #[test]
710 fn tagged_complex_template_expression() {
711 let src = "foo`bar${ 42 }baz`;";
712 let mock = Mock::new();
713
714 let expected = TaggedTemplateExpression {
715 tag: mock.ptr("foo"),
716 quasi: mock.ptr(TemplateLiteral {
717 expressions: mock.list([
718 Literal::Number("42"),
719 ]),
720 quasis: mock.list(["bar", "baz"]),
721 })
722 };
723
724 assert_expr!(src, expected);
725 }
726
727 #[test]
728 fn sequence_expression() {
729 let src = "foo, bar, baz;";
730 let mock = Mock::new();
731
732 let expected = SequenceExpression {
733 body: mock.list(["foo", "bar", "baz"]),
734 };
735
736 assert_expr!(src, expected);
737 }
738
739 #[test]
740 fn binary_expression() {
741 let src = "foo + bar;";
742 let mock = Mock::new();
743
744 let expected = BinaryExpression {
745 operator: OperatorKind::Addition,
746 left: mock.ptr("foo"),
747 right: mock.ptr("bar"),
748 };
749
750 assert_expr!(src, expected);
751 }
752
753 #[test]
754 fn parenthesized_binary_expression() {
755 let src = "(2 + 2);";
756 let mock = Mock::new();
757
758 let expected = BinaryExpression {
759 operator: OperatorKind::Addition,
760 left: mock.number("2"),
761 right: mock.number("2"),
762 };
763
764 assert_expr!(src, expected);
765 }
766
767 #[test]
768 fn conditional_expression() {
769 let src = "true ? foo : bar";
770
771 let mock = Mock::new();
772
773 let expected = ConditionalExpression {
774 test: mock.ptr(Expression::Literal(Literal::True)),
775 consequent: mock.ptr("foo"),
776 alternate: mock.ptr("bar"),
777 };
778
779 assert_expr!(src, expected);
780 }
781
782 #[test]
783 fn complex_conditional_expression() {
784 let src = "true ? foo = bar : baz";
785
786 let mock = Mock::new();
787
788 let expected = ConditionalExpression {
789 test: mock.ptr(Expression::Literal(Literal::True)),
790 consequent: mock.ptr(BinaryExpression {
791 operator: OperatorKind::Assign,
792 left: mock.ptr("foo"),
793 right: mock.ptr("bar"),
794 }),
795 alternate: mock.ptr("baz"),
796 };
797
798 assert_expr!(src, expected);
799 }
800
801 #[test]
802 fn postfix_expression() {
803 let src = "baz++;";
804 let mock = Mock::new();
805
806 let expected = PostfixExpression {
807 operator: OperatorKind::Increment,
808 operand: mock.ptr("baz"),
809 };
810
811 assert_expr!(src, expected);
812 }
813
814 #[test]
815 fn call_expression() {
816 {
817 let src = "foo();";
818 let mock = Mock::new();
819
820 let expected = CallExpression {
821 callee: mock.ptr("foo"),
822 arguments: NodeList::empty(),
823 };
824
825 assert_expr!(src, expected);
826 }
827
828 {
829 let src = "foo(1);";
830 let mock = Mock::new();
831
832 let expected = CallExpression {
833 callee: mock.ptr("foo"),
834 arguments: mock.list([
835 Literal::Number("1"),
836 ]),
837 };
838
839 assert_expr!(src, expected);
840 }
841
842 {
843 let src = "foo(1,2);";
844 let mock = Mock::new();
845
846 let expected = CallExpression {
847 callee: mock.ptr("foo"),
848 arguments: mock.list([
849 Literal::Number("1"),
850 Literal::Number("2"),
851 ]),
852 };
853
854 assert_expr!(src, expected);
855 }
856
857 {
858 let src = "foo(1,);";
859 let mock = Mock::new();
860
861 let expected = CallExpression {
862 callee: mock.ptr("foo"),
863 arguments: mock.list([
864 Literal::Number("1"),
865 ]),
866 };
867
868 assert_expr!(src, expected);
869 }
870
871 {
872 let src = "foo(1,2,);";
873 let mock = Mock::new();
874
875 let expected = CallExpression {
876 callee: mock.ptr("foo"),
877 arguments: mock.list([
878 Literal::Number("1"),
879 Literal::Number("2"),
880 ]),
881 };
882
883 assert_expr!(src, expected);
884 }
885 }
886
887 #[test]
888 fn member_expression() {
889 let src = "foo.bar";
890 let mock = Mock::new();
891
892 let expected = MemberExpression {
893 object: mock.ptr("foo"),
894 property: mock.ptr("bar"),
895 };
896
897 assert_expr!(src, expected);
898 }
899
900 #[test]
901 fn keyword_member_expression() {
902 let src = "foo.function";
903 let mock = Mock::new();
904
905 let expected = MemberExpression {
906 object: mock.ptr("foo"),
907 property: mock.ptr("function"),
908 };
909
910 assert_expr!(src, expected);
911 }
912
913 #[test]
914 fn computed_member_expression() {
915 let src = "foo[10]";
916 let mock = Mock::new();
917
918 let expected = ComputedMemberExpression {
919 object: mock.ptr("foo"),
920 property: mock.number("10"),
921 };
922
923 assert_expr!(src, expected);
924 }
925
926 #[test]
927 fn meta_property_expression() {
928 let src = "new.target";
929 let mock = Mock::new();
930 let expected = MetaPropertyExpression {
931 meta: mock.ptr("new"),
932 property: mock.ptr("target"),
933 };
934 assert_expr!(src, expected);
935 }
936
937 #[test]
938 fn meta_property_expression_throws() {
939 assert!(parse("new.callee").is_err());
940 }
941
942 #[test]
943 fn regular_expression() {
944 let src = r#"/^[A-Z]+\/[\d]+/g"#;
945
946 let expected = Literal::RegEx("/^[A-Z]+\\/[\\d]+/g");
947
948 assert_expr!(src, expected);
949 }
950
951 #[test]
952 fn array_expression() {
953 let src = "[0, 1, 2]";
954 let mock = Mock::new();
955
956 let expected = ArrayExpression {
957 body: mock.list([
958 Literal::Number("0"),
959 Literal::Number("1"),
960 Literal::Number("2"),
961 ])
962 };
963
964 assert_expr!(src, expected);
965 }
966
967 #[test]
968 fn sparse_array_expression() {
969 let src = "[,,foo,bar,,]";
970 let mock = Mock::new();
971
972 let expected = ArrayExpression {
973 body: mock.list([
974 Expression::Void,
975 Expression::Void,
976 Expression::Identifier("foo"),
977 Expression::Identifier("bar"),
978 Expression::Void,
979 Expression::Void,
980 ])
981 };
982
983 assert_expr!(src, expected);
984 }
985
986 #[test]
987 fn spread_expression_in_array() {
988 let src = "[a, b, ...c]";
989 let mock = Mock::new();
990
991 let expected = ArrayExpression {
992 body: mock.list([
993 Expression::Identifier("a"),
994 Expression::Identifier("b"),
995 Expression::Spread(SpreadExpression {
996 argument: mock.ptr("c")
997 })
998 ])
999 };
1000
1001 assert_expr!(src, expected);
1002 }
1003
1004 #[test]
1005 fn spread_expression_in_call() {
1006 let src = "foo(a, b, ...c)";
1007 let mock = Mock::new();
1008
1009 let expected = CallExpression {
1010 callee: mock.ptr("foo"),
1011 arguments: mock.list([
1012 Expression::Identifier("a"),
1013 Expression::Identifier("b"),
1014 Expression::Spread(SpreadExpression {
1015 argument: mock.ptr("c")
1016 })
1017 ])
1018 };
1019
1020 assert_expr!(src, expected);
1021 }
1022
1023 #[test]
1024 fn spread_expression_illegal_bare() {
1025 assert!(parse("let foo = ...c;").is_err());
1026 }
1027
1028 #[test]
1029 fn function_expression() {
1030 let src = "(function () {})";
1031 let mock = Mock::new();
1032
1033 let expected = Function {
1034 name: None.into(),
1035 generator: false,
1036 params: NodeList::empty(),
1037 body: mock.empty_block()
1038 };
1039
1040 assert_expr!(src, expected);
1041 }
1042
1043 #[test]
1044 fn named_function_expression() {
1045 let src = "(function foo () {})";
1046 let mock = Mock::new();
1047
1048 let expected = Function {
1049 name: mock.name("foo"),
1050 generator: false,
1051 params: NodeList::empty(),
1052 body: mock.empty_block()
1053 };
1054
1055 assert_expr!(src, expected);
1056 }
1057
1058 #[test]
1059 fn arrow_function_expression() {
1060 let src = "() => bar";
1061 let mock = Mock::new();
1062
1063 let expected = ArrowExpression {
1064 params: NodeList::empty(),
1065 body: ArrowBody::Expression(mock.ptr("bar")),
1066 };
1067 assert_expr!(src, expected);
1068 }
1069
1070 #[test]
1071 fn arrow_function_shorthand() {
1072 let src = "n => n * n";
1073 let mock = Mock::new();
1074
1075 let expected = ArrowExpression {
1076 params: mock.list([
1077 Pattern::Identifier("n")
1078 ]),
1079
1080 body: ArrowBody::Expression(mock.ptr(BinaryExpression {
1081 operator: OperatorKind::Multiplication,
1082 left: mock.ptr("n"),
1083 right: mock.ptr("n"),
1084 }))
1085
1086 };
1087 assert_expr!(src, expected);
1088 }
1089
1090 #[test]
1091 fn arrow_function_with_params() {
1092 let src = "(a, b, c) => bar";
1093 let mock = Mock::new();
1094
1095 let expected = ArrowExpression {
1096 params: mock.list([
1097 Pattern::Identifier("a"),
1098 Pattern::Identifier("b"),
1099 Pattern::Identifier("c")
1100 ]),
1101 body: ArrowBody::Expression(mock.ptr("bar"))
1102 };
1103 assert_expr!(src, expected);
1104 }
1105
1106 #[test]
1107 fn arrow_function_invalid_params_throws() {
1108 assert!(parse("(a, b, c * 2) => bar").is_err());
1109 }
1110
1111 #[test]
1112 fn arrow_function_with_default_params() {
1113 let src = "(a, b, c = 2) => bar";
1114 let mock = Mock::new();
1115
1116 let expected = ArrowExpression {
1117 params: mock.list([
1118 Pattern::Identifier("a"),
1119 Pattern::Identifier("b"),
1120 Pattern::AssignmentPattern {
1121 left: mock.ptr(Pattern::Identifier("c")),
1122 right: mock.number("2")
1123 }
1124 ]),
1125 body: ArrowBody::Expression(mock.ptr("bar"))
1126 };
1127 assert_expr!(src, expected);
1128 }
1129
1130 #[test]
1131 fn class_expression() {
1132 let src = "(class {})";
1133 let mock = Mock::new();
1134
1135 let expected = Class {
1136 name: None.into(),
1137 extends: None,
1138 body: mock.empty_block()
1139 };
1140
1141 assert_expr!(src, expected);
1142 }
1143
1144 #[test]
1145 fn named_class_expression() {
1146 let src = "(class Foo {})";
1147 let mock = Mock::new();
1148
1149 let expected = Class {
1150 name: mock.name("Foo"),
1151 extends: None,
1152 body: mock.empty_block()
1153 };
1154
1155 assert_expr!(src, expected);
1156 }
1157
1158 #[test]
1159 fn named_child_class_expression() {
1160 let src = "(class Foo extends Bar {})";
1161 let mock = Mock::new();
1162
1163 let expected = Class {
1164 name: mock.name("Foo"),
1165 extends: Some(mock.ptr("Bar")),
1166 body: mock.empty_block()
1167 };
1168
1169 assert_expr!(src, expected);
1170 }
1171
1172 #[test]
1173 fn regression_operator_precedence() {
1174 let src = "true === true && false === false";
1175 let mock = Mock::new();
1176
1177 let expected = BinaryExpression {
1178 operator: OperatorKind::LogicalAnd,
1179 left: mock.ptr(BinaryExpression {
1180 operator: OperatorKind::StrictEquality,
1181 left: mock.ptr(Literal::True),
1182 right: mock.ptr(Literal::True),
1183 }),
1184 right: mock.ptr(BinaryExpression {
1185 operator: OperatorKind::StrictEquality,
1186 left: mock.ptr(Literal::False),
1187 right: mock.ptr(Literal::False),
1188 }),
1189 };
1190
1191 assert_expr!(src, expected);
1192 }
1193
1194 #[test]
1195 fn arrow_function_in_sequence() {
1196 let src = "(() => {}, foo)";
1197 let mock = Mock::new();
1198
1199 let expected = SequenceExpression {
1200 body: mock.list([
1201 Expression::Arrow(ArrowExpression {
1202 params: NodeList::empty(),
1203 body: ArrowBody::Block(mock.ptr(BlockStatement {
1204 body: NodeList::empty()
1205 }))
1206 }),
1207 Expression::Identifier("foo"),
1208 ])
1209 };
1210
1211 assert_expr!(src, expected);
1212 }
1213
1214 #[test]
1215 fn regression_increments() {
1216 let src = "x++ + ++y";
1217 let mock = Mock::new();
1218
1219 let expected = BinaryExpression {
1220 operator: OperatorKind::Addition,
1221 left: mock.ptr(PostfixExpression {
1222 operator: OperatorKind::Increment,
1223 operand: mock.ptr("x"),
1224 }),
1225 right: mock.ptr(PrefixExpression {
1226 operator: OperatorKind::Increment,
1227 operand: mock.ptr("y"),
1228 })
1229 };
1230
1231 assert_expr!(src, expected);
1232 }
1233
1234 #[test]
1235 fn regression_decrements() {
1236 let src = "x-- - --y";
1237 let mock = Mock::new();
1238
1239 let expected = BinaryExpression {
1240 operator: OperatorKind::Subtraction,
1241 left: mock.ptr(PostfixExpression {
1242 operator: OperatorKind::Decrement,
1243 operand: mock.ptr("x"),
1244 }),
1245 right: mock.ptr(PrefixExpression {
1246 operator: OperatorKind::Decrement,
1247 operand: mock.ptr("y"),
1248 })
1249 };
1250
1251 assert_expr!(src, expected);
1252 }
1253
1254 #[test]
1255 fn assignment_to_lvalue() {
1256 assert!(parse("(x++)++").is_err());
1257 assert!(parse("x+++++y").is_err());
1258 }
1259
1260 #[test]
1261 fn regression_asi_increments() {
1262 let src = r#"x
1263 ++
1264 y"#;
1265 let mock = Mock::new();
1266
1267 let expected = mock.list([
1268 mock.ptr(Expression::Identifier("x")),
1269 mock.ptr(PrefixExpression {
1270 operator: OperatorKind::Increment,
1271 operand: mock.ptr("y"),
1272 }),
1273 ]);
1274 assert_eq!(parse(src).unwrap().body(), expected);
1275 }
1276
1277 #[test]
1278 fn regression_asi_decrements() {
1279 let src = r#"x
1280 --
1281 y"#;
1282 let mock = Mock::new();
1283
1284 let expected = mock.list([
1285 mock.ptr(Expression::Identifier("x")),
1286 mock.ptr(PrefixExpression {
1287 operator: OperatorKind::Decrement,
1288 operand: mock.ptr("y"),
1289 }),
1290 ]);
1291 assert_eq!(parse(src).unwrap().body(), expected);
1292 }
1293
1294 #[test]
1295 fn regression_asi_safe() {
1296 let src = r#"foo
1297 .bar"#;
1298 let mock = Mock::new();
1299
1300 let expected = MemberExpression {
1301 object: mock.ptr("foo"),
1302 property: mock.ptr("bar"),
1303 };
1304
1305 assert_expr!(src, expected);
1306 }
1307}