From a9736a603603f09cedb508964b886ee31d258e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 25 Sep 2023 20:13:45 +0200 Subject: [PATCH] Ensure all JSX spread properties get visited in ES2018+ --- src/compiler/transformers/jsx.ts | 4 +- ...=> jsxSpreadTag(target=es2015).errors.txt} | 0 ...dTag.js => jsxSpreadTag(target=es2015).js} | 0 ...ls => jsxSpreadTag(target=es2015).symbols} | 0 ...ypes => jsxSpreadTag(target=es2015).types} | 0 .../jsxSpreadTag(target=esnext).errors.txt | 36 +++++++ .../reference/jsxSpreadTag(target=esnext).js | 32 ++++++ .../jsxSpreadTag(target=esnext).symbols | 56 ++++++++++ .../jsxSpreadTag(target=esnext).types | 100 ++++++++++++++++++ tests/cases/compiler/jsxSpreadTag.ts | 2 +- 10 files changed, 228 insertions(+), 2 deletions(-) rename tests/baselines/reference/{jsxSpreadTag.errors.txt => jsxSpreadTag(target=es2015).errors.txt} (100%) rename tests/baselines/reference/{jsxSpreadTag.js => jsxSpreadTag(target=es2015).js} (100%) rename tests/baselines/reference/{jsxSpreadTag.symbols => jsxSpreadTag(target=es2015).symbols} (100%) rename tests/baselines/reference/{jsxSpreadTag.types => jsxSpreadTag(target=es2015).types} (100%) create mode 100644 tests/baselines/reference/jsxSpreadTag(target=esnext).errors.txt create mode 100644 tests/baselines/reference/jsxSpreadTag(target=esnext).js create mode 100644 tests/baselines/reference/jsxSpreadTag(target=esnext).symbols create mode 100644 tests/baselines/reference/jsxSpreadTag(target=esnext).types diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts index d0e191d537ad0..29c4f7b4f3c5a 100644 --- a/src/compiler/transformers/jsx.ts +++ b/src/compiler/transformers/jsx.ts @@ -36,6 +36,7 @@ import { isJsxSelfClosingElement, isJsxSpreadAttribute, isLineBreak, + isObjectLiteralElementLike, isObjectLiteralExpression, isPropertyAssignment, isSourceFile, @@ -63,6 +64,7 @@ import { ObjectLiteralElementLike, ObjectLiteralExpression, PropertyAssignment, + sameMap, ScriptTarget, setIdentifierGeneratedImportReference, setParentRecursive, @@ -444,7 +446,7 @@ export function transformJsx(context: TransformationContext): (x: SourceFile | B function transformJsxSpreadAttributeToProps(node: JsxSpreadAttribute) { if (isObjectLiteralExpression(node.expression) && !hasProto(node.expression)) { - return node.expression.properties; + return sameMap(node.expression.properties, p => Debug.checkDefined(visitNode(p, visitor, isObjectLiteralElementLike))); } return factory.createSpreadAssignment(Debug.checkDefined(visitNode(node.expression, visitor, isExpression))); } diff --git a/tests/baselines/reference/jsxSpreadTag.errors.txt b/tests/baselines/reference/jsxSpreadTag(target=es2015).errors.txt similarity index 100% rename from tests/baselines/reference/jsxSpreadTag.errors.txt rename to tests/baselines/reference/jsxSpreadTag(target=es2015).errors.txt diff --git a/tests/baselines/reference/jsxSpreadTag.js b/tests/baselines/reference/jsxSpreadTag(target=es2015).js similarity index 100% rename from tests/baselines/reference/jsxSpreadTag.js rename to tests/baselines/reference/jsxSpreadTag(target=es2015).js diff --git a/tests/baselines/reference/jsxSpreadTag.symbols b/tests/baselines/reference/jsxSpreadTag(target=es2015).symbols similarity index 100% rename from tests/baselines/reference/jsxSpreadTag.symbols rename to tests/baselines/reference/jsxSpreadTag(target=es2015).symbols diff --git a/tests/baselines/reference/jsxSpreadTag.types b/tests/baselines/reference/jsxSpreadTag(target=es2015).types similarity index 100% rename from tests/baselines/reference/jsxSpreadTag.types rename to tests/baselines/reference/jsxSpreadTag(target=es2015).types diff --git a/tests/baselines/reference/jsxSpreadTag(target=esnext).errors.txt b/tests/baselines/reference/jsxSpreadTag(target=esnext).errors.txt new file mode 100644 index 0000000000000..56375b473f63a --- /dev/null +++ b/tests/baselines/reference/jsxSpreadTag(target=esnext).errors.txt @@ -0,0 +1,36 @@ +/a.tsx(5,13): error TS2304: Cannot find name 'Comp'. +/a.tsx(9,13): error TS2304: Cannot find name 'Comp'. +/a.tsx(13,13): error TS2304: Cannot find name 'Comp'. +/a.tsx(17,13): error TS2304: Cannot find name 'Comp'. + + +==== /a.tsx (4 errors) ==== + declare const React: any; + + const t1 =
} />; + const t2 =
} />; + const t3 = x
} + {...{ wrong:
x
}} + />; + const t4 = x
} + {...{ wrong() { return
x
; }}} + />; + const t5 = x} + {...{ get wrong() { return
x
; }}} + />; + const t6 = x} + {...{ set wrong(s) { let a =
x
; }}} + />; + \ No newline at end of file diff --git a/tests/baselines/reference/jsxSpreadTag(target=esnext).js b/tests/baselines/reference/jsxSpreadTag(target=esnext).js new file mode 100644 index 0000000000000..e08bd32974457 --- /dev/null +++ b/tests/baselines/reference/jsxSpreadTag(target=esnext).js @@ -0,0 +1,32 @@ +//// [tests/cases/compiler/jsxSpreadTag.ts] //// + +//// [a.tsx] +declare const React: any; + +const t1 =
} />; +const t2 =
} />; +const t3 = x
} + {...{ wrong:
x
}} +/>; +const t4 = x
} + {...{ wrong() { return
x
; }}} +/>; +const t5 = x} + {...{ get wrong() { return
x
; }}} +/>; +const t6 = x} + {...{ set wrong(s) { let a =
x
; }}} +/>; + + +//// [a.js] +const t1 = React.createElement("div", { ...React.createElement("span", null) }); +const t2 = React.createElement("div", { ...React.createElement("span", { className: "foo" }) }); +const t3 = React.createElement(Comp, { right: React.createElement("div", null, "x"), wrong: React.createElement("div", null, "x") }); +const t4 = React.createElement(Comp, { right: React.createElement("div", null, "x"), wrong() { return React.createElement("div", null, "x"); } }); +const t5 = React.createElement(Comp, { right: React.createElement("div", null, "x"), get wrong() { return React.createElement("div", null, "x"); } }); +const t6 = React.createElement(Comp, { right: React.createElement("div", null, "x"), set wrong(s) { let a = React.createElement("div", null, "x"); } }); diff --git a/tests/baselines/reference/jsxSpreadTag(target=esnext).symbols b/tests/baselines/reference/jsxSpreadTag(target=esnext).symbols new file mode 100644 index 0000000000000..924dceb10df6e --- /dev/null +++ b/tests/baselines/reference/jsxSpreadTag(target=esnext).symbols @@ -0,0 +1,56 @@ +//// [tests/cases/compiler/jsxSpreadTag.ts] //// + +=== /a.tsx === +declare const React: any; +>React : Symbol(React, Decl(a.tsx, 0, 13)) + +const t1 =
} />; +>t1 : Symbol(t1, Decl(a.tsx, 2, 5)) + +const t2 =
} />; +>t2 : Symbol(t2, Decl(a.tsx, 3, 5)) +>className : Symbol(className, Decl(a.tsx, 3, 25)) + +const t3 = t3 : Symbol(t3, Decl(a.tsx, 4, 5)) + + right={
x
} +>right : Symbol(right, Decl(a.tsx, 4, 16)) + + {...{ wrong:
x
}} +>wrong : Symbol(wrong, Decl(a.tsx, 6, 9)) + +/>; +const t4 = t4 : Symbol(t4, Decl(a.tsx, 8, 5)) + + right={
x
} +>right : Symbol(right, Decl(a.tsx, 8, 16)) + + {...{ wrong() { return
x
; }}} +>wrong : Symbol(wrong, Decl(a.tsx, 10, 9)) + +/>; +const t5 = t5 : Symbol(t5, Decl(a.tsx, 12, 5)) + + right={
x
} +>right : Symbol(right, Decl(a.tsx, 12, 16)) + + {...{ get wrong() { return
x
; }}} +>wrong : Symbol(wrong, Decl(a.tsx, 14, 9)) + +/>; +const t6 = t6 : Symbol(t6, Decl(a.tsx, 16, 5)) + + right={
x
} +>right : Symbol(right, Decl(a.tsx, 16, 16)) + + {...{ set wrong(s) { let a =
x
; }}} +>wrong : Symbol(wrong, Decl(a.tsx, 18, 9)) +>s : Symbol(s, Decl(a.tsx, 18, 20)) +>a : Symbol(a, Decl(a.tsx, 18, 28)) + +/>; + diff --git a/tests/baselines/reference/jsxSpreadTag(target=esnext).types b/tests/baselines/reference/jsxSpreadTag(target=esnext).types new file mode 100644 index 0000000000000..2ba64ac4526c7 --- /dev/null +++ b/tests/baselines/reference/jsxSpreadTag(target=esnext).types @@ -0,0 +1,100 @@ +//// [tests/cases/compiler/jsxSpreadTag.ts] //// + +=== /a.tsx === +declare const React: any; +>React : any + +const t1 =
} />; +>t1 : any +>
} /> : any +>div : any +> : any +>span : any + +const t2 =
} />; +>t2 : any +>
} /> : any +>div : any +> : any +>span : any +>className : string + +const t3 = t3 : any +>x
} {...{ wrong:
x
}}/> : any +>Comp : any + + right={
x
} +>right : any +>
x
: any +>div : any +>div : any + + {...{ wrong:
x
}} +>{ wrong:
x
} : { wrong: any; } +>wrong : any +>
x
: any +>div : any +>div : any + +/>; +const t4 = t4 : any +>x
} {...{ wrong() { return
x
; }}}/> : any +>Comp : any + + right={
x
} +>right : any +>
x
: any +>div : any +>div : any + + {...{ wrong() { return
x
; }}} +>{ wrong() { return
x
; }} : { wrong(): any; } +>wrong : () => any +>
x
: any +>div : any +>div : any + +/>; +const t5 = t5 : any +>x
} {...{ get wrong() { return
x
; }}}/> : any +>Comp : any + + right={
x
} +>right : any +>
x
: any +>div : any +>div : any + + {...{ get wrong() { return
x
; }}} +>{ get wrong() { return
x
; }} : { readonly wrong: any; } +>wrong : any +>
x
: any +>div : any +>div : any + +/>; +const t6 = t6 : any +>x
} {...{ set wrong(s) { let a =
x
; }}}/> : any +>Comp : any + + right={
x
} +>right : any +>
x
: any +>div : any +>div : any + + {...{ set wrong(s) { let a =
x
; }}} +>{ set wrong(s) { let a =
x
; }} : { wrong: any; } +>wrong : any +>s : any +>a : any +>
x
: any +>div : any +>div : any + +/>; + diff --git a/tests/cases/compiler/jsxSpreadTag.ts b/tests/cases/compiler/jsxSpreadTag.ts index f767497f442ee..06e5fec1f6ab0 100644 --- a/tests/cases/compiler/jsxSpreadTag.ts +++ b/tests/cases/compiler/jsxSpreadTag.ts @@ -1,5 +1,5 @@ // @jsx: react -// @target: es2015 +// @target: es2015,esnext // @filename: /a.tsx declare const React: any;