diff --git a/lib/ast-converter.js b/lib/ast-converter.js index d80831b..220ff6d 100644 --- a/lib/ast-converter.js +++ b/lib/ast-converter.js @@ -1860,9 +1860,11 @@ module.exports = function(ast, extra) { // Convert SyntaxKind.JsxSelfClosingElement to SyntaxKind.JsxOpeningElement, // TypeScript does not seem to have the idea of openingElement when tag is self-closing node.kind = SyntaxKind.JsxOpeningElement; + var openingElement = convertChild(node); + openingElement.selfClosing = true; assign(result, { type: "JSXElement", - openingElement: convertChild(node), + openingElement: openingElement, closingElement: null, children: [] }); @@ -1873,7 +1875,7 @@ module.exports = function(ast, extra) { var openingTagName = convertTypeScriptJSXTagNameToESTreeName(node.tagName); assign(result, { type: "JSXOpeningElement", - selfClosing: !(node.parent && node.parent.closingElement), + selfClosing: false, name: openingTagName, attributes: node.attributes.map(convertChild) }); @@ -1915,6 +1917,7 @@ module.exports = function(ast, extra) { case SyntaxKind.JsxAttribute: var attributeName = convertToken(node.name, ast); + attributeName.type = "JSXIdentifier"; attributeName.name = attributeName.value; delete attributeName.value; diff --git a/tests/fixtures/ecma-features/jsx/attributes.result.js b/tests/fixtures/ecma-features/jsx/attributes.result.js new file mode 100644 index 0000000..aa44d4f --- /dev/null +++ b/tests/fixtures/ecma-features/jsx/attributes.result.js @@ -0,0 +1,740 @@ +module.exports = { + "type": "Program", + "range": [ + 0, + 52 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "range": [ + 0, + 52 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "expression": { + "type": "JSXElement", + "range": [ + 0, + 52 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "openingElement": { + "type": "JSXOpeningElement", + "range": [ + 0, + 42 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 42 + } + }, + "selfClosing": false, + "name": { + "type": "JSXIdentifier", + "range": [ + 1, + 4 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "name": "foo" + }, + "attributes": [ + { + "type": "JSXAttribute", + "range": [ + 5, + 14 + ], + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "name": { + "type": "JSXIdentifier", + "range": [ + 5, + 8 + ], + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 8 + } + }, + "name": "bar" + }, + "value": { + "type": "Literal", + "range": [ + 9, + 14 + ], + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 14 + } + }, + "value": "baz", + "raw": "\"baz\"" + } + }, + { + "type": "JSXAttribute", + "range": [ + 15, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "name": { + "type": "JSXIdentifier", + "range": [ + 15, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 18 + } + }, + "name": "qux" + }, + "value": { + "type": "JSXExpressionContainer", + "range": [ + 19, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 24 + } + }, + "expression": { + "type": "Identifier", + "range": [ + 20, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 23 + } + }, + "name": "quz" + } + } + }, + { + "type": "JSXAttribute", + "range": [ + 25, + 41 + ], + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 41 + } + }, + "name": { + "type": "JSXIdentifier", + "range": [ + 25, + 31 + ], + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 31 + } + }, + "name": "spread" + }, + "value": { + "type": "JSXExpressionContainer", + "range": [ + 32, + 41 + ], + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 41 + } + }, + "expression": { + "type": "Identifier", + "range": [ + 36, + 40 + ], + "loc": { + "start": { + "line": 1, + "column": 36 + }, + "end": { + "line": 1, + "column": 40 + } + }, + "name": "rest" + } + } + } + ] + }, + "closingElement": { + "type": "JSXClosingElement", + "range": [ + 46, + 52 + ], + "loc": { + "start": { + "line": 1, + "column": 46 + }, + "end": { + "line": 1, + "column": 52 + } + }, + "name": { + "type": "JSXIdentifier", + "range": [ + 48, + 51 + ], + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 51 + } + }, + "name": "foo" + } + }, + "children": [ + { + "type": "Literal", + "range": [ + 42, + 46 + ], + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 46 + } + }, + "value": "test", + "raw": "test" + } + ] + } + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Punctuator", + "value": "<", + "range": [ + 0, + 1 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "JSXIdentifier", + "value": "foo", + "range": [ + 1, + 4 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 4 + } + } + }, + { + "type": "JSXIdentifier", + "value": "bar", + "range": [ + 5, + 8 + ], + "loc": { + "start": { + "line": 1, + "column": 5 + }, + "end": { + "line": 1, + "column": 8 + } + } + }, + { + "type": "Punctuator", + "value": "=", + "range": [ + 8, + 9 + ], + "loc": { + "start": { + "line": 1, + "column": 8 + }, + "end": { + "line": 1, + "column": 9 + } + } + }, + { + "type": "JSXText", + "value": "\"baz\"", + "range": [ + 9, + 14 + ], + "loc": { + "start": { + "line": 1, + "column": 9 + }, + "end": { + "line": 1, + "column": 14 + } + } + }, + { + "type": "JSXIdentifier", + "value": "qux", + "range": [ + 15, + 18 + ], + "loc": { + "start": { + "line": 1, + "column": 15 + }, + "end": { + "line": 1, + "column": 18 + } + } + }, + { + "type": "Punctuator", + "value": "=", + "range": [ + 18, + 19 + ], + "loc": { + "start": { + "line": 1, + "column": 18 + }, + "end": { + "line": 1, + "column": 19 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 19, + 20 + ], + "loc": { + "start": { + "line": 1, + "column": 19 + }, + "end": { + "line": 1, + "column": 20 + } + } + }, + { + "type": "Identifier", + "value": "quz", + "range": [ + 20, + 23 + ], + "loc": { + "start": { + "line": 1, + "column": 20 + }, + "end": { + "line": 1, + "column": 23 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 23, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 23 + }, + "end": { + "line": 1, + "column": 24 + } + } + }, + { + "type": "JSXIdentifier", + "value": "spread", + "range": [ + 25, + 31 + ], + "loc": { + "start": { + "line": 1, + "column": 25 + }, + "end": { + "line": 1, + "column": 31 + } + } + }, + { + "type": "Punctuator", + "value": "=", + "range": [ + 31, + 32 + ], + "loc": { + "start": { + "line": 1, + "column": 31 + }, + "end": { + "line": 1, + "column": 32 + } + } + }, + { + "type": "Punctuator", + "value": "{", + "range": [ + 32, + 33 + ], + "loc": { + "start": { + "line": 1, + "column": 32 + }, + "end": { + "line": 1, + "column": 33 + } + } + }, + { + "type": "Punctuator", + "value": "...", + "range": [ + 33, + 36 + ], + "loc": { + "start": { + "line": 1, + "column": 33 + }, + "end": { + "line": 1, + "column": 36 + } + } + }, + { + "type": "Identifier", + "value": "rest", + "range": [ + 36, + 40 + ], + "loc": { + "start": { + "line": 1, + "column": 36 + }, + "end": { + "line": 1, + "column": 40 + } + } + }, + { + "type": "Punctuator", + "value": "}", + "range": [ + 40, + 41 + ], + "loc": { + "start": { + "line": 1, + "column": 40 + }, + "end": { + "line": 1, + "column": 41 + } + } + }, + { + "type": "Punctuator", + "value": ">", + "range": [ + 41, + 42 + ], + "loc": { + "start": { + "line": 1, + "column": 41 + }, + "end": { + "line": 1, + "column": 42 + } + } + }, + { + "type": "JSXText", + "value": "test", + "range": [ + 42, + 46 + ], + "loc": { + "start": { + "line": 1, + "column": 42 + }, + "end": { + "line": 1, + "column": 46 + } + } + }, + { + "type": "Punctuator", + "value": "<", + "range": [ + 46, + 47 + ], + "loc": { + "start": { + "line": 1, + "column": 46 + }, + "end": { + "line": 1, + "column": 47 + } + } + }, + { + "type": "Punctuator", + "value": "/", + "range": [ + 47, + 48 + ], + "loc": { + "start": { + "line": 1, + "column": 47 + }, + "end": { + "line": 1, + "column": 48 + } + } + }, + { + "type": "JSXIdentifier", + "value": "foo", + "range": [ + 48, + 51 + ], + "loc": { + "start": { + "line": 1, + "column": 48 + }, + "end": { + "line": 1, + "column": 51 + } + } + }, + { + "type": "Punctuator", + "value": ">", + "range": [ + 51, + 52 + ], + "loc": { + "start": { + "line": 1, + "column": 51 + }, + "end": { + "line": 1, + "column": 52 + } + } + } + ] +}; diff --git a/tests/fixtures/ecma-features/jsx/attributes.src.js b/tests/fixtures/ecma-features/jsx/attributes.src.js new file mode 100644 index 0000000..c70e86b --- /dev/null +++ b/tests/fixtures/ecma-features/jsx/attributes.src.js @@ -0,0 +1 @@ +test diff --git a/tests/fixtures/ecma-features/jsx/self-closing-tag-inside-tag.result.js b/tests/fixtures/ecma-features/jsx/self-closing-tag-inside-tag.result.js new file mode 100644 index 0000000..450dcb7 --- /dev/null +++ b/tests/fixtures/ecma-features/jsx/self-closing-tag-inside-tag.result.js @@ -0,0 +1,458 @@ +module.exports = { + "type": "Program", + "range": [ + 0, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 6 + } + }, + "body": [ + { + "type": "ExpressionStatement", + "range": [ + 0, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 6 + } + }, + "expression": { + "type": "JSXElement", + "range": [ + 0, + 24 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 3, + "column": 6 + } + }, + "openingElement": { + "type": "JSXOpeningElement", + "range": [ + 0, + 5 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 5 + } + }, + "selfClosing": false, + "name": { + "type": "JSXIdentifier", + "range": [ + 1, + 4 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 4 + } + }, + "name": "div" + }, + "attributes": [] + }, + "closingElement": { + "type": "JSXClosingElement", + "range": [ + 18, + 24 + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 6 + } + }, + "name": { + "type": "JSXIdentifier", + "range": [ + 20, + 23 + ], + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 5 + } + }, + "name": "div" + } + }, + "children": [ + { + "type": "Literal", + "range": [ + 5, + 10 + ], + "loc": { + "start": { + "line": 2, + "column": 5 + }, + "end": { + "line": 2, + "column": 4 + } + }, + "value": "\n ", + "raw": "\n " + }, + { + "type": "JSXElement", + "range": [ + 10, + 17 + ], + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "openingElement": { + "type": "JSXOpeningElement", + "range": [ + 10, + 17 + ], + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 11 + } + }, + "selfClosing": true, + "name": { + "type": "JSXIdentifier", + "range": [ + 11, + 14 + ], + "loc": { + "start": { + "line": 2, + "column": 5 + }, + "end": { + "line": 2, + "column": 8 + } + }, + "name": "foo" + }, + "attributes": [] + }, + "closingElement": null, + "children": [] + }, + { + "type": "Literal", + "range": [ + 17, + 18 + ], + "loc": { + "start": { + "line": 3, + "column": 17 + }, + "end": { + "line": 3, + "column": 0 + } + }, + "value": "\n", + "raw": "\n" + } + ] + } + } + ], + "sourceType": "script", + "tokens": [ + { + "type": "Punctuator", + "value": "<", + "range": [ + 0, + 1 + ], + "loc": { + "start": { + "line": 1, + "column": 0 + }, + "end": { + "line": 1, + "column": 1 + } + } + }, + { + "type": "JSXIdentifier", + "value": "div", + "range": [ + 1, + 4 + ], + "loc": { + "start": { + "line": 1, + "column": 1 + }, + "end": { + "line": 1, + "column": 4 + } + } + }, + { + "type": "Punctuator", + "value": ">", + "range": [ + 4, + 5 + ], + "loc": { + "start": { + "line": 1, + "column": 4 + }, + "end": { + "line": 1, + "column": 5 + } + } + }, + { + "type": "JSXText", + "value": "", + "range": [ + 10, + 10 + ], + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 4 + } + } + }, + { + "type": "Punctuator", + "value": "<", + "range": [ + 10, + 11 + ], + "loc": { + "start": { + "line": 2, + "column": 4 + }, + "end": { + "line": 2, + "column": 5 + } + } + }, + { + "type": "JSXIdentifier", + "value": "foo", + "range": [ + 11, + 14 + ], + "loc": { + "start": { + "line": 2, + "column": 5 + }, + "end": { + "line": 2, + "column": 8 + } + } + }, + { + "type": "Punctuator", + "value": "/", + "range": [ + 15, + 16 + ], + "loc": { + "start": { + "line": 2, + "column": 9 + }, + "end": { + "line": 2, + "column": 10 + } + } + }, + { + "type": "Punctuator", + "value": ">", + "range": [ + 16, + 17 + ], + "loc": { + "start": { + "line": 2, + "column": 10 + }, + "end": { + "line": 2, + "column": 11 + } + } + }, + { + "type": "JSXText", + "value": "", + "range": [ + 18, + 18 + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 0 + } + } + }, + { + "type": "Punctuator", + "value": "<", + "range": [ + 18, + 19 + ], + "loc": { + "start": { + "line": 3, + "column": 0 + }, + "end": { + "line": 3, + "column": 1 + } + } + }, + { + "type": "Punctuator", + "value": "/", + "range": [ + 19, + 20 + ], + "loc": { + "start": { + "line": 3, + "column": 1 + }, + "end": { + "line": 3, + "column": 2 + } + } + }, + { + "type": "JSXIdentifier", + "value": "div", + "range": [ + 20, + 23 + ], + "loc": { + "start": { + "line": 3, + "column": 2 + }, + "end": { + "line": 3, + "column": 5 + } + } + }, + { + "type": "Punctuator", + "value": ">", + "range": [ + 23, + 24 + ], + "loc": { + "start": { + "line": 3, + "column": 5 + }, + "end": { + "line": 3, + "column": 6 + } + } + } + ] +}; diff --git a/tests/fixtures/ecma-features/jsx/self-closing-tag-inside-tag.src.js b/tests/fixtures/ecma-features/jsx/self-closing-tag-inside-tag.src.js new file mode 100644 index 0000000..b1b2540 --- /dev/null +++ b/tests/fixtures/ecma-features/jsx/self-closing-tag-inside-tag.src.js @@ -0,0 +1,3 @@ +
+ +