@kernlang/review 3.1.5 → 3.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +17 -0
- package/dist/cache.d.ts +1 -1
- package/dist/cache.js +5 -3
- package/dist/cache.js.map +1 -1
- package/dist/call-graph.d.ts +63 -0
- package/dist/call-graph.js +380 -0
- package/dist/call-graph.js.map +1 -0
- package/dist/concept-rules/boundary-mutation.d.ts +1 -1
- package/dist/concept-rules/boundary-mutation.js.map +1 -1
- package/dist/concept-rules/ignored-error.d.ts +1 -1
- package/dist/concept-rules/ignored-error.js.map +1 -1
- package/dist/concept-rules/illegal-dependency.d.ts +1 -1
- package/dist/concept-rules/illegal-dependency.js.map +1 -1
- package/dist/concept-rules/index.js +1 -6
- package/dist/concept-rules/index.js.map +1 -1
- package/dist/concept-rules/unguarded-effect.d.ts +1 -1
- package/dist/concept-rules/unguarded-effect.js.map +1 -1
- package/dist/concept-rules/unrecovered-effect.d.ts +1 -1
- package/dist/concept-rules/unrecovered-effect.js +2 -1
- package/dist/concept-rules/unrecovered-effect.js.map +1 -1
- package/dist/confidence.js +12 -8
- package/dist/confidence.js.map +1 -1
- package/dist/differ.js +3 -7
- package/dist/differ.js.map +1 -1
- package/dist/external-tools.js +5 -6
- package/dist/external-tools.js.map +1 -1
- package/dist/file-context.d.ts +21 -0
- package/dist/file-context.js +234 -0
- package/dist/file-context.js.map +1 -0
- package/dist/file-role.js +14 -7
- package/dist/file-role.js.map +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/graph.js +24 -16
- package/dist/graph.js.map +1 -1
- package/dist/index.d.ts +44 -35
- package/dist/index.js +221 -68
- package/dist/index.js.map +1 -1
- package/dist/inferrer.d.ts +8 -2
- package/dist/inferrer.js +80 -47
- package/dist/inferrer.js.map +1 -1
- package/dist/kern-lint.d.ts +3 -4
- package/dist/kern-lint.js +7 -5
- package/dist/kern-lint.js.map +1 -1
- package/dist/llm-bridge.d.ts +23 -7
- package/dist/llm-bridge.js +267 -31
- package/dist/llm-bridge.js.map +1 -1
- package/dist/llm-review.d.ts +16 -2
- package/dist/llm-review.js +240 -35
- package/dist/llm-review.js.map +1 -1
- package/dist/mappers/ts-concepts.d.ts +1 -1
- package/dist/mappers/ts-concepts.js +303 -32
- package/dist/mappers/ts-concepts.js.map +1 -1
- package/dist/norm-miner.d.ts +31 -0
- package/dist/norm-miner.js +119 -0
- package/dist/norm-miner.js.map +1 -0
- package/dist/obligations.d.ts +63 -0
- package/dist/obligations.js +158 -0
- package/dist/obligations.js.map +1 -0
- package/dist/quality-rules.d.ts +3 -3
- package/dist/quality-rules.js +4 -2
- package/dist/quality-rules.js.map +1 -1
- package/dist/reporter.d.ts +7 -2
- package/dist/reporter.js +82 -51
- package/dist/reporter.js.map +1 -1
- package/dist/rule-eval.d.ts +1 -2
- package/dist/rule-eval.js +5 -9
- package/dist/rule-eval.js.map +1 -1
- package/dist/rule-loader.js +16 -14
- package/dist/rule-loader.js.map +1 -1
- package/dist/rules/base.js +153 -69
- package/dist/rules/base.js.map +1 -1
- package/dist/rules/cli.d.ts +7 -0
- package/dist/rules/cli.js +99 -0
- package/dist/rules/cli.js.map +1 -0
- package/dist/rules/confidence.d.ts +1 -1
- package/dist/rules/confidence.js +5 -5
- package/dist/rules/confidence.js.map +1 -1
- package/dist/rules/dead-code.d.ts +10 -0
- package/dist/rules/dead-code.js +75 -0
- package/dist/rules/dead-code.js.map +1 -0
- package/dist/rules/dead-logic.js +35 -31
- package/dist/rules/dead-logic.js.map +1 -1
- package/dist/rules/express.d.ts +2 -1
- package/dist/rules/express.js +380 -126
- package/dist/rules/express.js.map +1 -1
- package/dist/rules/fastapi.d.ts +10 -0
- package/dist/rules/fastapi.js +183 -0
- package/dist/rules/fastapi.js.map +1 -0
- package/dist/rules/ground-layer.js +3 -3
- package/dist/rules/ground-layer.js.map +1 -1
- package/dist/rules/index.d.ts +5 -1
- package/dist/rules/index.js +602 -84
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/ink.d.ts +8 -0
- package/dist/rules/ink.js +88 -0
- package/dist/rules/ink.js.map +1 -0
- package/dist/rules/kern-source.js +202 -63
- package/dist/rules/kern-source.js.map +1 -1
- package/dist/rules/nextjs.js +88 -33
- package/dist/rules/nextjs.js.map +1 -1
- package/dist/rules/null-safety.js +52 -26
- package/dist/rules/null-safety.js.map +1 -1
- package/dist/rules/nuxt.js +24 -29
- package/dist/rules/nuxt.js.map +1 -1
- package/dist/rules/react.js +355 -69
- package/dist/rules/react.js.map +1 -1
- package/dist/rules/security-v2.js +71 -57
- package/dist/rules/security-v2.js.map +1 -1
- package/dist/rules/security-v3.js.map +1 -1
- package/dist/rules/security-v4.js +54 -27
- package/dist/rules/security-v4.js.map +1 -1
- package/dist/rules/security.js +35 -5
- package/dist/rules/security.js.map +1 -1
- package/dist/rules/terminal.d.ts +8 -0
- package/dist/rules/terminal.js +139 -0
- package/dist/rules/terminal.js.map +1 -0
- package/dist/rules/vue.js +162 -107
- package/dist/rules/vue.js.map +1 -1
- package/dist/semantic-diff.d.ts +52 -0
- package/dist/semantic-diff.js +342 -0
- package/dist/semantic-diff.js.map +1 -0
- package/dist/spec-checker.js +11 -10
- package/dist/spec-checker.js.map +1 -1
- package/dist/suppression/apply-suppression.d.ts +2 -3
- package/dist/suppression/apply-suppression.js +3 -3
- package/dist/suppression/apply-suppression.js.map +1 -1
- package/dist/suppression/index.d.ts +2 -2
- package/dist/suppression/index.js +1 -1
- package/dist/suppression/index.js.map +1 -1
- package/dist/suppression/parse-directives.d.ts +1 -1
- package/dist/suppression/parse-directives.js +9 -4
- package/dist/suppression/parse-directives.js.map +1 -1
- package/dist/taint-ast.d.ts +20 -0
- package/dist/taint-ast.js +427 -0
- package/dist/taint-ast.js.map +1 -0
- package/dist/taint-crossfile.d.ts +28 -0
- package/dist/taint-crossfile.js +174 -0
- package/dist/taint-crossfile.js.map +1 -0
- package/dist/taint-findings.d.ts +17 -0
- package/dist/taint-findings.js +131 -0
- package/dist/taint-findings.js.map +1 -0
- package/dist/taint-regex.d.ts +61 -0
- package/dist/taint-regex.js +379 -0
- package/dist/taint-regex.js.map +1 -0
- package/dist/taint-types.d.ts +128 -0
- package/dist/taint-types.js +174 -0
- package/dist/taint-types.js.map +1 -0
- package/dist/taint.d.ts +13 -107
- package/dist/taint.js +16 -1067
- package/dist/taint.js.map +1 -1
- package/dist/template-detector.d.ts +2 -2
- package/dist/template-detector.js +11 -16
- package/dist/template-detector.js.map +1 -1
- package/dist/types.d.ts +35 -0
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
package/LICENSE
CHANGED
|
@@ -659,3 +659,20 @@ specific requirements.
|
|
|
659
659
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
660
660
|
For more information on this, and how to apply and follow the GNU AGPL, see
|
|
661
661
|
<https://www.gnu.org/licenses/>.
|
|
662
|
+
|
|
663
|
+
===============================================================================
|
|
664
|
+
|
|
665
|
+
Copyright (c) 2026 KERNlang
|
|
666
|
+
|
|
667
|
+
Additional permission under GNU AGPL version 3 section 7:
|
|
668
|
+
|
|
669
|
+
If you modify this Program, or any covered work, by linking or combining
|
|
670
|
+
it with other code, such other code is not for that reason alone subject
|
|
671
|
+
to any of the requirements of the GNU Affero GPL version 3.
|
|
672
|
+
|
|
673
|
+
---
|
|
674
|
+
|
|
675
|
+
COMMERCIAL USE
|
|
676
|
+
|
|
677
|
+
Using this software as part of a paid product or service requires a
|
|
678
|
+
commercial license. Contact: hello@kernlang.dev
|
package/dist/cache.d.ts
CHANGED
package/dist/cache.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash } from 'crypto';
|
|
2
|
-
import {
|
|
3
|
-
import { join } from 'path';
|
|
2
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'fs';
|
|
4
3
|
import { homedir } from 'os';
|
|
4
|
+
import { join } from 'path';
|
|
5
5
|
export class ReviewCache {
|
|
6
6
|
l1 = new Map();
|
|
7
7
|
cacheDir;
|
|
@@ -81,7 +81,9 @@ export function computeCacheKey(fileContent, config, filePath) {
|
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
catch {
|
|
84
|
+
catch {
|
|
85
|
+
/* skip unreadable dirs */
|
|
86
|
+
}
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
return hash.digest('hex');
|
package/dist/cache.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call Graph — function-level call resolution across the import graph.
|
|
3
|
+
*
|
|
4
|
+
* Intentionally unsound — resolves what it can and marks what it can't:
|
|
5
|
+
*
|
|
6
|
+
* Resolved (high confidence):
|
|
7
|
+
* - Direct function calls: foo()
|
|
8
|
+
* - Named imports: import { foo } from './bar'
|
|
9
|
+
* - Property access on imports: bar.foo()
|
|
10
|
+
* - Re-exports: export { foo } from './bar'
|
|
11
|
+
* - Class method calls: this.foo()
|
|
12
|
+
*
|
|
13
|
+
* Skipped (marked unresolved):
|
|
14
|
+
* - Dynamic imports: import(), require()
|
|
15
|
+
* - Higher-order functions: arr.map(callback)
|
|
16
|
+
* - Computed property access: obj[key]()
|
|
17
|
+
* - Framework magic: decorators, DI containers
|
|
18
|
+
* - Aliased function variables: const f = foo; f()
|
|
19
|
+
*
|
|
20
|
+
* Dead export findings from unresolved edges get lower confidence (0.70 vs 0.90).
|
|
21
|
+
*/
|
|
22
|
+
import { type Project } from 'ts-morph';
|
|
23
|
+
import type { GraphResult } from './types.js';
|
|
24
|
+
export interface CallSite {
|
|
25
|
+
callerName: string;
|
|
26
|
+
callerFile: string;
|
|
27
|
+
targetName: string;
|
|
28
|
+
/** Resolved target file path. Empty string if unresolved. */
|
|
29
|
+
targetFile: string;
|
|
30
|
+
line: number;
|
|
31
|
+
argumentCount: number;
|
|
32
|
+
/** False = could not resolve target (HOF, dynamic, computed property, etc.) */
|
|
33
|
+
resolved: boolean;
|
|
34
|
+
/** Whether the call site is awaited */
|
|
35
|
+
hasAwait: boolean;
|
|
36
|
+
}
|
|
37
|
+
export interface FunctionNode {
|
|
38
|
+
name: string;
|
|
39
|
+
filePath: string;
|
|
40
|
+
line: number;
|
|
41
|
+
isExported: boolean;
|
|
42
|
+
isAsync: boolean;
|
|
43
|
+
paramCount: number;
|
|
44
|
+
/** Outgoing calls from this function */
|
|
45
|
+
calls: CallSite[];
|
|
46
|
+
/** Incoming calls to this function (populated during cross-file linking) */
|
|
47
|
+
calledBy: CallSite[];
|
|
48
|
+
}
|
|
49
|
+
export interface CallGraph {
|
|
50
|
+
/** All functions. Key: filePath#fnName */
|
|
51
|
+
functions: Map<string, FunctionNode>;
|
|
52
|
+
/** Exported functions with zero resolved incoming calledBy edges */
|
|
53
|
+
deadExports: string[];
|
|
54
|
+
/** Non-exported functions never called within the file */
|
|
55
|
+
orphanFunctions: string[];
|
|
56
|
+
/** How many calls couldn't be resolved */
|
|
57
|
+
unresolvedCallCount: number;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Build a function-level call graph from the import graph.
|
|
61
|
+
* Requires a ts-morph Project with all files loaded.
|
|
62
|
+
*/
|
|
63
|
+
export declare function buildCallGraph(graph: GraphResult, project: Project): CallGraph;
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call Graph — function-level call resolution across the import graph.
|
|
3
|
+
*
|
|
4
|
+
* Intentionally unsound — resolves what it can and marks what it can't:
|
|
5
|
+
*
|
|
6
|
+
* Resolved (high confidence):
|
|
7
|
+
* - Direct function calls: foo()
|
|
8
|
+
* - Named imports: import { foo } from './bar'
|
|
9
|
+
* - Property access on imports: bar.foo()
|
|
10
|
+
* - Re-exports: export { foo } from './bar'
|
|
11
|
+
* - Class method calls: this.foo()
|
|
12
|
+
*
|
|
13
|
+
* Skipped (marked unresolved):
|
|
14
|
+
* - Dynamic imports: import(), require()
|
|
15
|
+
* - Higher-order functions: arr.map(callback)
|
|
16
|
+
* - Computed property access: obj[key]()
|
|
17
|
+
* - Framework magic: decorators, DI containers
|
|
18
|
+
* - Aliased function variables: const f = foo; f()
|
|
19
|
+
*
|
|
20
|
+
* Dead export findings from unresolved edges get lower confidence (0.70 vs 0.90).
|
|
21
|
+
*/
|
|
22
|
+
import { SyntaxKind } from 'ts-morph';
|
|
23
|
+
// ── Import Resolution ───────────────────────────────────────────────────
|
|
24
|
+
/** Build a map of importName → resolvedFilePath#exportName for a source file */
|
|
25
|
+
function buildImportBindings(sourceFile, graphFiles) {
|
|
26
|
+
const bindings = new Map();
|
|
27
|
+
for (const decl of sourceFile.getImportDeclarations()) {
|
|
28
|
+
const resolvedSf = decl.getModuleSpecifierSourceFile();
|
|
29
|
+
if (!resolvedSf)
|
|
30
|
+
continue;
|
|
31
|
+
const resolvedPath = resolvedSf.getFilePath();
|
|
32
|
+
if (!graphFiles.has(resolvedPath))
|
|
33
|
+
continue;
|
|
34
|
+
// Named imports: import { foo, bar as baz } from './mod'
|
|
35
|
+
for (const named of decl.getNamedImports()) {
|
|
36
|
+
const localName = named.getName();
|
|
37
|
+
const _originalName = named.getAliasNode()?.getText() || localName;
|
|
38
|
+
// The imported name is the original export name
|
|
39
|
+
const importedName = named.getName();
|
|
40
|
+
bindings.set(localName, `${resolvedPath}#${importedName}`);
|
|
41
|
+
}
|
|
42
|
+
// Default import: import Foo from './mod'
|
|
43
|
+
const defaultImport = decl.getDefaultImport();
|
|
44
|
+
if (defaultImport) {
|
|
45
|
+
bindings.set(defaultImport.getText(), `${resolvedPath}#default`);
|
|
46
|
+
}
|
|
47
|
+
// Namespace import: import * as mod from './mod'
|
|
48
|
+
const namespaceImport = decl.getNamespaceImport();
|
|
49
|
+
if (namespaceImport) {
|
|
50
|
+
bindings.set(namespaceImport.getText(), `${resolvedPath}#*`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return bindings;
|
|
54
|
+
}
|
|
55
|
+
// ── Function Collection ─────────────────────────────────────────────────
|
|
56
|
+
/** Collect all function declarations from a source file */
|
|
57
|
+
function collectFunctions(sourceFile, filePath) {
|
|
58
|
+
const functions = [];
|
|
59
|
+
const exportedNames = new Set();
|
|
60
|
+
// Track what's exported
|
|
61
|
+
for (const decl of sourceFile.getExportedDeclarations()) {
|
|
62
|
+
exportedNames.add(decl[0]);
|
|
63
|
+
}
|
|
64
|
+
// Named function declarations
|
|
65
|
+
for (const fn of sourceFile.getFunctions()) {
|
|
66
|
+
const name = fn.getName();
|
|
67
|
+
if (!name)
|
|
68
|
+
continue;
|
|
69
|
+
functions.push({
|
|
70
|
+
name,
|
|
71
|
+
filePath,
|
|
72
|
+
line: fn.getStartLineNumber(),
|
|
73
|
+
isExported: exportedNames.has(name) || fn.hasExportKeyword(),
|
|
74
|
+
isAsync: fn.isAsync(),
|
|
75
|
+
paramCount: fn.getParameters().length,
|
|
76
|
+
calls: [],
|
|
77
|
+
calledBy: [],
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
// Arrow function / function expression variables
|
|
81
|
+
for (const stmt of sourceFile.getVariableStatements()) {
|
|
82
|
+
const isExportedStmt = stmt.hasExportKeyword();
|
|
83
|
+
for (const decl of stmt.getDeclarations()) {
|
|
84
|
+
const init = decl.getInitializer();
|
|
85
|
+
if (!init)
|
|
86
|
+
continue;
|
|
87
|
+
const kind = init.getKindName();
|
|
88
|
+
if (kind !== 'ArrowFunction' && kind !== 'FunctionExpression')
|
|
89
|
+
continue;
|
|
90
|
+
const name = decl.getName();
|
|
91
|
+
const fn = init;
|
|
92
|
+
functions.push({
|
|
93
|
+
name,
|
|
94
|
+
filePath,
|
|
95
|
+
line: stmt.getStartLineNumber(),
|
|
96
|
+
isExported: isExportedStmt || exportedNames.has(name),
|
|
97
|
+
isAsync: fn.isAsync(),
|
|
98
|
+
paramCount: fn.getParameters().length,
|
|
99
|
+
calls: [],
|
|
100
|
+
calledBy: [],
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Class methods
|
|
105
|
+
for (const cls of sourceFile.getClasses()) {
|
|
106
|
+
const clsName = cls.getName() || 'anonymous';
|
|
107
|
+
for (const method of cls.getMethods()) {
|
|
108
|
+
const name = `${clsName}.${method.getName()}`;
|
|
109
|
+
functions.push({
|
|
110
|
+
name,
|
|
111
|
+
filePath,
|
|
112
|
+
line: method.getStartLineNumber(),
|
|
113
|
+
isExported: exportedNames.has(clsName),
|
|
114
|
+
isAsync: method.isAsync(),
|
|
115
|
+
paramCount: method.getParameters().length,
|
|
116
|
+
calls: [],
|
|
117
|
+
calledBy: [],
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return functions;
|
|
122
|
+
}
|
|
123
|
+
// ── Call Site Extraction ────────────────────────────────────────────────
|
|
124
|
+
/** Extract all call sites from a function body */
|
|
125
|
+
function extractCallSites(fnNode, sourceFile, localFnNames, importBindings) {
|
|
126
|
+
const callSites = [];
|
|
127
|
+
// Find the AST node for this function
|
|
128
|
+
const body = findFunctionBody(fnNode, sourceFile);
|
|
129
|
+
if (!body)
|
|
130
|
+
return callSites;
|
|
131
|
+
// Walk all call expressions in the body
|
|
132
|
+
body.forEachDescendant((node) => {
|
|
133
|
+
if (node.getKind() !== SyntaxKind.CallExpression)
|
|
134
|
+
return;
|
|
135
|
+
const call = node;
|
|
136
|
+
const callee = call.getExpression();
|
|
137
|
+
const args = call.getArguments();
|
|
138
|
+
// Check if the call is awaited
|
|
139
|
+
const parent = call.getParent();
|
|
140
|
+
const hasAwait = parent?.getKind() === SyntaxKind.AwaitExpression;
|
|
141
|
+
const calleeKind = callee.getKindName();
|
|
142
|
+
// Case 1: Direct call — foo()
|
|
143
|
+
if (calleeKind === 'Identifier') {
|
|
144
|
+
const targetName = callee.getText();
|
|
145
|
+
// Skip builtins and common non-function identifiers
|
|
146
|
+
if (isBuiltin(targetName))
|
|
147
|
+
return;
|
|
148
|
+
// Local function in same file?
|
|
149
|
+
if (localFnNames.has(targetName)) {
|
|
150
|
+
callSites.push({
|
|
151
|
+
callerName: fnNode.name,
|
|
152
|
+
callerFile: fnNode.filePath,
|
|
153
|
+
targetName,
|
|
154
|
+
targetFile: fnNode.filePath,
|
|
155
|
+
line: call.getStartLineNumber(),
|
|
156
|
+
argumentCount: args.length,
|
|
157
|
+
resolved: true,
|
|
158
|
+
hasAwait,
|
|
159
|
+
});
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Imported function?
|
|
163
|
+
const binding = importBindings.get(targetName);
|
|
164
|
+
if (binding) {
|
|
165
|
+
const [targetFile, exportName] = splitBinding(binding);
|
|
166
|
+
callSites.push({
|
|
167
|
+
callerName: fnNode.name,
|
|
168
|
+
callerFile: fnNode.filePath,
|
|
169
|
+
targetName: exportName,
|
|
170
|
+
targetFile,
|
|
171
|
+
line: call.getStartLineNumber(),
|
|
172
|
+
argumentCount: args.length,
|
|
173
|
+
resolved: true,
|
|
174
|
+
hasAwait,
|
|
175
|
+
});
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
// Unresolved
|
|
179
|
+
callSites.push({
|
|
180
|
+
callerName: fnNode.name,
|
|
181
|
+
callerFile: fnNode.filePath,
|
|
182
|
+
targetName,
|
|
183
|
+
targetFile: '',
|
|
184
|
+
line: call.getStartLineNumber(),
|
|
185
|
+
argumentCount: args.length,
|
|
186
|
+
resolved: false,
|
|
187
|
+
hasAwait,
|
|
188
|
+
});
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
// Case 2: Property access — obj.method()
|
|
192
|
+
if (calleeKind === 'PropertyAccessExpression') {
|
|
193
|
+
const prop = callee;
|
|
194
|
+
const methodName = prop.getName();
|
|
195
|
+
const objExpr = prop.getExpression();
|
|
196
|
+
const objName = objExpr.getKindName() === 'Identifier' ? objExpr.getText() : '';
|
|
197
|
+
// this.method() — resolved within class
|
|
198
|
+
if (objName === 'this') {
|
|
199
|
+
callSites.push({
|
|
200
|
+
callerName: fnNode.name,
|
|
201
|
+
callerFile: fnNode.filePath,
|
|
202
|
+
targetName: methodName,
|
|
203
|
+
targetFile: fnNode.filePath,
|
|
204
|
+
line: call.getStartLineNumber(),
|
|
205
|
+
argumentCount: args.length,
|
|
206
|
+
resolved: localFnNames.has(methodName),
|
|
207
|
+
hasAwait,
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
// Namespace import: mod.foo()
|
|
212
|
+
const nsBinding = importBindings.get(objName);
|
|
213
|
+
if (nsBinding?.endsWith('#*')) {
|
|
214
|
+
const targetFile = nsBinding.slice(0, -2);
|
|
215
|
+
callSites.push({
|
|
216
|
+
callerName: fnNode.name,
|
|
217
|
+
callerFile: fnNode.filePath,
|
|
218
|
+
targetName: methodName,
|
|
219
|
+
targetFile,
|
|
220
|
+
line: call.getStartLineNumber(),
|
|
221
|
+
argumentCount: args.length,
|
|
222
|
+
resolved: true,
|
|
223
|
+
hasAwait,
|
|
224
|
+
});
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
// Unresolved property access — can't statically resolve obj.method()
|
|
228
|
+
callSites.push({
|
|
229
|
+
callerName: fnNode.name,
|
|
230
|
+
callerFile: fnNode.filePath,
|
|
231
|
+
targetName: `${objName}.${methodName}`,
|
|
232
|
+
targetFile: '',
|
|
233
|
+
line: call.getStartLineNumber(),
|
|
234
|
+
argumentCount: args.length,
|
|
235
|
+
resolved: false,
|
|
236
|
+
hasAwait,
|
|
237
|
+
});
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// Case 3: Everything else (computed, tagged template, etc.) — unresolved
|
|
241
|
+
callSites.push({
|
|
242
|
+
callerName: fnNode.name,
|
|
243
|
+
callerFile: fnNode.filePath,
|
|
244
|
+
targetName: callee.getText().substring(0, 30),
|
|
245
|
+
targetFile: '',
|
|
246
|
+
line: call.getStartLineNumber(),
|
|
247
|
+
argumentCount: args.length,
|
|
248
|
+
resolved: false,
|
|
249
|
+
hasAwait,
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
return callSites;
|
|
253
|
+
}
|
|
254
|
+
/** Find the AST body node for a FunctionNode */
|
|
255
|
+
function findFunctionBody(fnNode, sourceFile) {
|
|
256
|
+
// Try named function
|
|
257
|
+
for (const fn of sourceFile.getFunctions()) {
|
|
258
|
+
if (fn.getName() === fnNode.name && fn.getStartLineNumber() === fnNode.line) {
|
|
259
|
+
return fn.getBody();
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
// Try variable declarations (arrow / function expression)
|
|
263
|
+
for (const stmt of sourceFile.getVariableStatements()) {
|
|
264
|
+
for (const decl of stmt.getDeclarations()) {
|
|
265
|
+
if (decl.getName() === fnNode.name && stmt.getStartLineNumber() === fnNode.line) {
|
|
266
|
+
const init = decl.getInitializer();
|
|
267
|
+
if (init && (init.getKindName() === 'ArrowFunction' || init.getKindName() === 'FunctionExpression')) {
|
|
268
|
+
return init.getBody();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return undefined;
|
|
274
|
+
}
|
|
275
|
+
function splitBinding(binding) {
|
|
276
|
+
const idx = binding.lastIndexOf('#');
|
|
277
|
+
return [binding.slice(0, idx), binding.slice(idx + 1)];
|
|
278
|
+
}
|
|
279
|
+
const BUILTINS = new Set([
|
|
280
|
+
'console',
|
|
281
|
+
'setTimeout',
|
|
282
|
+
'setInterval',
|
|
283
|
+
'clearTimeout',
|
|
284
|
+
'clearInterval',
|
|
285
|
+
'parseInt',
|
|
286
|
+
'parseFloat',
|
|
287
|
+
'String',
|
|
288
|
+
'Number',
|
|
289
|
+
'Boolean',
|
|
290
|
+
'Array',
|
|
291
|
+
'Object',
|
|
292
|
+
'JSON',
|
|
293
|
+
'Math',
|
|
294
|
+
'Date',
|
|
295
|
+
'Error',
|
|
296
|
+
'Promise',
|
|
297
|
+
'Map',
|
|
298
|
+
'Set',
|
|
299
|
+
'Symbol',
|
|
300
|
+
'require',
|
|
301
|
+
'import',
|
|
302
|
+
'typeof',
|
|
303
|
+
'void',
|
|
304
|
+
]);
|
|
305
|
+
function isBuiltin(name) {
|
|
306
|
+
return BUILTINS.has(name);
|
|
307
|
+
}
|
|
308
|
+
// ── Main API ────────────────────────────────────────────────────────────
|
|
309
|
+
/**
|
|
310
|
+
* Build a function-level call graph from the import graph.
|
|
311
|
+
* Requires a ts-morph Project with all files loaded.
|
|
312
|
+
*/
|
|
313
|
+
export function buildCallGraph(graph, project) {
|
|
314
|
+
const graphFiles = new Map();
|
|
315
|
+
for (const gf of graph.files) {
|
|
316
|
+
graphFiles.set(gf.path, gf);
|
|
317
|
+
}
|
|
318
|
+
const allFunctions = new Map();
|
|
319
|
+
const fileFunctions = new Map();
|
|
320
|
+
// Phase 1: Collect all functions from all files
|
|
321
|
+
for (const gf of graph.files) {
|
|
322
|
+
const sf = project.getSourceFile(gf.path);
|
|
323
|
+
if (!sf)
|
|
324
|
+
continue;
|
|
325
|
+
const fns = collectFunctions(sf, gf.path);
|
|
326
|
+
fileFunctions.set(gf.path, fns);
|
|
327
|
+
for (const fn of fns) {
|
|
328
|
+
allFunctions.set(`${fn.filePath}#${fn.name}`, fn);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// Phase 2: Extract call sites for each function
|
|
332
|
+
let unresolvedCount = 0;
|
|
333
|
+
for (const gf of graph.files) {
|
|
334
|
+
const sf = project.getSourceFile(gf.path);
|
|
335
|
+
if (!sf)
|
|
336
|
+
continue;
|
|
337
|
+
const fns = fileFunctions.get(gf.path) || [];
|
|
338
|
+
const localFnNames = new Set(fns.map((f) => f.name));
|
|
339
|
+
const importBindings = buildImportBindings(sf, graphFiles);
|
|
340
|
+
for (const fn of fns) {
|
|
341
|
+
fn.calls = extractCallSites(fn, sf, localFnNames, importBindings);
|
|
342
|
+
unresolvedCount += fn.calls.filter((c) => !c.resolved).length;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// Phase 3: Link calledBy edges (cross-file)
|
|
346
|
+
for (const fn of allFunctions.values()) {
|
|
347
|
+
for (const call of fn.calls) {
|
|
348
|
+
if (!call.resolved || !call.targetFile)
|
|
349
|
+
continue;
|
|
350
|
+
const targetKey = `${call.targetFile}#${call.targetName}`;
|
|
351
|
+
const target = allFunctions.get(targetKey);
|
|
352
|
+
if (target) {
|
|
353
|
+
target.calledBy.push(call);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
// Phase 4: Identify dead exports and orphan functions
|
|
358
|
+
const deadExports = [];
|
|
359
|
+
const orphanFunctions = [];
|
|
360
|
+
for (const [key, fn] of allFunctions) {
|
|
361
|
+
if (fn.isExported && fn.calledBy.length === 0) {
|
|
362
|
+
deadExports.push(key);
|
|
363
|
+
}
|
|
364
|
+
if (!fn.isExported && fn.calledBy.length === 0) {
|
|
365
|
+
// Check if called locally (within same file)
|
|
366
|
+
const calledLocally = [...allFunctions.values()].some((other) => other.filePath === fn.filePath &&
|
|
367
|
+
other.calls.some((c) => c.resolved && c.targetFile === fn.filePath && c.targetName === fn.name));
|
|
368
|
+
if (!calledLocally) {
|
|
369
|
+
orphanFunctions.push(key);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
return {
|
|
374
|
+
functions: allFunctions,
|
|
375
|
+
deadExports,
|
|
376
|
+
orphanFunctions,
|
|
377
|
+
unresolvedCallCount: unresolvedCount,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
//# sourceMappingURL=call-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-graph.js","sourceRoot":"","sources":["../src/call-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
* Python: mutating a shared module-level dict
|
|
9
9
|
* Go: mutating shared package-level state
|
|
10
10
|
*/
|
|
11
|
-
import type { ConceptRuleContext } from './index.js';
|
|
12
11
|
import type { ReviewFinding } from '../types.js';
|
|
12
|
+
import type { ConceptRuleContext } from './index.js';
|
|
13
13
|
export declare function boundaryMutation(ctx: ConceptRuleContext): ReviewFinding[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boundary-mutation.js","sourceRoot":"","sources":["../../src/concept-rules/boundary-mutation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"boundary-mutation.js","sourceRoot":"","sources":["../../src/concept-rules/boundary-mutation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,UAAU,gBAAgB,CAAC,GAAuB;IACtD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,IAAI,KAAK,gBAAgB;YAAE,SAAS;QAC7C,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,gBAAgB;YAAE,SAAS;QACrD,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,QAAQ;YAAE,SAAS;QAEjF,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,mBAAmB;YAC3B,QAAQ,EAAE,SAAS;YACnB,QAAQ,EAAE,SAAS;YACnB,OAAO,EAAE,4EAA4E;YACrF,WAAW,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;gBAC3B,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS;gBACrC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ;gBACnC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO;gBACjC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM;aAChC;YACD,WAAW,EAAE,iBAAiB,CAAC,mBAAmB,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;YAC1G,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
* Python: except: pass
|
|
9
9
|
* Go: if err != nil {}
|
|
10
10
|
*/
|
|
11
|
-
import type { ConceptRuleContext } from './index.js';
|
|
12
11
|
import type { ReviewFinding } from '../types.js';
|
|
12
|
+
import type { ConceptRuleContext } from './index.js';
|
|
13
13
|
export declare function ignoredError(ctx: ConceptRuleContext): ReviewFinding[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ignored-error.js","sourceRoot":"","sources":["../../src/concept-rules/ignored-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"ignored-error.js","sourceRoot":"","sources":["../../src/concept-rules/ignored-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,UAAU,YAAY,CAAC,GAAuB;IAClD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc;YAAE,SAAS;QAC3C,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,cAAc;YAAE,SAAS;QACnD,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,KAAK,SAAS;YAAE,SAAS;QAErD,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,eAAe;YACvB,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,KAAK;YACf,OAAO,EAAE,uDAAuD;YAChE,WAAW,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;gBAC3B,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS;gBACrC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ;gBACnC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO;gBACjC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM;aAChC;YACD,WAAW,EAAE,iBAAiB,CAAC,eAAe,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;YACtG,UAAU,EAAE,IAAI,CAAC,UAAU;SAC5B,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
* Python: from ...core.shared import x
|
|
9
9
|
* Go: internal import path that walks too far upward
|
|
10
10
|
*/
|
|
11
|
-
import type { ConceptRuleContext } from './index.js';
|
|
12
11
|
import type { ReviewFinding } from '../types.js';
|
|
12
|
+
import type { ConceptRuleContext } from './index.js';
|
|
13
13
|
export declare function illegalDependency(ctx: ConceptRuleContext): ReviewFinding[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"illegal-dependency.js","sourceRoot":"","sources":["../../src/concept-rules/illegal-dependency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"illegal-dependency.js","sourceRoot":"","sources":["../../src/concept-rules/illegal-dependency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,UAAU,iBAAiB,CAAC,GAAuB;IACvD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;YAAE,SAAS;QACzC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY;YAAE,SAAS;QACjD,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,UAAU;YAAE,SAAS;QAElD,MAAM,QAAQ,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACvD,IAAI,QAAQ,IAAI,CAAC;YAAE,SAAS;QAE5B,QAAQ,CAAC,IAAI,CAAC;YACZ,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,oBAAoB;YAC5B,QAAQ,EAAE,SAAS;YACnB,QAAQ,EAAE,WAAW;YACrB,OAAO,EAAE,8DAA8D;YACvE,WAAW,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;gBAC3B,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS;gBACrC,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ;gBACnC,OAAO,EAAE,IAAI,CAAC,WAAW,CAAC,OAAO;gBACjC,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,MAAM;aAChC;YACD,WAAW,EAAE,iBAAiB,CAAC,oBAAoB,EAAE,IAAI,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;YAC3G,UAAU,EAAE,IAAI,CAAC,UAAU,GAAG,GAAG,EAAE,wDAAwD;SAC5F,CAAC,CAAC;IACL,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,aAAa,CAAC,SAAiB;IACtC,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAC7B,CAAC"}
|
|
@@ -8,12 +8,7 @@ import { boundaryMutation } from './boundary-mutation.js';
|
|
|
8
8
|
import { ignoredError } from './ignored-error.js';
|
|
9
9
|
import { unguardedEffect } from './unguarded-effect.js';
|
|
10
10
|
import { unrecoveredEffect } from './unrecovered-effect.js';
|
|
11
|
-
export const conceptRules = [
|
|
12
|
-
boundaryMutation,
|
|
13
|
-
ignoredError,
|
|
14
|
-
unguardedEffect,
|
|
15
|
-
unrecoveredEffect,
|
|
16
|
-
];
|
|
11
|
+
export const conceptRules = [boundaryMutation, ignoredError, unguardedEffect, unrecoveredEffect];
|
|
17
12
|
export function runConceptRules(concepts, filePath, allConcepts, graphImports) {
|
|
18
13
|
const ctx = { concepts, filePath, allConcepts, graphImports };
|
|
19
14
|
const findings = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/concept-rules/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAa5D,MAAM,CAAC,MAAM,YAAY,GAAkB
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/concept-rules/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAa5D,MAAM,CAAC,MAAM,YAAY,GAAkB,CAAC,gBAAgB,EAAE,YAAY,EAAE,eAAe,EAAE,iBAAiB,CAAC,CAAC;AAEhH,MAAM,UAAU,eAAe,CAC7B,QAAoB,EACpB,QAAgB,EAChB,WAAqC,EACrC,YAAoC;IAEpC,MAAM,GAAG,GAAuB,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE,CAAC;IAClF,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
* Python: requests.get() in a view without auth/validation
|
|
9
9
|
* Go: db.Query() in a handler without auth/validation
|
|
10
10
|
*/
|
|
11
|
-
import type { ConceptRuleContext } from './index.js';
|
|
12
11
|
import type { ReviewFinding } from '../types.js';
|
|
12
|
+
import type { ConceptRuleContext } from './index.js';
|
|
13
13
|
export declare function unguardedEffect(ctx: ConceptRuleContext): ReviewFinding[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unguarded-effect.js","sourceRoot":"","sources":["../../src/concept-rules/unguarded-effect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"unguarded-effect.js","sourceRoot":"","sources":["../../src/concept-rules/unguarded-effect.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,6 @@
|
|
|
8
8
|
* Python: requests.get() without try/except
|
|
9
9
|
* Go: http.Get() with err ignored
|
|
10
10
|
*/
|
|
11
|
-
import type { ConceptRuleContext } from './index.js';
|
|
12
11
|
import type { ReviewFinding } from '../types.js';
|
|
12
|
+
import type { ConceptRuleContext } from './index.js';
|
|
13
13
|
export declare function unrecoveredEffect(ctx: ConceptRuleContext): ReviewFinding[];
|
|
@@ -37,7 +37,8 @@ export function unrecoveredEffect(ctx) {
|
|
|
37
37
|
continue;
|
|
38
38
|
// Also check if there's any error_handle in the same container (even logged)
|
|
39
39
|
// Guard: undefined === undefined would match unrelated top-level nodes
|
|
40
|
-
const hasAnyHandler = node.containerId !== undefined &&
|
|
40
|
+
const hasAnyHandler = node.containerId !== undefined &&
|
|
41
|
+
ctx.concepts.nodes.some((n) => n.kind === 'error_handle' && n.containerId === node.containerId);
|
|
41
42
|
if (hasAnyHandler)
|
|
42
43
|
continue;
|
|
43
44
|
findings.push({
|