-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
/
no-redundant-should-component-update.js
109 lines (98 loc) · 2.97 KB
/
no-redundant-should-component-update.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/**
* @fileoverview Flag shouldComponentUpdate when extending PureComponent
*/
'use strict';
var Components = require('../util/Components');
function errorMessage(node) {
return `${node} does not need shouldComponentUpdate when extending React.PureComponent.`;
}
// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------
module.exports = {
meta: {
docs: {
description: 'Flag shouldComponentUpdate when extending PureComponent',
category: 'Possible Errors',
recommended: false
},
schema: []
},
create: Components.detect(function(context, components, utils) {
/**
* Get properties name
* @param {Object} node - Property.
* @returns {String} Property name.
*/
function getPropertyName(node) {
if (node.key) {
return node.key.name;
} else if (node.type === 'ClassProperty') {
// Special case for class properties
// (babel-eslint does not expose property name so we have to rely on tokens)
var tokens = context.getFirstTokens(node, 2);
return tokens[1] && tokens[1].type === 'Identifier' ? tokens[1].value : tokens[0].value;
}
return '';
}
/**
* Get properties for a given AST node
* @param {ASTNode} node The AST node being checked.
* @returns {Array} Properties array.
*/
function getComponentProperties(node) {
switch (node.type) {
case 'ClassExpression':
case 'ClassDeclaration':
return node.body.body;
default:
return [];
}
}
/**
* Checks for shouldComponentUpdate property
* @param {ASTNode} node The AST node being checked.
* @returns {Boolean} Whether or not the property exists.
*/
function hasShouldComponentUpdate(node) {
var properties = getComponentProperties(node);
return properties.some(function(property) {
var name = getPropertyName(property);
return name === 'shouldComponentUpdate';
});
}
/**
* Get name of node if available
* @param {ASTNode} node The AST node being checked.
* @return {String} The name of the node
*/
function getNodeName(node) {
if (node.id) {
return node.id.name;
} else if (node.parent && node.parent.id) {
return node.parent.id.name;
}
return '';
}
/**
* Checks for violation of rule
* @param {ASTNode} node The AST node being checked.
*/
function checkForViolation(node) {
if (utils.isPureComponent(node)) {
var hasScu = hasShouldComponentUpdate(node);
if (hasScu) {
var className = getNodeName(node);
context.report({
node: node,
message: errorMessage(className)
});
}
}
}
return {
ClassDeclaration: checkForViolation,
ClassExpression: checkForViolation
};
})
};