From 8ea227b2eb3887c13709e66f83ae4a80efa3f197 Mon Sep 17 00:00:00 2001 From: Will Sabransky Date: Tue, 4 Sep 2018 13:01:55 -0700 Subject: [PATCH 1/4] New: support for shorthand fragments (fixes #503) --- lib/ast-node-types.js | 3 +++ lib/convert.js | 23 +++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/lib/ast-node-types.js b/lib/ast-node-types.js index 155abac..597e9e1 100644 --- a/lib/ast-node-types.js +++ b/lib/ast-node-types.js @@ -62,13 +62,16 @@ module.exports = { ImportSpecifier: "ImportSpecifier", JSXAttribute: "JSXAttribute", JSXClosingElement: "JSXClosingElement", + JSXClosingFragment: "JSXClosingFragment", JSXElement: "JSXElement", JSXEmptyExpression: "JSXEmptyExpression", JSXExpressionContainer: "JSXExpressionContainer", + JSXFragment: "JSXFragment", JSXIdentifier: "JSXIdentifier", JSXMemberExpression: "JSXMemberExpression", JSXNamespacedName: "JSXNamespacedName", JSXOpeningElement: "JSXOpeningElement", + JSXOpeningFragment: "JSXOpeningFragment", JSXSpreadAttribute: "JSXSpreadAttribute", JSXSpreadChild: "JSXSpreadChild", JSXText: "JSXText", diff --git a/lib/convert.js b/lib/convert.js index ac295eb..a11beb4 100644 --- a/lib/convert.js +++ b/lib/convert.js @@ -1842,6 +1842,16 @@ module.exports = function convert(config) { break; + case SyntaxKind.JsxFragment: + Object.assign(result, { + type: AST_NODE_TYPES.JSXFragment, + openingElement: convertChild(node.openingElement), + closingElement: convertChild(node.closingElement), + children: node.children.map(convertChild) + }); + + break; + case SyntaxKind.JsxSelfClosingElement: { /** * Convert SyntaxKind.JsxSelfClosingElement to SyntaxKind.JsxOpeningElement, @@ -1882,6 +1892,19 @@ module.exports = function convert(config) { }); break; + case SyntaxKind.JsxOpeningFragment: + Object.assign(result, { + type: AST_NODE_TYPES.JSXOpeningFragment, + selfClosing: false, + }); + break; + + case SyntaxKind.JsxClosingFragment: + Object.assign(result, { + type: AST_NODE_TYPES.JSXClosingFragment, + }); + break; + case SyntaxKind.JsxExpression: { const eloc = ast.getLineAndCharacterOfPosition(result.range[0] + 1); const expression = (node.expression) ? convertChild(node.expression) : { From 88995c051adaa368d6efa9546f024d6b332b40ae Mon Sep 17 00:00:00 2001 From: Will Sabransky Date: Tue, 4 Sep 2018 13:08:36 -0700 Subject: [PATCH 2/4] add tests --- tests/fixtures/jsx/invalid-shorthand-fragment-no-closing.js | 1 + tests/fixtures/jsx/shorthand-fragment-with-child.js | 1 + tests/fixtures/jsx/shorthand-fragment.js | 1 + 3 files changed, 3 insertions(+) create mode 100644 tests/fixtures/jsx/invalid-shorthand-fragment-no-closing.js create mode 100644 tests/fixtures/jsx/shorthand-fragment-with-child.js create mode 100644 tests/fixtures/jsx/shorthand-fragment.js diff --git a/tests/fixtures/jsx/invalid-shorthand-fragment-no-closing.js b/tests/fixtures/jsx/invalid-shorthand-fragment-no-closing.js new file mode 100644 index 0000000..20c0a66 --- /dev/null +++ b/tests/fixtures/jsx/invalid-shorthand-fragment-no-closing.js @@ -0,0 +1 @@ +<>
diff --git a/tests/fixtures/jsx/shorthand-fragment-with-child.js b/tests/fixtures/jsx/shorthand-fragment-with-child.js new file mode 100644 index 0000000..ac72d17 --- /dev/null +++ b/tests/fixtures/jsx/shorthand-fragment-with-child.js @@ -0,0 +1 @@ +<>
diff --git a/tests/fixtures/jsx/shorthand-fragment.js b/tests/fixtures/jsx/shorthand-fragment.js new file mode 100644 index 0000000..4a80b22 --- /dev/null +++ b/tests/fixtures/jsx/shorthand-fragment.js @@ -0,0 +1 @@ +<> From fbdbafecf9f4b7c99b52186454a784596e282886 Mon Sep 17 00:00:00 2001 From: Will Sabransky Date: Tue, 4 Sep 2018 13:11:13 -0700 Subject: [PATCH 3/4] linting --- lib/convert.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/convert.js b/lib/convert.js index a11beb4..7ac84d4 100644 --- a/lib/convert.js +++ b/lib/convert.js @@ -1844,10 +1844,10 @@ module.exports = function convert(config) { case SyntaxKind.JsxFragment: Object.assign(result, { - type: AST_NODE_TYPES.JSXFragment, - openingElement: convertChild(node.openingElement), - closingElement: convertChild(node.closingElement), - children: node.children.map(convertChild) + type: AST_NODE_TYPES.JSXFragment, + openingElement: convertChild(node.openingElement), + closingElement: convertChild(node.closingElement), + children: node.children.map(convertChild) }); break; @@ -1894,14 +1894,14 @@ module.exports = function convert(config) { case SyntaxKind.JsxOpeningFragment: Object.assign(result, { - type: AST_NODE_TYPES.JSXOpeningFragment, - selfClosing: false, + type: AST_NODE_TYPES.JSXOpeningFragment, + selfClosing: false }); break; case SyntaxKind.JsxClosingFragment: Object.assign(result, { - type: AST_NODE_TYPES.JSXClosingFragment, + type: AST_NODE_TYPES.JSXClosingFragment }); break; From 808176ad841a45f0fc94d93de108729ef9f7c4ad Mon Sep 17 00:00:00 2001 From: Will Sabransky Date: Mon, 10 Sep 2018 11:15:33 -0700 Subject: [PATCH 4/4] snapshots --- ...alid-shorthand-fragment-no-closing.src.js} | 0 ...s => shorthand-fragment-with-child.src.js} | 0 ...-fragment.js => shorthand-fragment.src.js} | 0 tests/lib/__snapshots__/jsx.js.snap | 435 ++++++++++++++++++ 4 files changed, 435 insertions(+) rename tests/fixtures/jsx/{invalid-shorthand-fragment-no-closing.js => invalid-shorthand-fragment-no-closing.src.js} (100%) rename tests/fixtures/jsx/{shorthand-fragment-with-child.js => shorthand-fragment-with-child.src.js} (100%) rename tests/fixtures/jsx/{shorthand-fragment.js => shorthand-fragment.src.js} (100%) diff --git a/tests/fixtures/jsx/invalid-shorthand-fragment-no-closing.js b/tests/fixtures/jsx/invalid-shorthand-fragment-no-closing.src.js similarity index 100% rename from tests/fixtures/jsx/invalid-shorthand-fragment-no-closing.js rename to tests/fixtures/jsx/invalid-shorthand-fragment-no-closing.src.js diff --git a/tests/fixtures/jsx/shorthand-fragment-with-child.js b/tests/fixtures/jsx/shorthand-fragment-with-child.src.js similarity index 100% rename from tests/fixtures/jsx/shorthand-fragment-with-child.js rename to tests/fixtures/jsx/shorthand-fragment-with-child.src.js diff --git a/tests/fixtures/jsx/shorthand-fragment.js b/tests/fixtures/jsx/shorthand-fragment.src.js similarity index 100% rename from tests/fixtures/jsx/shorthand-fragment.js rename to tests/fixtures/jsx/shorthand-fragment.src.js diff --git a/tests/lib/__snapshots__/jsx.js.snap b/tests/lib/__snapshots__/jsx.js.snap index 0be9fe0..0372f0f 100644 --- a/tests/lib/__snapshots__/jsx.js.snap +++ b/tests/lib/__snapshots__/jsx.js.snap @@ -4311,6 +4311,8 @@ exports[`JSX useJSXTextNode: false fixtures/invalid-no-tag-name.src 1`] = `"Decl exports[`JSX useJSXTextNode: false fixtures/invalid-placeholder-in-closing-tag.src 1`] = `"'>' expected."`; +exports[`JSX useJSXTextNode: false fixtures/invalid-shorthand-fragment-no-closing.src 1`] = `"JSX fragment has no corresponding closing tag."`; + exports[`JSX useJSXTextNode: false fixtures/invalid-trailing-dot-tag-name.src 1`] = `"Identifier expected."`; exports[`JSX useJSXTextNode: false fixtures/invalid-unexpected-comma.src 1`] = `"Identifier expected."`; @@ -6824,6 +6826,439 @@ Object { exports[`JSX useJSXTextNode: false fixtures/self-closing-tag-with-newline.src 1`] = `"Invalid character."`; +exports[`JSX useJSXTextNode: false fixtures/shorthand-fragment.src 1`] = ` +Object { + "body": Array [ + Object { + "expression": Object { + "children": Array [], + "closingElement": null, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "openingElement": null, + "range": Array [ + 0, + 5, + ], + "type": "JSXFragment", + }, + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 5, + ], + "type": "ExpressionStatement", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 6, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 1, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 2, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "range": Array [ + 1, + 2, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 2, + "line": 1, + }, + }, + "range": Array [ + 2, + 3, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 4, + "line": 1, + }, + "start": Object { + "column": 3, + "line": 1, + }, + }, + "range": Array [ + 3, + 4, + ], + "type": "Punctuator", + "value": "/", + }, + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 5, + ], + "type": "Punctuator", + "value": ">", + }, + ], + "type": "Program", +} +`; + +exports[`JSX useJSXTextNode: false fixtures/shorthand-fragment-with-child.src 1`] = ` +Object { + "body": Array [ + Object { + "expression": Object { + "children": Array [ + Object { + "children": Array [], + "closingElement": null, + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 2, + "line": 1, + }, + }, + "openingElement": Object { + "attributes": Array [], + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 2, + "line": 1, + }, + }, + "name": Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 3, + "line": 1, + }, + }, + "name": "div", + "range": Array [ + 3, + 6, + ], + "type": "JSXIdentifier", + }, + "range": Array [ + 2, + 9, + ], + "selfClosing": true, + "type": "JSXOpeningElement", + }, + "range": Array [ + 2, + 9, + ], + "type": "JSXElement", + }, + ], + "closingElement": null, + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "openingElement": null, + "range": Array [ + 0, + 12, + ], + "type": "JSXFragment", + }, + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 12, + ], + "type": "ExpressionStatement", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 13, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 1, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 1, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 2, + "line": 1, + }, + "start": Object { + "column": 1, + "line": 1, + }, + }, + "range": Array [ + 1, + 2, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 2, + "line": 1, + }, + }, + "range": Array [ + 2, + 3, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 3, + "line": 1, + }, + }, + "range": Array [ + 3, + 6, + ], + "type": "JSXIdentifier", + "value": "div", + }, + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "Punctuator", + "value": "/", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "range": Array [ + 8, + 9, + ], + "type": "Punctuator", + "value": ">", + }, + Object { + "loc": Object { + "end": Object { + "column": 10, + "line": 1, + }, + "start": Object { + "column": 9, + "line": 1, + }, + }, + "range": Array [ + 9, + 10, + ], + "type": "Punctuator", + "value": "<", + }, + Object { + "loc": Object { + "end": Object { + "column": 11, + "line": 1, + }, + "start": Object { + "column": 10, + "line": 1, + }, + }, + "range": Array [ + 10, + 11, + ], + "type": "Punctuator", + "value": "/", + }, + Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 11, + "line": 1, + }, + }, + "range": Array [ + 11, + 12, + ], + "type": "Punctuator", + "value": ">", + }, + ], + "type": "Program", +} +`; + exports[`JSX useJSXTextNode: false fixtures/spread-child.src 1`] = ` Object { "body": Array [