Skip to content

Commit

Permalink
fix(es/parser): Allow parentheses in assignment target (#4105)
Browse files Browse the repository at this point in the history
  • Loading branch information
hanneslund committed Mar 20, 2022
1 parent ea0bbc6 commit d38117d
Show file tree
Hide file tree
Showing 13 changed files with 151 additions and 9 deletions.
5 changes: 5 additions & 0 deletions crates/swc/tests/fixture/issue-2834/input/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"jsc": {
"target": "es2022"
}
}
9 changes: 9 additions & 0 deletions crates/swc/tests/fixture/issue-2834/input/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[(a)] = arr;
[((a.b))] = arr;
[...(a.b)] = arr;
({ a: (b) } = obj);
({ a: (b.c) } = obj);
({ ...((a["b"])) } = obj);
for ([(a)] of arr) {}
for ([{ a: ((b)) }] of arr) {}
for ([{ ...((a.b)) }] of arr) {}
9 changes: 9 additions & 0 deletions crates/swc/tests/fixture/issue-2834/output/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[a] = arr;
[a.b] = arr;
[...a.b] = arr;
({ a: b } = obj);
({ a: b.c } = obj);
({ ...a["b"] } = obj);
for ([a] of arr){}
for ([{ a: b }] of arr){}
for ([{ ...a.b }] of arr){}
4 changes: 2 additions & 2 deletions crates/swc_ecma_parser/src/parser/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,7 @@ impl<'a, I: Tokens> Parser<I> {
| Expr::Ident(..)
| Expr::Fn(..)
| Expr::Class(..)
| Expr::Paren(..)
| Expr::Tpl(..) => {
if !expr.is_valid_simple_assignment_target(self.ctx().strict) {
self.emit_err(span, SyntaxError::NotSimpleAssign)
Expand Down Expand Up @@ -651,9 +652,8 @@ impl<'a, I: Tokens> Parser<I> {
Ok(ObjectPatProp::Rest(RestPat {
span,
dot3_token,
// FIXME: is BindingPat correct?
arg: Box::new(
self.reparse_expr_as_pat(PatType::BindingPat, expr)?,
self.reparse_expr_as_pat(pat_ty.element(), expr)?,
),
type_ann: None,
}))
Expand Down
80 changes: 80 additions & 0 deletions crates/swc_ecma_parser/tests/pat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use std::{
fs::read_to_string,
path::{Path, PathBuf},
};

use pretty_assertions::assert_eq;
use swc_common::{errors::Handler, sync::Lrc, SourceMap};
use swc_ecma_ast::*;
use swc_ecma_parser::{lexer::Lexer, PResult, Parser, StringInput};
use swc_ecma_visit::{Fold, FoldWith};
use testing::{run_test, StdErr};

fn parse_module(cm: Lrc<SourceMap>, handler: &Handler, file_name: &Path) -> Result<Module, ()> {
with_parser(cm, handler, file_name, |p| p.parse_module())
}

fn with_parser<F, Ret>(
cm: Lrc<SourceMap>,
handler: &Handler,
file_name: &Path,
f: F,
) -> Result<Ret, ()>
where
F: FnOnce(&mut Parser<Lexer<StringInput<'_>>>) -> PResult<Ret>,
{
let fm = cm
.load_file(file_name)
.unwrap_or_else(|e| panic!("failed to load {}: {}", file_name.display(), e));

let mut p = Parser::new(
::swc_ecma_parser::Syntax::Es(::swc_ecma_parser::EsConfig {
jsx: true,
..Default::default()
}),
(&*fm).into(),
None,
);

let res = f(&mut p).map_err(|e| e.into_diagnostic(handler).emit());

for e in p.take_errors() {
e.into_diagnostic(handler).emit();
}

res
}

#[cfg(feature = "verify")]
#[testing::fixture("tests/pat/errors/**/*.js")]
fn error(entry: PathBuf) {
let input = read_to_string(&entry).unwrap();

eprintln!(
"\n\n========== Running error reporting test \nSource:\n{}\n",
input
);

let err = run_test(false, |cm, handler| {
if false {
// Type annotation
return Ok(());
}

// Parse source
let _ = parse_module(cm, handler, &entry);
if !handler.has_errors() {
panic!("should emit error, but parsed without error")
}

Err(())
})
.expect_err("should fail, but parsed as");

if err
.compare_to_file(format!("{}.stderr", entry.display()))
.is_err()
{
panic!()
}
}
3 changes: 3 additions & 0 deletions crates/swc_ecma_parser/tests/pat/errors/issue-2834/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
([(a)]) => {};
({ a: (b) }) => {};
for (const [(a)] of arr) {}
18 changes: 18 additions & 0 deletions crates/swc_ecma_parser/tests/pat/errors/issue-2834/input.js.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

x Unexpected token `(`. Expected yield, an identifier, [ or {
,-[$DIR/tests/pat/errors/issue-2834/input.js:3:1]
3 | for (const [(a)] of arr) {}
: ^
`----

x Not a pattern
,-[$DIR/tests/pat/errors/issue-2834/input.js:1:1]
1 | ([(a)]) => {};
: ^^^
`----

x Not a pattern
,-[$DIR/tests/pat/errors/issue-2834/input.js:2:1]
2 | ({ a: (b) }) => {};
: ^^^
`----
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

x Not a pattern
x Cannot assign to this
,-[$DIR/tests/test262-parser/fail/50a060984b757dc1.js:1:1]
1 | ({a:(b = 0)} = 1)
: ^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

x Not a pattern
x Cannot assign to this
,-[$DIR/tests/test262-parser/fail/8bf8438d0a686b4e.js:1:1]
1 | [a, ...(b = c)] = 0
: ^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

x Not a pattern
x Cannot assign to this
,-[$DIR/tests/test262-parser/fail/90cd97db35a1a503.js:1:1]
1 | ({a: (b = 0)} = {})
: ^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

x Not a pattern
x Cannot assign to this
,-[$DIR/tests/test262-parser/fail/db41a80ccf646002.js:1:1]
1 | [(a = 0)] = 1
: ^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
: ^
`----

x Not a pattern
x Cannot assign to this
,-[$DIR/tests/test262-parser/fail/e4963d9605864d9a.js:1:1]
1 | ([(a = b)] = []
: ^^^^^^^
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,20 @@
"ctxt": 0
},
"argument": {
"type": "Invalid",
"type": "ParenthesisExpression",
"span": {
"start": 21,
"end": 25,
"ctxt": 0
},
"expression": {
"type": "ObjectExpression",
"span": {
"start": 22,
"end": 24,
"ctxt": 0
},
"properties": []
}
},
"typeAnnotation": null
Expand Down Expand Up @@ -259,11 +268,20 @@
"ctxt": 0
},
"argument": {
"type": "Invalid",
"type": "ParenthesisExpression",
"span": {
"start": 55,
"end": 59,
"ctxt": 0
},
"expression": {
"type": "ArrayExpression",
"span": {
"start": 56,
"end": 58,
"ctxt": 0
},
"elements": []
}
},
"typeAnnotation": null
Expand Down

1 comment on commit d38117d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: d38117d Previous: ea0bbc6 Ratio
base_tr_fixer 26126 ns/iter (± 3350) 23207 ns/iter (± 299) 1.13
base_tr_resolver_and_hygiene 115214 ns/iter (± 18234) 94487 ns/iter (± 11592) 1.22
codegen_es2015 39496 ns/iter (± 3575) 31472 ns/iter (± 191) 1.25
codegen_es2016 39304 ns/iter (± 5198) 31405 ns/iter (± 196) 1.25
codegen_es2017 39179 ns/iter (± 5381) 31467 ns/iter (± 294) 1.25
codegen_es2018 42080 ns/iter (± 10380) 31473 ns/iter (± 261) 1.34
codegen_es2019 39653 ns/iter (± 5583) 31384 ns/iter (± 259) 1.26
codegen_es2020 40172 ns/iter (± 19081) 31383 ns/iter (± 375) 1.28
codegen_es3 39237 ns/iter (± 6236) 31390 ns/iter (± 222) 1.25
codegen_es5 40024 ns/iter (± 6673) 31087 ns/iter (± 220) 1.29
full_es2015 148533232 ns/iter (± 16827183) 136758030 ns/iter (± 9393134) 1.09
full_es2016 146747980 ns/iter (± 10815390) 137452850 ns/iter (± 5722455) 1.07
full_es2017 145798958 ns/iter (± 9674348) 136239821 ns/iter (± 4014273) 1.07
full_es2018 146240470 ns/iter (± 13220375) 135806395 ns/iter (± 3719017) 1.08
full_es2019 145818288 ns/iter (± 11052593) 135254968 ns/iter (± 6384204) 1.08
full_es2020 141462548 ns/iter (± 12077592) 119616587 ns/iter (± 5152778) 1.18
full_es3 198699128 ns/iter (± 14367156) 182558545 ns/iter (± 4840954) 1.09
full_es5 187169955 ns/iter (± 11954526) 172182159 ns/iter (± 5009753) 1.09
parser 679304 ns/iter (± 77478) 561504 ns/iter (± 16966) 1.21
ser_ast_node 168 ns/iter (± 34) 145 ns/iter (± 3) 1.16
ser_serde 160 ns/iter (± 30) 145 ns/iter (± 1) 1.10
emit_colors 9983790 ns/iter (± 7144257) 10296979 ns/iter (± 7217621) 0.97
emit_large 51811345 ns/iter (± 73335268) 73967040 ns/iter (± 98003732) 0.70
base_clone 2390972 ns/iter (± 233781) 2438662 ns/iter (± 45588) 0.98
fold_span 4157198 ns/iter (± 776055) 3913050 ns/iter (± 90864) 1.06
fold_span_panic 4212423 ns/iter (± 480947) 4090707 ns/iter (± 116681) 1.03
visit_mut_span 2883840 ns/iter (± 343196) 2838250 ns/iter (± 38430) 1.02
visit_mut_span_panic 2879157 ns/iter (± 312530) 2876340 ns/iter (± 44413) 1.00
usage_builtin_type 17219778 ns/iter (± 11008630) 15916786 ns/iter (± 9897875) 1.08
usage_property 428516 ns/iter (± 42259) 398699 ns/iter (± 1175) 1.07
boxing_boxed 141 ns/iter (± 10) 134 ns/iter (± 0) 1.05
boxing_boxed_clone 78 ns/iter (± 11) 70 ns/iter (± 0) 1.11
boxing_unboxed 134 ns/iter (± 24) 120 ns/iter (± 0) 1.12
boxing_unboxed_clone 67 ns/iter (± 7) 69 ns/iter (± 0) 0.97
time_10 322 ns/iter (± 27) 306 ns/iter (± 8) 1.05
time_15 715 ns/iter (± 128) 695 ns/iter (± 6) 1.03
time_20 1312 ns/iter (± 144) 1391 ns/iter (± 10) 0.94
time_40 4721 ns/iter (± 550) 7040 ns/iter (± 22) 0.67
time_5 109 ns/iter (± 10) 117 ns/iter (± 23) 0.93
time_60 9953 ns/iter (± 1314) 16321 ns/iter (± 43) 0.61
total 0 ns/iter (± 0) 0 ns/iter (± 0) NaN

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.