From 41108dbaaec656b3bfedc77be63ac143c56c76ee Mon Sep 17 00:00:00 2001 From: Kanchalai Tanglertsampan Date: Wed, 18 Jan 2017 15:12:36 -0800 Subject: [PATCH] Update emitter to use JSXAttributes node instead of JSXAttribute node array # Conflicts: # src/compiler/visitor.ts --- src/compiler/emitter.ts | 18 +++++++++++++++--- src/compiler/factory.ts | 26 ++++++++++++++++++++------ src/compiler/transformers/jsx.ts | 2 +- src/compiler/visitor.ts | 14 +++++++++++--- 4 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 2ff342138c8..814d6cd76c6 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -538,6 +538,8 @@ namespace ts { return emitJsxClosingElement(node); case SyntaxKind.JsxAttribute: return emitJsxAttribute(node); + case SyntaxKind.JsxAttributes: + return emitJsxAttributes(node); case SyntaxKind.JsxSpreadAttribute: return emitJsxSpreadAttribute(node); case SyntaxKind.JsxExpression: @@ -1824,15 +1826,21 @@ namespace ts { write("<"); emitJsxTagName(node.tagName); write(" "); - emitList(node, node.attributes, ListFormat.JsxElementAttributes); + // We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap + if (node.attributes.properties && node.attributes.properties.length > 0) { + emit(node.attributes); + } write("/>"); } function emitJsxOpeningElement(node: JsxOpeningElement) { write("<"); emitJsxTagName(node.tagName); - writeIfAny(node.attributes, " "); - emitList(node, node.attributes, ListFormat.JsxElementAttributes); + writeIfAny(node.attributes.properties, " "); + // We are checking here so we won't re-enter the emiting pipeline and emit extra sourcemap + if (node.attributes.properties && node.attributes.properties.length > 0) { + emit(node.attributes); + } write(">"); } @@ -1846,6 +1854,10 @@ namespace ts { write(">"); } + function emitJsxAttributes(node: JsxAttributes) { + emitList(node, node.properties, ListFormat.JsxElementAttributes); + } + function emitJsxAttribute(node: JsxAttribute) { emit(node.name); emitWithPrefix("=", node.initializer); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index f63094ae16d..dcac87a1d5e 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -1249,28 +1249,28 @@ namespace ts { return node; } - export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { + export function createJsxSelfClosingElement(tagName: JsxTagNameExpression, attributes: JsxAttributes, location?: TextRange) { const node = createNode(SyntaxKind.JsxSelfClosingElement, location); node.tagName = tagName; - node.attributes = createNodeArray(attributes); + node.attributes = attributes; return node; } - export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { + export function updateJsxSelfClosingElement(node: JsxSelfClosingElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) { if (node.tagName !== tagName || node.attributes !== attributes) { return updateNode(createJsxSelfClosingElement(tagName, attributes, node), node); } return node; } - export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributeLike[], location?: TextRange) { + export function createJsxOpeningElement(tagName: JsxTagNameExpression, attributes: JsxAttributes, location?: TextRange) { const node = createNode(SyntaxKind.JsxOpeningElement, location); node.tagName = tagName; - node.attributes = createNodeArray(attributes); + node.attributes = attributes; return node; } - export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributeLike[]) { + export function updateJsxOpeningElement(node: JsxOpeningElement, tagName: JsxTagNameExpression, attributes: JsxAttributes) { if (node.tagName !== tagName || node.attributes !== attributes) { return updateNode(createJsxOpeningElement(tagName, attributes, node), node); } @@ -1290,6 +1290,20 @@ namespace ts { return node; } + export function createJsxAttributes(properties: JsxAttributeLike[], location?: TextRange) { + const jsxAttributes = createNode(SyntaxKind.JsxAttributes, location); + setEmitFlags(jsxAttributes, EmitFlags.NoSourceMap); + jsxAttributes.properties = createNodeArray(properties); + return jsxAttributes; + } + + export function updateJsxAttributes(jsxAttributes: JsxAttributes, properties: JsxAttributeLike[]) { + if (jsxAttributes.properties !== properties) { + return updateNode(createJsxAttributes(properties, jsxAttributes), jsxAttributes); + } + return jsxAttributes; + } + export function createJsxAttribute(name: Identifier, initializer: StringLiteral | JsxExpression, location?: TextRange) { const node = createNode(SyntaxKind.JsxAttribute, location); node.name = name; diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index 1307a7f8551..854ab428e54 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -85,7 +85,7 @@ namespace ts { function visitJsxOpeningLikeElement(node: JsxOpeningLikeElement, children: JsxChild[], isChild: boolean, location: TextRange) { const tagName = getTagName(node); let objectProperties: Expression; - const attrs = node.attributes; + const attrs = node.attributes.properties; if (attrs.length === 0) { // When there are no attributes, React wants "null" objectProperties = createNull(); diff --git a/src/compiler/visitor.ts b/src/compiler/visitor.ts index f3efc040e35..fb0d76e6c71 100644 --- a/src/compiler/visitor.ts +++ b/src/compiler/visitor.ts @@ -469,13 +469,17 @@ namespace ts { case SyntaxKind.JsxSelfClosingElement: case SyntaxKind.JsxOpeningElement: result = reduceNode((node).tagName, cbNode, result); - result = reduceNodes((node).attributes, cbNodes, result); + result = reduceNode((node).attributes, cbNode, result); break; case SyntaxKind.JsxClosingElement: result = reduceNode((node).tagName, cbNode, result); break; + case SyntaxKind.JsxAttributes: + result = reduceNodes((node).properties, cbNodes, result); + break; + case SyntaxKind.JsxAttribute: result = reduceNode((node).name, cbNode, result); result = reduceNode((node).initializer, cbNode, result); @@ -1117,15 +1121,19 @@ namespace ts { visitNodes((node).children, visitor, isJsxChild), visitNode((node).closingElement, visitor, isJsxClosingElement)); + case SyntaxKind.JsxAttributes: + return updateJsxAttributes(node, + visitNodes((node).properties, visitor, isJsxAttributeLike)); + case SyntaxKind.JsxSelfClosingElement: return updateJsxSelfClosingElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression), - visitNodes((node).attributes, visitor, isJsxAttributeLike)); + visitNode((node).attributes, visitor, isJsxAttributes)); case SyntaxKind.JsxOpeningElement: return updateJsxOpeningElement(node, visitNode((node).tagName, visitor, isJsxTagNameExpression), - visitNodes((node).attributes, visitor, isJsxAttributeLike)); + visitNode((node).attributes, visitor, isJsxAttributes)); case SyntaxKind.JsxClosingElement: return updateJsxClosingElement(node,