Improve internal ESLint rule (#14112)
This commit is contained in:
1 parent
01a9241959
commit
52140cc6ad
3 files changed
+94
-17
No files matched your search
+65
-9
@@ -17,24 +17,32 @@ const isTypeAccess = (node, parameterName) => {
|
||||
);
|
||||
};
|
||||
|
||||
const isTypeCheck = (node, parameterName) =>
|
||||
const isEqualCheck = (node) =>
|
||||
node.type === "BinaryExpression" &&
|
||||
node.operator === "===" &&
|
||||
isTypeAccess(node.left, parameterName) &&
|
||||
node.right.type === "Literal" &&
|
||||
typeof node.right.value === "string";
|
||||
function getTypes(node, parameterName) {
|
||||
if (isTypeCheck(node, parameterName)) {
|
||||
|
||||
const isTypeIdentifierCheck = (node) =>
|
||||
isEqualCheck(node) &&
|
||||
node.left.type === "Identifier" &&
|
||||
node.left.name === "type";
|
||||
|
||||
const isTypeAccessCheck = (node, parameterName) =>
|
||||
isEqualCheck(node) && isTypeAccess(node.left, parameterName);
|
||||
|
||||
function getTypesFromNodeParameter(node, parameterName) {
|
||||
if (isTypeAccessCheck(node, parameterName)) {
|
||||
return [node.right.value];
|
||||
}
|
||||
|
||||
if (node.type === "LogicalExpression" && node.operator === "||") {
|
||||
const left = getTypes(node.left, parameterName);
|
||||
const left = getTypesFromNodeParameter(node.left, parameterName);
|
||||
|
||||
if (!left) {
|
||||
return;
|
||||
}
|
||||
const right = getTypes(node.right, parameterName);
|
||||
const right = getTypesFromNodeParameter(node.right, parameterName);
|
||||
|
||||
if (!right) {
|
||||
return;
|
||||
@@ -44,6 +52,54 @@ function getTypes(node, parameterName) {
|
||||
}
|
||||
}
|
||||
|
||||
function getTypesFromTypeParameter(node) {
|
||||
if (isTypeIdentifierCheck(node)) {
|
||||
return [node.right.value];
|
||||
}
|
||||
|
||||
if (node.type === "LogicalExpression" && node.operator === "||") {
|
||||
const left = getTypesFromTypeParameter(node.left);
|
||||
|
||||
if (!left) {
|
||||
return;
|
||||
}
|
||||
const right = getTypesFromTypeParameter(node.right);
|
||||
|
||||
if (!right) {
|
||||
return;
|
||||
}
|
||||
|
||||
return [...left, ...right];
|
||||
}
|
||||
}
|
||||
|
||||
function getTypes(node, parameter) {
|
||||
// `function(node) {}`
|
||||
if (parameter.type === "Identifier") {
|
||||
return getTypesFromNodeParameter(node, parameter.name);
|
||||
}
|
||||
|
||||
// `function({type}) {}`
|
||||
if (
|
||||
parameter.type === "ObjectPattern" &&
|
||||
parameter.properties.length === 1 &&
|
||||
parameter.properties[0].type === "Property"
|
||||
) {
|
||||
const [{ shorthand, computed, key, value }] = parameter.properties;
|
||||
|
||||
if (
|
||||
shorthand &&
|
||||
!computed &&
|
||||
key.type === "Identifier" &&
|
||||
key.name === "type" &&
|
||||
value.type === "Identifier" &&
|
||||
value.name === "type"
|
||||
) {
|
||||
return getTypesFromTypeParameter(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isTopLevelFunction(node) {
|
||||
return (
|
||||
node.parent.type === "Program" ||
|
||||
@@ -57,7 +113,6 @@ function isTopLevelFunction(node) {
|
||||
const selector = [
|
||||
":function",
|
||||
"[params.length=1]",
|
||||
'[params.0.type="Identifier"]',
|
||||
"[async!=true]",
|
||||
"[generator!=true]",
|
||||
].join("");
|
||||
@@ -116,8 +171,9 @@ module.exports = {
|
||||
returnStatementArgument = body.body[0].argument;
|
||||
}
|
||||
|
||||
const parameterName = functionNode.params[0].name;
|
||||
const types = getTypes(returnStatementArgument, parameterName);
|
||||
const [parameter] = functionNode.params;
|
||||
const types = getTypes(returnStatementArgument, parameter);
|
||||
|
||||
if (!types) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -423,6 +423,11 @@ test("prefer-create-type-check-function", {
|
||||
return node.kind === "get" || node.kind === "set";
|
||||
}
|
||||
`,
|
||||
outdent`
|
||||
const isClassProperty = ({ notType }) =>
|
||||
notType === "ClassProperty" ||
|
||||
notType === "PropertyDefinition";
|
||||
`,
|
||||
],
|
||||
invalid: [
|
||||
{
|
||||
@@ -541,6 +546,20 @@ test("prefer-create-type-check-function", {
|
||||
`,
|
||||
errors: 1,
|
||||
},
|
||||
{
|
||||
code: outdent`
|
||||
const isClassProperty = ({ type }) =>
|
||||
type === "ClassProperty" ||
|
||||
type === "PropertyDefinition";
|
||||
`,
|
||||
output: outdent`
|
||||
const isClassProperty = createTypeCheckFunction([
|
||||
"ClassProperty",
|
||||
"PropertyDefinition"
|
||||
]);
|
||||
`,
|
||||
errors: 1,
|
||||
},
|
||||
].map((testCase) => ({
|
||||
...testCase,
|
||||
parserOptions: { sourceType: "module" },
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
hasComment,
|
||||
CommentCheckFlags,
|
||||
isNextLineEmpty,
|
||||
createTypeCheckFunction,
|
||||
} from "../utils/index.js";
|
||||
import { shouldPrintParamsWithoutParens } from "./function.js";
|
||||
|
||||
@@ -157,14 +158,15 @@ function printSwitchCaseConsequent(path, options, print) {
|
||||
return printStatementSequence(path, options, print, "consequent");
|
||||
}
|
||||
|
||||
const isClassProperty = ({ type }) =>
|
||||
type === "ClassProperty" ||
|
||||
type === "PropertyDefinition" ||
|
||||
type === "ClassPrivateProperty" ||
|
||||
type === "ClassAccessorProperty" ||
|
||||
type === "AccessorProperty" ||
|
||||
type === "TSAbstractPropertyDefinition" ||
|
||||
type === "TSAbstractAccessorProperty";
|
||||
const isClassProperty = createTypeCheckFunction([
|
||||
"ClassProperty",
|
||||
"PropertyDefinition",
|
||||
"ClassPrivateProperty",
|
||||
"ClassAccessorProperty",
|
||||
"AccessorProperty",
|
||||
"TSAbstractPropertyDefinition",
|
||||
"TSAbstractAccessorProperty",
|
||||
]);
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user