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

Improve error messages #980

Merged
merged 29 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
da9e114
#[inline(never)]
kdy1 Aug 21, 2020
d608b18
Replace unexpected with detailed error
kdy1 Aug 21, 2020
e003a8d
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
ee00ffc
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
5beb4b0
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
b5866ec
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
fd01ced
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
94bcc69
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
60645f5
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
3d498e1
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
400a817
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
4ca3a34
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
f568054
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
cf7391f
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
01a7f44
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
ae66f11
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
c664754
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
b536c6b
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
72dcdf5
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
fec072d
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
be5a680
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
5a7b6b5
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
a00aa4c
fixup! Replace unexpected with detailed error
kdy1 Aug 21, 2020
56bc92f
Fix
kdy1 Aug 21, 2020
a54fcdf
Update test refs
kdy1 Aug 21, 2020
7e58078
Better debug for Token
kdy1 Aug 21, 2020
a9ae9a2
Improve unexpected~
kdy1 Aug 21, 2020
1e53d8f
typo
kdy1 Aug 21, 2020
fb98fcb
Improve error message
kdy1 Aug 21, 2020
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
2 changes: 1 addition & 1 deletion ecmascript/parser/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "swc_ecma_parser"
version = "0.34.0"
version = "0.34.1"
authors = ["강동윤 <[email protected]>"]
license = "Apache-2.0/MIT"
repository = "https://github.com/swc-project/swc.git"
Expand Down
375 changes: 266 additions & 109 deletions ecmascript/parser/src/error.rs

Large diffs are not rendered by default.

11 changes: 6 additions & 5 deletions ecmascript/parser/src/parser/class_and_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ impl<'a, I: Tokens> Parser<I> {

if is!("export") {
if !allow_export {
unexpected!();
syntax_error!(self.input.cur_span(), SyntaxError::ExportNotAllowed);
}

if !self.syntax().decorators_before_export() {
Expand Down Expand Up @@ -454,11 +454,12 @@ impl<'a, I: Tokens> Parser<I> {
// generator method
let key = self.parse_class_prop_name()?;
if readonly {
syntax_error!(span!(start), SyntaxError::ReadOnlyMethod);
self.emit_err(span!(start), SyntaxError::ReadOnlyMethod);
}
if is_constructor(&key) {
unexpected!();
self.emit_err(span!(start), SyntaxError::GeneratorConstructor);
}

return self.make_method(
|p| p.parse_unique_formal_params(),
MakeMethodArgs {
Expand Down Expand Up @@ -656,7 +657,7 @@ impl<'a, I: Tokens> Parser<I> {
let key = self.parse_class_prop_name()?;

if readonly {
unexpected!()
self.emit_err(key_span, SyntaxError::GetterSetterCannotBeReadonly);
}

return match i.sym {
Expand Down Expand Up @@ -718,7 +719,7 @@ impl<'a, I: Tokens> Parser<I> {
_ => {}
}

unexpected!()
unexpected!("* for generator, private key, identifier or async")
}

fn make_property(
Expand Down
29 changes: 19 additions & 10 deletions ecmascript/parser/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl<'a, I: Tokens> Parser<I> {
}) => {
*type_params = Some(type_parameters);
}
_ => unexpected!(),
_ => unexpected!("("),
}
Ok(Some(arrow))
});
Expand Down Expand Up @@ -374,7 +374,11 @@ impl<'a, I: Tokens> Parser<I> {
}
}

unexpected!()
unexpected!(
"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"
)
}

fn parse_array_lit(&mut self) -> PResult<Box<Expr>> {
Expand Down Expand Up @@ -422,7 +426,7 @@ impl<'a, I: Tokens> Parser<I> {
let prop = if is!("meta") {
self.parse_ident_name()?
} else {
unexpected!();
unexpected!("meta");
};

Ok(MetaPropExpr { meta, prop })
Expand All @@ -446,7 +450,7 @@ impl<'a, I: Tokens> Parser<I> {
return self.parse_subscripts(ExprOrSuper::Expr(expr), true);
}

unexpected!()
unexpected!("target")
}

// 'NewExpression' allows new call without paren.
Expand All @@ -457,7 +461,8 @@ impl<'a, I: Tokens> Parser<I> {
self.try_parse_ts(|p| {
let args = p.parse_ts_type_args()?;
if !is!('(') {
unexpected!()
// This will fail
expect!('(');
}
Ok(Some(args))
})
Expand Down Expand Up @@ -626,7 +631,7 @@ impl<'a, I: Tokens> Parser<I> {
syntax_error!(span!(expr_start), SyntaxError::LineBreakBeforeArrow);
}
if !can_be_arrow {
unexpected!()
syntax_error!(span!(expr_start), SyntaxError::ArrowNotAllowed);
}
expect!("=>");

Expand Down Expand Up @@ -834,7 +839,7 @@ impl<'a, I: Tokens> Parser<I> {
),
_ => unreachable!(),
},
_ => unexpected!(),
_ => unexpected!("template token"),
};
let tail = is!('`');
Ok(TplElement {
Expand Down Expand Up @@ -934,7 +939,11 @@ impl<'a, I: Tokens> Parser<I> {
.map(|expr| (Box::new(Expr::TaggedTpl(expr)), true))
.map(Some)
} else {
unexpected!()
if no_call {
unexpected!("`")
} else {
unexpected!("( or `")
}
}
});
if let Some(result) = result {
Expand Down Expand Up @@ -1037,9 +1046,9 @@ impl<'a, I: Tokens> Parser<I> {
}
ExprOrSuper::Super(..) => {
if no_call {
unexpected!()
syntax_error!(self.input.cur_span(), SyntaxError::InvalidSuperCall);
}
unexpected!()
syntax_error!(self.input.cur_span(), SyntaxError::InvalidSuper);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions ecmascript/parser/src/parser/jsx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl<'a, I: Tokens> Parser<I> {
_ => unreachable!(),
},
_ if ctx.in_forced_jsx_context => self.parse_ident_ref(),
_ => unexpected!(),
_ => unexpected!("jsx identifier"),
}
}

Expand Down Expand Up @@ -216,7 +216,7 @@ impl<'a, I: Tokens> Parser<I> {
}
let self_closing = eat!('/');
if !eat!(JSXTagEnd) & !(self.ctx().in_forced_jsx_context && eat!('>')) {
unexpected!()
unexpected!("> (jsx closing tag)");
}
Ok(JSXOpeningElement {
span: span!(start),
Expand Down Expand Up @@ -314,7 +314,7 @@ impl<'a, I: Tokens> Parser<I> {
);
}
}
_ => unexpected!(),
_ => unexpected!("< (jsx tag start), jsx text or {"),
}
}
}
Expand Down
16 changes: 13 additions & 3 deletions ecmascript/parser/src/parser/macros.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
macro_rules! unexpected {
($p:expr) => {{
let got = format!("{:?}", cur!($p, false).ok());
syntax_error!($p, $p.input.cur_span(), SyntaxError::Unexpected { got })
($p:expr, $expected:literal) => {{
let got = match cur!($p, false).ok() {
Some(v) => format!("{:?}", v),
None => format!("<eof>"),
};
syntax_error!(
$p,
$p.input.cur_span(),
SyntaxError::Unexpected {
got,
expected: $expected
}
)
}};
}

Expand Down
4 changes: 4 additions & 0 deletions ecmascript/parser/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ impl<I: Tokens> Parser<I> {
self.input.get_ctx()
}

#[cold]
#[inline(never)]
fn emit_err(&self, span: Span, error: SyntaxError) {
if !self.emit_err || !self.syntax().early_errors() {
return;
Expand All @@ -163,6 +165,8 @@ impl<I: Tokens> Parser<I> {
})
}

#[cold]
#[inline(never)]
fn emit_error(&self, error: Error) {
if !self.emit_err || !self.syntax().early_errors() {
return;
Expand Down
20 changes: 16 additions & 4 deletions ecmascript/parser/src/parser/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,9 @@ impl<'a, I: Tokens> Parser<I> {
expr,
})
}
_ => unexpected!(),
_ => unexpected!(
"identifier, string literal, numeric literal or [ for the computed key"
),
};

Ok(v)
Expand Down Expand Up @@ -198,7 +200,8 @@ impl<I: Tokens> ParseObject<Box<Expr>> for Parser<I> {

let ident = match key {
PropName::Ident(ident) => ident,
_ => unexpected!(),
// TODO
_ => unexpected!("identifier"),
};

if eat!('?') {
Expand Down Expand Up @@ -347,7 +350,16 @@ impl<I: Tokens> ParseObject<Box<Expr>> for Parser<I> {
_ => unreachable!(),
}
}
_ => unexpected!(),
_ => {
if self.input.syntax().typescript() {
unexpected!(
"... , *, (, [, :, , ?, =, an identifier, public, protected, private, \
readonly, <."
)
} else {
unexpected!("... , *, (, [, :, , ?, = or an identifier")
}
}
}
}
}
Expand Down Expand Up @@ -412,7 +424,7 @@ impl<I: Tokens> ParseObject<Pat> for Parser<I> {
}
let key = match key {
PropName::Ident(ident) => ident,
_ => unexpected!(),
_ => unexpected!("an identifier"),
};

let value = if eat!('=') {
Expand Down
2 changes: 1 addition & 1 deletion ecmascript/parser/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ impl<'a, I: Tokens> Parser<I> {
// expect!(')');
// Ok(pat)
// }
_ => unexpected!(),
_ => unexpected!("yield, an identifier, [ or {"),
}
}

Expand Down
4 changes: 2 additions & 2 deletions ecmascript/parser/src/parser/stmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,15 @@ impl<'a, I: Tokens> Parser<I> {

if is!("function") {
if !include_decl {
unexpected!()
self.emit_err(self.input.cur_span(), SyntaxError::DeclNotAllowed);
}

return self.parse_fn_decl(decorators).map(Stmt::from);
}

if is!("class") {
if !include_decl {
unexpected!()
self.emit_err(self.input.cur_span(), SyntaxError::DeclNotAllowed);
}
return self
.parse_class_decl(start, start, decorators)
Expand Down
4 changes: 2 additions & 2 deletions ecmascript/parser/src/parser/stmt/module_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ impl<'a, I: Tokens> Parser<I> {
imported: None,
}))
}
_ => unexpected!(),
_ => unexpected!("an identifier"),
}
}

Expand Down Expand Up @@ -503,7 +503,7 @@ impl<'a, I: Tokens> Parser<I> {
},
_ => unreachable!(),
},
_ => unexpected!(),
_ => unexpected!("a string literal"),
};
expect!(';');
Ok(src)
Expand Down
Loading