Skip to content

Commit 747dc5b

Browse files
author
Keyan Zhang
committed
dont sort and bind everything
1 parent 311f472 commit 747dc5b

File tree

3 files changed

+110
-126
lines changed

3 files changed

+110
-126
lines changed

transforms/__testfixtures__/class.input.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,13 +80,13 @@ var MyComponent3 = React.createClass({
8080
},
8181

8282
autobindMe: function() {},
83-
dontAutobindMe: function(): number { return 12; },
83+
okBindMe: function(): number { return 12; },
8484

8585
// Function comment
8686
_renderRange: function(text: string, range, bla: Promise<string>): ReactElement<any> {
8787
var self = this;
8888

89-
self.dontAutobindMe();
89+
self.okBindMe();
9090
call(self.autobindMe);
9191

9292
var type = rage.type;
@@ -132,3 +132,37 @@ module.exports = Relay.createContainer(MyComponent, {
132132
me: Relay.graphql`this is not graphql`,
133133
},
134134
});
135+
136+
var MyComponent5 = React.createClass({
137+
getDefaultProps: function() {
138+
return {
139+
thisIs: true,
140+
andThisIs: false,
141+
};
142+
},
143+
144+
statics: {},
145+
146+
getInitialState: function() {
147+
return {
148+
todos: [],
149+
};
150+
},
151+
152+
renderTodo: function(): ReactElement<any> {
153+
return (
154+
<div>
155+
{this.state.todos.map((item) => <p key={item.id}>{item.text}</p>)}
156+
</div>
157+
);
158+
},
159+
160+
render: function() {
161+
return (
162+
<div>
163+
<h1>TODOs</h1>
164+
{this.renderTodo()}
165+
</div>
166+
);
167+
},
168+
});

transforms/__testfixtures__/class.output.js

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class MyComponent extends React.Component {
1818
};
1919
}
2020

21-
foo(): void {
21+
foo = (): void => {
2222
this.setState({heyoo: 24});
23-
}
23+
};
2424
}
2525

2626
// Class comment
@@ -34,6 +34,9 @@ class MyComponent2 extends React.Component {
3434
}
3535

3636
class MyComponent3 extends React.Component {
37+
static someThing = 10;
38+
static funcThatDoesNothing = function(): void {};
39+
3740
static propTypes = {
3841
highlightEntities: React.PropTypes.bool,
3942
linkifyEntities: React.PropTypes.bool,
@@ -51,9 +54,6 @@ class MyComponent3 extends React.Component {
5154
};
5255
}();
5356

54-
static someThing = 10;
55-
static funcThatDoesNothing = function(): void {};
56-
5757
constructor(props, context) {
5858
super(props, context);
5959
props.foo();
@@ -68,13 +68,27 @@ class MyComponent3 extends React.Component {
6868
return <Text text={text} />;
6969
};
7070

71+
_renderImageRange = (text: string, range): ReactElement<any> => {
72+
var image = range.image;
73+
if (image) {
74+
return (
75+
<Image
76+
src={image.uri}
77+
height={image.height / image.scale}
78+
width={image.width / image.scale}
79+
/>
80+
);
81+
}
82+
};
83+
7184
autobindMe = () => {};
85+
okBindMe = (): number => { return 12; };
7286

7387
// Function comment
7488
_renderRange = (text: string, range, bla: Promise<string>): ReactElement<any> => {
7589
var self = this;
7690

77-
self.dontAutobindMe();
91+
self.okBindMe();
7892
call(self.autobindMe);
7993

8094
var type = rage.type;
@@ -96,21 +110,6 @@ class MyComponent3 extends React.Component {
96110
return text;
97111
};
98112

99-
_renderImageRange(text: string, range): ReactElement<any> {
100-
var image = range.image;
101-
if (image) {
102-
return (
103-
<Image
104-
src={image.uri}
105-
height={image.height / image.scale}
106-
width={image.width / image.scale}
107-
/>
108-
);
109-
}
110-
}
111-
112-
dontAutobindMe(): number { return 12; }
113-
114113
/* This is a comment */
115114
render() {
116115
var content = this.props.text;
@@ -135,3 +134,31 @@ module.exports = Relay.createContainer(MyComponent, {
135134
me: Relay.graphql`this is not graphql`,
136135
},
137136
});
137+
138+
class MyComponent5 extends React.Component {
139+
static defaultProps = {
140+
thisIs: true,
141+
andThisIs: false,
142+
};
143+
144+
state = {
145+
todos: [],
146+
};
147+
148+
renderTodo = (): ReactElement<any> => {
149+
return (
150+
<div>
151+
{this.state.todos.map((item) => <p key={item.id}>{item.text}</p>)}
152+
</div>
153+
);
154+
};
155+
156+
render() {
157+
return (
158+
<div>
159+
<h1>TODOs</h1>
160+
{this.renderTodo()}
161+
</div>
162+
);
163+
}
164+
}

transforms/class.js

Lines changed: 26 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,6 @@ module.exports = (file, api, options) => {
135135
const filterGetInitialStateField = node =>
136136
createFindPropFn(GET_INITIAL_STATE_FIELD)(node);
137137

138-
const findGetDefaultProps = specPath =>
139-
specPath.properties.find(createFindPropFn(DEFAULT_PROPS_FIELD));
140-
141138
const findGetInitialState = specPath =>
142139
specPath.properties.find(createFindPropFn(GET_INITIAL_STATE_FIELD));
143140

@@ -155,24 +152,23 @@ module.exports = (file, api, options) => {
155152
node.value.type === 'FunctionExpression'
156153
);
157154

158-
// Collects `childContextTypes`, `contextTypes`, `displayName`, and `propTypes` first;
159-
// then simplifies `getDefaultProps` or converts it to an IIFE;
160-
// finally it collects everything in the `statics` property object.
155+
// Collects `childContextTypes`, `contextTypes`, `displayName`, and `propTypes`;
156+
// simplifies `getDefaultProps` or converts it to an IIFE;
157+
// and collects everything else in the `statics` property object.
161158
const collectStatics = specPath => {
162-
let result = specPath.properties.filter(property =>
163-
property.key && STATIC_KEYS[property.key.name]
164-
);
165-
166-
const getDefaultProps = findGetDefaultProps(specPath);
167-
if (getDefaultProps) {
168-
result.push(createDefaultProps(getDefaultProps));
159+
const result = [];
160+
161+
for (let i = 0; i < specPath.properties.length; i++) {
162+
const property = specPath.properties[i];
163+
if (createFindPropFn('statics')(property) && property.value && property.value.properties) {
164+
result.push(...property.value.properties);
165+
} else if (createFindPropFn(DEFAULT_PROPS_FIELD)(property)) {
166+
result.push(createDefaultProps(property));
167+
} else if (property.key && STATIC_KEYS[property.key.name]) {
168+
result.push(property);
169+
}
169170
}
170171

171-
const statics = specPath.properties.find(createFindPropFn('statics'));
172-
result = result.concat(
173-
(statics && statics.value && statics.value.properties) || []
174-
);
175-
176172
return result;
177173
};
178174

@@ -182,69 +178,6 @@ module.exports = (file, api, options) => {
182178
)
183179
.filter(isFunctionExpression);
184180

185-
const findAutobindNamesFor = (subtree, fnNames, literalOrIdentifier) => {
186-
const node = literalOrIdentifier;
187-
const autobindNames = {};
188-
189-
j(subtree)
190-
.find(j.MemberExpression, {
191-
object: node.name ? {
192-
type: node.type,
193-
name: node.name,
194-
} : {type: node.type},
195-
property: {
196-
type: 'Identifier',
197-
},
198-
})
199-
.filter(path => path.value.property && fnNames[path.value.property.name])
200-
.filter(path => {
201-
const call = path.parent.value;
202-
return !(
203-
call &&
204-
call.type === 'CallExpression' &&
205-
call.callee.type === 'MemberExpression' &&
206-
call.callee.object.type === node.type &&
207-
call.callee.object.name === node.name &&
208-
call.callee.property.type === 'Identifier' &&
209-
call.callee.property.name === path.value.property.name
210-
);
211-
})
212-
.forEach(path => autobindNames[path.value.property.name] = true);
213-
214-
return Object.keys(autobindNames);
215-
};
216-
217-
const collectAutoBindFunctions = (functions, classPath) => {
218-
const fnNames = {};
219-
functions
220-
.filter(fn => !AUTOBIND_IGNORE_KEYS[fn.key.name])
221-
.forEach(fn => fnNames[fn.key.name] = true);
222-
223-
const autobindNames = {};
224-
const add = name => autobindNames[name] = true;
225-
226-
// Find `this.<foo>`
227-
findAutobindNamesFor(classPath, fnNames, j.thisExpression()).forEach(add);
228-
229-
// Find `self.<foo>` if `self = this`
230-
j(classPath)
231-
.findVariableDeclarators()
232-
.filter(path => (
233-
path.value.id.type === 'Identifier' &&
234-
path.value.init &&
235-
path.value.init.type === 'ThisExpression'
236-
))
237-
.forEach(path =>
238-
findAutobindNamesFor(
239-
j(path).closest(j.FunctionExpression).get(),
240-
fnNames,
241-
path.value.id
242-
).forEach(add)
243-
);
244-
245-
return Object.keys(autobindNames);
246-
};
247-
248181
const findRequirePathAndBinding = (moduleName) => {
249182
let result = null;
250183

@@ -435,42 +368,34 @@ module.exports = (file, api, options) => {
435368
baseClassName,
436369
staticProperties,
437370
getInitialState,
438-
autobindFunctionNames,
439371
methods,
440372
comments
441373
) => {
442-
let newConstructor = [];
443-
const newProperties = [];
374+
let maybeConstructor = [];
375+
const initialStateProperty = [];
444376

445377
if (isInitialStateLiftable(getInitialState)) {
446378
if (getInitialState) {
447-
newProperties.push(convertInitialStateToClassProperty(getInitialState));
379+
initialStateProperty.push(convertInitialStateToClassProperty(getInitialState));
448380
}
449381
} else {
450-
newConstructor = createConstructor(getInitialState);
382+
maybeConstructor = createConstructor(getInitialState);
451383
}
452384

453-
const arrowBindFunctions = [];
454-
const newMethods = [];
455-
456-
for (let i = 0; i < methods.length; i++) {
457-
const method = methods[i];
458-
if (autobindFunctionNames.indexOf(method.key.name) !== -1) {
459-
arrowBindFunctions.push(method);
460-
} else {
461-
newMethods.push(method);
462-
}
463-
}
385+
const arrowBindFunctionsAndMethods = methods.map(method =>
386+
AUTOBIND_IGNORE_KEYS[method.key.name] ?
387+
method :
388+
createArrowPropertyFromMethod(method)
389+
);
464390

465391
return withComments(j.classDeclaration(
466392
name ? j.identifier(name) : null,
467393
j.classBody(
468394
[].concat(
469395
staticProperties,
470-
newConstructor,
471-
newProperties,
472-
arrowBindFunctions.map(createArrowPropertyFromMethod),
473-
newMethods
396+
maybeConstructor,
397+
initialStateProperty,
398+
arrowBindFunctionsAndMethods
474399
)
475400
),
476401
j.memberExpression(
@@ -531,7 +456,6 @@ module.exports = (file, api, options) => {
531456
const functions = collectFunctions(specPath);
532457
const comments = getComments(classPath);
533458

534-
const autobindFunctionNames = collectAutoBindFunctions(functions, classPath);
535459
const getInitialState = findGetInitialState(specPath);
536460

537461
var path;
@@ -554,7 +478,6 @@ module.exports = (file, api, options) => {
554478
baseClassName,
555479
staticProperties,
556480
getInitialState,
557-
autobindFunctionNames,
558481
functions.map(createMethodDefinition),
559482
comments
560483
)

0 commit comments

Comments
 (0)