diff --git a/crates/swc_ecma_parser/src/lexer/state.rs b/crates/swc_ecma_parser/src/lexer/state.rs index 58cebcf42e49..3f588eda7686 100644 --- a/crates/swc_ecma_parser/src/lexer/state.rs +++ b/crates/swc_ecma_parser/src/lexer/state.rs @@ -25,6 +25,8 @@ pub(super) struct State { pub next_regexp: Option, /// if line break exists between previous token and new token? pub had_line_break: bool, + /// if line break exists before last? + pub had_line_break_before_last: bool, /// TODO: Remove this field. is_first: bool, pub start: BytePos, @@ -352,8 +354,10 @@ impl<'a, I: Input> Iterator for Lexer<'a, I> { }); } } + self.state.update(start, token); self.state.prev_hi = self.last_pos(); + self.state.had_line_break_before_last = self.had_line_break_before_last(); } token.map(|token| { @@ -376,6 +380,7 @@ impl State { next_regexp: None, is_first: true, had_line_break: false, + had_line_break_before_last: false, prev_hi: start_pos, context, token_type: None, @@ -438,6 +443,7 @@ impl State { start, next, self.had_line_break, + self.had_line_break_before_last, self.is_expr_allowed, ); } @@ -451,6 +457,7 @@ impl State { start: BytePos, next: &Token, had_line_break: bool, + had_line_break_before_last: bool, is_expr_allowed: bool, ) -> bool { let is_next_keyword = matches!(*next, Word(Word::Keyword(..))); @@ -544,7 +551,7 @@ impl State { TokenType::Keyword(Let) | TokenType::Keyword(Const) | TokenType::Keyword(Var) - if had_line_break => + if had_line_break_before_last => { true } diff --git a/crates/swc_ecma_parser/tests/jsx/basic/issue-6522/input.js b/crates/swc_ecma_parser/tests/jsx/basic/issue-6522/input.js new file mode 100644 index 000000000000..eb1a46e813fe --- /dev/null +++ b/crates/swc_ecma_parser/tests/jsx/basic/issue-6522/input.js @@ -0,0 +1,32 @@ +let x + + +let x + + + +let x; + + +var x + + +var x; + + +function x() { + let x +
+} + +{ foo: 'test' } + + +function test1() {} + + +class Foo {} +<> + + + diff --git a/crates/swc_ecma_parser/tests/jsx/basic/issue-6522/input.js.json b/crates/swc_ecma_parser/tests/jsx/basic/issue-6522/input.js.json new file mode 100644 index 000000000000..7123568906c6 --- /dev/null +++ b/crates/swc_ecma_parser/tests/jsx/basic/issue-6522/input.js.json @@ -0,0 +1,941 @@ +{ + "type": "Module", + "span": { + "start": 1, + "end": 262, + "ctxt": 0 + }, + "body": [ + { + "type": "VariableDeclaration", + "span": { + "start": 1, + "end": 6, + "ctxt": 0 + }, + "kind": "let", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 5, + "end": 6, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 5, + "end": 6, + "ctxt": 0 + }, + "value": "x", + "optional": false, + "typeAnnotation": null + }, + "init": null, + "definite": false + } + ] + }, + { + "type": "ExpressionStatement", + "span": { + "start": 7, + "end": 20, + "ctxt": 0 + }, + "expression": { + "type": "JSXElement", + "span": { + "start": 7, + "end": 20, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 8, + "end": 12, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + }, + "span": { + "start": 7, + "end": 13, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": false, + "typeArguments": null + }, + "children": [], + "closing": { + "type": "JSXClosingElement", + "span": { + "start": 13, + "end": 20, + "ctxt": 0 + }, + "name": { + "type": "Identifier", + "span": { + "start": 15, + "end": 19, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + } + } + } + }, + { + "type": "VariableDeclaration", + "span": { + "start": 22, + "end": 27, + "ctxt": 0 + }, + "kind": "let", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 26, + "end": 27, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 26, + "end": 27, + "ctxt": 0 + }, + "value": "x", + "optional": false, + "typeAnnotation": null + }, + "init": null, + "definite": false + } + ] + }, + { + "type": "ExpressionStatement", + "span": { + "start": 29, + "end": 42, + "ctxt": 0 + }, + "expression": { + "type": "JSXElement", + "span": { + "start": 29, + "end": 42, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 30, + "end": 34, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + }, + "span": { + "start": 29, + "end": 35, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": false, + "typeArguments": null + }, + "children": [], + "closing": { + "type": "JSXClosingElement", + "span": { + "start": 35, + "end": 42, + "ctxt": 0 + }, + "name": { + "type": "Identifier", + "span": { + "start": 37, + "end": 41, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + } + } + } + }, + { + "type": "VariableDeclaration", + "span": { + "start": 44, + "end": 50, + "ctxt": 0 + }, + "kind": "let", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 48, + "end": 49, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 48, + "end": 49, + "ctxt": 0 + }, + "value": "x", + "optional": false, + "typeAnnotation": null + }, + "init": null, + "definite": false + } + ] + }, + { + "type": "ExpressionStatement", + "span": { + "start": 51, + "end": 64, + "ctxt": 0 + }, + "expression": { + "type": "JSXElement", + "span": { + "start": 51, + "end": 64, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 52, + "end": 56, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + }, + "span": { + "start": 51, + "end": 57, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": false, + "typeArguments": null + }, + "children": [], + "closing": { + "type": "JSXClosingElement", + "span": { + "start": 57, + "end": 64, + "ctxt": 0 + }, + "name": { + "type": "Identifier", + "span": { + "start": 59, + "end": 63, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + } + } + } + }, + { + "type": "VariableDeclaration", + "span": { + "start": 66, + "end": 71, + "ctxt": 0 + }, + "kind": "var", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 70, + "end": 71, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 70, + "end": 71, + "ctxt": 0 + }, + "value": "x", + "optional": false, + "typeAnnotation": null + }, + "init": null, + "definite": false + } + ] + }, + { + "type": "ExpressionStatement", + "span": { + "start": 72, + "end": 85, + "ctxt": 0 + }, + "expression": { + "type": "JSXElement", + "span": { + "start": 72, + "end": 85, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 73, + "end": 77, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + }, + "span": { + "start": 72, + "end": 78, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": false, + "typeArguments": null + }, + "children": [], + "closing": { + "type": "JSXClosingElement", + "span": { + "start": 78, + "end": 85, + "ctxt": 0 + }, + "name": { + "type": "Identifier", + "span": { + "start": 80, + "end": 84, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + } + } + } + }, + { + "type": "VariableDeclaration", + "span": { + "start": 87, + "end": 93, + "ctxt": 0 + }, + "kind": "var", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 91, + "end": 92, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 91, + "end": 92, + "ctxt": 0 + }, + "value": "x", + "optional": false, + "typeAnnotation": null + }, + "init": null, + "definite": false + } + ] + }, + { + "type": "ExpressionStatement", + "span": { + "start": 94, + "end": 107, + "ctxt": 0 + }, + "expression": { + "type": "JSXElement", + "span": { + "start": 94, + "end": 107, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 95, + "end": 99, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + }, + "span": { + "start": 94, + "end": 100, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": false, + "typeArguments": null + }, + "children": [], + "closing": { + "type": "JSXClosingElement", + "span": { + "start": 100, + "end": 107, + "ctxt": 0 + }, + "name": { + "type": "Identifier", + "span": { + "start": 102, + "end": 106, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + } + } + } + }, + { + "type": "FunctionDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 118, + "end": 119, + "ctxt": 0 + }, + "value": "x", + "optional": false + }, + "declare": false, + "params": [], + "decorators": [], + "span": { + "start": 109, + "end": 147, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 122, + "end": 147, + "ctxt": 0 + }, + "stmts": [ + { + "type": "VariableDeclaration", + "span": { + "start": 128, + "end": 133, + "ctxt": 0 + }, + "kind": "let", + "declare": false, + "declarations": [ + { + "type": "VariableDeclarator", + "span": { + "start": 132, + "end": 133, + "ctxt": 0 + }, + "id": { + "type": "Identifier", + "span": { + "start": 132, + "end": 133, + "ctxt": 0 + }, + "value": "x", + "optional": false, + "typeAnnotation": null + }, + "init": null, + "definite": false + } + ] + }, + { + "type": "ExpressionStatement", + "span": { + "start": 138, + "end": 145, + "ctxt": 0 + }, + "expression": { + "type": "JSXElement", + "span": { + "start": 138, + "end": 145, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 139, + "end": 142, + "ctxt": 0 + }, + "value": "div", + "optional": false + }, + "span": { + "start": 138, + "end": 145, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": true, + "typeArguments": null + }, + "children": [], + "closing": null + } + } + ] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": null + }, + { + "type": "BlockStatement", + "span": { + "start": 149, + "end": 164, + "ctxt": 0 + }, + "stmts": [ + { + "type": "LabeledStatement", + "span": { + "start": 151, + "end": 162, + "ctxt": 0 + }, + "label": { + "type": "Identifier", + "span": { + "start": 151, + "end": 154, + "ctxt": 0 + }, + "value": "foo", + "optional": false + }, + "body": { + "type": "ExpressionStatement", + "span": { + "start": 156, + "end": 162, + "ctxt": 0 + }, + "expression": { + "type": "StringLiteral", + "span": { + "start": 156, + "end": 162, + "ctxt": 0 + }, + "value": "test", + "raw": "'test'" + } + } + } + ] + }, + { + "type": "ExpressionStatement", + "span": { + "start": 165, + "end": 178, + "ctxt": 0 + }, + "expression": { + "type": "JSXElement", + "span": { + "start": 165, + "end": 178, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 166, + "end": 170, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + }, + "span": { + "start": 165, + "end": 171, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": false, + "typeArguments": null + }, + "children": [], + "closing": { + "type": "JSXClosingElement", + "span": { + "start": 171, + "end": 178, + "ctxt": 0 + }, + "name": { + "type": "Identifier", + "span": { + "start": 173, + "end": 177, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + } + } + } + }, + { + "type": "FunctionDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 189, + "end": 194, + "ctxt": 0 + }, + "value": "test1", + "optional": false + }, + "declare": false, + "params": [], + "decorators": [], + "span": { + "start": 180, + "end": 199, + "ctxt": 0 + }, + "body": { + "type": "BlockStatement", + "span": { + "start": 197, + "end": 199, + "ctxt": 0 + }, + "stmts": [] + }, + "generator": false, + "async": false, + "typeParameters": null, + "returnType": null + }, + { + "type": "ExpressionStatement", + "span": { + "start": 200, + "end": 213, + "ctxt": 0 + }, + "expression": { + "type": "JSXElement", + "span": { + "start": 200, + "end": 213, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 201, + "end": 205, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + }, + "span": { + "start": 200, + "end": 206, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": false, + "typeArguments": null + }, + "children": [], + "closing": { + "type": "JSXClosingElement", + "span": { + "start": 206, + "end": 213, + "ctxt": 0 + }, + "name": { + "type": "Identifier", + "span": { + "start": 208, + "end": 212, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + } + } + } + }, + { + "type": "ClassDeclaration", + "identifier": { + "type": "Identifier", + "span": { + "start": 221, + "end": 224, + "ctxt": 0 + }, + "value": "Foo", + "optional": false + }, + "declare": false, + "span": { + "start": 215, + "end": 227, + "ctxt": 0 + }, + "decorators": [], + "body": [], + "superClass": null, + "isAbstract": false, + "typeParams": null, + "superTypeParams": null, + "implements": [] + }, + { + "type": "ExpressionStatement", + "span": { + "start": 228, + "end": 262, + "ctxt": 0 + }, + "expression": { + "type": "JSXFragment", + "span": { + "start": 228, + "end": 262, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningFragment", + "span": { + "start": 228, + "end": 230, + "ctxt": 0 + } + }, + "children": [ + { + "type": "JSXText", + "span": { + "start": 230, + "end": 231, + "ctxt": 0 + }, + "value": "\n\n", + "raw": "\n\n" + }, + { + "type": "JSXElement", + "span": { + "start": 231, + "end": 244, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 232, + "end": 236, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + }, + "span": { + "start": 231, + "end": 237, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": false, + "typeArguments": null + }, + "children": [], + "closing": { + "type": "JSXClosingElement", + "span": { + "start": 237, + "end": 244, + "ctxt": 0 + }, + "name": { + "type": "Identifier", + "span": { + "start": 239, + "end": 243, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + } + } + }, + { + "type": "JSXText", + "span": { + "start": 244, + "end": 245, + "ctxt": 0 + }, + "value": "\n\n", + "raw": "\n\n" + }, + { + "type": "JSXElement", + "span": { + "start": 245, + "end": 258, + "ctxt": 0 + }, + "opening": { + "type": "JSXOpeningElement", + "name": { + "type": "Identifier", + "span": { + "start": 246, + "end": 250, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + }, + "span": { + "start": 245, + "end": 251, + "ctxt": 0 + }, + "attributes": [], + "selfClosing": false, + "typeArguments": null + }, + "children": [], + "closing": { + "type": "JSXClosingElement", + "span": { + "start": 251, + "end": 258, + "ctxt": 0 + }, + "name": { + "type": "Identifier", + "span": { + "start": 253, + "end": 257, + "ctxt": 0 + }, + "value": "Comp", + "optional": false + } + } + }, + { + "type": "JSXText", + "span": { + "start": 258, + "end": 259, + "ctxt": 0 + }, + "value": "\n\n", + "raw": "\n\n" + } + ], + "closing": { + "type": "JSXClosingFragment", + "span": { + "start": 259, + "end": 262, + "ctxt": 0 + } + } + } + } + ], + "interpreter": null +}