Skip to content

Commit

Permalink
feat(es/parser): Ability to get script's potential module errors (#9682)
Browse files Browse the repository at this point in the history
**Description:**

In Deno I'm now parsing stuff as a program more often because I sometimes now need to discover if something is a script or es module by looking at the contents. A problem is that the module errors are discarded when parsing as a script, but I still might need them later if I discover the program the program should be treated as an ES module.

**BREAKING CHANGE:**

Adds a new method to the `Tokens` trait.
  • Loading branch information
dsherret authored Oct 29, 2024
1 parent 97c90a1 commit 2bbd1e8
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/fifty-goats-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
swc_core: breaking
swc_ecma_parser: breaking
---

feat(es/parser): Ability to get script's potential module errors
4 changes: 4 additions & 0 deletions crates/swc_ecma_parser/src/lexer/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,10 @@ impl Tokens for Lexer<'_> {
take(&mut self.errors.borrow_mut())
}

fn take_script_module_errors(&mut self) -> Vec<Error> {
take(&mut self.module_errors.borrow_mut())
}

fn end_pos(&self) -> BytePos {
self.input.end_pos()
}
Expand Down
12 changes: 12 additions & 0 deletions crates/swc_ecma_parser/src/parser/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ pub trait Tokens: Clone + Iterator<Item = TokenAndSpan> {
fn end_pos(&self) -> BytePos;

fn take_errors(&mut self) -> Vec<Error>;

/// If the program was parsed as a script, this contains the module
/// errors should the program be identified as a module in the future.
fn take_script_module_errors(&mut self) -> Vec<Error>;
}

#[derive(Clone)]
Expand Down Expand Up @@ -145,6 +149,10 @@ impl Tokens for TokensInput {
take(&mut self.errors.borrow_mut())
}

fn take_script_module_errors(&mut self) -> Vec<Error> {
take(&mut self.module_errors.borrow_mut())
}

fn end_pos(&self) -> BytePos {
self.iter
.as_slice()
Expand Down Expand Up @@ -269,6 +277,10 @@ impl<I: Tokens> Tokens for Capturing<I> {
self.inner.take_errors()
}

fn take_script_module_errors(&mut self) -> Vec<Error> {
self.inner.take_script_module_errors()
}

fn end_pos(&self) -> BytePos {
self.inner.end_pos()
}
Expand Down
4 changes: 4 additions & 0 deletions crates/swc_ecma_parser/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ impl<I: Tokens> Parser<I> {
self.input().take_errors()
}

pub fn take_script_module_errors(&mut self) -> Vec<Error> {
self.input().take_script_module_errors()
}

pub fn parse_script(&mut self) -> PResult<Script> {
trace_cur!(self, parse_script);

Expand Down
23 changes: 23 additions & 0 deletions crates/swc_ecma_parser/src/parser/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ fn illegal_language_mode_directive1() {
},
);
}

#[test]
fn illegal_language_mode_directive2() {
test_parser(
Expand Down Expand Up @@ -346,3 +347,25 @@ fn illegal_language_mode_directive2() {
fn parse_non_strict_for_loop() {
script("for (var v1 = 1 in v3) {}");
}

#[test]
fn parse_program_take_script_module_errors() {
test_parser(r#"077;"#, Default::default(), |p| {
let program = p.parse_program()?;

assert_eq!(p.take_errors(), vec![]);
// will contain the script's potential module errors
assert_eq!(
p.take_script_module_errors(),
vec![Error::new(
Span {
lo: BytePos(1),
hi: BytePos(4),
},
crate::parser::SyntaxError::LegacyOctal
)]
);

Ok(program)
});
}

0 comments on commit 2bbd1e8

Please sign in to comment.