diff --git a/packages/babel-generator/src/generators/jsx.js b/packages/babel-generator/src/generators/jsx.js
index 0b256f8ac9..7da237ff6a 100644
--- a/packages/babel-generator/src/generators/jsx.js
+++ b/packages/babel-generator/src/generators/jsx.js
@@ -35,6 +35,13 @@ export function JSXExpressionContainer(node: Object) {
this.token("}");
}
+export function JSXSpreadChild(node: Object) {
+ this.token("{");
+ this.token("...");
+ this.print(node.expression, node);
+ this.token("}");
+}
+
export function JSXText(node: Object) {
this.token(node.value);
}
diff --git a/packages/babel-generator/test/fixtures/types/XJSSpreadChildren/actual.js b/packages/babel-generator/test/fixtures/types/XJSSpreadChildren/actual.js
new file mode 100644
index 0000000000..8bef050d70
--- /dev/null
+++ b/packages/babel-generator/test/fixtures/types/XJSSpreadChildren/actual.js
@@ -0,0 +1 @@
+
{...this.props.children}
;
diff --git a/packages/babel-generator/test/fixtures/types/XJSSpreadChildren/expected.js b/packages/babel-generator/test/fixtures/types/XJSSpreadChildren/expected.js
new file mode 100644
index 0000000000..8bef050d70
--- /dev/null
+++ b/packages/babel-generator/test/fixtures/types/XJSSpreadChildren/expected.js
@@ -0,0 +1 @@
+{...this.props.children}
;
diff --git a/packages/babel-helper-builder-react-jsx/src/index.js b/packages/babel-helper-builder-react-jsx/src/index.js
index 2438070df0..22f963e342 100644
--- a/packages/babel-helper-builder-react-jsx/src/index.js
+++ b/packages/babel-helper-builder-react-jsx/src/index.js
@@ -17,6 +17,10 @@ export default function (opts) {
throw path.buildCodeFrameError("Namespace tags are not supported. ReactJSX is not XML.");
};
+ visitor.JSXSpreadChild = function(path) {
+ throw path.buildCodeFrameError("Spread children are not supported.");
+ };
+
visitor.JSXElement = {
exit(path, file) {
let callExpr = buildElementCall(path.get("openingElement"), file);
diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-spread-children/actual.js b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-spread-children/actual.js
new file mode 100644
index 0000000000..6a05e108dc
--- /dev/null
+++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-spread-children/actual.js
@@ -0,0 +1 @@
+{...children}
;
diff --git a/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-spread-children/options.json b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-spread-children/options.json
new file mode 100644
index 0000000000..ec71024507
--- /dev/null
+++ b/packages/babel-plugin-transform-react-jsx/test/fixtures/react/should-disallow-spread-children/options.json
@@ -0,0 +1,3 @@
+{
+ "throws": "Spread children are not supported."
+}
diff --git a/packages/babel-types/src/definitions/jsx.js b/packages/babel-types/src/definitions/jsx.js
index 5f13ec8349..51bcf1f9f9 100644
--- a/packages/babel-types/src/definitions/jsx.js
+++ b/packages/babel-types/src/definitions/jsx.js
@@ -39,7 +39,7 @@ defineType("JSXElement", {
children: {
validate: chain(
assertValueType("array"),
- assertEach(assertNodeType("JSXText", "JSXExpressionContainer", "JSXElement"))
+ assertEach(assertNodeType("JSXText", "JSXExpressionContainer", "JSXSpreadChild", "JSXElement"))
)
}
}
@@ -59,6 +59,16 @@ defineType("JSXExpressionContainer", {
}
});
+defineType("JSXSpreadChild", {
+ visitor: ["expression"],
+ aliases: ["JSX", "Immutable"],
+ fields: {
+ expression: {
+ validate: assertNodeType("Expression")
+ }
+ }
+});
+
defineType("JSXIdentifier", {
builder: ["name"],
aliases: ["JSX", "Expression"],