Skip to content
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
46 changes: 33 additions & 13 deletions crates/oxc_parser/src/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,14 @@ impl<'a> ParserImpl<'a> {
{
self.expect(open);
let mut list = self.ast.vec();
while !self.at(close) && !self.has_fatal_error() {
loop {
let kind = self.cur_kind();
if kind == close
|| matches!(kind, Kind::Eof | Kind::Undetermined)
|| self.fatal_error.is_some()
{
break;
}
list.push(f(self));
}
self.expect(close);
Expand Down Expand Up @@ -386,16 +393,25 @@ impl<'a> ParserImpl<'a> {
F: Fn(&mut Self) -> T,
{
let mut list = self.ast.vec();
if self.at(close) || self.has_fatal_error() {
// Cache cur_kind() to avoid redundant calls in compound checks
let kind = self.cur_kind();
if kind == close
|| matches!(kind, Kind::Eof | Kind::Undetermined)
|| self.fatal_error.is_some()
{
return (list, None);
}
list.push(f(self));
loop {
if self.at(close) || self.has_fatal_error() {
let kind = self.cur_kind();
if kind == close
|| matches!(kind, Kind::Eof | Kind::Undetermined)
|| self.fatal_error.is_some()
{
return (list, None);
}
self.expect(separator);
if self.at(close) {
if self.cur_kind() == close {
let trailing_separator = self.prev_token_end - 1;
return (list, Some(trailing_separator));
}
Expand All @@ -417,25 +433,27 @@ impl<'a> ParserImpl<'a> {
let mut rest: Option<BindingRestElement<'a>> = None;
let mut first = true;
loop {
if self.at(close) || self.has_fatal_error() {
let kind = self.cur_kind();
if kind == close
|| matches!(kind, Kind::Eof | Kind::Undetermined)
|| self.fatal_error.is_some()
{
break;
}

if first {
first = false;
} else {
let comma_span = self.cur_token().span();
if !self.at(Kind::Comma) {
let error = diagnostics::expect_token(
Kind::Comma.to_str(),
self.cur_kind().to_str(),
comma_span,
);
if kind != Kind::Comma {
let error =
diagnostics::expect_token(Kind::Comma.to_str(), kind.to_str(), comma_span);
self.set_fatal_error(error);
break;
}
self.bump_any();
if self.at(close) {
let kind = self.cur_kind();
if kind == close {
if rest.is_some() && !self.ctx.has_ambient() {
self.error(diagnostics::rest_element_trailing_comma(comma_span));
}
Expand All @@ -448,7 +466,9 @@ impl<'a> ParserImpl<'a> {
break;
}

if self.at(Kind::Dot3) {
// Re-capture kind to get the current token (may have changed after else branch)
let kind = self.cur_kind();
if kind == Kind::Dot3 {
rest.replace(self.parse_rest_element());
} else {
list.push(parse_element(self));
Expand Down
3 changes: 2 additions & 1 deletion crates/oxc_parser/src/js/arrow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ impl<'a> ParserImpl<'a> {
if self.cur_token().is_on_new_line() {
return Tristate::False;
}
if !self.at(Kind::LParen) && !self.at(Kind::LAngle) {
let kind = self.cur_kind();
if kind != Kind::LParen && kind != Kind::LAngle {
return Tristate::False;
}
}
Expand Down
5 changes: 3 additions & 2 deletions crates/oxc_parser/src/js/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,13 @@ impl<'a> ParserImpl<'a> {
self.error(diagnostics::escaped_keyword(token_after_import.span()));
}

if self.at(Kind::LCurly) || self.at(Kind::Star) {
let kind = self.cur_kind();
if kind == Kind::LCurly || kind == Kind::Star {
// `import type { ...`
// `import type * ...`
import_kind = ImportOrExportKind::Type;
has_default_specifier = false;
} else if self.cur_kind().is_binding_identifier() {
} else if kind.is_binding_identifier() {
// `import type something ...`
let token = self.cur_token();
let identifier_after_type = self.parse_binding_identifier();
Expand Down
12 changes: 9 additions & 3 deletions crates/oxc_parser/src/js/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,9 +620,15 @@ impl<'a> ParserImpl<'a> {
};
self.expect(Kind::Colon);
let mut consequent = self.ast.vec();
while !matches!(self.cur_kind(), Kind::Case | Kind::Default | Kind::RCurly)
&& !self.has_fatal_error()
{
loop {
let kind = self.cur_kind();
if matches!(
kind,
Kind::Case | Kind::Default | Kind::RCurly | Kind::Eof | Kind::Undetermined
) || self.fatal_error.is_some()
{
break;
}
let stmt = self.parse_statement_list_item(StatementContext::StatementList);
consequent.push(stmt);
}
Expand Down
22 changes: 14 additions & 8 deletions crates/oxc_parser/src/jsx/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,16 +241,17 @@ impl<'a> ParserImpl<'a> {
let span = self.start_span();
let checkpoint = self.checkpoint();
self.bump_any(); // bump `<`
let kind = self.cur_kind();
// <> open fragment
if self.at(Kind::RAngle) {
if kind == Kind::RAngle {
return Some(JSXChild::Fragment(self.parse_jsx_fragment(span, true)));
}
// <ident open element
if self.at(Kind::Ident) || self.cur_kind().is_any_keyword() {
if kind == Kind::Ident || kind.is_any_keyword() {
return Some(JSXChild::Element(self.parse_jsx_element(span, true)));
}
// </ close fragment
if self.at(Kind::Slash) {
if kind == Kind::Slash {
self.rewind(checkpoint);
return None;
}
Expand Down Expand Up @@ -318,10 +319,14 @@ impl<'a> ParserImpl<'a> {
/// `JSXAttribute` `JSXAttributes_opt`
fn parse_jsx_attributes(&mut self) -> Vec<'a, JSXAttributeItem<'a>> {
let mut attributes = self.ast.vec();
while !matches!(self.cur_kind(), Kind::LAngle | Kind::RAngle | Kind::Slash)
&& self.fatal_error.is_none()
{
let attribute = match self.cur_kind() {
loop {
let kind = self.cur_kind();
if matches!(kind, Kind::LAngle | Kind::RAngle | Kind::Slash)
|| self.fatal_error.is_some()
{
break;
}
let attribute = match kind {
Kind::LCurly => {
JSXAttributeItem::SpreadAttribute(self.parse_jsx_spread_attribute())
}
Expand Down Expand Up @@ -405,7 +410,8 @@ impl<'a> ParserImpl<'a> {
/// `JSXIdentifier` [no `WhiteSpace` or Comment here] -
fn parse_jsx_identifier(&mut self) -> JSXIdentifier<'a> {
let span = self.start_span();
if !self.at(Kind::Ident) && !self.cur_kind().is_any_keyword() {
let kind = self.cur_kind();
if kind != Kind::Ident && !kind.is_any_keyword() {
return self.unexpected();
}
// Currently at a valid normal Ident or Keyword, keep on lexing for `-` in `<component-name />`
Expand Down
3 changes: 2 additions & 1 deletion crates/oxc_parser/src/lexer/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,10 @@ impl Kind {
}

/// `IdentifierName`
/// All identifier names are either `Ident` or keywords (Await..=Null in the enum).
#[inline]
pub fn is_identifier_name(self) -> bool {
self == Ident || self.is_any_keyword()
self == Ident || matches!(self as u8, x if x >= Await as u8 && x <= Null as u8)
}

/// Check the succeeding token of a `let` keyword.
Expand Down
6 changes: 3 additions & 3 deletions crates/oxc_parser/src/modifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ impl<'a> ParserImpl<'a> {
let span = self.start_span();
let kind = self.cur_kind();

if matches!(self.cur_kind(), Kind::Const) {
if kind == Kind::Const {
if !permit_const_as_modifier {
return None;
}
Expand All @@ -398,10 +398,10 @@ impl<'a> ParserImpl<'a> {
} else if
// we're at the start of a static block
(stop_on_start_of_class_static_block
&& matches!(self.cur_kind(), Kind::Static)
&& kind == Kind::Static
&& self.lexer.peek_token().kind() == Kind::LCurly)
// we may be at the start of a static block
|| (has_seen_static_modifier && matches!(self.cur_kind(), Kind::Static))
|| (has_seen_static_modifier && kind == Kind::Static)
// next token is not a modifier
|| (!self.parse_any_contextual_modifier())
{
Expand Down
19 changes: 11 additions & 8 deletions crates/oxc_parser/src/ts/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,17 @@ impl<'a> ParserImpl<'a> {
if self.at(Kind::LAngle) {
return true;
}
if self.at(Kind::New) {
let kind = self.cur_kind();
if kind == Kind::New {
return true;
}
if !self.at(Kind::LParen) && !self.at(Kind::Abstract) {
if kind != Kind::LParen && kind != Kind::Abstract {
return false;
}
let checkpoint = self.checkpoint();
let first = self.cur_kind();
self.bump_any();

match first {
match kind {
Kind::Abstract => {
// `abstract new ...`
if self.at(Kind::New) {
Expand Down Expand Up @@ -140,11 +140,12 @@ impl<'a> ParserImpl<'a> {
if self.cur_kind().is_modifier_kind() {
self.parse_modifiers(false, false);
}
if self.cur_kind().is_identifier() || self.at(Kind::This) {
let kind = self.cur_kind();
if kind.is_identifier() || kind == Kind::This {
self.bump_any();
return true;
}
if matches!(self.cur_kind(), Kind::LBrack | Kind::LCurly) {
if matches!(kind, Kind::LBrack | Kind::LCurly) {
let errors_count = self.errors_count();
self.parse_binding_pattern_kind();
if !self.has_fatal_error() && errors_count == self.errors_count() {
Expand Down Expand Up @@ -555,7 +556,8 @@ impl<'a> ParserImpl<'a> {

fn is_start_of_mapped_type(&mut self) -> bool {
self.bump_any();
if self.at(Kind::Plus) || self.at(Kind::Minus) {
let kind = self.cur_kind();
if kind == Kind::Plus || kind == Kind::Minus {
self.bump_any();
return self.at(Kind::Readonly);
}
Expand Down Expand Up @@ -1184,7 +1186,8 @@ impl<'a> ParserImpl<'a> {
let (key, computed) = self.parse_property_name();
let optional = self.eat(Kind::Question);

if self.at(Kind::LParen) || self.at(Kind::LAngle) {
let kind = self.cur_kind();
if kind == Kind::LParen || kind == Kind::LAngle {
for modifier in modifiers.iter() {
if modifier.kind == ModifierKind::Readonly {
self.error(
Expand Down
Loading