Skip to content

Commit 236f45e

Browse files
committed
Advance opt: opt parse_subscript
1 parent cf2e302 commit 236f45e

File tree

1 file changed

+30
-37
lines changed
  • crates/swc_ecma_parser/src/parser

1 file changed

+30
-37
lines changed

crates/swc_ecma_parser/src/parser/expr.rs

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,7 +1217,7 @@ impl<I: Tokens> Parser<I> {
12171217
}
12181218
}
12191219

1220-
let type_args = if self.syntax().typescript() && self.input().is(Token::Lt) {
1220+
let ts_instantiation = if self.syntax().typescript() && self.input().is(Token::Lt) {
12211221
self.try_parse_ts_type_args()
12221222
} else {
12231223
None
@@ -1233,21 +1233,21 @@ impl<I: Tokens> Parser<I> {
12331233
&& peek!(self).is_some_and(|peek| peek == Token::Dot)
12341234
{
12351235
let start = self.cur_pos();
1236-
expect!(self, Token::QuestionMark);
1237-
Some(self.span(start))
1236+
self.bump();
1237+
1238+
let span = Some(self.span(start));
1239+
self.bump();
1240+
1241+
span
12381242
} else {
12391243
None
12401244
};
12411245

1246+
// If question_dot_token is Some, then `self.cur == Token::Dot`
1247+
let question_dot = question_dot_token.is_some();
1248+
12421249
// $obj[name()]
1243-
if !no_computed_member
1244-
&& ((question_dot_token.is_some()
1245-
&& self.input().is(Token::Dot)
1246-
&& peek!(self).is_some_and(|peek| peek == Token::LBracket)
1247-
&& self.input_mut().eat(Token::Dot)
1248-
&& self.input_mut().eat(Token::LBracket))
1249-
|| self.input_mut().eat(Token::LBracket))
1250-
{
1250+
if !no_computed_member && self.input_mut().eat(Token::LBracket) {
12511251
let bracket_lo = self.input().prev_span().lo;
12521252
let prop = self.allow_in_expr(|p| p.parse_expr())?;
12531253
expect!(self, Token::RBracket);
@@ -1272,7 +1272,7 @@ impl<I: Tokens> Parser<I> {
12721272
&& !self.input().syntax().allow_super_outside_method()
12731273
{
12741274
syntax_error!(self, obj.span, SyntaxError::InvalidSuper);
1275-
} else if question_dot_token.is_some() {
1275+
} else if question_dot {
12761276
if no_call {
12771277
syntax_error!(self, obj.span, SyntaxError::InvalidSuperCall);
12781278
} else {
@@ -1294,10 +1294,10 @@ impl<I: Tokens> Parser<I> {
12941294
obj,
12951295
prop: MemberProp::Computed(prop),
12961296
};
1297-
let expr = if is_opt_chain || question_dot_token.is_some() {
1297+
let expr = if is_opt_chain || question_dot {
12981298
OptChainExpr {
12991299
span,
1300-
optional: question_dot_token.is_some(),
1300+
optional: question_dot,
13011301
base: Box::new(OptChainBase::Member(expr)),
13021302
}
13031303
.into()
@@ -1321,24 +1321,19 @@ impl<I: Tokens> Parser<I> {
13211321
));
13221322
}
13231323

1324-
if (question_dot_token.is_some()
1325-
&& self.input().is(Token::Dot)
1326-
&& (peek!(self).is_some_and(|peek| peek == Token::LParen)
1327-
|| (self.syntax().typescript()
1328-
&& peek!(self).is_some_and(|peek| peek == Token::Lt)))
1329-
&& self.input_mut().eat(Token::Dot))
1330-
|| (!no_call && self.input().is(Token::LParen))
1324+
let type_args = if self.syntax().typescript() && self.input().is(Token::Lt) && question_dot
13311325
{
1332-
let type_args = if self.syntax().typescript() && self.input().is(Token::Lt) {
1333-
let ret = self.parse_ts_type_args()?;
1334-
self.assert_and_bump(Token::Gt);
1335-
Some(ret)
1336-
} else {
1337-
None
1338-
};
1326+
let ret = self.parse_ts_type_args()?;
1327+
self.assert_and_bump(Token::Gt);
1328+
Some(ret)
1329+
} else {
1330+
None
1331+
};
1332+
1333+
if (self.input.is(Token::LParen) && (!no_call || question_dot)) || type_args.is_some() {
13391334
let args = self.parse_args(obj.is_import())?;
13401335
let span = self.span(start);
1341-
return if question_dot_token.is_some()
1336+
return if question_dot
13421337
|| match &obj {
13431338
Callee::Expr(obj) => unwrap_ts_non_null(obj).is_opt_chain(),
13441339
_ => false,
@@ -1354,7 +1349,7 @@ impl<I: Tokens> Parser<I> {
13541349
Callee::Expr(callee) => Ok((
13551350
OptChainExpr {
13561351
span,
1357-
optional: question_dot_token.is_some(),
1352+
optional: question_dot,
13581353
base: Box::new(OptChainBase::Call(OptCall {
13591354
span: self.span(start),
13601355
callee,
@@ -1383,7 +1378,7 @@ impl<I: Tokens> Parser<I> {
13831378

13841379
// member expression
13851380
// $obj.name
1386-
if self.input_mut().eat(Token::Dot) {
1381+
if question_dot || self.input_mut().eat(Token::Dot) {
13871382
let prop = self.parse_maybe_private_name().map(|e| match e {
13881383
Either::Left(p) => MemberProp::PrivateName(p),
13891384
Either::Right(i) => MemberProp::Ident(i),
@@ -1435,7 +1430,7 @@ impl<I: Tokens> Parser<I> {
14351430
&& !self.input().syntax().allow_super_outside_method()
14361431
{
14371432
syntax_error!(self, obj.span, SyntaxError::InvalidSuper);
1438-
} else if question_dot_token.is_some() {
1433+
} else if question_dot {
14391434
if no_call {
14401435
syntax_error!(self, obj.span, SyntaxError::InvalidSuperCall);
14411436
} else {
@@ -1462,12 +1457,10 @@ impl<I: Tokens> Parser<I> {
14621457
}
14631458
Callee::Expr(obj) => {
14641459
let expr = MemberExpr { span, obj, prop };
1465-
let expr = if unwrap_ts_non_null(&expr.obj).is_opt_chain()
1466-
|| question_dot_token.is_some()
1467-
{
1460+
let expr = if unwrap_ts_non_null(&expr.obj).is_opt_chain() || question_dot {
14681461
OptChainExpr {
14691462
span: self.span(start),
1470-
optional: question_dot_token.is_some(),
1463+
optional: question_dot,
14711464
base: Box::new(OptChainBase::Member(expr)),
14721465
}
14731466
.into()
@@ -1492,7 +1485,7 @@ impl<I: Tokens> Parser<I> {
14921485

14931486
match obj {
14941487
Callee::Expr(expr) => {
1495-
let expr = if let Some(type_args) = type_args {
1488+
let expr = if let Some(type_args) = ts_instantiation {
14961489
TsInstantiation {
14971490
expr,
14981491
type_args,

0 commit comments

Comments
 (0)