Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(es/parser): Revert #9141 #9171

Merged
merged 2 commits into from
Jul 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions crates/swc_ecma_parser/src/parser/class_and_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -745,7 +745,7 @@ impl<I: Tokens> Parser<I> {
}

trace_cur!(self, parse_class_member_with_is_static__normal_class_member);
let mut key = if readonly.is_some() && is!(self, '!' | ':') {
let mut key = if readonly.is_some() && is_one_of!(self, '!', ':') {
Key::Public(PropName::Ident(Ident::new(
"readonly".into(),
readonly.unwrap(),
Expand Down Expand Up @@ -1155,8 +1155,8 @@ impl<I: Tokens> Parser<I> {
}

fn is_class_property(&mut self, asi: bool) -> bool {
(self.input.syntax().typescript() && is!(self, '!' | ':'))
|| is!(self, '=' | '}')
(self.input.syntax().typescript() && is_one_of!(self, '!', ':'))
|| is_one_of!(self, '=', '}')
|| if asi {
is!(self, ';')
} else {
Expand Down
48 changes: 11 additions & 37 deletions crates/swc_ecma_parser/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl<I: Tokens> Parser<I> {
let start = self.input.cur_span();

if self.input.syntax().typescript()
&& (is!(self, '<' | JSXTagStart))
&& (is_one_of!(self, '<', JSXTagStart))
&& (peeked_is!(self, IdentName) || peeked_is!(self, JSXName))
{
let ctx = Context {
Expand Down Expand Up @@ -395,7 +395,7 @@ impl<I: Tokens> Parser<I> {
}

if is!(self, "let")
|| (self.input.syntax().typescript() && is!(self, IdentRef | "await"))
|| (self.input.syntax().typescript() && is_one_of!(self, IdentRef, "await"))
|| is!(self, IdentRef)
{
let ctx = self.ctx();
Expand Down Expand Up @@ -1226,7 +1226,7 @@ impl<I: Tokens> Parser<I> {
)
.map(|expr| (Box::new(Expr::TaggedTpl(expr)), true))
.map(Some)
} else if is!(p, '=' | "as") {
} else if is_one_of!(p, '=', "as") {
Ok(Some((
Box::new(Expr::TsInstantiation(TsInstantiation {
span: span!(p, start),
Expand Down Expand Up @@ -1258,7 +1258,7 @@ impl<I: Tokens> Parser<I> {
None
};

if obj.is_import() && !is!(self, '.' | '(') {
if obj.is_import() && !is_one_of!(self, '.', '(') {
unexpected!(self, "`.` or `(`")
}

Expand Down Expand Up @@ -1597,7 +1597,7 @@ impl<I: Tokens> Parser<I> {
let callee = self.parse_new_expr()?;
return_if_arrow!(self, callee);

let type_args = if self.input.syntax().typescript() && is!(self, '<' | "<<") {
let type_args = if self.input.syntax().typescript() && is_one_of!(self, '<', "<<") {
self.try_parse_ts(|p| {
let type_args = p.parse_ts_type_args()?;
if is!(p, '(') {
Expand Down Expand Up @@ -2145,44 +2145,18 @@ impl<I: Tokens> Parser<I> {
}

fn is_start_of_left_hand_side_expr(&mut self) -> PResult<bool> {
Ok(is!(
self,
"this"
| "super"
| "null"
| "true"
| "false"
| Num
| BigInt
| Str
| '`'
| '('
| '['
| '{'
| "function"
| "class"
| "new"
| Regex
| IdentRef
Ok(is_one_of!(
self, "this", "super", "null", "true", "false", Num, BigInt, Str, '`', '(', '[', '{',
"function", "class", "new", Regex, IdentRef
) || (is!(self, "import")
&& (peeked_is!(self, '(') || peeked_is!(self, '<') || peeked_is!(self, '.'))))
}

pub(super) fn is_start_of_expr(&mut self) -> PResult<bool> {
Ok(self.is_start_of_left_hand_side_expr()?
|| is!(
self,
'+' | '-'
| '~'
| '!'
| "delete"
| "typeof"
| "void"
| "++"
| "--"
| '<'
| "await"
| "yield"
|| is_one_of!(
self, '+', '-', '~', '!', "delete", "typeof", "void", "++", "--", '<', "await",
"yield"
)
|| (is!(self, '#') && peeked_is!(self, IdentName)))
}
Expand Down
6 changes: 3 additions & 3 deletions crates/swc_ecma_parser/src/parser/expr/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ impl<I: Tokens> Parser<I> {
}

// Parse unary expression
if is!(self, "delete" | "void" | "typeof" | '+' | '-' | '~' | '!') {
if is_one_of!(self, "delete", "void", "typeof", '+', '-', '~', '!') {
let op = match bump!(self) {
tok!("delete") => op!("delete"),
tok!("void") => op!("void"),
Expand Down Expand Up @@ -341,7 +341,7 @@ impl<I: Tokens> Parser<I> {
return Ok(expr);
}

if is!(self, "++" | "--") {
if is_one_of!(self, "++", "--") {
self.check_assign_target(&expr, false);

let op = if bump!(self) == tok!("++") {
Expand Down Expand Up @@ -378,7 +378,7 @@ impl<I: Tokens> Parser<I> {

let span = span!(self, start);

if is!(self, ')' | ']' | ';' | ',') && !ctx.in_async {
if is_one_of!(self, ')', ']', ';', ',') && !ctx.in_async {
if ctx.module {
self.emit_err(span, SyntaxError::InvalidIdentInAsync);
}
Expand Down
64 changes: 30 additions & 34 deletions crates/swc_ecma_parser/src/parser/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@ macro_rules! is {
($p:expr, BindingIdent) => {{
let ctx = $p.ctx();
match $p.input.cur() {
Some(&crate::token::Word(ref w)) => !ctx.is_reserved(w),
Some(&Word(ref w)) => !ctx.is_reserved(w),
_ => false,
}
}};

($p:expr, IdentRef) => {{
let ctx = $p.ctx();
match $p.input.cur() {
Some(&crate::token::Word(ref w)) => !ctx.is_reserved(w),
Some(&Word(ref w)) => !ctx.is_reserved(w),
_ => false,
}
}};

($p:expr,IdentName) => {{
match $p.input.cur() {
Some(&crate::token::Word(..)) => true,
Some(&Word(..)) => true,
_ => false,
}
}};
Expand Down Expand Up @@ -77,33 +77,29 @@ macro_rules! is {
($p:expr, $t:tt) => {
is_exact!($p, $t)
};

($p:expr, $t:tt | $($rest:tt)*) => {{
is!($p, $t) || is!($p, $($rest)*)
}};
}

#[allow(unused)]
macro_rules! peeked_is {
($p:expr, BindingIdent) => {{
let ctx = $p.ctx();
match peek!($p) {
Some(&crate::token::Word(ref w)) => !ctx.is_reserved(w),
Some(&Word(ref w)) => !ctx.is_reserved(w),
_ => false,
}
}};

($p:expr, IdentRef) => {{
let ctx = $p.ctx();
match peek!($p) {
Some(&crate::token::Word(ref w)) => !ctx.is_reserved(w),
Some(&Word(ref w)) => !ctx.is_reserved(w),
_ => false,
}
}};

($p:expr,IdentName) => {{
match peek!($p) {
Some(&crate::token::Word(..)) => true,
Some(&Word(..)) => true,
_ => false,
}
}};
Expand All @@ -125,10 +121,6 @@ macro_rules! peeked_is {
_ => false,
}
};

($p:expr, $t:tt | $($rest:tt)*) => {
peeked_is!($p, $t) || peeked_is!($p, $($rest)*)
};
}

/// Returns true on eof.
Expand All @@ -138,6 +130,15 @@ macro_rules! eof {
};
}

macro_rules! is_one_of {
($p:expr, $($t:tt),+) => {{
false
$(
|| is!($p, $t)
)*
}};
}

// This will panic if current != token
macro_rules! assert_and_bump {
($p:expr, $t:tt) => {{
Expand All @@ -160,6 +161,9 @@ macro_rules! assert_and_bump {
/// if token has data like string.
macro_rules! eat {
($p:expr, ';') => {{
if cfg!(feature = "debug") {
tracing::trace!("eat(';'): cur={:?}", cur!($p, false));
}
match $p.input.cur() {
Some(&Token::Semi) => {
$p.input.bump();
Expand Down Expand Up @@ -206,11 +210,7 @@ macro_rules! expect {
const TOKEN: &Token = &token_including_semi!($t);
if !eat!($p, $t) {
let cur = $p.input.dump_cur();
syntax_error!(
$p,
$p.input.cur_span(),
crate::error::SyntaxError::Expected(TOKEN, cur)
)
syntax_error!($p, $p.input.cur_span(), SyntaxError::Expected(TOKEN, cur))
}
}};
}
Expand All @@ -220,11 +220,7 @@ macro_rules! expect_exact {
const TOKEN: &Token = &token_including_semi!($t);
if !eat_exact!($p, $t) {
let cur = $p.input.dump_cur();
syntax_error!(
$p,
$p.input.cur_span(),
crate::error::SyntaxError::Expected(TOKEN, cur)
)
syntax_error!($p, $p.input.cur_span(), SyntaxError::Expected(TOKEN, cur))
}
}};
}
Expand Down Expand Up @@ -295,9 +291,6 @@ macro_rules! bump {
$p.input.knows_cur(),
"parser should not call bump() without knowing current token"
);
if cfg!(feature = "debug") {
tracing::info!("Bump: {:?}", $p.input.cur());
}
$p.input.bump()
}};
}
Expand Down Expand Up @@ -384,13 +377,16 @@ macro_rules! syntax_error {
}
}
}
tracing::error!(
"Syntax error called from {}:{}:{}\nCurrent token = {:?}",
file!(),
line!(),
column!(),
$p.input.cur()
);

if cfg!(feature = "debug") {
tracing::error!(
"Syntax error called from {}:{}:{}\nCurrent token = {:?}",
file!(),
line!(),
column!(),
$p.input.cur()
);
}
return Err(err.into());
}};
}
Expand Down
7 changes: 2 additions & 5 deletions crates/swc_ecma_parser/src/parser/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,7 @@ impl<I: Tokens> ParseObject<Box<Expr>> for Parser<I> {
let key = self.parse_prop_name()?;

if self.input.syntax().typescript()
&& !is!(
self,
'(' | '[' | ':' | ',' | '?' | '=' | '*' | IdentName | Str | Num
)
&& !is_one_of!(self, '(', '[', ':', ',', '?', '=', '*', IdentName, Str, Num)
&& !(self.input.syntax().typescript() && is!(self, '<'))
&& !(is!(self, '}') && matches!(key, PropName::Ident(..)))
{
Expand Down Expand Up @@ -245,7 +242,7 @@ impl<I: Tokens> ParseObject<Box<Expr>> for Parser<I> {

// `ident` from parse_prop_name is parsed as 'IdentifierName'
// It means we should check for invalid expressions like { for, }
if is!(self, '=' | ',' | '}') {
if is_one_of!(self, '=', ',', '}') {
let is_reserved_word = { self.ctx().is_reserved_word(&ident.sym) };
if is_reserved_word {
self.emit_err(ident.span, SyntaxError::ReservedWordInObjShorthandOrPat);
Expand Down
16 changes: 8 additions & 8 deletions crates/swc_ecma_parser/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl<'a, I: Tokens> Parser<I> {
let start = cur_pos!(self);
let decorators = self.parse_decorators(true)?;

if is!(self, "import" | "export") {
if is_one_of!(self, "import", "export") {
return self.handle_import_export(top_level, decorators);
}

Expand Down Expand Up @@ -640,7 +640,7 @@ impl<'a, I: Tokens> Parser<I> {
};

self.with_ctx(ctx).parse_with(|p| {
while is!(p, "case" | "default") {
while is_one_of!(p, "case", "default") {
let mut cons = vec![];
let is_case = is!(p, "case");
let case_start = cur_pos!(p);
Expand All @@ -657,7 +657,7 @@ impl<'a, I: Tokens> Parser<I> {
};
expect!(p, ':');

while !eof!(p) && !is!(p, "case" | "default" | '}') {
while !eof!(p) && !is_one_of!(p, "case", "default", '}') {
cons.push(p.parse_stmt_list_item(false)?);
}

Expand Down Expand Up @@ -868,7 +868,7 @@ impl<'a, I: Tokens> Parser<I> {
let should_include_in = kind != VarDeclKind::Var || !for_loop;

if self.syntax().typescript() && for_loop {
let res = if is!(self, "in" | "of") {
let res = if is_one_of!(self, "in", "of") {
self.ts_look_ahead(|p| {
//
if !eat!(p, "of") && !eat!(p, "in") {
Expand Down Expand Up @@ -999,7 +999,7 @@ impl<'a, I: Tokens> Parser<I> {
}

//FIXME: This is wrong. Should check in/of only on first loop.
let init = if !for_loop || !is!(self, "in" | "of") {
let init = if !for_loop || !is_one_of!(self, "in", "of") {
if eat!(self, '=') {
let expr = self.parse_assignment_expr()?;
let expr = self.verify_expr(expr)?;
Expand Down Expand Up @@ -1243,13 +1243,13 @@ impl<'a, I: Tokens> Parser<I> {
fn parse_for_head(&mut self) -> PResult<TempForHead> {
let strict = self.ctx().strict;

if is!(self, "const" | "var")
if is_one_of!(self, "const", "var")
|| (is!(self, "let")
&& peek!(self).map_or(false, |v| v.kind().follows_keyword_let(strict)))
{
let decl = self.parse_var_stmt(true)?;

if is!(self, "of" | "in") {
if is_one_of!(self, "of", "in") {
if decl.decls.len() != 1 {
for d in decl.decls.iter().skip(1) {
self.emit_err(d.name.span(), SyntaxError::TooManyVarInForInHead);
Expand Down Expand Up @@ -1342,7 +1342,7 @@ impl<'a, I: Tokens> Parser<I> {
}

// for (a of b)
if is!(self, "of" | "in") {
if is_one_of!(self, "of", "in") {
let is_in = is!(self, "in");

let pat = self.reparse_expr_as_pat(PatType::AssignPat, init)?;
Expand Down
Loading
Loading