esr/parser/
expression.rs

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,
15//  EOF   ;     :     ,     (     )     [     ]     {     }     =>    NEW
16
17    OP,   OP,   OP,   OP,   OP,   OP,   OP,   ____, REG,  ____, ____, OP,
18//  ++    --    !     ~     TYPOF VOID  DELET *     /     %     **    +
19
20    OP,   ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
21//  -     <<    >>    >>>   <     <=    >     >=    INSOF IN    ===   !==
22
23    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
24//  ==    !=    &     ^     |     &&    ||    ?     =     +=    -=    **=
25
26    ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____,
27//  *=    /=    %=    <<=   >>=   >>>=  &=    ^=    |=    ...   VAR   LET
28
29    ____, ____, ____, ____, ____, ____, ____, CLAS, ____, ____, ____, ____,
30//  CONST BREAK DO    CASE  ELSE  CATCH EXPRT CLASS EXTND RET   WHILE FINLY
31
32    ____, ____, ____, ____, ____, ____, ____, FUNC, THIS, ____, ____, ____,
33//  SUPER WITH  CONT  FOR   SWTCH YIELD DBGGR FUNCT THIS  DEFLT IF    THROW
34
35    ____, ____, ____, TRUE, FALS, NULL, UNDE, STR,  NUM,  BIN,  ____, ____,
36//  IMPRT TRY   STATI TRUE  FALSE NULL  UNDEF STR   NUM   BIN   REGEX ENUM
37
38    ____, ____, ____, ____, ____, ____, IDEN, ____, TPLE, TPLS, ____, ____,
39//  IMPL  PCKG  PROT  IFACE PRIV  PUBLI IDENT ACCSS TPL_O TPL_C ERR_T ERR_E
40];
41
42// Adds handlers for VoidExpression and SpreadExpression
43pub 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
55// Adds handler for SpreadExpression
56pub 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        // Only `NewTarget` is a valid MetaProperty.
363        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    /// Only in ArrayExpression
487    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}