From 80e1a2924853f87926fc13d684920813499193e4 Mon Sep 17 00:00:00 2001 From: Oleksandr T Date: Fri, 15 Oct 2021 00:23:50 +0300 Subject: [PATCH] fix(46305): omit converting jsx (react-jsx) spread attributes to Object.assign for ES2018 and up (#46317) --- src/compiler/transformers/jsx.ts | 132 +++++++----------- ...ReactEmitSpreadAttribute(target=es2015).js | 56 ++++++++ ...EmitSpreadAttribute(target=es2015).symbols | 99 +++++++++++++ ...ctEmitSpreadAttribute(target=es2015).types | 117 ++++++++++++++++ ...ReactEmitSpreadAttribute(target=es2018).js | 56 ++++++++ ...EmitSpreadAttribute(target=es2018).symbols | 99 +++++++++++++ ...ctEmitSpreadAttribute(target=es2018).types | 117 ++++++++++++++++ ...ReactEmitSpreadAttribute(target=esnext).js | 56 ++++++++ ...EmitSpreadAttribute(target=esnext).symbols | 99 +++++++++++++ ...ctEmitSpreadAttribute(target=esnext).types | 117 ++++++++++++++++ .../jsx/tsxReactEmitSpreadAttribute.ts | 32 +++++ 11 files changed, 898 insertions(+), 82 deletions(-) create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).js create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).symbols create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).types create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).js create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).symbols create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).types create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).js create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).symbols create mode 100644 tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).types create mode 100644 tests/cases/conformance/jsx/tsxReactEmitSpreadAttribute.ts diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index ef296d779a..166a91dfa6 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -200,59 +200,27 @@ namespace ts { } function convertJsxChildrenToChildrenPropObject(children: readonly JsxChild[]) { + const prop = convertJsxChildrenToChildrenPropAssignment(children); + return prop && factory.createObjectLiteralExpression([prop]); + } + + function convertJsxChildrenToChildrenPropAssignment(children: readonly JsxChild[]) { const nonWhitespaceChildren = getSemanticJsxChildren(children); if (length(nonWhitespaceChildren) === 1) { const result = transformJsxChildToExpression(nonWhitespaceChildren[0]); - return result && factory.createObjectLiteralExpression([ - factory.createPropertyAssignment("children", result) - ]); + return result && factory.createPropertyAssignment("children", result); } const result = mapDefined(children, transformJsxChildToExpression); - return !result.length ? undefined : factory.createObjectLiteralExpression([ - factory.createPropertyAssignment("children", factory.createArrayLiteralExpression(result)) - ]); + return length(result) ? factory.createPropertyAssignment("children", factory.createArrayLiteralExpression(result)) : undefined; } function visitJsxOpeningLikeElementJSX(node: JsxOpeningLikeElement, children: readonly JsxChild[] | undefined, isChild: boolean, location: TextRange) { const tagName = getTagName(node); - let objectProperties: Expression; + const childrenProp = children && children.length ? convertJsxChildrenToChildrenPropAssignment(children) : undefined; const keyAttr = find(node.attributes.properties, p => !!p.name && isIdentifier(p.name) && p.name.escapedText === "key") as JsxAttribute | undefined; const attrs = keyAttr ? filter(node.attributes.properties, p => p !== keyAttr) : node.attributes.properties; - - let segments: Expression[] = []; - if (attrs.length) { - // Map spans of JsxAttribute nodes into object literals and spans - // of JsxSpreadAttribute nodes into expressions. - segments = flatten( - spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread - ? map(attrs, transformJsxSpreadAttributeToExpression) - : factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement)) - ) - ); - - if (isJsxSpreadAttribute(attrs[0])) { - // We must always emit at least one object literal before a spread - // argument.factory.createObjectLiteral - segments.unshift(factory.createObjectLiteralExpression()); - } - } - if (children && children.length) { - const result = convertJsxChildrenToChildrenPropObject(children); - if (result) { - segments.push(result); - } - } - - if (segments.length === 0) { - objectProperties = factory.createObjectLiteralExpression([]); - // When there are no attributes, React wants {} - } - else { - // Either emit one big object literal (no spread attribs), or - // a call to the __assign helper. - objectProperties = singleOrUndefined(segments) || emitHelpers().createAssignHelper(segments); - } - + const objectProperties = length(attrs) ? transformJsxAttributesToObjectProps(attrs, childrenProp) : + factory.createObjectLiteralExpression(childrenProp ? [childrenProp] : emptyArray); // When there are no attributes, React wants {} return visitJsxOpeningLikeElementOrFragmentJSX(tagName, objectProperties, keyAttr, length(getSemanticJsxChildren(children || emptyArray)), isChild, location); } @@ -285,47 +253,9 @@ namespace ts { function visitJsxOpeningLikeElementCreateElement(node: JsxOpeningLikeElement, children: readonly JsxChild[] | undefined, isChild: boolean, location: TextRange) { const tagName = getTagName(node); - let objectProperties: Expression | undefined; const attrs = node.attributes.properties; - if (attrs.length === 0) { - objectProperties = factory.createNull(); - // When there are no attributes, React wants "null" - } - else { - const target = getEmitScriptTarget(compilerOptions); - if (target && target >= ScriptTarget.ES2018) { - objectProperties = factory.createObjectLiteralExpression( - flatten( - spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => - isSpread ? map(attrs, transformJsxSpreadAttributeToSpreadAssignment) : map(attrs, transformJsxAttributeToObjectLiteralElement) - ) - ) - ); - } - else { - // Map spans of JsxAttribute nodes into object literals and spans - // of JsxSpreadAttribute nodes into expressions. - const segments = flatten( - spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread - ? map(attrs, transformJsxSpreadAttributeToExpression) - : factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement)) - ) - ); - - if (isJsxSpreadAttribute(attrs[0])) { - // We must always emit at least one object literal before a spread - // argument.factory.createObjectLiteral - segments.unshift(factory.createObjectLiteralExpression()); - } - - // Either emit one big object literal (no spread attribs), or - // a call to the __assign helper. - objectProperties = singleOrUndefined(segments); - if (!objectProperties) { - objectProperties = emitHelpers().createAssignHelper(segments); - } - } - } + const objectProperties = length(attrs) ? transformJsxAttributesToObjectProps(attrs) : + factory.createNull(); // When there are no attributes, React wants "null" const callee = currentFileState.importSpecifier === undefined ? createJsxFactoryExpression( @@ -392,6 +322,44 @@ namespace ts { return factory.createSpreadAssignment(visitNode(node.expression, visitor, isExpression)); } + function transformJsxAttributesToObjectProps(attrs: readonly(JsxSpreadAttribute | JsxAttribute)[], children?: PropertyAssignment) { + const target = getEmitScriptTarget(compilerOptions); + return target && target >= ScriptTarget.ES2018 ? factory.createObjectLiteralExpression(transformJsxAttributesToProps(attrs, children)) : + transformJsxAttributesToExpression(attrs, children); + } + + function transformJsxAttributesToProps(attrs: readonly(JsxSpreadAttribute | JsxAttribute)[], children?: PropertyAssignment) { + const props = flatten(spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => + map(attrs, attr => isSpread ? transformJsxSpreadAttributeToSpreadAssignment(attr as JsxSpreadAttribute) : transformJsxAttributeToObjectLiteralElement(attr as JsxAttribute)))); + if (children) { + props.push(children); + } + return props; + } + + function transformJsxAttributesToExpression(attrs: readonly(JsxSpreadAttribute | JsxAttribute)[], children?: PropertyAssignment) { + // Map spans of JsxAttribute nodes into object literals and spans + // of JsxSpreadAttribute nodes into expressions. + const expressions = flatten( + spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread + ? map(attrs, transformJsxSpreadAttributeToExpression) + : factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement)) + ) + ); + + if (isJsxSpreadAttribute(attrs[0])) { + // We must always emit at least one object literal before a spread + // argument.factory.createObjectLiteral + expressions.unshift(factory.createObjectLiteralExpression()); + } + + if (children) { + expressions.push(factory.createObjectLiteralExpression([children])); + } + + return singleOrUndefined(expressions) || emitHelpers().createAssignHelper(expressions); + } + function transformJsxSpreadAttributeToExpression(node: JsxSpreadAttribute) { return visitNode(node.expression, visitor, isExpression); } diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).js b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).js new file mode 100644 index 0000000000..24705934a2 --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).js @@ -0,0 +1,56 @@ +//// [test.tsx] +/// + +export function T1(a: any) { + return
T1
; +} + +export function T2(a: any, b: any) { + return
T2
; +} + +export function T3(a: any, b: any) { + return
T3
; +} + +export function T4(a: any, b: any) { + return
T4
; +} + +export function T5(a: any, b: any, c: any, d: any) { + return
T5
; +} + +export function T6(a: any, b: any, c: any, d: any) { + return
T6
; +} + +export function T7(a: any, b: any, c: any, d: any) { + return
T7
; +} + + +//// [test.js] +import { jsx as _jsx } from "react/jsx-runtime"; +/// +export function T1(a) { + return _jsx("div", Object.assign({ className: "T1" }, a, { children: "T1" }), void 0); +} +export function T2(a, b) { + return _jsx("div", Object.assign({ className: "T2" }, a, b, { children: "T2" }), void 0); +} +export function T3(a, b) { + return _jsx("div", Object.assign({}, a, { className: "T3" }, b, { children: "T3" }), void 0); +} +export function T4(a, b) { + return _jsx("div", Object.assign({ className: "T4" }, Object.assign(Object.assign({}, a), b), { children: "T4" }), void 0); +} +export function T5(a, b, c, d) { + return _jsx("div", Object.assign({ className: "T5" }, Object.assign(Object.assign(Object.assign({}, a), b), { c, d }), { children: "T5" }), void 0); +} +export function T6(a, b, c, d) { + return _jsx("div", Object.assign({ className: "T6" }, Object.assign(Object.assign(Object.assign({}, a), b), Object.assign(Object.assign({}, c), d)), { children: "T6" }), void 0); +} +export function T7(a, b, c, d) { + return _jsx("div", { children: "T7" }, void 0); +} diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).symbols b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).symbols new file mode 100644 index 0000000000..09b030724b --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).symbols @@ -0,0 +1,99 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : Symbol(T1, Decl(test.tsx, 0, 0)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) + + return
T1
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 3, 15)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T2(a: any, b: any) { +>T2 : Symbol(T2, Decl(test.tsx, 4, 1)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) + + return
T2
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 7, 15)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T3(a: any, b: any) { +>T3 : Symbol(T3, Decl(test.tsx, 8, 1)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) + + return
T3
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>className : Symbol(className, Decl(test.tsx, 11, 24)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T4(a: any, b: any) { +>T4 : Symbol(T4, Decl(test.tsx, 12, 1)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) + + return
T4
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 15, 15)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : Symbol(T5, Decl(test.tsx, 16, 1)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 18, 34)) +>d : Symbol(d, Decl(test.tsx, 18, 42)) + + return
T5
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 19, 15)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 19, 56)) +>d : Symbol(d, Decl(test.tsx, 19, 59)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : Symbol(T6, Decl(test.tsx, 20, 1)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) + + return
T6
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 23, 15)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : Symbol(T7, Decl(test.tsx, 24, 1)) +>a : Symbol(a, Decl(test.tsx, 26, 19)) +>b : Symbol(b, Decl(test.tsx, 26, 26)) +>c : Symbol(c, Decl(test.tsx, 26, 34)) +>d : Symbol(d, Decl(test.tsx, 26, 42)) + + return
T7
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).types b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).types new file mode 100644 index 0000000000..7fc232939b --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2015).types @@ -0,0 +1,117 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : (a: any) => JSX.Element +>a : any + + return
T1
; +>
T1
: JSX.Element +>div : any +>className : string +>"T1" : "T1" +>a : any +>div : any +} + +export function T2(a: any, b: any) { +>T2 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T2
; +>
T2
: JSX.Element +>div : any +>className : string +>"T2" : "T2" +>a : any +>b : any +>div : any +} + +export function T3(a: any, b: any) { +>T3 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T3
; +>
T3
: JSX.Element +>div : any +>a : any +>className : string +>"T3" : "T3" +>b : any +>div : any +} + +export function T4(a: any, b: any) { +>T4 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T4
; +>
T4
: JSX.Element +>div : any +>className : string +>"T4" : "T4" +>{ ...a, ...b } : any +>a : any +>b : any +>div : any +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T5
; +>
T5
: JSX.Element +>div : any +>className : string +>"T5" : "T5" +>{ ...a, ...b, ...{ c, d } } : any +>a : any +>b : any +>{ c, d } : { c: any; d: any; } +>c : any +>d : any +>div : any +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T6
; +>
T6
: JSX.Element +>div : any +>className : string +>"T6" : "T6" +>{ ...a, ...b, ...{ ...c, ...d } } : any +>a : any +>b : any +>{ ...c, ...d } : any +>c : any +>d : any +>div : any +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T7
; +>
T7
: JSX.Element +>div : any +>div : any +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).js b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).js new file mode 100644 index 0000000000..5e870a365b --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).js @@ -0,0 +1,56 @@ +//// [test.tsx] +/// + +export function T1(a: any) { + return
T1
; +} + +export function T2(a: any, b: any) { + return
T2
; +} + +export function T3(a: any, b: any) { + return
T3
; +} + +export function T4(a: any, b: any) { + return
T4
; +} + +export function T5(a: any, b: any, c: any, d: any) { + return
T5
; +} + +export function T6(a: any, b: any, c: any, d: any) { + return
T6
; +} + +export function T7(a: any, b: any, c: any, d: any) { + return
T7
; +} + + +//// [test.js] +import { jsx as _jsx } from "react/jsx-runtime"; +/// +export function T1(a) { + return _jsx("div", { className: "T1", ...a, children: "T1" }, void 0); +} +export function T2(a, b) { + return _jsx("div", { className: "T2", ...a, ...b, children: "T2" }, void 0); +} +export function T3(a, b) { + return _jsx("div", { ...a, className: "T3", ...b, children: "T3" }, void 0); +} +export function T4(a, b) { + return _jsx("div", { className: "T4", ...{ ...a, ...b }, children: "T4" }, void 0); +} +export function T5(a, b, c, d) { + return _jsx("div", { className: "T5", ...{ ...a, ...b, ...{ c, d } }, children: "T5" }, void 0); +} +export function T6(a, b, c, d) { + return _jsx("div", { className: "T6", ...{ ...a, ...b, ...{ ...c, ...d } }, children: "T6" }, void 0); +} +export function T7(a, b, c, d) { + return _jsx("div", { children: "T7" }, void 0); +} diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).symbols b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).symbols new file mode 100644 index 0000000000..09b030724b --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).symbols @@ -0,0 +1,99 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : Symbol(T1, Decl(test.tsx, 0, 0)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) + + return
T1
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 3, 15)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T2(a: any, b: any) { +>T2 : Symbol(T2, Decl(test.tsx, 4, 1)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) + + return
T2
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 7, 15)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T3(a: any, b: any) { +>T3 : Symbol(T3, Decl(test.tsx, 8, 1)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) + + return
T3
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>className : Symbol(className, Decl(test.tsx, 11, 24)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T4(a: any, b: any) { +>T4 : Symbol(T4, Decl(test.tsx, 12, 1)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) + + return
T4
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 15, 15)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : Symbol(T5, Decl(test.tsx, 16, 1)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 18, 34)) +>d : Symbol(d, Decl(test.tsx, 18, 42)) + + return
T5
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 19, 15)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 19, 56)) +>d : Symbol(d, Decl(test.tsx, 19, 59)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : Symbol(T6, Decl(test.tsx, 20, 1)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) + + return
T6
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 23, 15)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : Symbol(T7, Decl(test.tsx, 24, 1)) +>a : Symbol(a, Decl(test.tsx, 26, 19)) +>b : Symbol(b, Decl(test.tsx, 26, 26)) +>c : Symbol(c, Decl(test.tsx, 26, 34)) +>d : Symbol(d, Decl(test.tsx, 26, 42)) + + return
T7
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).types b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).types new file mode 100644 index 0000000000..7fc232939b --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=es2018).types @@ -0,0 +1,117 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : (a: any) => JSX.Element +>a : any + + return
T1
; +>
T1
: JSX.Element +>div : any +>className : string +>"T1" : "T1" +>a : any +>div : any +} + +export function T2(a: any, b: any) { +>T2 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T2
; +>
T2
: JSX.Element +>div : any +>className : string +>"T2" : "T2" +>a : any +>b : any +>div : any +} + +export function T3(a: any, b: any) { +>T3 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T3
; +>
T3
: JSX.Element +>div : any +>a : any +>className : string +>"T3" : "T3" +>b : any +>div : any +} + +export function T4(a: any, b: any) { +>T4 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T4
; +>
T4
: JSX.Element +>div : any +>className : string +>"T4" : "T4" +>{ ...a, ...b } : any +>a : any +>b : any +>div : any +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T5
; +>
T5
: JSX.Element +>div : any +>className : string +>"T5" : "T5" +>{ ...a, ...b, ...{ c, d } } : any +>a : any +>b : any +>{ c, d } : { c: any; d: any; } +>c : any +>d : any +>div : any +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T6
; +>
T6
: JSX.Element +>div : any +>className : string +>"T6" : "T6" +>{ ...a, ...b, ...{ ...c, ...d } } : any +>a : any +>b : any +>{ ...c, ...d } : any +>c : any +>d : any +>div : any +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T7
; +>
T7
: JSX.Element +>div : any +>div : any +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).js b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).js new file mode 100644 index 0000000000..5e870a365b --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).js @@ -0,0 +1,56 @@ +//// [test.tsx] +/// + +export function T1(a: any) { + return
T1
; +} + +export function T2(a: any, b: any) { + return
T2
; +} + +export function T3(a: any, b: any) { + return
T3
; +} + +export function T4(a: any, b: any) { + return
T4
; +} + +export function T5(a: any, b: any, c: any, d: any) { + return
T5
; +} + +export function T6(a: any, b: any, c: any, d: any) { + return
T6
; +} + +export function T7(a: any, b: any, c: any, d: any) { + return
T7
; +} + + +//// [test.js] +import { jsx as _jsx } from "react/jsx-runtime"; +/// +export function T1(a) { + return _jsx("div", { className: "T1", ...a, children: "T1" }, void 0); +} +export function T2(a, b) { + return _jsx("div", { className: "T2", ...a, ...b, children: "T2" }, void 0); +} +export function T3(a, b) { + return _jsx("div", { ...a, className: "T3", ...b, children: "T3" }, void 0); +} +export function T4(a, b) { + return _jsx("div", { className: "T4", ...{ ...a, ...b }, children: "T4" }, void 0); +} +export function T5(a, b, c, d) { + return _jsx("div", { className: "T5", ...{ ...a, ...b, ...{ c, d } }, children: "T5" }, void 0); +} +export function T6(a, b, c, d) { + return _jsx("div", { className: "T6", ...{ ...a, ...b, ...{ ...c, ...d } }, children: "T6" }, void 0); +} +export function T7(a, b, c, d) { + return _jsx("div", { children: "T7" }, void 0); +} diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).symbols b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).symbols new file mode 100644 index 0000000000..09b030724b --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).symbols @@ -0,0 +1,99 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : Symbol(T1, Decl(test.tsx, 0, 0)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) + + return
T1
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 3, 15)) +>a : Symbol(a, Decl(test.tsx, 2, 19)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T2(a: any, b: any) { +>T2 : Symbol(T2, Decl(test.tsx, 4, 1)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) + + return
T2
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 7, 15)) +>a : Symbol(a, Decl(test.tsx, 6, 19)) +>b : Symbol(b, Decl(test.tsx, 6, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T3(a: any, b: any) { +>T3 : Symbol(T3, Decl(test.tsx, 8, 1)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) + + return
T3
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>a : Symbol(a, Decl(test.tsx, 10, 19)) +>className : Symbol(className, Decl(test.tsx, 11, 24)) +>b : Symbol(b, Decl(test.tsx, 10, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T4(a: any, b: any) { +>T4 : Symbol(T4, Decl(test.tsx, 12, 1)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) + + return
T4
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 15, 15)) +>a : Symbol(a, Decl(test.tsx, 14, 19)) +>b : Symbol(b, Decl(test.tsx, 14, 26)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : Symbol(T5, Decl(test.tsx, 16, 1)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 18, 34)) +>d : Symbol(d, Decl(test.tsx, 18, 42)) + + return
T5
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 19, 15)) +>a : Symbol(a, Decl(test.tsx, 18, 19)) +>b : Symbol(b, Decl(test.tsx, 18, 26)) +>c : Symbol(c, Decl(test.tsx, 19, 56)) +>d : Symbol(d, Decl(test.tsx, 19, 59)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : Symbol(T6, Decl(test.tsx, 20, 1)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) + + return
T6
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>className : Symbol(className, Decl(test.tsx, 23, 15)) +>a : Symbol(a, Decl(test.tsx, 22, 19)) +>b : Symbol(b, Decl(test.tsx, 22, 26)) +>c : Symbol(c, Decl(test.tsx, 22, 34)) +>d : Symbol(d, Decl(test.tsx, 22, 42)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : Symbol(T7, Decl(test.tsx, 24, 1)) +>a : Symbol(a, Decl(test.tsx, 26, 19)) +>b : Symbol(b, Decl(test.tsx, 26, 26)) +>c : Symbol(c, Decl(test.tsx, 26, 34)) +>d : Symbol(d, Decl(test.tsx, 26, 42)) + + return
T7
; +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2546, 114)) +} + diff --git a/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).types b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).types new file mode 100644 index 0000000000..7fc232939b --- /dev/null +++ b/tests/baselines/reference/tsxReactEmitSpreadAttribute(target=esnext).types @@ -0,0 +1,117 @@ +=== tests/cases/conformance/jsx/test.tsx === +/// + +export function T1(a: any) { +>T1 : (a: any) => JSX.Element +>a : any + + return
T1
; +>
T1
: JSX.Element +>div : any +>className : string +>"T1" : "T1" +>a : any +>div : any +} + +export function T2(a: any, b: any) { +>T2 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T2
; +>
T2
: JSX.Element +>div : any +>className : string +>"T2" : "T2" +>a : any +>b : any +>div : any +} + +export function T3(a: any, b: any) { +>T3 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T3
; +>
T3
: JSX.Element +>div : any +>a : any +>className : string +>"T3" : "T3" +>b : any +>div : any +} + +export function T4(a: any, b: any) { +>T4 : (a: any, b: any) => JSX.Element +>a : any +>b : any + + return
T4
; +>
T4
: JSX.Element +>div : any +>className : string +>"T4" : "T4" +>{ ...a, ...b } : any +>a : any +>b : any +>div : any +} + +export function T5(a: any, b: any, c: any, d: any) { +>T5 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T5
; +>
T5
: JSX.Element +>div : any +>className : string +>"T5" : "T5" +>{ ...a, ...b, ...{ c, d } } : any +>a : any +>b : any +>{ c, d } : { c: any; d: any; } +>c : any +>d : any +>div : any +} + +export function T6(a: any, b: any, c: any, d: any) { +>T6 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T6
; +>
T6
: JSX.Element +>div : any +>className : string +>"T6" : "T6" +>{ ...a, ...b, ...{ ...c, ...d } } : any +>a : any +>b : any +>{ ...c, ...d } : any +>c : any +>d : any +>div : any +} + +export function T7(a: any, b: any, c: any, d: any) { +>T7 : (a: any, b: any, c: any, d: any) => JSX.Element +>a : any +>b : any +>c : any +>d : any + + return
T7
; +>
T7
: JSX.Element +>div : any +>div : any +} + diff --git a/tests/cases/conformance/jsx/tsxReactEmitSpreadAttribute.ts b/tests/cases/conformance/jsx/tsxReactEmitSpreadAttribute.ts new file mode 100644 index 0000000000..2ddc20ae39 --- /dev/null +++ b/tests/cases/conformance/jsx/tsxReactEmitSpreadAttribute.ts @@ -0,0 +1,32 @@ +// @jsx: react-jsx +// @target: es2015,es2018,esnext +// @filename: test.tsx +/// + +export function T1(a: any) { + return
T1
; +} + +export function T2(a: any, b: any) { + return
T2
; +} + +export function T3(a: any, b: any) { + return
T3
; +} + +export function T4(a: any, b: any) { + return
T4
; +} + +export function T5(a: any, b: any, c: any, d: any) { + return
T5
; +} + +export function T6(a: any, b: any, c: any, d: any) { + return
T6
; +} + +export function T7(a: any, b: any, c: any, d: any) { + return
T7
; +}