@samitouri / QOS-React-2 / commits / f0fdabae7b

Add display name in more cases

Ben Alpert committed Jan 3, 2014 at 17:25 UTC f0fdabae7bbeadde9245d00893b194e0310c8d9b
1 file changed +59 -25
vendor/fbtransform/transforms/reactDisplayName.js
+59 -25
@@ -19,6 +19,32 @@
19 var Syntax = require('esprima-fb').Syntax;
20 var utils = require('jstransform/src/utils');
21
22 +function addDisplayName(displayName, object, state) {
23 + if (object &&
24 + object.type === Syntax.CallExpression &&
25 + object.callee.type === Syntax.MemberExpression &&
26 + object.callee.object.type === Syntax.Identifier &&
27 + object.callee.object.name === 'React' &&
28 + object.callee.property.type === Syntax.Identifier &&
29 + object.callee.property.name === 'createClass' &&
30 + object['arguments'].length === 1 &&
31 + object['arguments'][0].type === Syntax.ObjectExpression) {
32 + // Verify that the displayName property isn't already set
33 + var properties = object['arguments'][0].properties;
34 + var safe = properties.every(function(property) {
35 + var value = property.key.type === Syntax.Identifier ?
36 + property.key.name :
37 + property.key.value;
38 + return value !== 'displayName';
39 + });
40 +
41 + if (safe) {
42 + utils.catchup(object['arguments'][0].range[0] + 1, state);
43 + utils.append("displayName: '" + displayName + "',", state);
44 + }
45 + }
46 +}
47 +
48 /**
49 * Transforms the following:
50 *
@@ -32,40 +58,48 @@ var utils = require('jstransform/src/utils');
58 * displayName: 'MyComponent',
59 * render: ...
60 * });
61 + *
62 + * Also catches:
63 + *
64 + * MyComponent = React.createClass(...);
65 + * exports.MyComponent = React.createClass(...);
66 + * module.exports = {MyComponent: React.createClass(...)};
67 */
68 function visitReactDisplayName(traverse, object, path, state) {
37 - var displayName = object.id.name;
38 - utils.catchup(object.init['arguments'][0].range[0] + 1, state);
39 - utils.append("displayName: '" + displayName + "',", state);
69 + var left, right;
70 +
71 + if (object.type === Syntax.AssignmentExpression) {
72 + left = object.left;
73 + right = object.right;
74 + } else if (object.type === Syntax.Property) {
75 + left = object.key;
76 + right = object.value;
77 + } else if (object.type === Syntax.VariableDeclarator) {
78 + left = object.id;
79 + right = object.init;
80 + }
81 +
82 + if (left && left.type === Syntax.MemberExpression) {
83 + left = left.property;
84 + }
85 + if (left && left.type === Syntax.Identifier) {
86 + addDisplayName(left.name, right, state);
87 + }
88 }
89
90 /**
91 * Will only run on @jsx files for now.
92 */
93 visitReactDisplayName.test = function(object, path, state) {
46 - if (!!utils.getDocblock(state).jsx &&
47 - object.type === Syntax.VariableDeclarator &&
48 - object.id.type === Syntax.Identifier &&
49 - object.init &&
50 - object.init.type === Syntax.CallExpression &&
51 - object.init.callee.type === Syntax.MemberExpression &&
52 - object.init.callee.object.type === Syntax.Identifier &&
53 - object.init.callee.object.name === 'React' &&
54 - object.init.callee.property.type === Syntax.Identifier &&
55 - object.init.callee.property.name === 'createClass' &&
56 - object.init['arguments'].length === 1 &&
57 - object.init['arguments'][0].type === Syntax.ObjectExpression) {
58 -
59 - // Verify that the displayName property isn't already set
60 - var properties = object.init['arguments'][0].properties;
61 - return properties.reduce(function (safe, property) {
62 - var value = property.key.type === 'Identifier'
63 - ? property.key.name
64 - : property.key.value;
65 - return safe && value !== 'displayName';
66 - }, true);
94 + if (utils.getDocblock(state).jsx) {
95 + return (
96 + object.type === Syntax.AssignmentExpression ||
97 + object.type === Syntax.Property ||
98 + object.type === Syntax.VariableDeclarator
99 + );
100 + } else {
101 + return false;
102 }
68 - return false;
103 };
104
105 exports.visitReactDisplayName = visitReactDisplayName;