pi-lens
Version:
Real-time code feedback for pi — LSP, linters, formatters, type-checking, structural analysis & booboo
40 lines (39 loc) • 1.78 kB
JavaScript
import { isTestFile } from "../../file-utils.js";
export const asyncNoiseRule = {
id: "async-noise",
requires: ["file.functionSummaries"],
appliesTo(ctx) {
return /\.tsx?$/.test(ctx.filePath) && !isTestFile(ctx.filePath);
},
evaluate(ctx, store) {
const summaries = store.getFileFact(ctx.filePath, "file.functionSummaries");
if (!summaries)
return [];
const diagnostics = [];
// Function name patterns that legitimately declare async for interface compliance
// or future-proofing (lifecycle hooks, event handlers, middleware, abstract stubs)
const ASYNC_INTERFACE_PATTERN = /^(on[A-Z]|handle[A-Z]|before[A-Z]|after[A-Z]|setup|teardown|init|dispose|connect|disconnect|open|close|start|stop|run|execute|invoke|dispatch|middleware)/;
for (const fn of summaries) {
if (fn.isAsync &&
!fn.hasAwait &&
!fn.hasReturnAwaitCall &&
!fn.isPassThroughWrapper &&
!ASYNC_INTERFACE_PATTERN.test(fn.name) &&
// Skip single-statement functions — likely interface stubs or thin wrappers
fn.statementCount > 1) {
diagnostics.push({
id: `async-noise:${ctx.filePath}:${fn.line}:${fn.column}`,
tool: "fact-rules",
filePath: ctx.filePath,
line: fn.line,
column: fn.column,
severity: "warning",
semantic: "warning",
message: `Async function '${fn.name}' has no await and appears to add async noise`,
rule: "async-noise",
});
}
}
return diagnostics;
},
};