fix(es/parser): Fix parsing of static blocks (#2200)

swc_ecma_parser:
 - Fix parsing of static blocks with line breaks. (#2195)
This commit is contained in:
Sosuke Suzuki 2021-09-03 14:57:23 +09:00 committed by GitHub
parent 87f30b21a3
commit cbc8230310
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 437 additions and 19 deletions

2
Cargo.lock generated
View File

@ -2661,7 +2661,7 @@ dependencies = [
[[package]]
name = "swc_ecma_parser"
version = "0.70.0"
version = "0.70.1"
dependencies = [
"either",
"enum_kind",

View File

@ -7,7 +7,7 @@ include = ["Cargo.toml", "src/**/*.rs", "examples/**/*.rs"]
license = "Apache-2.0/MIT"
name = "swc_ecma_parser"
repository = "https://github.com/swc-project/swc.git"
version = "0.70.0"
version = "0.70.1"
[package.metadata.docs.rs]
all-features = true

View File

@ -404,23 +404,30 @@ impl<'a, I: Tokens> Parser<I> {
} else if self.is_class_property()? {
// Property named `static`
let key = Either::Right(PropName::Ident(Ident::new(
js_word!("static"),
static_token,
)));
let is_optional = self.input.syntax().typescript() && eat!(self, '?');
return self.make_property(
start,
decorators,
accessibility,
key,
false,
is_optional,
false,
declare,
false,
false,
);
// Avoid to parse
// static
// {}
let is_parsing_static_blocks =
self.input.syntax().static_blocks() && is!(self, '{');
if !is_parsing_static_blocks {
let key = Either::Right(PropName::Ident(Ident::new(
js_word!("static"),
static_token,
)));
let is_optional = self.input.syntax().typescript() && eat!(self, '?');
return self.make_property(
start,
decorators,
accessibility,
key,
false,
is_optional,
false,
declare,
false,
false,
);
}
} else {
// TODO: error if static contains escape
}

View File

@ -1976,6 +1976,90 @@ export default function waitUntil(callback, options = {}) {
);
}
#[test]
fn class_static_blocks_with_line_breaks_01() {
let src = "class Foo {
static
{
1 + 1;
}
}";
assert_eq_ignore_span!(
test_parser(
src,
Syntax::Es(EsConfig {
static_blocks: true,
..Default::default()
}),
|p| p.parse_expr()
),
Box::new(Expr::Class(ClassExpr {
ident: Some(Ident {
span,
sym: "Foo".into(),
optional: false,
}),
class: Class {
span,
decorators: Vec::new(),
super_class: None,
type_params: None,
super_type_params: None,
is_abstract: false,
implements: Vec::new(),
body: vec!(ClassMember::StaticBlock(StaticBlock {
span,
body: BlockStmt {
span,
stmts: vec!(stmt("1 + 1;")),
}
}))
}
}))
);
}
#[test]
fn class_static_blocks_with_line_breaks_02() {
let src = "class Foo {
static
{}
}";
assert_eq_ignore_span!(
test_parser(
src,
Syntax::Es(EsConfig {
static_blocks: true,
..Default::default()
}),
|p| p.parse_expr()
),
Box::new(Expr::Class(ClassExpr {
ident: Some(Ident {
span,
sym: "Foo".into(),
optional: false,
}),
class: Class {
span,
decorators: Vec::new(),
super_class: None,
type_params: None,
super_type_params: None,
is_abstract: false,
implements: Vec::new(),
body: vec!(ClassMember::StaticBlock(StaticBlock {
span,
body: BlockStmt {
span,
stmts: Vec::new(),
}
}))
}
}))
);
}
#[test]
fn class_static_blocks_in_ts() {
let src = "class Foo { static { 1 + 1 }; }";
@ -1984,6 +2068,30 @@ export default function waitUntil(callback, options = {}) {
});
}
#[test]
fn class_static_blocks_with_line_breaks_in_ts_01() {
let src = "class Foo {
static
{
1 + 1;
}
}";
test_parser(src, Syntax::Typescript(Default::default()), |p| {
p.parse_expr()
});
}
#[test]
fn class_static_blocks_with_line_breaks_in_ts_02() {
let src = "class Foo {
static
{}
}";
test_parser(src, Syntax::Typescript(Default::default()), |p| {
p.parse_expr()
});
}
#[test]
#[should_panic(expected = "Modifiers cannot appear here")]
fn class_static_blocks_in_ts_with_invalid_modifier_01() {

View File

@ -0,0 +1,6 @@
class Foo {
static
{
1 + 1;
}
}

View File

@ -0,0 +1,149 @@
warning: Module
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:1:1
|
1 | / class Foo {
2 | | static
3 | | {
4 | | 1 + 1;
5 | | }
6 | | }
| |_^
warning: ModuleItem
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:1:1
|
1 | / class Foo {
2 | | static
3 | | {
4 | | 1 + 1;
5 | | }
6 | | }
| |_^
warning: Stmt
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:1:1
|
1 | / class Foo {
2 | | static
3 | | {
4 | | 1 + 1;
5 | | }
6 | | }
| |_^
warning: Decl
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:1:1
|
1 | / class Foo {
2 | | static
3 | | {
4 | | 1 + 1;
5 | | }
6 | | }
| |_^
warning: ClassDecl
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:1:1
|
1 | / class Foo {
2 | | static
3 | | {
4 | | 1 + 1;
5 | | }
6 | | }
| |_^
warning: Ident
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:1:7
|
1 | class Foo {
| ^^^
warning: Class
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:1:1
|
1 | / class Foo {
2 | | static
3 | | {
4 | | 1 + 1;
5 | | }
6 | | }
| |_^
warning: ClassMember
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:2:5
|
2 | / static
3 | | {
4 | | 1 + 1;
5 | | }
| |_____^
warning: BlockStmt
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:3:5
|
3 | / {
4 | | 1 + 1;
5 | | }
| |_____^
warning: Stmt
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:9
|
4 | 1 + 1;
| ^^^^^^
warning: ExprStmt
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:9
|
4 | 1 + 1;
| ^^^^^^
warning: Expr
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:9
|
4 | 1 + 1;
| ^^^^^
warning: BinExpr
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:9
|
4 | 1 + 1;
| ^^^^^
warning: Expr
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:9
|
4 | 1 + 1;
| ^
warning: Lit
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:9
|
4 | 1 + 1;
| ^
warning: Number
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:9
|
4 | 1 + 1;
| ^
warning: Expr
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:13
|
4 | 1 + 1;
| ^
warning: Lit
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:13
|
4 | 1 + 1;
| ^
warning: Number
--> $DIR/tests/span/js/decl/static-blocks-with-line-breaks.js:4:13
|
4 | 1 + 1;
| ^

View File

@ -0,0 +1,5 @@
class Foo {
static {
1 + 1;
}
}

View File

@ -0,0 +1,143 @@
warning: Module
--> $DIR/tests/span/js/decl/static-blocks.js:1:1
|
1 | / class Foo {
2 | | static {
3 | | 1 + 1;
4 | | }
5 | | }
| |_^
warning: ModuleItem
--> $DIR/tests/span/js/decl/static-blocks.js:1:1
|
1 | / class Foo {
2 | | static {
3 | | 1 + 1;
4 | | }
5 | | }
| |_^
warning: Stmt
--> $DIR/tests/span/js/decl/static-blocks.js:1:1
|
1 | / class Foo {
2 | | static {
3 | | 1 + 1;
4 | | }
5 | | }
| |_^
warning: Decl
--> $DIR/tests/span/js/decl/static-blocks.js:1:1
|
1 | / class Foo {
2 | | static {
3 | | 1 + 1;
4 | | }
5 | | }
| |_^
warning: ClassDecl
--> $DIR/tests/span/js/decl/static-blocks.js:1:1
|
1 | / class Foo {
2 | | static {
3 | | 1 + 1;
4 | | }
5 | | }
| |_^
warning: Ident
--> $DIR/tests/span/js/decl/static-blocks.js:1:7
|
1 | class Foo {
| ^^^
warning: Class
--> $DIR/tests/span/js/decl/static-blocks.js:1:1
|
1 | / class Foo {
2 | | static {
3 | | 1 + 1;
4 | | }
5 | | }
| |_^
warning: ClassMember
--> $DIR/tests/span/js/decl/static-blocks.js:2:5
|
2 | / static {
3 | | 1 + 1;
4 | | }
| |_____^
warning: BlockStmt
--> $DIR/tests/span/js/decl/static-blocks.js:2:12
|
2 | static {
| ____________^
3 | | 1 + 1;
4 | | }
| |_____^
warning: Stmt
--> $DIR/tests/span/js/decl/static-blocks.js:3:9
|
3 | 1 + 1;
| ^^^^^^
warning: ExprStmt
--> $DIR/tests/span/js/decl/static-blocks.js:3:9
|
3 | 1 + 1;
| ^^^^^^
warning: Expr
--> $DIR/tests/span/js/decl/static-blocks.js:3:9
|
3 | 1 + 1;
| ^^^^^
warning: BinExpr
--> $DIR/tests/span/js/decl/static-blocks.js:3:9
|
3 | 1 + 1;
| ^^^^^
warning: Expr
--> $DIR/tests/span/js/decl/static-blocks.js:3:9
|
3 | 1 + 1;
| ^
warning: Lit
--> $DIR/tests/span/js/decl/static-blocks.js:3:9
|
3 | 1 + 1;
| ^
warning: Number
--> $DIR/tests/span/js/decl/static-blocks.js:3:9
|
3 | 1 + 1;
| ^
warning: Expr
--> $DIR/tests/span/js/decl/static-blocks.js:3:13
|
3 | 1 + 1;
| ^
warning: Lit
--> $DIR/tests/span/js/decl/static-blocks.js:3:13
|
3 | 1 + 1;
| ^
warning: Number
--> $DIR/tests/span/js/decl/static-blocks.js:3:13
|
3 | 1 + 1;
| ^