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

feat(es/parser): Make error message helpful #6535

Merged
merged 17 commits into from Nov 29, 2022
16 changes: 14 additions & 2 deletions crates/swc_ecma_parser/src/error.rs
Expand Up @@ -272,6 +272,12 @@ pub enum SyntaxError {
TS4112,
TSTypeAnnotationAfterAssign,
TsNonNullAssertionNotAllowed(JsWord),

WithLabel {
inner: Box<Error>,
span: Span,
note: &'static str,
},
}

impl SyntaxError {
Expand Down Expand Up @@ -698,6 +704,7 @@ impl SyntaxError {
};
format!("Unexpected token. Did you mean {}?", did_you_mean).into()
}
SyntaxError::WithLabel { inner, .. } => inner.error.1.msg(),
}
}
}
Expand All @@ -706,13 +713,18 @@ impl Error {
#[cold]
#[inline(never)]
pub fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder {
if let SyntaxError::WithLabel { inner, note, span } = self.error.1 {
let mut db = inner.into_diagnostic(handler);
db.span_label(span, note);
return db;
}

let span = self.span();

let kind = self.into_kind();
let msg = kind.msg();

let mut db = handler.struct_err(&msg);
db.set_span(span);
let mut db = handler.struct_span_err(span, &msg);

match kind {
SyntaxError::ExpectedSemiForExprStmt { expr } => {
Expand Down
20 changes: 13 additions & 7 deletions crates/swc_ecma_parser/src/parser/expr.rs
Expand Up @@ -495,12 +495,7 @@ impl<I: Tokens> Parser<I> {
})));
}

unexpected!(
self,
"this, import, async, function, [ for array literal, { for object literal, @ for \
decorator, function, class, null, true, false, number, bigint, string, regexp, ` for \
template literal, (, or an identifier"
)
syntax_error!(self, self.input.cur_span(), SyntaxError::TS1109)
}

#[cfg_attr(feature = "debug", tracing::instrument(skip_all))]
Expand Down Expand Up @@ -1911,7 +1906,18 @@ impl<I: Tokens> Parser<I> {
})))
} else {
let has_star = eat!(self, '*');
let arg = self.parse_assignment_expr()?;
let err_span = span!(self, start);

let arg = self.parse_assignment_expr().map_err(|err| {
Error::new(
err.span(),
SyntaxError::WithLabel {
inner: Box::new(err),
span: err_span,
note: "Tried to parse an argument of yield",
},
)
})?;

Ok(Box::new(Expr::Yield(YieldExpr {
span: span!(self, start),
Expand Down
16 changes: 15 additions & 1 deletion crates/swc_ecma_parser/src/parser/stmt.rs
Expand Up @@ -449,13 +449,27 @@ impl<'a, I: Tokens> Parser<I> {
let start = cur_pos!(self);

assert_and_bump!(self, "if");
let if_token = self.input.prev_span();

expect!(self, '(');
let ctx = Context {
ignore_else_clause: false,
..self.ctx()
};
let test = self.with_ctx(ctx).include_in_expr(true).parse_expr()?;
let test = self
.with_ctx(ctx)
.include_in_expr(true)
.parse_expr()
.map_err(|err| {
Error::new(
err.span(),
SyntaxError::WithLabel {
inner: Box::new(err),
span: if_token,
note: "Tried to parse the condition for an if statement",
},
)
})?;
if !eat!(self, ')') {
self.emit_err(self.input.cur_span(), SyntaxError::TS1005);

Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `public`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp,
| ` for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/errors/conflict_marker_trivia_2/input.ts:8:1]
8 | }
9 | ,-> >>>>>>> A
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `> (jsx tag end)`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint,
| string, regexp, ` for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/jsx/errors/attribute-empty-expression/input.js:1:1]
1 | <foo bar={} />
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `;`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/0abefbc80bf651fa.js:1:1]
1 | for (let let;;;) {}
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `.`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/17904d9a6b6ec31b.js:1:1]
1 | f(..a)
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `=>`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/211656c4eaff2d9c.js:1:1]
1 | a
2 | => 0
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `yield`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp,
| ` for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/247e71c8786de6b6.js:1:1]
1 | (function() { "use strict"; f(yield v) })
: ^^^^^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `]`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/3118eaa619345896.js:1:1]
1 | /*
2 | */]
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `...`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/363ecb9e2e556694.js:1:1]
1 | new f(... ... g);
: ^^^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `;`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/39551fb86dcd3b29.js:1:1]
1 | for (const let = 1;;;) {}
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `]`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/42cb3f2a38cb2930.js:1:1]
1 | /*
2 | */]
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `;`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/49624f905645b7d0.js:1:1]
1 | for (let x, y, z, let;;;) {}
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `if`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/4c3f75c2ad9dc102.js:1:1]
1 | ({ set: s(if) { } })
: ^^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `]`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/62d72a3c3d14d150.js:1:1]
1 |
2 | ]
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `]`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/67419010fc81184a.js:1:1]
1 | /*
2 | */]
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `]`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/679ab0881c66b0cf.js:1:1]
1 |
2 | ]
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `yield`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp,
| ` for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/6aeff33ceda72475.js:1:1]
1 | class A extends yield B { }
: ^^^^^
Expand Down
@@ -1,11 +1,4 @@

x Unexpected token `<eof>`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp,
| ` for template literal, (, or an identifier
,-[$DIR/tests/test262-parser/fail/7562c2148b3f455c.js:1:1]
1 | ;/**/-->
: ^
`----

x Expression expected
,-[$DIR/tests/test262-parser/fail/7562c2148b3f455c.js:1:1]
1 | ;/**/-->
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `default`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string,
| regexp, ` for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/77e5dccd799284ee.module.js:1:1]
1 | export default default
: ^^^^^^^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `.`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/7dd7279ecf6a7eb8.js:1:1]
1 | f(..g);
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `!`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/7fc173197c3cc75d.js:1:1]
1 | (class extends !a {})
: ^
Expand Down
@@ -1,7 +1,7 @@

x Unexpected token `}`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/80d1e106056a576f.js:1:1]
1 | function *a(){yield*}
: ^
: ^^^|^^^
: `-- Tried to parse an argument of yield
`----
@@ -1,6 +1,5 @@

x Unexpected token `.`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/8262e85f06cb459c.js:1:1]
1 | new f(....g);
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `%`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/8355671c9cafd876.js:1:1]
1 | 1 / %
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `.`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/842c5cb4a70228de.js:1:1]
1 | new f(..g);
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `]`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/85bb33accf520f1d.js:1:1]
1 | //
2 | ]
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `:`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/85ee036d67974729.js:1:1]
1 | ({get +:3})
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `;`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/8dc7370bc6dec92b.js:1:1]
1 | throw;
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `]`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/8f7c7b7f4d70f975.js:1:1]
1 |
2 | ]
Expand Down
@@ -1,11 +1,4 @@

x Unexpected token `<eof>`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp,
| ` for template literal, (, or an identifier
,-[$DIR/tests/test262-parser/fail/983987033f0e1170.js:1:1]
1 | **
: ^^
`----

x Expression expected
,-[$DIR/tests/test262-parser/fail/983987033f0e1170.js:1:1]
1 | **
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `.`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/9fc6ddfbb0f1cbe3.js:1:1]
1 | f(....a)
: ^
Expand Down
@@ -1,7 +1,7 @@

x Unexpected token `...`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/9fdb9877fcc446e2.js:1:1]
1 | if (b,...a, );
: ^^^
: ^| ^^^
: `-- Tried to parse the condition for an if statement
`----
@@ -1,6 +1,5 @@

x Unexpected token `.`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/a3710b36f9b97324.js:1:1]
1 | f(....g);
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `;`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/ac4ee5fb095faad0.js:1:1]
1 | for (let x, y, z, let = 1;;;) {}
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `;`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/b02b296bd115b9b9.js:1:1]
1 | for (const x = 1, y = 2, z = 3, let = 0;;;) {}
: ^
Expand Down
@@ -1,6 +1,5 @@

x Unexpected token `]`. Expected this, import, async, function, [ for array literal, { for object literal, @ for decorator, function, class, null, true, false, number, bigint, string, regexp, `
| for template literal, (, or an identifier
x Expression expected
,-[$DIR/tests/test262-parser/fail/b7ae8c17f892abf6.js:1:1]
1 | //
2 | ]
Expand Down