feat: ESLint 自定义规则增强 — 空函数和 catch 模式的项目修复指引

This commit is contained in:
2026-06-01 16:23:04 +08:00
parent 60843f7dbf
commit df5b60eb53
3 changed files with 162 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
export const noEmptyFunction = {
meta: {
type: "problem",
docs: {
description:
"禁止空函数体,并提供项目约定的修复指引:生产代码使用 () => undefined测试代码使用 () => {} + eslint-disable",
},
messages: {
unexpectedProduction:
"生产代码中空函数应使用 () => undefined 明确表意(如 noop/voidLog。如果确需空实现且为接口契约请添加注释说明原因。",
unexpectedTest:
"测试代码中空函数使用 () => {} 并在文件顶部添加 /* eslint-disable @typescript-eslint/no-empty-function */。",
},
schema: [],
},
create(context) {
const sourceCode = context.sourceCode ?? context.getSourceCode();
const allowedFunctionTypes = new Set([
"ArrowFunctionExpression",
"FunctionDeclaration",
"FunctionExpression",
]);
function isEmptyBody(body) {
return (
body.type === "BlockStatement" &&
body.body.length === 0 &&
sourceCode.getCommentsInside(body).length === 0
);
}
function hasDecorator(node) {
return Array.isArray(node.decorators) && node.decorators.length > 0;
}
function isPrivateOrProtectedConstructor(node) {
if (node.parent?.type !== "MethodDefinition") return false;
if (node.parent.kind !== "constructor") return false;
const accessibility = node.parent.accessibility;
return accessibility === "private" || accessibility === "protected";
}
function isOverrideMethod(node) {
if (node.parent?.type !== "MethodDefinition") return false;
return node.parent.override === true;
}
function check(node) {
if (!allowedFunctionTypes.has(node.type)) return;
if (!isEmptyBody(node.body)) return;
if (hasDecorator(node)) return;
if (isPrivateOrProtectedConstructor(node)) return;
if (isOverrideMethod(node)) return;
const isTest = /[\\/]tests?[\\/]/.test(context.filename ?? "") || context.filename?.includes("test");
context.report({
node,
messageId: isTest ? "unexpectedTest" : "unexpectedProduction",
data: { name: node.id?.name ?? node.key?.name ?? "function" },
});
}
return {
ArrowFunctionExpression: check,
FunctionDeclaration: check,
FunctionExpression: check,
};
},
};