Skip to content

Commit 8d66521

Browse files
committed
Re-write Components as a class
1 parent 64cf2d7 commit 8d66521

File tree

1 file changed

+137
-135
lines changed

1 file changed

+137
-135
lines changed

lib/util/Components.js

Lines changed: 137 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -11,164 +11,166 @@ const variableUtil = require('./variable');
1111
const pragmaUtil = require('./pragma');
1212
const astUtil = require('./ast');
1313

14-
const usedPropTypesAreEquivalent = (propA, propB) => {
15-
if (propA.name === propB.name) {
16-
if (!propA.allNames && !propB.allNames) {
17-
return true;
18-
} else if (Array.isArray(propA.allNames) && Array.isArray(propB.allNames) && propA.allNames.join('') === propB.allNames.join('')) {
19-
return true;
20-
}
21-
return false;
22-
}
23-
return false;
24-
};
25-
26-
const mergeUsedPropTypes = (propsList, newPropsList) => {
27-
const propsToAdd = [];
28-
newPropsList.forEach(newProp => {
29-
const newPropisAlreadyInTheList = propsList.some(prop => usedPropTypesAreEquivalent(prop, newProp));
30-
if (!newPropisAlreadyInTheList) {
31-
propsToAdd.push(newProp);
32-
}
33-
});
34-
return propsList.concat(propsToAdd);
35-
};
36-
37-
3814
/**
3915
* Components
4016
* @class
4117
*/
42-
function Components() {
43-
this._list = {};
44-
this._getId = function(node) {
18+
class Components {
19+
constructor() {
20+
this._list = {};
21+
}
22+
23+
_getId(node) {
4524
return node && node.range.join(':');
46-
};
47-
}
25+
}
4826

49-
/**
50-
* Add a node to the components list, or update it if it's already in the list
51-
*
52-
* @param {ASTNode} node The AST node being added.
53-
* @param {Number} confidence Confidence in the component detection (0=banned, 1=maybe, 2=yes)
54-
* @returns {Object} Added component object
55-
*/
56-
Components.prototype.add = function(node, confidence) {
57-
const id = this._getId(node);
58-
if (this._list[id]) {
59-
if (confidence === 0 || this._list[id].confidence === 0) {
60-
this._list[id].confidence = 0;
61-
} else {
62-
this._list[id].confidence = Math.max(this._list[id].confidence, confidence);
27+
/**
28+
* Add a node to the components list, or update it if it's already in the list
29+
*
30+
* @param {ASTNode} node The AST node being added.
31+
* @param {Number} confidence Confidence in the component detection (0=banned, 1=maybe, 2=yes)
32+
* @returns {Object} Added component object
33+
*/
34+
add(node, confidence) {
35+
const id = this._getId(node);
36+
if (this._list[id]) {
37+
if (confidence === 0 || this._list[id].confidence === 0) {
38+
this._list[id].confidence = 0;
39+
} else {
40+
this._list[id].confidence = Math.max(this._list[id].confidence, confidence);
41+
}
42+
return this._list[id];
6343
}
44+
this._list[id] = {
45+
node: node,
46+
confidence: confidence
47+
};
6448
return this._list[id];
6549
}
66-
this._list[id] = {
67-
node: node,
68-
confidence: confidence
69-
};
70-
return this._list[id];
71-
};
72-
73-
/**
74-
* Find a component in the list using its node
75-
*
76-
* @param {ASTNode} node The AST node being searched.
77-
* @returns {Object} Component object, undefined if the component is not found
78-
*/
79-
Components.prototype.get = function(node) {
80-
const id = this._getId(node);
81-
return this._list[id];
82-
};
8350

84-
/**
85-
* Update a component in the list
86-
*
87-
* @param {ASTNode} node The AST node being updated.
88-
* @param {Object} props Additional properties to add to the component.
89-
*/
90-
Components.prototype.set = function(node, props) {
91-
while (node && !this._list[this._getId(node)]) {
92-
node = node.parent;
93-
}
94-
if (!node) {
95-
return;
96-
}
97-
const id = this._getId(node);
98-
let copyUsedPropTypes;
99-
if (this._list[id]) {
100-
// usedPropTypes is an array. _extend replaces existing array with a new one which caused issue #1309.
101-
// preserving original array so it can be merged later on.
102-
copyUsedPropTypes = this._list[id].usedPropTypes && this._list[id].usedPropTypes.slice();
51+
/**
52+
* Find a component in the list using its node
53+
*
54+
* @param {ASTNode} node The AST node being searched.
55+
* @returns {Object} Component object, undefined if the component is not found
56+
*/
57+
get(node) {
58+
const id = this._getId(node);
59+
return this._list[id];
10360
}
104-
this._list[id] = util._extend(this._list[id], props);
105-
if (this._list[id] && props.usedPropTypes) {
106-
this._list[id].usedPropTypes = mergeUsedPropTypes(copyUsedPropTypes || [], props.usedPropTypes);
61+
62+
/**
63+
* Update a component in the list
64+
*
65+
* @param {ASTNode} node The AST node being updated.
66+
* @param {Object} props Additional properties to add to the component.
67+
*/
68+
set(node, props) {
69+
while (node && !this._list[this._getId(node)]) {
70+
node = node.parent;
71+
}
72+
if (!node) {
73+
return;
74+
}
75+
const id = this._getId(node);
76+
let copyUsedPropTypes;
77+
if (this._list[id]) {
78+
// usedPropTypes is an array. _extend replaces existing array with a new one which caused issue #1309.
79+
// preserving original array so it can be merged later on.
80+
copyUsedPropTypes = this._list[id].usedPropTypes && this._list[id].usedPropTypes.slice();
81+
}
82+
this._list[id] = util._extend(this._list[id], props);
83+
if (this._list[id] && props.usedPropTypes) {
84+
this._list[id].usedPropTypes = this._mergeUsedPropTypes(copyUsedPropTypes || [], props.usedPropTypes);
85+
}
10786
}
108-
};
10987

110-
/**
111-
* Return the components list
112-
* Components for which we are not confident are not returned
113-
*
114-
* @returns {Object} Components list
115-
*/
116-
Components.prototype.list = function() {
117-
const list = {};
118-
const usedPropTypes = {};
119-
// Find props used in components for which we are not confident
120-
for (const i in this._list) {
121-
if (!has(this._list, i) || this._list[i].confidence >= 2) {
122-
continue;
88+
/**
89+
* Return the components list
90+
* Components for which we are not confident are not returned
91+
*
92+
* @returns {Object} Components list
93+
*/
94+
list() {
95+
const list = {};
96+
const usedPropTypes = {};
97+
// Find props used in components for which we are not confident
98+
for (const i in this._list) {
99+
if (!has(this._list, i) || this._list[i].confidence >= 2) {
100+
continue;
101+
}
102+
let component = null;
103+
let node = null;
104+
node = this._list[i].node;
105+
while (!component && node.parent) {
106+
node = node.parent;
107+
// Stop moving up if we reach a decorator
108+
if (node.type === 'Decorator') {
109+
break;
110+
}
111+
component = this.get(node);
112+
}
113+
if (component) {
114+
const newUsedProps = (this._list[i].usedPropTypes || []).filter(propType => !propType.node || propType.node.kind !== 'init');
115+
116+
const componentId = this._getId(component.node);
117+
usedPropTypes[componentId] = (usedPropTypes[componentId] || []).concat(newUsedProps);
118+
}
123119
}
124-
let component = null;
125-
let node = null;
126-
node = this._list[i].node;
127-
while (!component && node.parent) {
128-
node = node.parent;
129-
// Stop moving up if we reach a decorator
130-
if (node.type === 'Decorator') {
131-
break;
120+
// Assign used props in not confident components to the parent component
121+
for (const j in this._list) {
122+
if (!has(this._list, j) || this._list[j].confidence < 2) {
123+
continue;
124+
}
125+
const id = this._getId(this._list[j].node);
126+
list[j] = this._list[j];
127+
if (usedPropTypes[id]) {
128+
list[j].usedPropTypes = (list[j].usedPropTypes || []).concat(usedPropTypes[id]);
132129
}
133-
component = this.get(node);
134130
}
135-
if (component) {
136-
const newUsedProps = (this._list[i].usedPropTypes || []).filter(propType => !propType.node || propType.node.kind !== 'init');
131+
return list;
132+
}
137133

138-
const componentId = this._getId(component.node);
139-
usedPropTypes[componentId] = (usedPropTypes[componentId] || []).concat(newUsedProps);
134+
/**
135+
* Return the length of the components list
136+
* Components for which we are not confident are not counted
137+
*
138+
* @returns {Number} Components list length
139+
*/
140+
length() {
141+
let length = 0;
142+
for (const i in this._list) {
143+
if (!has(this._list, i) || this._list[i].confidence < 2) {
144+
continue;
145+
}
146+
length++;
140147
}
148+
return length;
141149
}
142-
// Assign used props in not confident components to the parent component
143-
for (const j in this._list) {
144-
if (!has(this._list, j) || this._list[j].confidence < 2) {
145-
continue;
146-
}
147-
const id = this._getId(this._list[j].node);
148-
list[j] = this._list[j];
149-
if (usedPropTypes[id]) {
150-
list[j].usedPropTypes = (list[j].usedPropTypes || []).concat(usedPropTypes[id]);
151-
}
150+
151+
_mergeUsedPropTypes(propsList, newPropsList) {
152+
const propsToAdd = [];
153+
newPropsList.forEach(newProp => {
154+
const newPropisAlreadyInTheList = propsList.some(prop => this._usedPropTypesAreEquivalent(prop, newProp));
155+
if (!newPropisAlreadyInTheList) {
156+
propsToAdd.push(newProp);
157+
}
158+
});
159+
return propsList.concat(propsToAdd);
152160
}
153-
return list;
154-
};
155161

156-
/**
157-
* Return the length of the components list
158-
* Components for which we are not confident are not counted
159-
*
160-
* @returns {Number} Components list length
161-
*/
162-
Components.prototype.length = function() {
163-
let length = 0;
164-
for (const i in this._list) {
165-
if (!has(this._list, i) || this._list[i].confidence < 2) {
166-
continue;
162+
_usedPropTypesAreEquivalent(propA, propB) {
163+
if (propA.name === propB.name) {
164+
if (!propA.allNames && !propB.allNames) {
165+
return true;
166+
} else if (Array.isArray(propA.allNames) && Array.isArray(propB.allNames) && propA.allNames.join('') === propB.allNames.join('')) {
167+
return true;
168+
}
169+
return false;
167170
}
168-
length++;
171+
return false;
169172
}
170-
return length;
171-
};
173+
}
172174

173175
function componentRule(rule, context) {
174176
const createClass = pragmaUtil.getCreateClassFromContext(context);

0 commit comments

Comments
 (0)