Improve internal ESLint rule (#14112)

This commit is contained in:
fisker Cheung authored and GitHub committed 2023-01-11 11:22:44 +08:00
1 parent 01a9241959
commit 52140cc6ad
3 files changed
+94 -17

No files matched your search

@@ -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" },
+10 -8
View File
@@ -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}
*/