Add isNonEmptyArray (#9902)
This commit is contained in:
1 parent
0fd2a28cff
commit
c7e354e38c
23 files changed
+215
-48
No files matched your search
@@ -7,6 +7,7 @@ module.exports = {
|
||||
"jsx-identifier-case": require("./jsx-identifier-case"),
|
||||
"no-node-comments": require("./no-node-comments"),
|
||||
"prefer-fast-path-each": require("./prefer-fast-path-each"),
|
||||
"prefer-is-non-empty-array": require("./prefer-is-non-empty-array"),
|
||||
"require-json-extensions": require("./require-json-extensions"),
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,152 @@
|
||||
"use strict";
|
||||
|
||||
const getLengthSelector = (path) =>
|
||||
`[${path}.type="MemberExpression"][${path}.property.type="Identifier"][${path}.property.name="length"]`;
|
||||
const selector = [
|
||||
"LogicalExpression",
|
||||
':not(FunctionDeclaration[id.name="isNonEmptyArray"] *)',
|
||||
'[operator="&&"]',
|
||||
`:matches(${[
|
||||
// `&& foo.length`
|
||||
getLengthSelector("right"),
|
||||
// `&& foo.length !== 0`
|
||||
// `&& foo.length > 0`
|
||||
[
|
||||
'[right.type="BinaryExpression"]',
|
||||
':matches([right.operator="!=="], [right.operator=">"])',
|
||||
getLengthSelector("right.left"),
|
||||
'[right.right.type="Literal"]',
|
||||
'[right.right.raw="0"]',
|
||||
].join(""),
|
||||
].join(", ")})`,
|
||||
].join("");
|
||||
|
||||
const negativeSelector = [
|
||||
"LogicalExpression",
|
||||
'[operator="||"]',
|
||||
`:matches(${[
|
||||
// `|| !foo.length`
|
||||
[
|
||||
'[right.type="UnaryExpression"]',
|
||||
'[right.operator="!"]',
|
||||
getLengthSelector("right.argument"),
|
||||
].join(""),
|
||||
// `|| foo.length === 0`
|
||||
[
|
||||
'[right.type="BinaryExpression"]',
|
||||
'[right.operator="==="]',
|
||||
getLengthSelector("right.left"),
|
||||
'[right.right.type="Literal"]',
|
||||
'[right.right.raw="0"]',
|
||||
].join(""),
|
||||
].join(", ")})`,
|
||||
].join("");
|
||||
|
||||
const isArrayIsArrayCall = (node) =>
|
||||
node.type === "CallExpression" &&
|
||||
node.callee.type === "MemberExpression" &&
|
||||
node.callee.object.type === "Identifier" &&
|
||||
node.callee.object.name === "Array" &&
|
||||
node.callee.property.type === "Identifier" &&
|
||||
node.callee.property.name === "isArray";
|
||||
|
||||
const MESSAGE_ID = "prefer-is-non-empty-array";
|
||||
|
||||
module.exports = {
|
||||
meta: {
|
||||
type: "suggestion",
|
||||
docs: {
|
||||
url:
|
||||
"https://github.com/prettier/prettier/blob/master/scripts/eslint-plugin-prettier-internal-rules/prefer-is-non-empty-array.js",
|
||||
},
|
||||
messages: {
|
||||
[MESSAGE_ID]: "Please use `isNonEmptyArray()`.",
|
||||
},
|
||||
fixable: "code",
|
||||
},
|
||||
create(context) {
|
||||
const sourceCode = context.getSourceCode();
|
||||
|
||||
return {
|
||||
[selector](node) {
|
||||
let { left, right } = node;
|
||||
|
||||
while (left.type === "LogicalExpression" && left.operator === "&&") {
|
||||
left = left.right;
|
||||
}
|
||||
|
||||
let leftObject = left;
|
||||
// `Array.isArray(foo)`
|
||||
if (isArrayIsArrayCall(leftObject)) {
|
||||
leftObject = leftObject.arguments[0];
|
||||
}
|
||||
|
||||
const rightObject =
|
||||
right.type === "BinaryExpression" ? right.left.object : right.object;
|
||||
const objectText = sourceCode.getText(rightObject);
|
||||
// Simple compare with code
|
||||
if (sourceCode.getText(leftObject) !== objectText) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [start] = left.range;
|
||||
const [, end] = node.range;
|
||||
context.report({
|
||||
loc: {
|
||||
start: sourceCode.getLocFromIndex(start),
|
||||
end: sourceCode.getLocFromIndex(end),
|
||||
},
|
||||
messageId: MESSAGE_ID,
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange(
|
||||
[start, end],
|
||||
`isNonEmptyArray(${objectText})`
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
[negativeSelector](node) {
|
||||
let { left, right } = node;
|
||||
|
||||
while (left.type === "LogicalExpression" && left.operator === "||") {
|
||||
left = left.right;
|
||||
}
|
||||
|
||||
if (!left.type === "UnaryExpression" || left.operator !== "!") {
|
||||
return;
|
||||
}
|
||||
|
||||
const rightObject =
|
||||
right.type === "UnaryExpression"
|
||||
? right.argument.object
|
||||
: right.left.object;
|
||||
let leftObject = left.argument;
|
||||
if (isArrayIsArrayCall(leftObject)) {
|
||||
leftObject = leftObject.arguments[0];
|
||||
}
|
||||
|
||||
const objectText = sourceCode.getText(rightObject);
|
||||
// Simple compare with code
|
||||
if (sourceCode.getText(leftObject) !== objectText) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [start] = left.range;
|
||||
const [, end] = node.range;
|
||||
context.report({
|
||||
loc: {
|
||||
start: sourceCode.getLocFromIndex(start),
|
||||
end: sourceCode.getLocFromIndex(end),
|
||||
},
|
||||
messageId: MESSAGE_ID,
|
||||
fix(fixer) {
|
||||
return fixer.replaceTextRange(
|
||||
[start, end],
|
||||
`!isNonEmptyArray(${objectText})`
|
||||
);
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
Reference in new issue
Block a user