diff --git a/crates/oxc_parser/src/cursor.rs b/crates/oxc_parser/src/cursor.rs index df7189dba0965..e8cde13cda723 100644 --- a/crates/oxc_parser/src/cursor.rs +++ b/crates/oxc_parser/src/cursor.rs @@ -481,6 +481,53 @@ impl<'a, C: Config> ParserImpl<'a, C> { } } + pub(crate) fn parse_delimited_list_into( + &mut self, + list: &mut Vec<'a, T>, + close: Kind, + separator: Kind, + opening_span: Span, + mut f: F, + ) -> Option + where + F: FnMut(&mut Self) -> T, + { + // 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 None; + } + list.push(f(self)); + loop { + let kind = self.cur_kind(); + if kind == close + || matches!(kind, Kind::Eof | Kind::Undetermined) + || self.fatal_error.is_some() + { + return None; + } + if !self.at(separator) { + self.set_fatal_error(diagnostics::expect_closing_or_separator( + close.to_str(), + separator.to_str(), + kind.to_str(), + self.cur_token().span(), + opening_span, + )); + return None; + } + self.advance(separator); + if self.cur_kind() == close { + let trailing_separator = self.prev_token_end - 1; + return Some(trailing_separator); + } + list.push(f(self)); + } + } + pub(crate) fn parse_delimited_list_with_rest( &mut self, close: Kind, diff --git a/crates/oxc_parser/src/js/module.rs b/crates/oxc_parser/src/js/module.rs index 428b49ba5b08c..31884b03bb2a9 100644 --- a/crates/oxc_parser/src/js/module.rs +++ b/crates/oxc_parser/src/js/module.rs @@ -287,8 +287,7 @@ impl<'a, C: Config> ParserImpl<'a, C> { default_span, )); } - let mut import_specifiers = self.parse_import_specifiers(import_kind); - specifiers.append(&mut import_specifiers); + self.parse_import_specifiers_into(&mut specifiers, import_kind); } _ => return self.unexpected(), } @@ -309,8 +308,7 @@ impl<'a, C: Config> ParserImpl<'a, C> { specifiers.push(self.parse_import_namespace_specifier()); } else if self.at(Kind::LCurly) { // import { export1 , export2 as alias2 , [...] } from "module-name"; - let mut import_specifiers = self.parse_import_specifiers(import_kind); - specifiers.append(&mut import_specifiers); + self.parse_import_specifiers_into(&mut specifiers, import_kind); } self.expect(Kind::From); @@ -328,19 +326,23 @@ impl<'a, C: Config> ParserImpl<'a, C> { } // import { export1 , export2 as alias2 , [...] } from "module-name"; - fn parse_import_specifiers( + fn parse_import_specifiers_into( &mut self, + specifiers: &mut Vec<'a, ImportDeclarationSpecifier<'a>>, import_kind: ImportOrExportKind, - ) -> Vec<'a, ImportDeclarationSpecifier<'a>> { + ) { let opening_span = self.cur_token().span(); self.expect(Kind::LCurly); - let (list, _) = self.context_remove(self.ctx, |p| { - p.parse_delimited_list(Kind::RCurly, Kind::Comma, opening_span, |parser| { - parser.parse_import_specifier(import_kind) - }) + self.context_remove(self.ctx, |p| { + let _ = p.parse_delimited_list_into( + specifiers, + Kind::RCurly, + Kind::Comma, + opening_span, + |parser| parser.parse_import_specifier(import_kind), + ); }); self.expect(Kind::RCurly); - list } /// [Import Attributes](https://tc39.es/proposal-import-attributes) diff --git a/tasks/track_memory_allocations/allocs_parser.snap b/tasks/track_memory_allocations/allocs_parser.snap index 97d89210e2063..0818977702630 100644 --- a/tasks/track_memory_allocations/allocs_parser.snap +++ b/tasks/track_memory_allocations/allocs_parser.snap @@ -1,14 +1,14 @@ File | File size || Sys allocs | Sys reallocs || Arena allocs | Arena reallocs | Arena bytes ------------------------------------------------------------------------------------------------------------------------------------------- -checker.ts | 2.92 MB || 9672 | 21 || 267678 | 22847 +checker.ts | 2.92 MB || 9672 | 21 || 267677 | 22847 -cal.com.tsx | 1.06 MB || 1083 | 49 || 138159 | 13699 +cal.com.tsx | 1.06 MB || 1083 | 49 || 136164 | 13698 -RadixUIAdoptionSection.jsx | 2.52 kB || 1 | 0 || 365 | 66 +RadixUIAdoptionSection.jsx | 2.52 kB || 1 | 0 || 363 | 66 pdf.mjs | 567.30 kB || 703 | 75 || 90678 | 8148 antd.js | 6.69 MB || 7132 | 235 || 528505 | 55357 -binder.ts | 193.08 kB || 530 | 7 || 16791 | 1467 +binder.ts | 193.08 kB || 530 | 7 || 16790 | 1467