mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-09 12:15:34 -06:00
Ensure whitespace jsx elements are not counted when determining if a jsx child is the only child (#40839)
* Ensure whitespace jsx elements are not counted when determining if a jsx child is the only child * Use filtered children count for deciding constructor used * Accept updated baselines post-merge
This commit is contained in:
parent
5fbe9806db
commit
3ea81e652a
@ -26,12 +26,12 @@ namespace ts {
|
||||
return currentFileState.filenameDeclaration.name;
|
||||
}
|
||||
|
||||
function getJsxFactoryCalleePrimitive(children: readonly JsxChild[] | undefined): "jsx" | "jsxs" | "jsxDEV" {
|
||||
return compilerOptions.jsx === JsxEmit.ReactJSXDev ? "jsxDEV" : children && children.length > 1 ? "jsxs" : "jsx";
|
||||
function getJsxFactoryCalleePrimitive(childrenLength: number): "jsx" | "jsxs" | "jsxDEV" {
|
||||
return compilerOptions.jsx === JsxEmit.ReactJSXDev ? "jsxDEV" : childrenLength > 1 ? "jsxs" : "jsx";
|
||||
}
|
||||
|
||||
function getJsxFactoryCallee(children: readonly JsxChild[] | undefined) {
|
||||
const type = getJsxFactoryCalleePrimitive(children);
|
||||
function getJsxFactoryCallee(childrenLength: number) {
|
||||
const type = getJsxFactoryCalleePrimitive(childrenLength);
|
||||
return getImplicitImportForName(type);
|
||||
}
|
||||
|
||||
@ -191,8 +191,9 @@ namespace ts {
|
||||
}
|
||||
|
||||
function convertJsxChildrenToChildrenPropObject(children: readonly JsxChild[]) {
|
||||
if (children.length === 1) {
|
||||
const result = transformJsxChildToExpression(children[0]);
|
||||
const nonWhitespaceChildren = filter(children, c => !isJsxText(c) || !c.containsOnlyTriviaWhiteSpaces);
|
||||
if (length(nonWhitespaceChildren) === 1) {
|
||||
const result = transformJsxChildToExpression(nonWhitespaceChildren[0]);
|
||||
return result && factory.createObjectLiteralExpression([
|
||||
factory.createPropertyAssignment("children", result)
|
||||
]);
|
||||
@ -243,16 +244,16 @@ namespace ts {
|
||||
objectProperties = singleOrUndefined(segments) || emitHelpers().createAssignHelper(segments);
|
||||
}
|
||||
|
||||
return visitJsxOpeningLikeElementOrFragmentJSX(tagName, objectProperties, keyAttr, children, isChild, location);
|
||||
return visitJsxOpeningLikeElementOrFragmentJSX(tagName, objectProperties, keyAttr, length(filter(children, c => !isJsxText(c) || !c.containsOnlyTriviaWhiteSpaces)), isChild, location);
|
||||
}
|
||||
|
||||
function visitJsxOpeningLikeElementOrFragmentJSX(tagName: Expression, objectProperties: Expression, keyAttr: JsxAttribute | undefined, children: readonly JsxChild[] | undefined, isChild: boolean, location: TextRange) {
|
||||
function visitJsxOpeningLikeElementOrFragmentJSX(tagName: Expression, objectProperties: Expression, keyAttr: JsxAttribute | undefined, childrenLength: number, isChild: boolean, location: TextRange) {
|
||||
const args: Expression[] = [tagName, objectProperties, !keyAttr ? factory.createVoidZero() : transformJsxAttributeInitializer(keyAttr.initializer)];
|
||||
if (compilerOptions.jsx === JsxEmit.ReactJSXDev) {
|
||||
const originalFile = getOriginalNode(currentSourceFile);
|
||||
if (originalFile && isSourceFile(originalFile)) {
|
||||
// isStaticChildren development flag
|
||||
args.push(children && children.length > 1 ? factory.createTrue() : factory.createFalse());
|
||||
args.push(childrenLength > 1 ? factory.createTrue() : factory.createFalse());
|
||||
// __source development flag
|
||||
const lineCol = getLineAndCharacterOfPosition(originalFile, location.pos);
|
||||
args.push(factory.createObjectLiteralExpression([
|
||||
@ -264,7 +265,7 @@ namespace ts {
|
||||
args.push(factory.createThis());
|
||||
}
|
||||
}
|
||||
const element = setTextRange(factory.createCallExpression(getJsxFactoryCallee(children), /*typeArguments*/ undefined, args), location);
|
||||
const element = setTextRange(factory.createCallExpression(getJsxFactoryCallee(childrenLength), /*typeArguments*/ undefined, args), location);
|
||||
|
||||
if (isChild) {
|
||||
startOnNewLine(element);
|
||||
@ -335,7 +336,7 @@ namespace ts {
|
||||
getImplicitJsxFragmentReference(),
|
||||
childrenProps || factory.createObjectLiteralExpression([]),
|
||||
/*keyAttr*/ undefined,
|
||||
children,
|
||||
length(filter(children, c => !isJsxText(c) || !c.containsOnlyTriviaWhiteSpaces)),
|
||||
isChild,
|
||||
location
|
||||
);
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
//// [jsxJsxsCjsTransformNestedSelfClosingChild.tsx]
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
import type * as React from 'react';
|
||||
|
||||
console.log(
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
)
|
||||
|
||||
console.log(
|
||||
<div>
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
)
|
||||
|
||||
console.log(
|
||||
<div>
|
||||
{[1, 2].map(i => <div key={i}>{i}</div>)}
|
||||
</div>
|
||||
)
|
||||
|
||||
//// [jsxJsxsCjsTransformNestedSelfClosingChild.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var jsx_runtime_js_1 = require("react/jsx-runtime.js");
|
||||
console.log(jsx_runtime_js_1.jsx("div", { children: jsx_runtime_js_1.jsx("div", {}, void 0) }, void 0));
|
||||
console.log(jsx_runtime_js_1.jsxs("div", { children: [jsx_runtime_js_1.jsx("div", {}, void 0),
|
||||
jsx_runtime_js_1.jsx("div", {}, void 0)] }, void 0));
|
||||
console.log(jsx_runtime_js_1.jsx("div", { children: [1, 2].map(function (i) { return jsx_runtime_js_1.jsx("div", { children: i }, i); }) }, void 0));
|
||||
@ -0,0 +1,62 @@
|
||||
=== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformNestedSelfClosingChild.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
import type * as React from 'react';
|
||||
>React : Symbol(React, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 1, 11))
|
||||
|
||||
console.log(
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
<div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
<div />
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
</div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
)
|
||||
|
||||
console.log(
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
<div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
<div />
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
<div />
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
</div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
)
|
||||
|
||||
console.log(
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
<div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
{[1, 2].map(i => <div key={i}>{i}</div>)}
|
||||
>[1, 2].map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
|
||||
>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
|
||||
>i : Symbol(i, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 18, 16))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
>key : Symbol(key, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 18, 25))
|
||||
>i : Symbol(i, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 18, 16))
|
||||
>i : Symbol(i, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 18, 16))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
</div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
)
|
||||
@ -0,0 +1,77 @@
|
||||
=== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformNestedSelfClosingChild.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
import type * as React from 'react';
|
||||
>React : typeof React
|
||||
|
||||
console.log(
|
||||
>console.log( <div> <div /> </div>) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
|
||||
<div>
|
||||
><div> <div /> </div> : JSX.Element
|
||||
>div : any
|
||||
|
||||
<div />
|
||||
><div /> : JSX.Element
|
||||
>div : any
|
||||
|
||||
</div>
|
||||
>div : any
|
||||
|
||||
)
|
||||
|
||||
console.log(
|
||||
>console.log( <div> <div /> <div /> </div>) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
|
||||
<div>
|
||||
><div> <div /> <div /> </div> : JSX.Element
|
||||
>div : any
|
||||
|
||||
<div />
|
||||
><div /> : JSX.Element
|
||||
>div : any
|
||||
|
||||
<div />
|
||||
><div /> : JSX.Element
|
||||
>div : any
|
||||
|
||||
</div>
|
||||
>div : any
|
||||
|
||||
)
|
||||
|
||||
console.log(
|
||||
>console.log( <div> {[1, 2].map(i => <div key={i}>{i}</div>)} </div>) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
|
||||
<div>
|
||||
><div> {[1, 2].map(i => <div key={i}>{i}</div>)} </div> : JSX.Element
|
||||
>div : any
|
||||
|
||||
{[1, 2].map(i => <div key={i}>{i}</div>)}
|
||||
>[1, 2].map(i => <div key={i}>{i}</div>) : JSX.Element[]
|
||||
>[1, 2].map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
|
||||
>[1, 2] : number[]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
|
||||
>i => <div key={i}>{i}</div> : (i: number) => JSX.Element
|
||||
>i : number
|
||||
><div key={i}>{i}</div> : JSX.Element
|
||||
>div : any
|
||||
>key : number
|
||||
>i : number
|
||||
>i : number
|
||||
>div : any
|
||||
|
||||
</div>
|
||||
>div : any
|
||||
|
||||
)
|
||||
@ -0,0 +1,33 @@
|
||||
//// [jsxJsxsCjsTransformNestedSelfClosingChild.tsx]
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
import type * as React from 'react';
|
||||
|
||||
console.log(
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
)
|
||||
|
||||
console.log(
|
||||
<div>
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
)
|
||||
|
||||
console.log(
|
||||
<div>
|
||||
{[1, 2].map(i => <div key={i}>{i}</div>)}
|
||||
</div>
|
||||
)
|
||||
|
||||
//// [jsxJsxsCjsTransformNestedSelfClosingChild.js]
|
||||
"use strict";
|
||||
var _this = this;
|
||||
exports.__esModule = true;
|
||||
var jsx_dev_runtime_js_1 = require("react/jsx-dev-runtime.js");
|
||||
var _jsxFileName = "tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformNestedSelfClosingChild.tsx";
|
||||
console.log(jsx_dev_runtime_js_1.jsxDEV("div", { children: jsx_dev_runtime_js_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 6, columnNumber: 5 }, this) }, void 0, false, { fileName: _jsxFileName, lineNumber: 4, columnNumber: 13 }, this));
|
||||
console.log(jsx_dev_runtime_js_1.jsxDEV("div", { children: [jsx_dev_runtime_js_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 12, columnNumber: 5 }, this),
|
||||
jsx_dev_runtime_js_1.jsxDEV("div", {}, void 0, false, { fileName: _jsxFileName, lineNumber: 13, columnNumber: 5 }, this)] }, void 0, true, { fileName: _jsxFileName, lineNumber: 10, columnNumber: 13 }, this));
|
||||
console.log(jsx_dev_runtime_js_1.jsxDEV("div", { children: [1, 2].map(function (i) { return jsx_dev_runtime_js_1.jsxDEV("div", { children: i }, i, false, { fileName: _jsxFileName, lineNumber: 19, columnNumber: 21 }, _this); }) }, void 0, false, { fileName: _jsxFileName, lineNumber: 17, columnNumber: 13 }, this));
|
||||
@ -0,0 +1,62 @@
|
||||
=== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformNestedSelfClosingChild.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
import type * as React from 'react';
|
||||
>React : Symbol(React, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 1, 11))
|
||||
|
||||
console.log(
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
<div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
<div />
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
</div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
)
|
||||
|
||||
console.log(
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
<div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
<div />
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
<div />
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
</div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
)
|
||||
|
||||
console.log(
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
|
||||
<div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
{[1, 2].map(i => <div key={i}>{i}</div>)}
|
||||
>[1, 2].map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
|
||||
>map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --))
|
||||
>i : Symbol(i, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 18, 16))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
>key : Symbol(key, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 18, 25))
|
||||
>i : Symbol(i, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 18, 16))
|
||||
>i : Symbol(i, Decl(jsxJsxsCjsTransformNestedSelfClosingChild.tsx, 18, 16))
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
</div>
|
||||
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
|
||||
|
||||
)
|
||||
@ -0,0 +1,77 @@
|
||||
=== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformNestedSelfClosingChild.tsx ===
|
||||
/// <reference path="react16.d.ts" />
|
||||
import type * as React from 'react';
|
||||
>React : typeof React
|
||||
|
||||
console.log(
|
||||
>console.log( <div> <div /> </div>) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
|
||||
<div>
|
||||
><div> <div /> </div> : JSX.Element
|
||||
>div : any
|
||||
|
||||
<div />
|
||||
><div /> : JSX.Element
|
||||
>div : any
|
||||
|
||||
</div>
|
||||
>div : any
|
||||
|
||||
)
|
||||
|
||||
console.log(
|
||||
>console.log( <div> <div /> <div /> </div>) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
|
||||
<div>
|
||||
><div> <div /> <div /> </div> : JSX.Element
|
||||
>div : any
|
||||
|
||||
<div />
|
||||
><div /> : JSX.Element
|
||||
>div : any
|
||||
|
||||
<div />
|
||||
><div /> : JSX.Element
|
||||
>div : any
|
||||
|
||||
</div>
|
||||
>div : any
|
||||
|
||||
)
|
||||
|
||||
console.log(
|
||||
>console.log( <div> {[1, 2].map(i => <div key={i}>{i}</div>)} </div>) : void
|
||||
>console.log : (...data: any[]) => void
|
||||
>console : Console
|
||||
>log : (...data: any[]) => void
|
||||
|
||||
<div>
|
||||
><div> {[1, 2].map(i => <div key={i}>{i}</div>)} </div> : JSX.Element
|
||||
>div : any
|
||||
|
||||
{[1, 2].map(i => <div key={i}>{i}</div>)}
|
||||
>[1, 2].map(i => <div key={i}>{i}</div>) : JSX.Element[]
|
||||
>[1, 2].map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
|
||||
>[1, 2] : number[]
|
||||
>1 : 1
|
||||
>2 : 2
|
||||
>map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
|
||||
>i => <div key={i}>{i}</div> : (i: number) => JSX.Element
|
||||
>i : number
|
||||
><div key={i}>{i}</div> : JSX.Element
|
||||
>div : any
|
||||
>key : number
|
||||
>i : number
|
||||
>i : number
|
||||
>div : any
|
||||
|
||||
</div>
|
||||
>div : any
|
||||
|
||||
)
|
||||
@ -0,0 +1,24 @@
|
||||
// @jsx: react-jsx,react-jsxdev
|
||||
// @strict: true
|
||||
// @module: commonjs
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
import type * as React from 'react';
|
||||
|
||||
console.log(
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
)
|
||||
|
||||
console.log(
|
||||
<div>
|
||||
<div />
|
||||
<div />
|
||||
</div>
|
||||
)
|
||||
|
||||
console.log(
|
||||
<div>
|
||||
{[1, 2].map(i => <div key={i}>{i}</div>)}
|
||||
</div>
|
||||
)
|
||||
Loading…
x
Reference in New Issue
Block a user