Skip to content

Commit dae95cc

Browse files
author
Barzilay, Oshri (ob143h)
committed
added destructured styles detection
1 parent 2fa23e2 commit dae95cc

File tree

2 files changed

+100
-71
lines changed

2 files changed

+100
-71
lines changed

lib/rules/no-unused-styles.js

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,7 @@ module.exports = Components.detect((context, components) => {
2020
if ({}.hasOwnProperty.call(unusedStyles, key)) {
2121
const styles = unusedStyles[key];
2222
styles.forEach((node) => {
23-
const message = [
24-
'Unused style detected: ',
25-
key,
26-
'.',
27-
node.key.name,
28-
].join('');
23+
const message = ['Unused style detected: ', key, '.', node.key.name].join('');
2924

3025
context.report(node, message);
3126
});
@@ -41,6 +36,26 @@ module.exports = Components.detect((context, components) => {
4136
}
4237
},
4338

39+
ArrayExpression: function (arrayNode) {
40+
if (arrayNode && arrayNode.elements && arrayNode.elements.length) {
41+
arrayNode.elements
42+
.flatMap((node) => {
43+
const styleRef = astHelpers.getPotentialStyleReferenceFromArrayExpression(node);
44+
return styleRef ? [styleRef] : [];
45+
})
46+
.forEach((styleRef) => {
47+
styleReferences.add(styleRef);
48+
});
49+
}
50+
},
51+
52+
JSXExpressionContainer: function (node) {
53+
const styleRef = astHelpers.getPotentialStyleReferenceFromJSXExpressionContainer(node);
54+
if (styleRef) {
55+
styleReferences.add(styleRef);
56+
}
57+
},
58+
4459
CallExpression: function (node) {
4560
if (astHelpers.isStyleSheetDeclaration(node, context.settings)) {
4661
const styleSheetName = astHelpers.getStyleSheetName(node);

lib/util/stylesheet.js

Lines changed: 79 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
'use strict';
32

43
/**
@@ -31,10 +30,16 @@ StyleSheets.prototype.markAsUsed = function (fullyQualifiedName) {
3130
const styleSheetName = nameSplit[0];
3231
const styleSheetProperty = nameSplit[1];
3332

34-
if (this.styleSheets[styleSheetName]) {
35-
this.styleSheets[styleSheetName] = this
36-
.styleSheets[styleSheetName]
37-
.filter((property) => property.key.name !== styleSheetProperty);
33+
if (nameSplit.length === 1) {
34+
Object.keys(this.styleSheets).forEach((key) => {
35+
this.styleSheets[key] = this.styleSheets[key].filter(
36+
(property) => property.key.name !== styleSheetName
37+
);
38+
});
39+
} else if (this.styleSheets[styleSheetName]) {
40+
this.styleSheets[styleSheetName] = this.styleSheets[styleSheetName].filter(
41+
(property) => property.key.name !== styleSheetProperty
42+
);
3843
}
3944
};
4045

@@ -86,41 +91,34 @@ StyleSheets.prototype.getObjectExpressions = function () {
8691
return this.objectExpressions;
8792
};
8893

89-
9094
let currentContent;
91-
const getSourceCode = (node) => currentContent
92-
.getSourceCode(node)
93-
.getText(node);
95+
const getSourceCode = (node) => currentContent.getSourceCode(node).getText(node);
9496

9597
const getStyleSheetObjectNames = (settings) => settings['react-native/style-sheet-object-names'] || ['StyleSheet'];
9698

9799
const astHelpers = {
98100
containsStyleSheetObject: function (node, objectNames) {
99101
return Boolean(
100102
node
101-
&& node.type === 'CallExpression'
102-
&& node.callee
103-
&& node.callee.object
104-
&& node.callee.object.name
105-
&& objectNames.includes(node.callee.object.name)
103+
&& node.type === 'CallExpression'
104+
&& node.callee
105+
&& node.callee.object
106+
&& node.callee.object.name
107+
&& objectNames.includes(node.callee.object.name)
106108
);
107109
},
108110

109111
containsCreateCall: function (node) {
110112
return Boolean(
111-
node
112-
&& node.callee
113-
&& node.callee.property
114-
&& node.callee.property.name === 'create'
113+
node && node.callee && node.callee.property && node.callee.property.name === 'create'
115114
);
116115
},
117116

118117
isStyleSheetDeclaration: function (node, settings) {
119118
const objectNames = getStyleSheetObjectNames(settings);
120119

121120
return Boolean(
122-
astHelpers.containsStyleSheetObject(node, objectNames)
123-
&& astHelpers.containsCreateCall(node)
121+
astHelpers.containsStyleSheetObject(node, objectNames) && astHelpers.containsCreateCall(node)
124122
);
125123
},
126124

@@ -200,10 +198,12 @@ const astHelpers = {
200198
case 'Literal':
201199
return node.value;
202200
case 'TemplateLiteral':
203-
return node.quasis.reduce((result, quasi, index) => result
204-
+ quasi.value.cooked
205-
+ astHelpers.getExpressionIdentifier(node.expressions[index]),
206-
'');
201+
return node.quasis.reduce(
202+
(result, quasi, index) => result
203+
+ quasi.value.cooked
204+
+ astHelpers.getExpressionIdentifier(node.expressions[index]),
205+
''
206+
);
207207
default:
208208
return '';
209209
}
@@ -213,34 +213,28 @@ const astHelpers = {
213213
},
214214

215215
getStylePropertyIdentifier: function (node) {
216-
if (
217-
node
218-
&& node.key
219-
) {
216+
if (node && node.key) {
220217
return astHelpers.getExpressionIdentifier(node.key);
221218
}
222219
},
223220

224221
isStyleAttribute: function (node) {
225222
return Boolean(
226223
node.type === 'JSXAttribute'
227-
&& node.name
228-
&& node.name.name
229-
&& node.name.name.toLowerCase().includes('style')
224+
&& node.name
225+
&& node.name.name
226+
&& node.name.name.toLowerCase().includes('style')
230227
);
231228
},
232229

233230
collectStyleObjectExpressions: function (node, context) {
234231
currentContent = context;
235232
if (astHelpers.hasArrayOfStyleReferences(node)) {
236-
const styleReferenceContainers = node
237-
.expression
238-
.elements;
233+
const styleReferenceContainers = node.expression.elements;
239234

240-
return astHelpers.collectStyleObjectExpressionFromContainers(
241-
styleReferenceContainers
242-
);
243-
} if (node && node.expression) {
235+
return astHelpers.collectStyleObjectExpressionFromContainers(styleReferenceContainers);
236+
}
237+
if (node && node.expression) {
244238
return astHelpers.getStyleObjectExpressionFromNode(node.expression);
245239
}
246240

@@ -254,13 +248,9 @@ const astHelpers = {
254248

255249
currentContent = context;
256250
if (astHelpers.hasArrayOfStyleReferences(node)) {
257-
const styleReferenceContainers = node
258-
.expression
259-
.elements;
251+
const styleReferenceContainers = node.expression.elements;
260252

261-
return astHelpers.collectColorLiteralsFromContainers(
262-
styleReferenceContainers
263-
);
253+
return astHelpers.collectColorLiteralsFromContainers(styleReferenceContainers);
264254
}
265255

266256
if (node.type === 'ObjectExpression') {
@@ -273,8 +263,9 @@ const astHelpers = {
273263
collectStyleObjectExpressionFromContainers: function (nodes) {
274264
let objectExpressions = [];
275265
nodes.forEach((node) => {
276-
objectExpressions = objectExpressions
277-
.concat(astHelpers.getStyleObjectExpressionFromNode(node));
266+
objectExpressions = objectExpressions.concat(
267+
astHelpers.getStyleObjectExpressionFromNode(node)
268+
);
278269
});
279270

280271
return objectExpressions;
@@ -283,8 +274,7 @@ const astHelpers = {
283274
collectColorLiteralsFromContainers: function (nodes) {
284275
let colorLiterals = [];
285276
nodes.forEach((node) => {
286-
colorLiterals = colorLiterals
287-
.concat(astHelpers.getColorLiteralsFromNode(node));
277+
colorLiterals = colorLiterals.concat(astHelpers.getColorLiteralsFromNode(node));
288278
});
289279

290280
return colorLiterals;
@@ -369,10 +359,13 @@ const astHelpers = {
369359
},
370360

371361
hasArrayOfStyleReferences: function (node) {
372-
return node && Boolean(
373-
node.type === 'JSXExpressionContainer'
374-
&& node.expression
375-
&& node.expression.type === 'ArrayExpression'
362+
return (
363+
node
364+
&& Boolean(
365+
node.type === 'JSXExpressionContainer'
366+
&& node.expression
367+
&& node.expression.type === 'ArrayExpression'
368+
)
376369
);
377370
},
378371

@@ -408,10 +401,18 @@ const astHelpers = {
408401
invalid = true;
409402
obj[p.key.name] = getSourceCode(innerNode);
410403
}
411-
} else if (p.value.type === 'UnaryExpression' && p.value.operator === '-' && p.value.argument.type === 'Literal') {
404+
} else if (
405+
p.value.type === 'UnaryExpression'
406+
&& p.value.operator === '-'
407+
&& p.value.argument.type === 'Literal'
408+
) {
412409
invalid = true;
413410
obj[p.key.name] = -1 * p.value.argument.value;
414-
} else if (p.value.type === 'UnaryExpression' && p.value.operator === '+' && p.value.argument.type === 'Literal') {
411+
} else if (
412+
p.value.type === 'UnaryExpression'
413+
&& p.value.operator === '+'
414+
&& p.value.argument.type === 'Literal'
415+
) {
415416
invalid = true;
416417
obj[p.key.name] = p.value.argument.value;
417418
}
@@ -443,21 +444,13 @@ const astHelpers = {
443444
},
444445

445446
getObjectName: function (node) {
446-
if (
447-
node
448-
&& node.object
449-
&& node.object.name
450-
) {
447+
if (node && node.object && node.object.name) {
451448
return node.object.name;
452449
}
453450
},
454451

455452
getPropertyName: function (node) {
456-
if (
457-
node
458-
&& node.property
459-
&& node.property.name
460-
) {
453+
if (node && node.property && node.property.name) {
461454
return node.property.name;
462455
}
463456
},
@@ -477,11 +470,32 @@ const astHelpers = {
477470
}
478471
},
479472

473+
getPotentialStyleReferenceFromArrayExpression: function (node) {
474+
if (node && node.type === 'Identifier' && node.name) {
475+
return node.name;
476+
}
477+
},
478+
479+
getPotentialStyleReferenceFromJSXExpressionContainer: function (node) {
480+
if (
481+
node
482+
&& node.expression
483+
&& node.expression.type === 'Identifier'
484+
&& node.expression.name
485+
&& node.parent
486+
&& node.parent.name
487+
&& node.parent.name.name === 'style'
488+
) {
489+
return node.expression.name;
490+
}
491+
},
492+
480493
isEitherShortHand: function (property1, property2) {
481494
const shorthands = ['margin', 'padding', 'border', 'flex'];
482495
if (shorthands.includes(property1)) {
483496
return property2.startsWith(property1);
484-
} if (shorthands.includes(property2)) {
497+
}
498+
if (shorthands.includes(property2)) {
485499
return property1.startsWith(property2);
486500
}
487501
return false;

0 commit comments

Comments
 (0)