1use syntax::decl::is_semi;
7
8use super::decl::{
9 arrow_body, class_decl, formal_parameters, function_decl, maybe_private_name, method,
10};
11use super::pat::pattern;
12use super::typescript::*;
13use super::util::*;
14use crate::{SyntaxKind::*, *};
15
16pub const LITERAL: TokenSet = token_set![TRUE_KW, FALSE_KW, NUMBER, STRING, NULL_KW, REGEX];
17
18pub const EXPR_RECOVERY_SET: TokenSet = token_set![VAR_KW, R_PAREN, L_PAREN, L_BRACK, R_BRACK];
19
20pub const ASSIGN_TOKENS: TokenSet = token_set![
21 T![=],
22 T![+=],
23 T![-=],
24 T![*=],
25 T![%=],
26 T![<<=],
27 T![>>=],
28 T![>>>=],
29 T![&=],
30 T![|=],
31 T![^=],
32 T![&&=],
33 T![||=],
34 T![??=],
35 T![/=],
36 T![>>=]
37];
38
39pub const STARTS_EXPR: TokenSet = token_set![
40 T![!],
41 T!['('],
42 T!['['],
43 T!['{'],
44 T![++],
45 T![--],
46 T![~],
47 T![+],
48 T![-],
49 T![throw],
50 T![new],
51 T![typeof],
52 T![void],
53 T![delete],
54 T![ident],
55 T![...],
56 T![this],
57 T![yield],
58 T![await],
59 T![function],
60 T![class],
61 T![import],
62 T![super],
63 BACKTICK,
64]
65.union(LITERAL);
66
67pub fn literal(p: &mut Parser) -> Option<CompletedMarker> {
79 if !p.at_ts(LITERAL) {
80 return None;
81 }
82 let m = p.start();
83 p.bump_any();
84 Some(m.complete(p, SyntaxKind::LITERAL))
85}
86
87pub fn assign_expr(p: &mut Parser) -> Option<CompletedMarker> {
89 if p.at(T![<])
90 && (token_set![T![ident], T![await], T![yield]].contains(p.nth(1)) || p.nth(1).is_keyword())
91 {
92 let res = try_parse_ts(p, |p| {
93 let m = p.start();
94 ts_type_params(p)?;
95 let res = assign_expr_base(p);
96 if res.map(|x| x.kind()) != Some(ARROW_EXPR) {
97 m.abandon(p);
98 None
99 } else {
100 res.unwrap().undo_completion(p).abandon(p);
101 Some(m.complete(p, ARROW_EXPR))
102 }
103 });
104 if let Some(mut res) = res {
105 res.err_if_not_ts(p, "type parameters can only be used in TypeScript files");
106 return Some(res);
107 }
108 }
109 assign_expr_base(p)
110}
111
112fn assign_expr_base(p: &mut Parser) -> Option<CompletedMarker> {
113 if p.state.in_generator && p.at(T![yield]) {
114 return Some(yield_expr(p));
115 }
116 let potential_arrow_start = matches!(p.cur(), T![ident] | T!['('] | T![yield] | T![await]);
117 let mut guard = p.with_state(ParserState {
118 potential_arrow_start,
119 ..p.state.clone()
120 });
121
122 let checkpoint = guard.checkpoint();
123 let target = conditional_expr(&mut *guard)?;
124 assign_expr_recursive(&mut *guard, target, checkpoint)
125}
126
127pub(crate) fn is_valid_target(p: &mut Parser, marker: &CompletedMarker) -> bool {
128 match marker.kind() {
129 DOT_EXPR | BRACKET_EXPR | NAME_REF | PRIVATE_PROP_ACCESS | TS_CONST_ASSERTION
130 | TS_ASSERTION | TS_NON_NULL => true,
131 GROUPING_EXPR => {
132 for (idx, event) in p.events[marker.start_pos as usize..].iter().enumerate() {
134 match event {
135 Event::Finish { .. } if marker.finish_pos as usize == idx => return true,
136 Event::Start {
137 kind: SyntaxKind::GROUPING_EXPR,
138 ..
139 } => {}
140 Event::Start {
141 kind: SyntaxKind::TOMBSTONE,
142 ..
143 } => {}
144 Event::Start { kind, .. } => {
145 return matches!(
146 kind,
147 DOT_EXPR
148 | BRACKET_EXPR
149 | NAME_REF
150 | PRIVATE_PROP_ACCESS
151 | TS_CONST_ASSERTION
152 | TS_ASSERTION
153 | TS_NON_NULL
154 );
155 }
156 _ => {}
157 }
158 }
159 true
160 }
161 _ => false,
162 }
163}
164
165fn check_assign_target_from_marker(p: &mut Parser, marker: &CompletedMarker) {
166 if !is_valid_target(p, marker) {
167 let err = p
168 .err_builder(&format!(
169 "Invalid assignment to `{}`",
170 p.source(marker.range(p))
171 ))
172 .primary(marker.range(p), "This expression cannot be assigned to");
173 p.error(err);
174 }
175}
176
177fn assign_expr_recursive(
184 p: &mut Parser,
185 mut target: CompletedMarker,
186 checkpoint: Checkpoint,
187) -> Option<CompletedMarker> {
188 if p.at_ts(ASSIGN_TOKENS) {
190 if p.at(T![=]) {
191 if !is_valid_target(p, &target) && target.kind() != TEMPLATE {
192 p.rewind(checkpoint);
193 target = pattern(p, false, true)?;
194 }
195 } else {
196 if !is_valid_target(p, &target) {
197 let err = p
198 .err_builder(&format!(
199 "Invalid assignment to `{}`",
200 p.source(target.range(p)).trim()
201 ))
202 .primary(target.range(p), "This expression cannot be assigned to");
203
204 p.error(err);
205 }
206 let text = p.source(target.range(p));
207 if (text == "eval" || text == "arguments") && p.state.strict.is_some() && p.typescript()
208 {
209 let err = p
210 .err_builder("`eval` and `arguments` cannot be assigned to")
211 .primary(target.range(p), "");
212
213 p.error(err);
214 }
215 }
216 let m = target.precede(p);
217 p.bump_any();
218 assign_expr(p);
219 Some(m.complete(p, ASSIGN_EXPR))
220 } else {
221 Some(target)
222 }
223}
224
225pub fn yield_expr(p: &mut Parser) -> CompletedMarker {
231 let m = p.start();
232 p.expect(T![yield]);
233
234 if !is_semi(p, 0) && (p.at(T![*]) || p.at_ts(STARTS_EXPR)) {
235 p.eat(T![*]);
236 assign_expr(p);
237 }
238
239 m.complete(p, YIELD_EXPR)
240}
241
242pub fn conditional_expr(p: &mut Parser) -> Option<CompletedMarker> {
247 let lhs = binary_expr(p);
251
252 if p.at(T![?]) {
253 let m = lhs?.precede(p);
254 p.bump_any();
255 assign_expr(&mut *p.with_state(ParserState {
256 in_cond_expr: true,
257 ..p.state.clone()
258 }));
259 p.expect(T![:]);
260 assign_expr(p);
261 return Some(m.complete(p, COND_EXPR));
262 }
263 lhs
264}
265
266pub fn binary_expr(p: &mut Parser) -> Option<CompletedMarker> {
268 let left = unary_expr(p);
269 binary_expr_recursive(p, left, 0)
270}
271
272fn binary_expr_recursive(
289 p: &mut Parser,
290 left: Option<CompletedMarker>,
291 min_prec: u8,
292) -> Option<CompletedMarker> {
293 if 7 > min_prec && !p.has_linebreak_before_n(0) && p.cur_src() == "as" {
294 let m = left.map(|x| x.precede(p)).unwrap_or_else(|| p.start());
295 p.bump_any();
296 let mut res = if p.eat(T![const]) {
297 m.complete(p, TS_CONST_ASSERTION)
298 } else {
299 ts_type(p);
300 m.complete(p, TS_ASSERTION)
301 };
302 res.err_if_not_ts(p, "type assertions can only be used in TypeScript files");
303 return binary_expr_recursive(p, Some(res), min_prec);
304 }
305 let kind = match p.cur() {
306 T![>] if p.nth_at(1, T![>]) && p.nth_at(2, T![>]) => T![>>>],
307 T![>] if p.nth_at(1, T![>]) => T![>>],
308 k => k,
309 };
310
311 let precedence = match kind {
312 T![in] if p.state.include_in => 7,
313 T![instanceof] => 7,
314 _ => {
315 if let Some(prec) = get_precedence(kind) {
316 prec
317 } else {
318 return left;
319 }
320 }
321 };
322
323 if precedence <= min_prec {
324 return left;
325 }
326
327 let op = kind;
328 let op_tok = p.cur_tok();
329
330 let m = left.map(|m| m.precede(p)).unwrap_or_else(|| p.start());
331 if op == T![>>] {
332 p.bump_multiple(2, T![>>]);
333 } else if op == T![>>>] {
334 p.bump_multiple(3, T![>>>]);
335 } else {
336 p.bump_any();
337 }
338
339 let right = if get_precedence(p.cur()).is_some() && !p.at_ts(token_set![T![-], T![+], T![<]]) {
341 let err = p.err_builder(&format!("Expected an expression for the right hand side of a `{}`, but found an operator instead", p.token_src(&op_tok)))
342 .secondary(op_tok.range, "This operator requires a right hand side value")
343 .primary(p.cur_tok().range, "But this operator was encountered instead");
344
345 p.error(err);
346 None
347 } else {
348 unary_expr(p)
349 };
350
351 binary_expr_recursive(
352 p,
353 right,
354 if op == T![**] {
356 precedence - 1
357 } else {
358 precedence
359 },
360 );
361
362 let complete = m.complete(p, BIN_EXPR);
363 binary_expr_recursive(p, Some(complete), min_prec)
364
365 }
369
370pub fn paren_expr(p: &mut Parser) -> CompletedMarker {
374 let m = p.start();
375 p.expect(T!['(']);
376 expr(p);
377 p.expect(T![')']);
378 m.complete(p, GROUPING_EXPR)
379}
380
381pub fn member_or_new_expr(p: &mut Parser, new_expr: bool) -> Option<CompletedMarker> {
389 if p.at(T![new]) {
390 let m = p.start();
393 p.bump_any();
394
395 if p.at(T![.]) && p.token_src(&p.nth_tok(1)) == "target" {
397 p.bump_any();
398 p.bump_any();
399 let complete = m.complete(p, NEW_TARGET);
400 return Some(subscripts(p, complete, true));
401 }
402
403 let complete = member_or_new_expr(p, new_expr)?;
404 if complete.kind() == ARROW_EXPR {
405 return Some(complete);
406 }
407
408 if p.at(T![<]) {
409 if let Some(mut complete) = try_parse_ts(p, |p| {
410 let compl = ts_type_args(p);
411 if !p.at(T!['(']) {
412 return None;
413 }
414 compl
415 }) {
416 complete.err_if_not_ts(
417 p,
418 "`new` expressions can only have type arguments in TypeScript files",
419 );
420 }
421 }
422
423 if !new_expr || p.at(T!['(']) {
424 args(p);
425 let complete = m.complete(p, NEW_EXPR);
426 return Some(subscripts(p, complete, true));
427 }
428 return Some(m.complete(p, NEW_EXPR));
429 }
430
431 if p.at(T![super]) && token_set!(T![.], T!['[']).contains(p.nth(1)) {
437 let m = p.start();
438 p.bump_any();
439 let lhs = match p.cur() {
440 T![.] => {
441 p.bump_any();
442 identifier_name(p);
443 m.complete(p, DOT_EXPR)
444 }
445 T!['['] => {
446 p.bump_any();
447 expr(p);
448 p.expect(T![']']);
449 m.complete(p, BRACKET_EXPR)
450 }
451 _ => unreachable!(),
452 };
453 return Some(subscripts(p, lhs, true));
454 }
455
456 let lhs = primary_expr(p)?;
457 Some(subscripts(p, lhs, true))
458}
459
460pub fn subscripts(p: &mut Parser, mut lhs: CompletedMarker, no_call: bool) -> CompletedMarker {
465 let mut should_try_parsing_ts = true;
469 while !p.at(EOF) {
470 match p.cur() {
471 T![?.] if p.nth_at(1, T!['(']) => {
472 lhs = {
473 let m = lhs.precede(p);
474 p.bump_any();
475 args(p);
476 m.complete(p, CALL_EXPR)
477 }
478 }
479 T!['('] if !no_call => {
480 lhs = {
481 let m = lhs.precede(p);
482 args(p);
483 m.complete(p, CALL_EXPR)
484 }
485 }
486 T![?.] if p.nth_at(1, T!['[']) => lhs = bracket_expr(p, lhs, true),
487 T!['['] => lhs = bracket_expr(p, lhs, false),
488 T![?.] => lhs = dot_expr(p, lhs, true),
489 T![.] => lhs = dot_expr(p, lhs, false),
490 T![!] if !p.has_linebreak_before_n(0) => {
491 lhs = {
492 let m = lhs.precede(p);
497 p.bump_any();
498 let mut comp = m.complete(p, TS_NON_NULL);
499 comp.err_if_not_ts(
500 p,
501 "non-null assertions can only be used in TypeScript files",
502 );
503 comp
504 }
505 }
506 T![<] if p.typescript() && should_try_parsing_ts => {
507 let res = try_parse_ts(p, |p| {
508 let m = lhs.precede(p);
509 ts_type_args(p)?;
511 if !no_call && p.at(T!['(']) {
512 args(p);
513 Some(m.complete(p, CALL_EXPR))
514 } else if p.at(BACKTICK) {
515 m.abandon(p);
516 Some(template(p, Some(lhs)))
517 } else {
518 None
519 }
520 });
521 if res.is_none() {
522 should_try_parsing_ts = false;
523 }
524 }
525 BACKTICK => lhs = template(p, Some(lhs)),
526 _ => return lhs,
527 }
528 }
529 lhs
530}
531
532pub fn dot_expr(p: &mut Parser, lhs: CompletedMarker, optional_chain: bool) -> CompletedMarker {
541 let m = lhs.precede(p);
542 let range = if optional_chain {
543 Some(p.cur_tok().range).filter(|_| p.expect(T![?.]))
544 } else {
545 p.expect(T![.]);
546 None
547 };
548 if let Some(priv_range) = maybe_private_name(p).filter(|x| x.kind() == PRIVATE_NAME) {
549 if !p.syntax.class_fields {
550 let err = p
551 .err_builder("private identifiers are unsupported")
552 .primary(priv_range.range(p), "");
553
554 p.error(err);
555 return m.complete(p, ERROR);
556 }
557 if let Some(range) = range {
558 let err = p
559 .err_builder("optional chaining cannot contain private identifiers")
560 .primary(range, "");
561
562 p.error(err);
563 m.complete(p, ERROR)
564 } else {
565 m.complete(p, PRIVATE_PROP_ACCESS)
566 }
567 } else {
568 m.complete(p, DOT_EXPR)
569 }
570}
571
572pub fn bracket_expr(p: &mut Parser, lhs: CompletedMarker, optional_chain: bool) -> CompletedMarker {
580 let m = lhs.precede(p);
585 if optional_chain {
586 p.expect(T![?.]);
587 }
588 p.expect(T!['[']);
589 expr(p);
590 p.expect(T![']']);
591 m.complete(p, BRACKET_EXPR)
592}
593
594pub fn identifier_name(p: &mut Parser) -> Option<CompletedMarker> {
596 let m = p.start();
597 match p.cur() {
598 t if t.is_keyword() || t == T![ident] => p.bump_remap(T![ident]),
599 _ => {
600 let err = p
601 .err_builder("Expected an identifier or keyword")
602 .primary(p.cur_tok().range, "Expected an identifier or keyword here");
603 p.error(err);
604 m.abandon(p);
605 return None;
606 }
607 }
608 Some(m.complete(p, NAME))
609}
610
611pub fn args(p: &mut Parser) -> CompletedMarker {
619 let m = p.start();
620 p.expect(T!['(']);
621
622 while !p.at(EOF) && !p.at(T![')']) {
623 if p.at(T![...]) {
624 spread_element(p);
625 } else {
626 assign_expr(p);
627 }
628
629 if p.at(T![,]) {
630 p.bump_any();
631 } else {
632 break;
633 }
634 }
635
636 p.expect(T![')']);
637 m.complete(p, ARG_LIST)
638}
639
640pub fn paren_or_arrow_expr(p: &mut Parser, can_be_arrow: bool) -> CompletedMarker {
650 let m = p.start();
651 let checkpoint = p.checkpoint();
652 let start = p.cur_tok().range.start;
653 p.expect(T!['(']);
654 let mut spread_range = None;
655 let mut trailing_comma_marker = None;
656 let mut had_comma = false;
657 let mut params_marker = None;
658
659 let mut temp = p.with_state(ParserState {
660 potential_arrow_start: true,
661 ..p.state.clone()
662 });
663 let expr_m = temp.start();
664 let mut is_empty = false;
665
666 if temp.eat(T![')']) {
667 is_empty = true;
668 } else {
669 loop {
670 if temp.at(T![...]) {
671 let m = temp.start();
672 temp.bump_any();
673 pattern(&mut *temp, false, false);
674 if temp.eat(T![:]) {
675 if let Some(mut ty) = ts_type(&mut *temp) {
676 ty.err_if_not_ts(
677 &mut *temp,
678 "spread elements can only have type annotations in TypeScript files",
679 );
680 }
681 }
682 let complete = m.complete(&mut *temp, REST_PATTERN);
683 spread_range = Some(complete.range(&*temp));
684 if !temp.eat(T![')']) {
685 if temp.eat(T![=]) {
686 assign_expr(&mut *temp);
688 temp.expect(T![')']);
689 } else {
690 let err = temp.err_builder(&format!("expect a closing parenthesis after a spread element, but instead found `{}`", temp.cur_src()))
691 .primary(temp.cur_tok().range, "");
692
693 temp.err_recover(err, EXPR_RECOVERY_SET, false);
694 }
695 }
696 break;
697 }
698 let expr = assign_expr(&mut *temp);
699 if expr.is_some() && temp.at(T![:]) {
700 temp.rewind(checkpoint);
701 params_marker = Some(formal_parameters(&mut *temp));
702 break;
703 }
704
705 let sub_m = temp.start();
706 if temp.eat(T![,]) {
707 if temp.at(T![')']) {
708 trailing_comma_marker = Some(sub_m.complete(&mut *temp, ERROR));
709 temp.bump_any();
710 break;
711 } else {
712 sub_m.abandon(&mut *temp);
713 }
714 had_comma = true;
715 } else {
716 sub_m.abandon(&mut *temp);
717 if had_comma {
718 expr_m.complete(&mut *temp, SEQUENCE_EXPR);
719 }
720 temp.expect(T![')']);
721 break;
722 }
723 }
724 }
725 drop(temp);
726 if p.state.in_cond_expr && p.at(T![:]) && params_marker.is_none() {
729 let func = |p: &mut Parser| {
730 let p = &mut *p.with_state(ParserState {
731 no_recovery: true,
732 ..p.state.clone()
733 });
734 p.rewind(checkpoint);
735 formal_parameters(p);
736 if p.at(T![:]) {
737 if let Some(mut ret) = ts_type_or_type_predicate_ann(p, T![:]) {
738 ret.err_if_not_ts(
739 p,
740 "arrow functions can only have return types in TypeScript files",
741 );
742 }
743 }
744 p.expect_no_recover(T![=>])?;
745 arrow_body(p)?;
746 Some(())
747 };
748 let cloned = p.clone();
751 if func(p).is_some() {
752 let c = m.complete(p, ARROW_EXPR);
753 return c;
754 } else {
755 *p = cloned;
756 }
757 }
758 let has_ret_type = !p.state.in_cond_expr && p.at(T![:]) && !p.state.in_case_cond;
759
760 if (p.at(T![=>]) && !p.has_linebreak_before_n(0)) || has_ret_type || params_marker.is_some() {
764 if !can_be_arrow && !p.at(T![:]) {
765 let err = p
766 .err_builder("Unexpected token `=>`")
767 .primary(p.cur_tok().range, "an arrow expression is not allowed here");
768
769 p.error(err);
770 } else {
771 if params_marker.is_none() {
772 p.rewind(checkpoint);
774 formal_parameters(p);
775 }
776
777 if p.at(T![:]) {
778 let complete = ts_type_or_type_predicate_ann(p, T![:]);
779 if let Some(mut complete) = complete {
780 complete.err_if_not_ts(
781 p,
782 "arrow functions can only have return types in TypeScript files",
783 );
784 }
785 }
786
787 p.bump_any();
788 arrow_body(p);
789 return m.complete(p, ARROW_EXPR);
790 }
791 }
792
793 if let Some(params) = params_marker {
794 let err = p
795 .err_builder("grouping expressions cannot contain parameters")
796 .primary(params.range(p), "");
797
798 p.error(err);
799 return m.complete(p, ERROR);
800 }
801
802 if is_empty {
803 let err = p
804 .err_builder("grouping expressions cannot be empty")
805 .primary(start..p.cur_tok().range.start, "");
806
807 p.error(err);
808 return m.complete(p, GROUPING_EXPR);
809 }
810
811 if let Some(range) = spread_range {
812 let err = p
813 .err_builder("Illegal spread element inside grouping expression")
814 .primary(range, "");
815
816 p.error(err);
817 }
818
819 if let Some(complete) = trailing_comma_marker {
820 let err = p
821 .err_builder("Illegal trailing comma in grouping expression")
822 .primary(complete.range(p), "");
823
824 p.error(err);
825 }
826
827 m.complete(p, GROUPING_EXPR)
828}
829
830pub fn expr_or_spread(p: &mut Parser) -> Option<CompletedMarker> {
831 if p.at(T![...]) {
832 let m = p.start();
833 p.bump_any();
834 assign_expr(p);
835 Some(m.complete(p, SPREAD_ELEMENT))
836 } else {
837 assign_expr(p)
838 }
839}
840
841pub fn expr(p: &mut Parser) -> Option<CompletedMarker> {
845 let first = assign_expr(p)?;
846
847 if p.at(T![,]) {
848 let m = first.precede(p);
849 p.bump_any();
850 assign_expr(p)?;
851
852 while p.at(T![,]) {
853 p.bump_any();
854 assign_expr(p)?;
855 }
856
857 return Some(m.complete(p, SEQUENCE_EXPR));
858 }
859
860 Some(first)
861}
862
863pub fn primary_expr(p: &mut Parser) -> Option<CompletedMarker> {
865 if let Some(m) = literal(p) {
866 return Some(m);
867 }
868
869 let complete = match p.cur() {
870 T![this] => {
871 let m = p.start();
875 p.bump_any();
876 m.complete(p, THIS_EXPR)
877 }
878 T![class] => {
879 let mut m = class_decl(p, true);
886 m.change_kind(p, CLASS_EXPR);
887 m
888 }
889 T![ident] if p.cur_src() == "async" => {
892 if p.nth_at(1, T![function]) {
896 let m = p.start();
897 p.bump_remap(T![async]);
898 let mut complete = function_decl(
899 &mut *p.with_state(ParserState {
900 in_async: true,
901 ..p.state.clone()
902 }),
903 m,
904 true,
905 );
906 complete.change_kind(p, FN_EXPR);
907 complete
908 } else {
909 if p.state.potential_arrow_start
911 && token_set![T![ident], T![yield], T!['(']].contains(p.nth(1))
912 {
913 let m = p.start();
918 p.bump_remap(T![async]);
919 if p.at(T!['(']) {
920 formal_parameters(p);
921 } else {
922 let m = p.start();
923 p.bump_remap(T![ident]);
926 m.complete(p, NAME);
927 }
928 if p.at(T![:]) {
929 let complete = ts_type_or_type_predicate_ann(p, T![:]);
930 if let Some(mut complete) = complete {
931 complete.err_if_not_ts(
932 p,
933 "arrow functions can only have return types in TypeScript files",
934 );
935 }
936 }
937 p.expect(T![=>]);
938 arrow_body(&mut *p.with_state(ParserState {
939 in_async: true,
940 ..p.state.clone()
941 }));
942 m.complete(p, ARROW_EXPR)
943 } else {
944 identifier_reference(p)?
945 }
946 }
947 }
948 T![function] => {
949 let m = p.start();
953 let mut complete = function_decl(p, m, true);
954 complete.change_kind(p, FN_EXPR);
955 complete
956 }
957 T![ident] | T![yield] | T![await] => {
958 let mut ident = identifier_reference(p)?;
963 if p.state.potential_arrow_start && p.at(T![=>]) && !p.has_linebreak_before_n(0) {
964 ident.change_kind(p, NAME);
973 let m = ident.precede(p);
974 p.bump_any();
975 arrow_body(p);
976 m.complete(p, ARROW_EXPR)
977 } else {
978 ident
979 }
980 }
981 T!['('] => paren_or_arrow_expr(p, p.state.potential_arrow_start),
985 T!['['] => array_expr(p),
986 T!['{'] if p.state.allow_object_expr => object_expr(p),
987 T![import] => {
988 let m = p.start();
989 p.bump_any();
990
991 if p.eat(T![.]) {
994 if p.at(T![ident]) && p.token_src(&p.cur_tok()) == "meta" {
998 p.bump_any();
999 m.complete(p, IMPORT_META)
1000 } else if p.at(T![ident]) {
1001 let err = p
1002 .err_builder(&format!(
1003 "Expected `meta` following an import keyword, but found `{}`",
1004 p.token_src(&p.cur_tok())
1005 ))
1006 .primary(p.cur_tok().range, "");
1007
1008 p.err_and_bump(err);
1009 m.complete(p, ERROR)
1010 } else {
1011 let err = p
1012 .err_builder("Expected `meta` following an import keyword, but found none")
1013 .primary(p.cur_tok().range, "");
1014
1015 p.error(err);
1016 m.complete(p, ERROR)
1017 }
1018 } else {
1019 p.expect(T!['(']);
1026 assign_expr(p);
1027 p.expect(T![')']);
1028 m.complete(p, IMPORT_CALL)
1029 }
1030 }
1031 BACKTICK => template(p, None),
1032 ERROR_TOKEN => {
1033 let m = p.start();
1034 p.bump_any();
1035 m.complete(p, ERROR)
1036 }
1037 _ => {
1040 let err = p
1041 .err_builder("Expected an expression, but found none")
1042 .primary(p.cur_tok().range, "Expected an expression here");
1043 p.err_recover(err, p.state.expr_recovery_set, true);
1044 return None;
1045 }
1046 };
1047
1048 Some(complete)
1049}
1050
1051pub fn identifier_reference(p: &mut Parser) -> Option<CompletedMarker> {
1052 match p.cur() {
1053 T![ident] | T![yield] | T![await] => {
1054 let m = p.start();
1055 p.bump_remap(T![ident]);
1056 Some(m.complete(p, NAME_REF))
1057 }
1058 _ => {
1059 let err = p
1060 .err_builder("Expected an identifier, but found none")
1061 .primary(p.cur_tok().range, "");
1062
1063 p.err_recover(err, p.state.expr_recovery_set, true);
1064 None
1065 }
1066 }
1067}
1068
1069pub fn template(p: &mut Parser, tag: Option<CompletedMarker>) -> CompletedMarker {
1076 let m = tag.map(|m| m.precede(p)).unwrap_or_else(|| p.start());
1077 p.expect(BACKTICK);
1078
1079 while !p.at(EOF) && !p.at(BACKTICK) {
1080 match p.cur() {
1081 TEMPLATE_CHUNK => p.bump_any(),
1082 DOLLARCURLY => {
1083 let e = p.start();
1084 p.bump_any();
1085 expr(p);
1086 p.expect(T!['}']);
1087 e.complete(p, TEMPLATE_ELEMENT);
1088 },
1089 t => unreachable!("Anything not template chunk or dollarcurly should have been eaten by the lexer, but {:?} was found", t),
1090 }
1091 }
1092
1093 p.eat(BACKTICK);
1098 m.complete(p, TEMPLATE)
1099}
1100
1101pub fn array_expr(p: &mut Parser) -> CompletedMarker {
1110 let m = p.start();
1111 p.expect(T!['[']);
1112
1113 while !p.at(EOF) {
1114 while p.eat(T![,]) {}
1115
1116 if p.at(T![']']) {
1117 break;
1118 }
1119
1120 if p.at(T![...]) {
1121 spread_element(p);
1122 } else {
1123 assign_expr(p);
1124 }
1125
1126 if p.at(T![']']) {
1127 break;
1128 }
1129
1130 p.expect(T![,]);
1131 }
1132
1133 p.expect(T![']']);
1134 m.complete(p, ARRAY_EXPR)
1135}
1136
1137pub fn spread_element(p: &mut Parser) -> CompletedMarker {
1139 let m = p.start();
1140 p.expect(T![...]);
1141 assign_expr(p);
1142 m.complete(p, SPREAD_ELEMENT)
1143}
1144
1145pub fn object_expr(p: &mut Parser) -> CompletedMarker {
1150 let m = p.start();
1151 p.expect(T!['{']);
1152 let mut first = true;
1153
1154 while !p.at(EOF) && !p.at(T!['}']) {
1155 if first {
1156 first = false;
1157 } else {
1158 p.expect(T![,]);
1159 if p.at(T!['}']) {
1160 break;
1161 }
1162 }
1163 object_property(p);
1164 }
1165
1166 p.expect(T!['}']);
1167 m.complete(p, OBJECT_EXPR)
1168}
1169
1170const STARTS_OBJ_PROP: TokenSet =
1171 token_set![STRING, NUMBER, T![ident], T![await], T![yield], T!['[']];
1172
1173pub fn object_property(p: &mut Parser) -> Option<CompletedMarker> {
1175 let m = p.start();
1176
1177 match p.cur() {
1178 T![ident]
1191 if (p.cur_src() == "get" || p.cur_src() == "set")
1192 && (p.nth_at(1, T![ident]) || p.nth_at(1, T!['['])) =>
1193 {
1194 method(p, None, None)
1195 }
1196 T![ident]
1202 if p.cur_src() == "async"
1203 && !p.has_linebreak_before_n(1)
1204 && (STARTS_OBJ_PROP.contains(p.nth(1)) || p.nth_at(1, T![*])) =>
1205 {
1206 method(p, None, None)
1207 }
1208 T![...] => {
1211 p.bump_any();
1212 assign_expr(p);
1213 Some(m.complete(p, SPREAD_PROP))
1214 }
1215 T![*] => {
1216 let m = p.start();
1219 method(p, m, None)
1220 }
1221 _ => {
1222 let prop = object_prop_name(p, false);
1223 if let Some(NAME) = prop.map(|m| m.kind()) {
1226 if p.eat(T![=]) {
1227 assign_expr(p);
1228 return Some(m.complete(p, INITIALIZED_PROP));
1229 }
1230 }
1231
1232 if p.at(T!['(']) || p.at(T![<]) {
1237 method(p, m, None)
1238 } else {
1239 if prop.is_none() {
1243 p.err_recover_no_err(token_set![T![:], T![,]], false);
1244 }
1245 if p.at(T![:]) || prop?.kind() != NAME {
1251 p.expect(T![:]);
1252 assign_expr(p);
1253 Some(m.complete(p, LITERAL_PROP))
1254 } else {
1255 Some(m.complete(p, IDENT_PROP))
1258 }
1259 }
1260 }
1261 }
1262}
1263
1264pub fn object_prop_name(p: &mut Parser, binding: bool) -> Option<CompletedMarker> {
1267 match p.cur() {
1268 STRING | NUMBER => literal(p),
1269 T!['['] => {
1270 let m = p.start();
1271 p.bump_any();
1272 assign_expr(p);
1273 p.expect(T![']']);
1274 Some(m.complete(p, COMPUTED_PROPERTY_NAME))
1275 }
1276 _ if binding => super::pat::binding_identifier(p),
1277 _ => identifier_name(p),
1278 }
1279}
1280
1281pub fn lhs_expr(p: &mut Parser) -> Option<CompletedMarker> {
1283 if p.at(T![super]) && p.nth_at(1, T!['(']) {
1284 let m = p.start();
1285 p.bump_any();
1286 args(p);
1287 let lhs = m.complete(p, SUPER_CALL);
1288 return Some(subscripts(p, lhs, false));
1289 }
1290
1291 let lhs = member_or_new_expr(p, true)?;
1292 if lhs.kind() == ARROW_EXPR {
1293 return Some(lhs);
1294 }
1295
1296 let m = lhs.precede(p);
1297 let type_args = if p.at(T![<]) {
1298 let checkpoint = p.checkpoint();
1299 let mut complete = try_parse_ts(p, |p| ts_type_args(p));
1300 if !p.at(T!['(']) {
1301 p.rewind(checkpoint);
1302 None
1303 } else {
1304 if let Some(ref mut comp) = complete {
1305 comp.err_if_not_ts(p, "type arguments can only be used in TypeScript files");
1306 }
1307 complete
1308 }
1309 } else {
1310 None
1311 };
1312
1313 if p.at(T!['(']) {
1314 args(p);
1315 let lhs = m.complete(p, CALL_EXPR);
1316 return Some(subscripts(p, lhs, false));
1317 }
1318
1319 if type_args.is_some() {
1320 p.expect(T!['(']);
1321 }
1322
1323 m.abandon(p);
1324 Some(lhs)
1325}
1326
1327pub fn postfix_expr(p: &mut Parser) -> Option<CompletedMarker> {
1332 let lhs = lhs_expr(p);
1333 if !p.has_linebreak_before_n(0) {
1334 match p.cur() {
1335 T![++] => {
1336 check_assign_target_from_marker(p, &lhs?);
1337 let m = lhs?.precede(p);
1338 p.bump(T![++]);
1339 let complete = m.complete(p, UNARY_EXPR);
1340 Some(complete)
1341 }
1342 T![--] => {
1343 check_assign_target_from_marker(p, &lhs?);
1344 let m = lhs?.precede(p);
1345 p.bump(T![--]);
1346 let complete = m.complete(p, UNARY_EXPR);
1347 Some(complete)
1348 }
1349 _ => lhs,
1350 }
1351 } else {
1352 lhs
1353 }
1354}
1355
1356pub fn unary_expr(p: &mut Parser) -> Option<CompletedMarker> {
1358 const UNARY_SINGLE: TokenSet =
1359 token_set![T![delete], T![void], T![typeof], T![+], T![-], T![~], T![!]];
1360
1361 if (p.state.in_async || p.syntax.top_level_await) && p.at(T![await]) {
1363 let m = p.start();
1364 p.bump_any();
1365 unary_expr(p);
1366 return Some(m.complete(p, AWAIT_EXPR));
1367 }
1368
1369 if p.at(T![<]) {
1370 let m = p.start();
1371 p.bump_any();
1372 if p.eat(T![const]) {
1373 p.expect(T![>]);
1374 unary_expr(p);
1375 let mut res = m.complete(p, TS_CONST_ASSERTION);
1376 res.err_if_not_ts(p, "const assertions can only be used in TypeScript files");
1377 return Some(res);
1378 } else {
1379 ts_type(p);
1380 p.expect(T![>]);
1381 unary_expr(p);
1382 let mut res = m.complete(p, TS_ASSERTION);
1383 res.err_if_not_ts(p, "type assertions can only be used in TypeScript files");
1384 return Some(res);
1385 }
1386 }
1387
1388 if p.at(T![++]) {
1389 let m = p.start();
1390 p.bump(T![++]);
1391 let right = unary_expr(p)?;
1392 let complete = m.complete(p, UNARY_EXPR);
1393 check_assign_target_from_marker(p, &right);
1394 return Some(complete);
1395 }
1396 if p.at(T![--]) {
1397 let m = p.start();
1398 p.bump(T![--]);
1399 let right = unary_expr(p)?;
1400 let complete = m.complete(p, UNARY_EXPR);
1401 check_assign_target_from_marker(p, &right);
1402 return Some(complete);
1403 }
1404
1405 if p.at_ts(UNARY_SINGLE) {
1406 let m = p.start();
1407 let op = p.cur();
1408 p.bump_any();
1409 let res = unary_expr(p)?;
1410 if op == T![delete] && p.typescript() {
1411 match res.kind() {
1412 DOT_EXPR | BRACKET_EXPR => {}
1413 _ => {
1414 let err = p
1415 .err_builder("the target for a delete operator must be a property access")
1416 .primary(res.range(p), "");
1417
1418 p.error(err);
1419 }
1420 }
1421 }
1422 return Some(m.complete(p, UNARY_EXPR));
1423 }
1424
1425 postfix_expr(p)
1426}