73 lines
2.3 KiB
JavaScript
73 lines
2.3 KiB
JavaScript
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,
|
||
};
|
||
},
|
||
};
|