From 6c492796d03b484dbeee7db46b2b1f37aba4a37a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Sun, 20 Jun 2021 23:17:40 +0900 Subject: [PATCH] fix(es/parser): Fix parsing of abstract class over multiple lines (#1837) swc_ecma_parser: - Don't allow `abstract` and `class` to be on different lines. --- ecmascript/parser/Cargo.toml | 2 +- .../parser/src/parser/stmt/module_item.rs | 5 ++- ecmascript/parser/src/parser/typescript.rs | 2 +- .../classAbstractSingleLineDecl/input.ts.json | 44 +++++++++++++++++-- 4 files changed, 46 insertions(+), 7 deletions(-) diff --git a/ecmascript/parser/Cargo.toml b/ecmascript/parser/Cargo.toml index 020856288722..7e1ed0dbd7ce 100644 --- a/ecmascript/parser/Cargo.toml +++ b/ecmascript/parser/Cargo.toml @@ -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.60.0" +version = "0.60.1" [features] default = [] diff --git a/ecmascript/parser/src/parser/stmt/module_item.rs b/ecmascript/parser/src/parser/stmt/module_item.rs index 3e3e7150e55f..a26f17f05dab 100644 --- a/ecmascript/parser/src/parser/stmt/module_item.rs +++ b/ecmascript/parser/src/parser/stmt/module_item.rs @@ -339,7 +339,10 @@ impl<'a, I: Tokens> Parser { if !type_only && export_ns.is_none() && eat!(self, "default") { if self.input.syntax().typescript() { - if is!(self, "abstract") && peeked_is!(self, "class") { + if is!(self, "abstract") + && peeked_is!(self, "class") + && !self.input.has_linebreak_between_cur_and_peeked() + { let class_start = cur_pos!(self); assert_and_bump!(self, "abstract"); let _ = cur!(self, true); diff --git a/ecmascript/parser/src/parser/typescript.rs b/ecmascript/parser/src/parser/typescript.rs index 64422e52bc5f..b8ec25687ee7 100644 --- a/ecmascript/parser/src/parser/typescript.rs +++ b/ecmascript/parser/src/parser/typescript.rs @@ -2304,7 +2304,7 @@ impl Parser { ) -> PResult> { match value { js_word!("abstract") => { - if next || is!(self, "class") { + if next || (is!(self, "class") && !self.input.had_line_break_before_cur()) { if next { bump!(self); } diff --git a/ecmascript/parser/tests/typescript/tsc/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl/input.ts.json b/ecmascript/parser/tests/typescript/tsc/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl/input.ts.json index ec60b02c8968..92821490570e 100644 --- a/ecmascript/parser/tests/typescript/tsc/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl/input.ts.json +++ b/ecmascript/parser/tests/typescript/tsc/classes/classDeclarations/classAbstractKeyword/classAbstractSingleLineDecl/input.ts.json @@ -32,6 +32,24 @@ "superTypeParams": null, "implements": [] }, + { + "type": "ExpressionStatement", + "span": { + "start": 21, + "end": 29, + "ctxt": 0 + }, + "expression": { + "type": "Identifier", + "span": { + "start": 21, + "end": 29, + "ctxt": 0 + }, + "value": "abstract", + "optional": false + } + }, { "type": "ClassDeclaration", "identifier": { @@ -46,18 +64,36 @@ }, "declare": false, "span": { - "start": 21, + "start": 30, "end": 40, "ctxt": 0 }, "decorators": [], "body": [], "superClass": null, - "isAbstract": true, + "isAbstract": false, "typeParams": null, "superTypeParams": null, "implements": [] }, + { + "type": "ExpressionStatement", + "span": { + "start": 42, + "end": 50, + "ctxt": 0 + }, + "expression": { + "type": "Identifier", + "span": { + "start": 42, + "end": 50, + "ctxt": 0 + }, + "value": "abstract", + "optional": false + } + }, { "type": "ClassDeclaration", "identifier": { @@ -72,14 +108,14 @@ }, "declare": false, "span": { - "start": 42, + "start": 52, "end": 62, "ctxt": 0 }, "decorators": [], "body": [], "superClass": null, - "isAbstract": true, + "isAbstract": false, "typeParams": null, "superTypeParams": null, "implements": []