Skip to content

Commit a09ac73

Browse files
committed
Ignore functions with the this keyword during component detection
1 parent 170c5f2 commit a09ac73

File tree

4 files changed

+66
-20
lines changed

4 files changed

+66
-20
lines changed

lib/util/Components.js

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,22 @@ function Components() {
2121
* Add a node to the components list, or update it if it's already in the list
2222
*
2323
* @param {ASTNode} node The AST node being added.
24-
* @param {Object} props Additional properties to add to the component.
24+
* @param {Number} confidence Confidence in the component detection (0=banned, 1=maybe, 2=yes)
2525
*/
26-
Components.prototype.add = function(node, props) {
26+
Components.prototype.add = function(node, confidence) {
2727
var id = this._getId(node);
2828
if (this._list[id]) {
29-
this._list[id] = util._extend(this._list[id], props);
29+
if (confidence === 0 || this._list[id].confidence === 0) {
30+
this._list[id].confidence = 0;
31+
} else {
32+
this._list[id].confidence = Math.max(this._list[id].confidence, confidence);
33+
}
3034
return;
3135
}
32-
props.node = node;
33-
this._list[id] = props;
36+
this._list[id] = {
37+
node: node,
38+
confidence: confidence
39+
};
3440
};
3541

3642
/**
@@ -70,7 +76,7 @@ Components.prototype.set = function(node, props) {
7076
Components.prototype.list = function() {
7177
var list = {};
7278
for (var i in this._list) {
73-
if (!this._list.hasOwnProperty(i) || !this._list[i].confident) {
79+
if (!this._list.hasOwnProperty(i) || this._list[i].confidence < 2) {
7480
continue;
7581
}
7682
list[i] = this._list[i];
@@ -87,7 +93,7 @@ Components.prototype.list = function() {
8793
Components.prototype.length = function() {
8894
var length = 0;
8995
for (var i in this._list) {
90-
if (!this._list.hasOwnProperty(i) || !this._list[i].confident) {
96+
if (!this._list.hasOwnProperty(i) || this._list[i].confidence < 2) {
9197
continue;
9298
}
9399
length++;
@@ -309,40 +315,38 @@ function componentRule(rule, context) {
309315
if (!context.react.isES6Component(node)) {
310316
return;
311317
}
312-
components.add(node, {confident: true});
318+
components.add(node, 2);
313319
},
314320

315321
ClassProperty: function(node) {
316322
node = context.react.getParentComponent();
317323
if (!node) {
318324
return;
319325
}
320-
components.add(node, {confident: true});
326+
components.add(node, 2);
321327
},
322328

323329
ObjectExpression: function(node) {
324330
if (!context.react.isES5Component(node)) {
325331
return;
326332
}
327-
components.add(node, {confident: true});
333+
components.add(node, 2);
328334
},
329335

330336
FunctionExpression: function(node) {
331337
node = context.react.getParentComponent();
332338
if (!node) {
333339
return;
334340
}
335-
var component = components.get(node);
336-
components.add(node, {confident: component && component.confident || false});
341+
components.add(node, 1);
337342
},
338343

339344
FunctionDeclaration: function(node) {
340345
node = context.react.getParentComponent();
341346
if (!node) {
342347
return;
343348
}
344-
var component = components.get(node);
345-
components.add(node, {confident: component && component.confident || false});
349+
components.add(node, 1);
346350
},
347351

348352
ArrowFunctionExpression: function(node) {
@@ -351,11 +355,19 @@ function componentRule(rule, context) {
351355
return;
352356
}
353357
if (node.expression && context.react.isReturningJSX(node)) {
354-
components.add(node, {confident: true});
358+
components.add(node, 2);
355359
} else {
356-
var component = components.get(node);
357-
components.add(node, {confident: component && component.confident || false});
360+
components.add(node, 1);
361+
}
362+
},
363+
364+
ThisExpression: function(node) {
365+
node = context.react.getParentComponent();
366+
if (!node || !/Function/.test(node.type)) {
367+
return;
358368
}
369+
// Ban functions with a ThisExpression
370+
components.add(node, 0);
359371
},
360372

361373
ReturnStatement: function(node) {
@@ -366,7 +378,7 @@ function componentRule(rule, context) {
366378
if (!node) {
367379
return;
368380
}
369-
components.add(node, {confident: true});
381+
components.add(node, 2);
370382
}
371383
};
372384

tests/lib/rules/display-name.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,16 @@ ruleTester.run('display-name', rule, {
308308
options: [{
309309
acceptTranspilerName: true
310310
}]
311+
}, {
312+
code: [
313+
'export default {',
314+
' renderHello() {',
315+
' let {name} = this.props;',
316+
' return <div>{name}</div>;',
317+
' }',
318+
'};'
319+
].join('\n'),
320+
parser: 'babel-eslint'
311321
}
312322
],
313323

@@ -378,7 +388,7 @@ ruleTester.run('display-name', rule, {
378388
}, {
379389
code: [
380390
'module.exports = () => {',
381-
' return <div>Hello {this.props.name}</div>;',
391+
' return <div>Hello {props.name}</div>;',
382392
'}'
383393
].join('\n'),
384394
parser: 'babel-eslint',
@@ -391,7 +401,7 @@ ruleTester.run('display-name', rule, {
391401
}, {
392402
code: [
393403
'module.exports = function() {',
394-
' return <div>Hello {this.props.name}</div>;',
404+
' return <div>Hello {props.name}</div>;',
395405
'}'
396406
].join('\n'),
397407
parser: 'babel-eslint',

tests/lib/rules/no-multi-comp.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,20 @@ ruleTester.run('no-multi-comp', rule, {
6262
classes: true,
6363
jsx: true
6464
}
65+
}, {
66+
code: [
67+
'export default {',
68+
' renderHello() {',
69+
' let {name} = this.props;',
70+
' return <div>{name}</div>;',
71+
' },',
72+
' renderHello2() {',
73+
' let {name2} = this.props;',
74+
' return <div>{name2}</div>;',
75+
' }',
76+
'};'
77+
].join('\n'),
78+
parser: 'babel-eslint'
6579
}],
6680

6781
invalid: [{

tests/lib/rules/prop-types.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,16 @@ ruleTester.run('prop-types', rule, {
883883
'};'
884884
].join('\n'),
885885
parser: 'babel-eslint'
886+
}, {
887+
code: [
888+
'export default {',
889+
' renderHello() {',
890+
' let {name} = this.props;',
891+
' return <div>{name}</div>;',
892+
' }',
893+
'};'
894+
].join('\n'),
895+
parser: 'babel-eslint'
886896
}
887897
],
888898

0 commit comments

Comments
 (0)