fix(es/react): Allow spread children (#6505)

**Related issue:**

 - Closes https://github.com/swc-project/swc/issues/2037.
This commit is contained in:
Donny/강동윤 2022-11-25 00:21:51 +09:00 committed by GitHub
parent bc61b0948a
commit 90aa6c8318
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 242 additions and 119 deletions

View File

@ -1,3 +1,6 @@
var A = function() { var A = function() {
return /*#__PURE__*/ React.createElement("div", null); return /*#__PURE__*/ React.createElement.apply(React, [
"div",
null
]);
}; };

View File

@ -3,22 +3,106 @@ export { };
//// [renderer2.d.ts] //// [renderer2.d.ts]
export { }; export { };
//// [component.tsx] //// [component.tsx]
//! /** @jsx predom */ import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
//! x Spread children are not supported in React. import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
//! ,---- var _this = this;
//! 4 | export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => <p>{props.x} + {props.y} = {props.x + props.y}{...this.props.children}</p>; import { predom } from "./renderer2";
//! : ^^^^^^^^^^^^^^^^^^^^^^^^ export var MySFC = function(props) {
//! `---- return /*#__PURE__*/ predom.apply(void 0, [
//! "p",
//! x Spread children are not supported in React. null,
//! ,---- props.x,
//! 12 | {...this.props.children} " + ",
//! : ^^^^^^^^^^^^^^^^^^^^^^^^ props.y,
//! `---- " = ",
props.x + props.y
].concat(_to_consumable_array(_this.props.children)));
};
export var MyClass = /*#__PURE__*/ function() {
"use strict";
function MyClass(props) {
_class_call_check(this, MyClass);
this.props = props;
}
var _proto = MyClass.prototype;
_proto.render = function render() {
return /*#__PURE__*/ predom.apply(void 0, [
"p",
null,
this.props.x,
" + ",
this.props.y,
" = ",
this.props.x + this.props.y
].concat(_to_consumable_array(this.props.children)));
};
return MyClass;
}();
export var tree = /*#__PURE__*/ predom(MySFC, {
x: 1,
y: 2
}, /*#__PURE__*/ predom(MyClass, {
x: 3,
y: 4
}), /*#__PURE__*/ predom(MyClass, {
x: 5,
y: 6
}));
export default /*#__PURE__*/ predom("h", null);
//// [index.tsx] //// [index.tsx]
//! /** @jsx dom */ import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
//! x Spread children are not supported in React. import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
//! ,---- import { dom } from "./renderer";
//! 13 | return <p>{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}</p>; import prerendered, { MySFC, MyClass, tree } from "./component";
//! : ^^^^^^^^^^^^^^^^^^^^^^^^ var elem = prerendered;
//! `---- elem = /*#__PURE__*/ dom("h", null); // Expect assignability error here
var DOMSFC = function(props) {
return /*#__PURE__*/ dom("p", null, props.x, " + ", props.y, " = ", props.x + props.y, props.children);
};
var DOMClass = /*#__PURE__*/ function() {
"use strict";
function DOMClass(props) {
_class_call_check(this, DOMClass);
this.props = props;
}
var _proto = DOMClass.prototype;
_proto.render = function render() {
return /*#__PURE__*/ dom.apply(void 0, [
"p",
null,
this.props.x,
" + ",
this.props.y,
" = ",
this.props.x + this.props.y
].concat(_to_consumable_array(this.props.children)));
};
return DOMClass;
}();
// Should work, everything is a DOM element
var _tree = /*#__PURE__*/ dom(DOMSFC, {
x: 1,
y: 2
}, /*#__PURE__*/ dom(DOMClass, {
x: 3,
y: 4
}), /*#__PURE__*/ dom(DOMClass, {
x: 5,
y: 6
}));
// Should fail, no dom elements
var _brokenTree = /*#__PURE__*/ dom(MySFC, {
x: 1,
y: 2
}, /*#__PURE__*/ dom(MyClass, {
x: 3,
y: 4
}), /*#__PURE__*/ dom(MyClass, {
x: 5,
y: 6
}));
// Should fail, nondom isn't allowed as children of dom
var _brokenTree2 = /*#__PURE__*/ dom(DOMSFC, {
x: 1,
y: 2
}, tree, tree);

View File

@ -3,22 +3,51 @@ export { };
//// [renderer2.d.ts] //// [renderer2.d.ts]
export { }; export { };
//// [component.tsx] //// [component.tsx]
//! import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
//! x Spread children are not supported in React. import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
//! ,---- var _this = this;
//! 4 | export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => <p>{props.x} + {props.y} = {props.x + props.y}{...this.props.children}</p>; import { predom } from "./renderer2";
//! : ^^^^^^^^^^^^^^^^^^^^^^^^ export var MySFC = function(props) {
//! `---- return predom.apply(void 0, [
//! "p",
//! x Spread children are not supported in React. null,
//! ,---- props.x,
//! 12 | {...this.props.children} " + ",
//! : ^^^^^^^^^^^^^^^^^^^^^^^^ props.y,
//! `---- " = ",
props.x + props.y
].concat(_to_consumable_array(_this.props.children)));
};
export var MyClass = function() {
"use strict";
function MyClass(props) {
_class_call_check(this, MyClass), this.props = props;
}
return MyClass.prototype.render = function() {
return predom.apply(void 0, [
"p",
null,
this.props.x,
" + ",
this.props.y,
" = ",
this.props.x + this.props.y
].concat(_to_consumable_array(this.props.children)));
}, MyClass;
}();
export var tree = predom(MySFC, {
x: 1,
y: 2
}, predom(MyClass, {
x: 3,
y: 4
}), predom(MyClass, {
x: 5,
y: 6
}));
export default predom("h", null);
//// [index.tsx] //// [index.tsx]
//! import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
//! x Spread children are not supported in React. import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
//! ,---- import { dom } from "./renderer";
//! 13 | return <p>{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}</p>; import prerendered, { MySFC, MyClass, tree } from "./component";
//! : ^^^^^^^^^^^^^^^^^^^^^^^^
//! `----

View File

@ -1,7 +1,20 @@
//// [tsxSpreadChildren.tsx] //// [tsxSpreadChildren.tsx]
//! import _extends from "@swc/helpers/src/_extends.mjs";
//! x Spread children are not supported in React. import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
//! ,---- function Todo(prop) {
//! 22 | {...todos.map(todo => <Todo key={todo.id} todo={todo.todo}/>)} return /*#__PURE__*/ React.createElement("div", null, prop.key.toString() + prop.todo);
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ }
//! `---- function TodoList(param) {
var todos = param.todos;
return /*#__PURE__*/ React.createElement.apply(React, [
"div",
null
].concat(_to_consumable_array(todos.map(function(todo) {
return /*#__PURE__*/ React.createElement(Todo, {
key: todo.id,
todo: todo.todo
});
}))));
}
var x;
/*#__PURE__*/ React.createElement(TodoList, _extends({}, x));

View File

@ -1,7 +1,5 @@
//// [tsxSpreadChildren.tsx] //// [tsxSpreadChildren.tsx]
//! var x;
//! x Spread children are not supported in React. import _extends from "@swc/helpers/src/_extends.mjs";
//! ,---- import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
//! 22 | {...todos.map(todo => <Todo key={todo.id} todo={todo.todo}/>)} _extends({}, x);
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! `----

View File

@ -1,13 +1,20 @@
//// [tsxSpreadChildrenInvalidType.tsx] //// [tsxSpreadChildrenInvalidType.tsx]
//! import _extends from "@swc/helpers/src/_extends.mjs";
//! x Spread children are not supported in React. function Todo(prop) {
//! ,---- return /*#__PURE__*/ React.createElement("div", null, prop.key.toString() + prop.todo);
//! 21 | {...<Todo key={todos[0].id} todo={todos[0].todo} />} }
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function TodoList({ todos }) {
//! `---- return /*#__PURE__*/ React.createElement("div", null, .../*#__PURE__*/ React.createElement(Todo, {
//! key: todos[0].id,
//! x Spread children are not supported in React. todo: todos[0].todo
//! ,---- }));
//! 27 | {...(<Todo key={todos[0].id} todo={todos[0].todo} /> as any)} }
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function TodoListNoError({ todos }) {
//! `---- // any is not checked
return /*#__PURE__*/ React.createElement("div", null, .../*#__PURE__*/ React.createElement(Todo, {
key: todos[0].id,
todo: todos[0].todo
}));
}
let x;
/*#__PURE__*/ React.createElement(TodoList, _extends({}, x));

View File

@ -1,13 +1,4 @@
//// [tsxSpreadChildrenInvalidType.tsx] //// [tsxSpreadChildrenInvalidType.tsx]
//! let x;
//! x Spread children are not supported in React. import _extends from "@swc/helpers/src/_extends.mjs";
//! ,---- _extends({}, x);
//! 21 | {...<Todo key={todos[0].id} todo={todos[0].todo} />}
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! `----
//!
//! x Spread children are not supported in React.
//! ,----
//! 27 | {...(<Todo key={todos[0].id} todo={todos[0].todo} /> as any)}
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! `----

View File

@ -1,13 +1,29 @@
//// [tsxSpreadChildrenInvalidType.tsx] //// [tsxSpreadChildrenInvalidType.tsx]
//! import _extends from "@swc/helpers/src/_extends.mjs";
//! x Spread children are not supported in React. import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
//! ,---- function Todo(prop) {
//! 21 | {...<Todo key={todos[0].id} todo={todos[0].todo} />} return /*#__PURE__*/ React.createElement("div", null, prop.key.toString() + prop.todo);
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ }
//! `---- function TodoList(param) {
//! var todos = param.todos;
//! x Spread children are not supported in React. return /*#__PURE__*/ React.createElement.apply(React, [
//! ,---- "div",
//! 27 | {...(<Todo key={todos[0].id} todo={todos[0].todo} /> as any)} null
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ].concat(_to_consumable_array(/*#__PURE__*/ React.createElement(Todo, {
//! `---- key: todos[0].id,
todo: todos[0].todo
}))));
}
function TodoListNoError(param) {
var todos = param.todos;
// any is not checked
return /*#__PURE__*/ React.createElement.apply(React, [
"div",
null
].concat(_to_consumable_array(/*#__PURE__*/ React.createElement(Todo, {
key: todos[0].id,
todo: todos[0].todo
}))));
}
var x;
/*#__PURE__*/ React.createElement(TodoList, _extends({}, x));

View File

@ -1,13 +1,5 @@
//// [tsxSpreadChildrenInvalidType.tsx] //// [tsxSpreadChildrenInvalidType.tsx]
//! var x;
//! x Spread children are not supported in React. import _extends from "@swc/helpers/src/_extends.mjs";
//! ,---- import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
//! 21 | {...<Todo key={todos[0].id} todo={todos[0].todo} />} _extends({}, x);
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! `----
//!
//! x Spread children are not supported in React.
//! ,----
//! 27 | {...(<Todo key={todos[0].id} todo={todos[0].todo} /> as any)}
//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//! `----

View File

@ -769,14 +769,10 @@ where
}) => return None, }) => return None,
JSXElementChild::JSXElement(el) => self.jsx_elem_to_expr(*el).as_arg(), JSXElementChild::JSXElement(el) => self.jsx_elem_to_expr(*el).as_arg(),
JSXElementChild::JSXFragment(el) => self.jsx_frag_to_expr(el).as_arg(), JSXElementChild::JSXFragment(el) => self.jsx_frag_to_expr(el).as_arg(),
JSXElementChild::JSXSpreadChild(JSXSpreadChild { span, .. }) => { JSXElementChild::JSXSpreadChild(JSXSpreadChild { span, expr, .. }) => ExprOrSpread {
HANDLER.with(|handler| { spread: Some(span),
handler expr,
.struct_span_err(span, "Spread children are not supported in React.") },
.emit();
});
return None;
}
}) })
} }

View File

@ -0,0 +1,3 @@
const A = () => {
return <div>{...[]}</div>;
};

View File

@ -0,0 +1,3 @@
const A = ()=>{
return /*#__PURE__*/ React.createElement("div", null, ...[]);
};

View File

@ -1 +1 @@
/*#__PURE__*/ React.createElement("div", null); /*#__PURE__*/ React.createElement("div", null, ...children);

View File

@ -1,6 +0,0 @@
x Spread children are not supported in React.
,-[input.js:1:1]
1 | <div>{...children}</div>;
: ^^^^^^^^^^^^^
`----

View File

@ -1 +1 @@
/*#__PURE__*/ React.createElement("div", null); /*#__PURE__*/ React.createElement("div", null, ...children);

View File

@ -1,6 +0,0 @@
x Spread children are not supported in React.
,-[input.js:1:1]
1 | <div>{...children}</div>;
: ^^^^^^^^^^^^^
`----