Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: Intellicode/eslint-plugin-react-native
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: tulitheprogrammer/eslint-plugin-react-native
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: feature/styles-destructuring-support
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 6 commits
  • 5 files changed
  • 1 contributor

Commits on Nov 1, 2021

  1. added destructured styles detection

    Barzilay, Oshri (ob143h) committed Nov 1, 2021
    Copy the full SHA
    dae95cc View commit details
  2. fix tests

    Barzilay, Oshri (ob143h) committed Nov 1, 2021
    Copy the full SHA
    16899b8 View commit details
  3. add textStyle destructuring support

    Barzilay, Oshri (ob143h) committed Nov 1, 2021
    Copy the full SHA
    a428adb View commit details
  4. fixed styles destructuring support

    Barzilay, Oshri (ob143h) committed Nov 1, 2021
    Copy the full SHA
    b618278 View commit details
  5. UTs update

    Barzilay, Oshri (ob143h) committed Nov 1, 2021
    Copy the full SHA
    a1e4a2a View commit details
  6. dups removed

    Barzilay, Oshri (ob143h) committed Nov 1, 2021
    Copy the full SHA
    c930a19 View commit details
Showing with 503 additions and 171 deletions.
  1. +7 −9 lib/rules/no-unused-styles.js
  2. +70 −64 lib/util/stylesheet.js
  3. +39 −29 tests/lib/rules/no-color-literals.js
  4. +11 −11 tests/lib/rules/no-inline-styles.js
  5. +376 −58 tests/lib/rules/no-unused-styles.js
16 changes: 7 additions & 9 deletions lib/rules/no-unused-styles.js
Original file line number Diff line number Diff line change
@@ -20,12 +20,7 @@ module.exports = Components.detect((context, components) => {
if ({}.hasOwnProperty.call(unusedStyles, key)) {
const styles = unusedStyles[key];
styles.forEach((node) => {
const message = [
'Unused style detected: ',
key,
'.',
node.key.name,
].join('');
const message = ['Unused style detected: ', key, '.', node.key.name].join('');

context.report(node, message);
});
@@ -41,6 +36,11 @@ module.exports = Components.detect((context, components) => {
}
},

VariableDeclarator: function (node) {
const styleRefs = astHelpers.getPotentialDestructuredStyleReferences(node);
styleRefs.forEach(styleReferences.add, styleReferences);
},

CallExpression: function (node) {
if (astHelpers.isStyleSheetDeclaration(node, context.settings)) {
const styleSheetName = astHelpers.getStyleSheetName(node);
@@ -53,9 +53,7 @@ module.exports = Components.detect((context, components) => {
'Program:exit': function () {
const list = components.all();
if (Object.keys(list).length > 0) {
styleReferences.forEach((reference) => {
styleSheets.markAsUsed(reference);
});
styleReferences.forEach(styleSheets.markAsUsed, styleSheets);
reportUnusedStyles(styleSheets.getUnusedReferences());
}
},
134 changes: 70 additions & 64 deletions lib/util/stylesheet.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

'use strict';

/**
@@ -32,9 +31,9 @@ StyleSheets.prototype.markAsUsed = function (fullyQualifiedName) {
const styleSheetProperty = nameSplit[1];

if (this.styleSheets[styleSheetName]) {
this.styleSheets[styleSheetName] = this
.styleSheets[styleSheetName]
.filter((property) => property.key.name !== styleSheetProperty);
this.styleSheets[styleSheetName] = this.styleSheets[styleSheetName].filter(
(property) => property.key.name !== styleSheetProperty
);
}
};

@@ -86,44 +85,45 @@ StyleSheets.prototype.getObjectExpressions = function () {
return this.objectExpressions;
};


let currentContent;
const getSourceCode = (node) => currentContent
.getSourceCode(node)
.getText(node);
const getSourceCode = (node) => currentContent.getSourceCode(node).getText(node);

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

const astHelpers = {
containsStyleSheetObject: function (node, objectNames) {
return Boolean(
node
&& node.type === 'CallExpression'
&& node.callee
&& node.callee.object
&& node.callee.object.name
&& objectNames.includes(node.callee.object.name)
&& node.type === 'CallExpression'
&& node.callee
&& node.callee.object
&& node.callee.object.name
&& objectNames.includes(node.callee.object.name)
);
},

containsCreateCall: function (node) {
return Boolean(
node
&& node.callee
&& node.callee.property
&& node.callee.property.name === 'create'
node && node.callee && node.callee.property && node.callee.property.name === 'create'
);
},

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

return Boolean(
astHelpers.containsStyleSheetObject(node, objectNames)
&& astHelpers.containsCreateCall(node)
astHelpers.containsStyleSheetObject(node, objectNames) && astHelpers.containsCreateCall(node)
);
},

getDestructuringAssignmentParts: function (node) {
if (node && node.id && node.id.type === 'ObjectPattern' && node.id.properties && node.init) {
return [node.init.name, node.id.properties];
}

return [null, null];
},

getStyleSheetName: function (node) {
if (node && node.parent && node.parent.id) {
return node.parent.id.name;
@@ -200,10 +200,12 @@ const astHelpers = {
case 'Literal':
return node.value;
case 'TemplateLiteral':
return node.quasis.reduce((result, quasi, index) => result
+ quasi.value.cooked
+ astHelpers.getExpressionIdentifier(node.expressions[index]),
'');
return node.quasis.reduce(
(result, quasi, index) => result
+ quasi.value.cooked
+ astHelpers.getExpressionIdentifier(node.expressions[index]),
''
);
default:
return '';
}
@@ -213,34 +215,28 @@ const astHelpers = {
},

getStylePropertyIdentifier: function (node) {
if (
node
&& node.key
) {
if (node && node.key) {
return astHelpers.getExpressionIdentifier(node.key);
}
},

isStyleAttribute: function (node) {
return Boolean(
node.type === 'JSXAttribute'
&& node.name
&& node.name.name
&& node.name.name.toLowerCase().includes('style')
&& node.name
&& node.name.name
&& node.name.name.toLowerCase().includes('style')
);
},

collectStyleObjectExpressions: function (node, context) {
currentContent = context;
if (astHelpers.hasArrayOfStyleReferences(node)) {
const styleReferenceContainers = node
.expression
.elements;
const styleReferenceContainers = node.expression.elements;

return astHelpers.collectStyleObjectExpressionFromContainers(
styleReferenceContainers
);
} if (node && node.expression) {
return astHelpers.collectStyleObjectExpressionFromContainers(styleReferenceContainers);
}
if (node && node.expression) {
return astHelpers.getStyleObjectExpressionFromNode(node.expression);
}

@@ -254,13 +250,9 @@ const astHelpers = {

currentContent = context;
if (astHelpers.hasArrayOfStyleReferences(node)) {
const styleReferenceContainers = node
.expression
.elements;
const styleReferenceContainers = node.expression.elements;

return astHelpers.collectColorLiteralsFromContainers(
styleReferenceContainers
);
return astHelpers.collectColorLiteralsFromContainers(styleReferenceContainers);
}

if (node.type === 'ObjectExpression') {
@@ -273,8 +265,9 @@ const astHelpers = {
collectStyleObjectExpressionFromContainers: function (nodes) {
let objectExpressions = [];
nodes.forEach((node) => {
objectExpressions = objectExpressions
.concat(astHelpers.getStyleObjectExpressionFromNode(node));
objectExpressions = objectExpressions.concat(
astHelpers.getStyleObjectExpressionFromNode(node)
);
});

return objectExpressions;
@@ -283,8 +276,7 @@ const astHelpers = {
collectColorLiteralsFromContainers: function (nodes) {
let colorLiterals = [];
nodes.forEach((node) => {
colorLiterals = colorLiterals
.concat(astHelpers.getColorLiteralsFromNode(node));
colorLiterals = colorLiterals.concat(astHelpers.getColorLiteralsFromNode(node));
});

return colorLiterals;
@@ -369,10 +361,13 @@ const astHelpers = {
},

hasArrayOfStyleReferences: function (node) {
return node && Boolean(
node.type === 'JSXExpressionContainer'
&& node.expression
&& node.expression.type === 'ArrayExpression'
return (
node
&& Boolean(
node.type === 'JSXExpressionContainer'
&& node.expression
&& node.expression.type === 'ArrayExpression'
)
);
},

@@ -408,10 +403,18 @@ const astHelpers = {
invalid = true;
obj[p.key.name] = getSourceCode(innerNode);
}
} else if (p.value.type === 'UnaryExpression' && p.value.operator === '-' && p.value.argument.type === 'Literal') {
} else if (
p.value.type === 'UnaryExpression'
&& p.value.operator === '-'
&& p.value.argument.type === 'Literal'
) {
invalid = true;
obj[p.key.name] = -1 * p.value.argument.value;
} else if (p.value.type === 'UnaryExpression' && p.value.operator === '+' && p.value.argument.type === 'Literal') {
} else if (
p.value.type === 'UnaryExpression'
&& p.value.operator === '+'
&& p.value.argument.type === 'Literal'
) {
invalid = true;
obj[p.key.name] = p.value.argument.value;
}
@@ -443,21 +446,13 @@ const astHelpers = {
},

getObjectName: function (node) {
if (
node
&& node.object
&& node.object.name
) {
if (node && node.object && node.object.name) {
return node.object.name;
}
},

getPropertyName: function (node) {
if (
node
&& node.property
&& node.property.name
) {
if (node && node.property && node.property.name) {
return node.property.name;
}
},
@@ -477,11 +472,22 @@ const astHelpers = {
}
},

getPotentialDestructuredStyleReferences: function (node) {
const [styleSheetName, properties] = this.getDestructuringAssignmentParts(node);

return styleSheetName && properties
? properties.flatMap((property) => (property.key && property.key.type === 'Identifier' && property.key.name
? `${styleSheetName}.${property.key.name}`
: []))
: [];
},

isEitherShortHand: function (property1, property2) {
const shorthands = ['margin', 'padding', 'border', 'flex'];
if (shorthands.includes(property1)) {
return property2.startsWith(property1);
} if (shorthands.includes(property2)) {
}
if (shorthands.includes(property2)) {
return property1.startsWith(property2);
}
return false;
Loading