Skip to content

Commit c72b337

Browse files
authored
Eslint/version 2 fixes (#1261)
* Fix some minor undefined handling and increase version * Handle migration from Component to Parent.Component and fix bugs related to components named the same in different sources * Move, fix and refactor getPrefix getSuffix * Remove duplicate line
1 parent 91fe059 commit c72b337

13 files changed

+223
-36
lines changed

eslint-rules/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ module.exports = {
33
'no-hard-coded-color': require('./lib/rules/no-hard-coded-color'),
44
'no-direct-import': require('./lib/rules/no-direct-import'),
55
'component-deprecation': require('./lib/rules/component-deprecation'),
6+
'component-prop-deprecation': require('./lib/rules/component-prop-deprecation'),
67
'assets-deprecation': require('./lib/rules/assets-deprecation'),
78
'typography-deprecation': require('./lib/rules/typography-deprecation'),
89
'function-deprecation': require('./lib/rules/function-deprecation'),
910
'prop-value-shape-deprecation': require('./lib/rules/prop-value-shape-deprecation'),
1011
// for duplicate rules usage
1112
'component-deprecation_warn': require('./lib/rules/component-deprecation'),
13+
'component-prop-deprecation_warn': require('./lib/rules/component-prop-deprecation'),
1214
'assets-deprecation_warn': require('./lib/rules/assets-deprecation'),
1315
'typography-deprecation_warn': require('./lib/rules/typography-deprecation'),
1416
'function-deprecation_warn': require('./lib/rules/function-deprecation'),
1517
'prop-value-shape-deprecation_warn': require('./lib/rules/prop-value-shape-deprecation'),
1618
'component-deprecation_error': require('./lib/rules/component-deprecation'),
19+
'component-prop-deprecation_error': require('./lib/rules/component-prop-deprecation'),
1720
'assets-deprecation_error': require('./lib/rules/assets-deprecation'),
1821
'typography-deprecation_error': require('./lib/rules/typography-deprecation'),
1922
'function-deprecation_error': require('./lib/rules/function-deprecation'),

eslint-rules/lib/rules/component-deprecation.js

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
const _ = require('lodash');
2-
const {addToImports, organizeDeprecations, getComponentLocalName, getComponentName} = require('../utils');
2+
const {addToImports, organizeDeprecations, getComponentLocalName, getPossibleDeprecations} = require('../utils');
33

44
const MAP_SCHEMA = {
55
type: 'object',
@@ -43,10 +43,27 @@ module.exports = {
4343
const organizedDeprecations = organizeDeprecations(deprecations);
4444

4545
const imports = [];
46+
const parents = [];
47+
48+
function getParent(localName) {
49+
const foundParents = parents.filter(parent => Object.keys(parent)[0] === localName);
50+
return !_.isEmpty(foundParents) ? foundParents[0][localName] : undefined;
51+
}
52+
53+
function isParent(foundDeprecation, localName) {
54+
if (foundDeprecation.parent) {
55+
const parent = getParent(localName);
56+
if (foundDeprecation.parent === parent) {
57+
return true;
58+
}
59+
}
60+
61+
return false;
62+
}
4663

4764
function importDeprecationCheck(node) {
4865
const previousImports = _.cloneDeep(imports);
49-
addToImports(node, imports);
66+
addToImports(node, imports, parents);
5067
const addedImports = _.differenceWith(imports, previousImports, _.isEqual);
5168
addedImports.forEach(currentImport => {
5269
const source = Object.keys(currentImport)[0];
@@ -60,11 +77,20 @@ module.exports = {
6077

6178
if (foundDeprecations.length > 0) {
6279
foundDeprecations.forEach(foundDeprecation => {
80+
const localName = Object.keys(components).find(key => components[key] === foundDeprecation.component);
81+
if (isParent(foundDeprecation, localName)) {
82+
return;
83+
}
84+
6385
let fixNode;
6486
if (node.type === 'ImportDeclaration') {
65-
fixNode = node.specifiers.filter(
87+
const foundSpecifiers = node.specifiers.filter(
6688
specifier => _.get(specifier, 'imported.name') === foundDeprecation.component
67-
)[0].imported;
89+
);
90+
91+
if (foundSpecifiers.length > 0) {
92+
fixNode = foundSpecifiers[0].imported;
93+
}
6894
} else if (node.type === 'VariableDeclarator') {
6995
const properties = _.get(node, 'id.properties');
7096
if (properties) {
@@ -88,13 +114,18 @@ module.exports = {
88114
const deprecationSource = organizedDeprecations[source];
89115
if (deprecationSource) {
90116
// There are deprecations from this source
91-
const componentName = getComponentName(componentLocalName, imports);
92-
const foundDeprecations = deprecationSource.filter(
93-
currentDeprecationSource => currentDeprecationSource.component === componentName
117+
const foundDeprecations = getPossibleDeprecations(
118+
componentLocalName,
119+
imports,
120+
currentImport,
121+
deprecationSource
94122
);
95123

96124
if (foundDeprecations.length > 0) {
97125
const foundDeprecation = foundDeprecations[0];
126+
if (isParent(foundDeprecation, componentLocalName)) {
127+
return;
128+
}
98129

99130
// This is a little hacky, is there a better way?
100131
if (componentLocalName.includes(foundDeprecation.component)) {

eslint-rules/lib/rules/component-prop-deprecation.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const {
55
addToImports,
66
getComponentLocalName,
77
getComponentName,
8+
getPossibleDeprecations,
89
findValueNodeOfIdentifier
910
} = require('../utils');
1011

@@ -116,9 +117,13 @@ module.exports = {
116117
if (deprecationSource) {
117118
// There are deprecations from this source
118119
const componentName = getComponentName(componentLocalName, imports);
119-
const foundPossibleDeprecations = deprecationSource.filter(
120-
currentDeprecationSource => currentDeprecationSource.component === componentName
120+
const foundPossibleDeprecations = getPossibleDeprecations(
121+
componentLocalName,
122+
imports,
123+
currentImport,
124+
deprecationSource
121125
);
126+
122127
foundPossibleDeprecations.forEach(foundPossibleDeprecation => {
123128
const deprecatedPropList = foundPossibleDeprecation.props;
124129
const attributes = node.attributes;

eslint-rules/lib/rules/prop-value-shape-deprecation.js

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
const _ = require('lodash');
2-
const {findValueNodeOfIdentifier, getComponentLocalName, addToImports, getComponentName} = require('../utils');
2+
const {
3+
getPrefix,
4+
getSuffix,
5+
findValueNodeOfIdentifier,
6+
getComponentLocalName,
7+
addToImports,
8+
getComponentName
9+
} = require('../utils');
310

411
const MAP_SCHEMA = {
512
type: 'object',
@@ -88,8 +95,8 @@ module.exports = {
8895
}
8996

9097
function recursiveDeprecation(attribute, deprecationProp, deprecation, deprecationPath, node) {
91-
const deprecationPrefix = getPathPrefix(deprecationProp);
92-
const deprecationSuffix = getPathSuffix(deprecationProp);
98+
const deprecationPrefix = getPrefix(deprecationProp);
99+
const deprecationSuffix = getSuffix(deprecationProp);
93100
let passedProps;
94101
let attributeName = _.get(attribute, 'name.name') || _.get(attribute, 'key.name');
95102
if (attribute.type === 'JSXSpreadAttribute' || attribute.type === 'ExperimentalSpreadProperty') {
@@ -132,16 +139,6 @@ module.exports = {
132139
}
133140
}
134141

135-
function getPathPrefix(str) {
136-
const index = str.indexOf('.');
137-
return index === -1 ? str : str.substring(0, index);
138-
}
139-
140-
function getPathSuffix(str) {
141-
const index = str.indexOf('.');
142-
return index === -1 ? undefined : str.substring(index + 1);
143-
}
144-
145142
function checkAttributeProperties(attributeProperties, attributeName, deprecation, node) {
146143
for (let i = 0; i < attributeProperties.length; i++) {
147144
const propertyType = _.get(attributeProperties[i], 'type');

eslint-rules/lib/utils/componentUtils.js

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
const _ = require('lodash');
1+
const {getPrefix} = require('./generalUtils');
22

33
function getComponentLocalName(node) {
44
if (!node) return;
@@ -10,17 +10,27 @@ function getComponentLocalName(node) {
1010
return `${start}.${end}`; // <List.Part/> OR <module.List.Part/> etc.
1111
}
1212

13+
function isNamespace(currentImport, componentLocalName) {
14+
const components = Object.values(currentImport)[0];
15+
const prefix = getPrefix(componentLocalName);
16+
if (prefix && components[prefix]) {
17+
return components[prefix].isNamespace;
18+
}
19+
20+
return false;
21+
}
22+
1323
function getComponentName(componentLocalName, imports) {
1424
for (let index = 0; index < imports.length; ++index) {
1525
const currentImport = imports[index];
1626
const components = Object.values(currentImport)[0];
1727
if (components[componentLocalName]) {
1828
return components[componentLocalName];
1929
} else if (componentLocalName.indexOf('.') > 0) {
20-
const indexOfDot = componentLocalName.indexOf('.');
21-
const prefix = componentLocalName.slice(0, indexOfDot);
30+
const prefix = getPrefix(componentLocalName);
2231
if (components[prefix]) {
2332
if (components[prefix].isNamespace) {
33+
const indexOfDot = componentLocalName.indexOf('.');
2434
return componentLocalName.slice(indexOfDot + 1);
2535
} else {
2636
return componentLocalName.replace(prefix, components[prefix]);
@@ -34,5 +44,7 @@ module.exports = {
3444
// The local name of the component (List as L --> L)
3545
getComponentLocalName,
3646
// Get the real name of the component
37-
getComponentName
47+
getComponentName,
48+
// Is the localName comes from a namespace (module.Component)
49+
isNamespace
3850
};

eslint-rules/lib/utils/deprecationsUtils.js

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
const {getPrefix} = require('./generalUtils');
2+
const {getComponentName, isNamespace} = require('./componentUtils');
3+
14
function _organizeDeprecationsBySource(deprecations, defaultSource) {
25
const obj = {};
36
deprecations.forEach(deprecation => {
@@ -21,6 +24,10 @@ function organizeDeprecations(deprecations, defaultSource) {
2124
}
2225

2326
function getLocalizedFix(fix, currentImport) {
27+
if (!fix) {
28+
return;
29+
}
30+
2431
let localizedFix = fix;
2532
const indexOfDot = fix.indexOf('.');
2633
if (indexOfDot > 0) {
@@ -38,7 +45,23 @@ function getLocalizedFix(fix, currentImport) {
3845
return localizedFix;
3946
}
4047

48+
function getPossibleDeprecations(componentLocalName, imports, currentImport, deprecationSource) {
49+
const source = Object.keys(currentImport)[0];
50+
const components = currentImport[source];
51+
const componentName = getComponentName(componentLocalName, imports);
52+
const prefix = getPrefix(componentLocalName);
53+
return deprecationSource.filter(currentDeprecationSource => {
54+
return (
55+
(isNamespace(currentImport, componentLocalName) ||
56+
components[componentLocalName] ||
57+
(prefix && components[prefix])) &&
58+
currentDeprecationSource.component === componentName
59+
);
60+
});
61+
}
62+
4163
module.exports = {
4264
organizeDeprecations,
43-
getLocalizedFix
65+
getLocalizedFix,
66+
getPossibleDeprecations
4467
};

eslint-rules/lib/utils/generalUtils.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
function getPrefix(str) {
2+
const indexOfDot = str.indexOf('.');
3+
return indexOfDot === -1 ? str : str.substring(0, indexOfDot);
4+
}
5+
6+
function getSuffix(str) {
7+
const indexOfDot = str.indexOf('.');
8+
return indexOfDot === -1 ? undefined : str.substring(indexOfDot + 1);
9+
}
10+
111
function findValueNodeOfIdentifier(identifierName, scope) {
212
const varsInScope = scope.variables;
313
let valueNode = false;
@@ -16,5 +26,7 @@ function findValueNodeOfIdentifier(identifierName, scope) {
1626

1727

1828
module.exports = {
29+
getPrefix,
30+
getSuffix,
1931
findValueNodeOfIdentifier
2032
};

eslint-rules/lib/utils/importUtils.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,34 @@ function _getSourceForComponent(component, imports) {
3838
}
3939
}
4040

41-
function _addToImports_fromSpreading(midSource, newImports, imports) {
41+
function _addToImports_fromSpreading(midSource, newImports, imports, parents) {
4242
if (midSource) {
4343
const source = _getSourceForComponent(midSource, imports);
4444
if (source) {
4545
_addToImports_aggregate(imports, source, newImports);
46+
if (parents) {
47+
_.forEach(Object.keys(newImports), currentImport => {
48+
if (!parents.includes(currentImport)) {
49+
parents.push({[currentImport]: midSource});
50+
}
51+
});
52+
}
4653
}
4754
}
4855
}
4956

5057
function _getImportsFromProperties(node) {
5158
const newImports = {};
5259
_.map(node.id.properties, property => {
53-
newImports[property.value.name] = property.key.name;
60+
if (property.type === 'Property') {
61+
newImports[property.value.name] = property.key.name;
62+
}
5463
});
5564

5665
return newImports;
5766
}
5867

59-
function _addToImports_fromDeclaration(node, imports) {
68+
function _addToImports_fromDeclaration(node, imports, parents) {
6069
let newImports, source, midSource;
6170
if (_.get(node, 'init.type') === 'CallExpression' && _.get(node, 'init.callee.name') === 'require') {
6271
source = node.init.arguments[0].value;
@@ -81,19 +90,19 @@ function _addToImports_fromDeclaration(node, imports) {
8190
}
8291

8392
_addToImports_aggregate(imports, source, newImports);
84-
_addToImports_fromSpreading(midSource, newImports, imports);
93+
_addToImports_fromSpreading(midSource, newImports, imports, parents);
8594
}
8695

8796
/**
8897
* Aggregate all components, from 'import', 'require' or 'spreading' of other components\imports
8998
* to a single object.
9099
*/
91-
function addToImports(node, imports) {
100+
function addToImports(node, imports, parents) {
92101
if (!node) return;
93102
if (node.type === 'ImportDeclaration') {
94103
_addToImports_fromImport(node, imports); // import
95104
} else if (node.type === 'VariableDeclarator') {
96-
_addToImports_fromDeclaration(node, imports); // require + spreading of sub-components etc
105+
_addToImports_fromDeclaration(node, imports, parents); // require + spreading of sub-components etc
97106
} else {
98107
console.log('Debug', 'addToImports', 'unknown type:', node.type);
99108
}

eslint-rules/lib/utils/index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
const {findValueNodeOfIdentifier} = require('./generalUtils');
2-
const {organizeDeprecations, getLocalizedFix} = require('./deprecationsUtils');
1+
const {getPrefix, getSuffix, findValueNodeOfIdentifier} = require('./generalUtils');
2+
const {organizeDeprecations, getLocalizedFix, getPossibleDeprecations} = require('./deprecationsUtils');
33
const {addToImports} = require('./importUtils');
44
const {getComponentLocalName, getComponentName} = require('./componentUtils');
55
const {findAndReportHardCodedValues} = require('./noHardCodedUtils');
66
const {stringify} = require('./debugUtils');
77

88
module.exports = {
99
// General
10+
getPrefix,
11+
getSuffix,
1012
findValueNodeOfIdentifier,
1113
// Deprecations
1214
organizeDeprecations,
1315
getLocalizedFix,
16+
getPossibleDeprecations,
1417
// Imports
1518
addToImports,
1619
// Components

eslint-rules/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "eslint-plugin-uilib",
3-
"version": "2.0.0",
3+
"version": "2.0.1",
44
"description": "uilib set of eslint rules",
55
"keywords": [
66
"eslint",

eslint-rules/tests/component_deprecation.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,11 @@
2828
"source": "another-module-with-deprecations",
2929
"message": "Please use the 'ListList' component instead.",
3030
"fix": {"componentName": "ListList"}
31+
},
32+
{
33+
"component": "ScrollView",
34+
"parent": "MyComponent",
35+
"source": "module-with-deprecations",
36+
"message": "Please use the 'MyComponent.ScrollView' component instead."
3137
}
3238
]

0 commit comments

Comments
 (0)