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;