From 35601c5a6db4fdf6a8b52ba239b94e63798bd1b0 Mon Sep 17 00:00:00 2001 From: silifatzoffun74-art Date: Mon, 29 Jun 2026 16:36:00 +0100 Subject: [PATCH] feat(rules): add detect-missing-return-docs detector Adds auditability rule that flags functions with non-void return types lacking @return NatSpec comments. Closes #343 Closes #341 Closes #340 Closes #339 --- .../docs/detect-missing-return-docs.ts | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 rules/auditability/docs/detect-missing-return-docs.ts diff --git a/rules/auditability/docs/detect-missing-return-docs.ts b/rules/auditability/docs/detect-missing-return-docs.ts new file mode 100644 index 0000000..65e575c --- /dev/null +++ b/rules/auditability/docs/detect-missing-return-docs.ts @@ -0,0 +1,48 @@ +// Detect missing function return documentation (issue #343) +export interface MissingReturnDocViolation { + type: string; + line: number; + description: string; + recommendation: string; +} + +export interface MissingReturnDocResult { + detected: boolean; + violations: MissingReturnDocViolation[]; + message: string; + suggestion: string; +} + +// Matches functions that have a non-void return type but no @return / @returns NatSpec +const FN_WITH_RETURN = /function\s+\w+\s*\([^)]*\)\s*(?:public|private|internal|external|pure|view|payable|\s)*returns\s*\(/g; +const HAS_RETURN_DOC = /@returns?\s+/; + +export function detectMissingReturnDocs(source: string): MissingReturnDocResult { + const violations: MissingReturnDocViolation[] = []; + const lines = source.split("\n"); + + lines.forEach((line, idx) => { + if (FN_WITH_RETURN.test(line)) { + // Look back up to 5 lines for a @return / @returns NatSpec tag + const window = lines.slice(Math.max(0, idx - 5), idx).join("\n"); + if (!HAS_RETURN_DOC.test(window)) { + violations.push({ + type: "missing-return-docs", + line: idx + 1, + description: `Function at line ${idx + 1} returns a value but has no @return NatSpec comment.`, + recommendation: "Add a /// @return NatSpec comment above the function.", + }); + } + } + FN_WITH_RETURN.lastIndex = 0; // reset stateful regex + }); + + return { + detected: violations.length > 0, + violations, + message: violations.length > 0 + ? `Found ${violations.length} function(s) with missing return documentation.` + : "All returning functions have return documentation.", + suggestion: "Document every non-void return value with /// @return to improve auditability.", + }; +}