diff --git a/lib/6to5/transformers/react.js b/lib/6to5/transformers/react.js index e69de29bb2..9a413abba7 100644 --- a/lib/6to5/transformers/react.js +++ b/lib/6to5/transformers/react.js @@ -0,0 +1,63 @@ +var b = require("recast").types.builders; +var _ = require("lodash"); + +var addDisplayName = function (id, call) { + if (!call || call.type !== "CallExpression") return; + + var callee = call.callee; + if (callee.type !== "MemberExpression") return; + + // not React + var obj = callee.object; + if (obj.type !== "Identifier" || obj.name !== "React") return; + + // not createClass + var prop = callee.property; + if (prop.type !== "Identifier" || prop.name !== "createClass") return; + + // no arguments + var args = call.arguments; + if (args.length !== 1) return; + + // not an object + var first = args[0]; + if (first.type !== "ObjectExpression") return; + + var props = first.properties; + var safe = true; + + _.each(props, function (prop) { + if (prop.key.name === "displayName") { + return safe = false; + } + }); + + if (safe) { + props.unshift(b.property("init", b.identifier("displayName"), b.literal(id))); + } +}; + +exports.AssignmentExpression = +exports.Property = +exports.VariableDeclarator = function (node) { + var left, right; + + if (node.type === "AssignmentExpression") { + left = node.left; + right = node.right; + } else if (node.type === "Property") { + left = node.key; + right = node.value; + } else if (node.type === "VariableDeclarator") { + left = node.id; + right = node.init; + } + + if (left && left.type === "MemberExpression") { + left = left.property; + } + + if (left && left.type === "Identifier") { + addDisplayName(left.name, right); + } +}; diff --git a/test/fixtures/syntax/react/display-name-assignment-expression/actual.js b/test/fixtures/syntax/react/display-name-assignment-expression/actual.js new file mode 100644 index 0000000000..c58b749322 --- /dev/null +++ b/test/fixtures/syntax/react/display-name-assignment-expression/actual.js @@ -0,0 +1,6 @@ +var Component; +Component = React.createClass({ + render: function() { + return null; + } +}); diff --git a/test/fixtures/syntax/react/display-name-assignment-expression/expected.js b/test/fixtures/syntax/react/display-name-assignment-expression/expected.js new file mode 100644 index 0000000000..1e6abef43d --- /dev/null +++ b/test/fixtures/syntax/react/display-name-assignment-expression/expected.js @@ -0,0 +1,7 @@ +var Component; +Component = React.createClass({ + displayName: "Component", + render: function() { + return null; + } +}); diff --git a/test/fixtures/syntax/react/display-name-if-missing/actual.js b/test/fixtures/syntax/react/display-name-if-missing/actual.js new file mode 100644 index 0000000000..a9e92052e0 --- /dev/null +++ b/test/fixtures/syntax/react/display-name-if-missing/actual.js @@ -0,0 +1,6 @@ +var Whateva = React.createClass({ + displayName: "Whatever", + render: function() { + return null; + } +}); diff --git a/test/fixtures/syntax/react/display-name-if-missing/expected.js b/test/fixtures/syntax/react/display-name-if-missing/expected.js new file mode 100644 index 0000000000..a9e92052e0 --- /dev/null +++ b/test/fixtures/syntax/react/display-name-if-missing/expected.js @@ -0,0 +1,6 @@ +var Whateva = React.createClass({ + displayName: "Whatever", + render: function() { + return null; + } +}); diff --git a/test/fixtures/syntax/react/display-name-object-declaration/actual.js b/test/fixtures/syntax/react/display-name-object-declaration/actual.js new file mode 100644 index 0000000000..ab60bcdb44 --- /dev/null +++ b/test/fixtures/syntax/react/display-name-object-declaration/actual.js @@ -0,0 +1,7 @@ +exports = { + Component: React.createClass({ + render: function() { + return null; + } + }) +}; diff --git a/test/fixtures/syntax/react/display-name-object-declaration/expected.js b/test/fixtures/syntax/react/display-name-object-declaration/expected.js new file mode 100644 index 0000000000..d5510ba674 --- /dev/null +++ b/test/fixtures/syntax/react/display-name-object-declaration/expected.js @@ -0,0 +1,8 @@ +exports = { + Component: React.createClass({ + displayName: "Component", + render: function() { + return null; + } + }) +}; diff --git a/test/fixtures/syntax/react/display-name-property-assignment/actual.js b/test/fixtures/syntax/react/display-name-property-assignment/actual.js new file mode 100644 index 0000000000..a5b575416b --- /dev/null +++ b/test/fixtures/syntax/react/display-name-property-assignment/actual.js @@ -0,0 +1,5 @@ +exports.Component = React.createClass({ + render: function() { + return null; + } +}); diff --git a/test/fixtures/syntax/react/display-name-property-assignment/expected.js b/test/fixtures/syntax/react/display-name-property-assignment/expected.js new file mode 100644 index 0000000000..38c91c0540 --- /dev/null +++ b/test/fixtures/syntax/react/display-name-property-assignment/expected.js @@ -0,0 +1,6 @@ +exports.Component = React.createClass({ + displayName: "Component", + render: function() { + return null; + } +}); diff --git a/test/fixtures/syntax/react/display-name-variable-declaration/actual.js b/test/fixtures/syntax/react/display-name-variable-declaration/actual.js new file mode 100644 index 0000000000..d9354e21fc --- /dev/null +++ b/test/fixtures/syntax/react/display-name-variable-declaration/actual.js @@ -0,0 +1,5 @@ +var Component = React.createClass({ + render: function() { + return null; + } +}); diff --git a/test/fixtures/syntax/react/display-name-variable-declaration/expected.js b/test/fixtures/syntax/react/display-name-variable-declaration/expected.js new file mode 100644 index 0000000000..b73a672c3b --- /dev/null +++ b/test/fixtures/syntax/react/display-name-variable-declaration/expected.js @@ -0,0 +1,6 @@ +var Component = React.createClass({ + displayName: "Component", + render: function() { + return null; + } +});