@kernlang/review 2.0.0 → 3.1.0
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/dist/concept-rules/boundary-mutation.d.ts +13 -0
- package/dist/concept-rules/boundary-mutation.js +40 -0
- package/dist/concept-rules/boundary-mutation.js.map +1 -0
- package/dist/concept-rules/ignored-error.d.ts +13 -0
- package/dist/concept-rules/ignored-error.js +40 -0
- package/dist/concept-rules/ignored-error.js.map +1 -0
- package/dist/concept-rules/illegal-dependency.d.ts +13 -0
- package/dist/concept-rules/illegal-dependency.js +49 -0
- package/dist/concept-rules/illegal-dependency.js.map +1 -0
- package/dist/concept-rules/index.d.ts +15 -0
- package/dist/concept-rules/index.js +27 -0
- package/dist/concept-rules/index.js.map +1 -0
- package/dist/concept-rules/unguarded-effect.d.ts +13 -0
- package/dist/concept-rules/unguarded-effect.js +58 -0
- package/dist/concept-rules/unguarded-effect.js.map +1 -0
- package/dist/concept-rules/unrecovered-effect.d.ts +13 -0
- package/dist/concept-rules/unrecovered-effect.js +61 -0
- package/dist/concept-rules/unrecovered-effect.js.map +1 -0
- package/dist/confidence.d.ts +92 -0
- package/dist/confidence.js +263 -0
- package/dist/confidence.js.map +1 -0
- package/dist/differ.js +4 -2
- package/dist/differ.js.map +1 -1
- package/dist/external-tools.js +7 -3
- package/dist/external-tools.js.map +1 -1
- package/dist/file-role.d.ts +10 -0
- package/dist/file-role.js +80 -0
- package/dist/file-role.js.map +1 -0
- package/dist/graph.d.ts +11 -0
- package/dist/graph.js +152 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +46 -3
- package/dist/index.js +313 -27
- package/dist/index.js.map +1 -1
- package/dist/inferrer.js +123 -25
- package/dist/inferrer.js.map +1 -1
- package/dist/kern-lint.d.ts +18 -0
- package/dist/kern-lint.js +24 -0
- package/dist/kern-lint.js.map +1 -0
- package/dist/llm-bridge.d.ts +42 -0
- package/dist/llm-bridge.js +176 -0
- package/dist/llm-bridge.js.map +1 -0
- package/dist/llm-review.d.ts +8 -1
- package/dist/llm-review.js +20 -7
- package/dist/llm-review.js.map +1 -1
- package/dist/mappers/ts-concepts.d.ts +9 -0
- package/dist/mappers/ts-concepts.js +518 -0
- package/dist/mappers/ts-concepts.js.map +1 -0
- package/dist/quality-rules.d.ts +3 -3
- package/dist/quality-rules.js +3 -11
- package/dist/quality-rules.js.map +1 -1
- package/dist/reporter.d.ts +19 -3
- package/dist/reporter.js +232 -20
- package/dist/reporter.js.map +1 -1
- package/dist/rules/base.js +167 -15
- package/dist/rules/base.js.map +1 -1
- package/dist/rules/confidence.d.ts +37 -0
- package/dist/rules/confidence.js +159 -0
- package/dist/rules/confidence.js.map +1 -0
- package/dist/rules/dead-logic.d.ts +13 -0
- package/dist/rules/dead-logic.js +393 -0
- package/dist/rules/dead-logic.js.map +1 -0
- package/dist/rules/express.js +69 -2
- package/dist/rules/express.js.map +1 -1
- package/dist/rules/ground-layer.d.ts +23 -0
- package/dist/rules/ground-layer.js +132 -0
- package/dist/rules/ground-layer.js.map +1 -0
- package/dist/rules/index.d.ts +1 -1
- package/dist/rules/index.js +8 -2
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/kern-source.d.ts +16 -0
- package/dist/rules/kern-source.js +726 -0
- package/dist/rules/kern-source.js.map +1 -0
- package/dist/rules/nextjs.js +38 -10
- package/dist/rules/nextjs.js.map +1 -1
- package/dist/rules/null-safety.d.ts +12 -0
- package/dist/rules/null-safety.js +123 -0
- package/dist/rules/null-safety.js.map +1 -0
- package/dist/rules/react.js +64 -1
- package/dist/rules/react.js.map +1 -1
- package/dist/rules/security-v2.d.ts +12 -0
- package/dist/rules/security-v2.js +415 -0
- package/dist/rules/security-v2.js.map +1 -0
- package/dist/rules/security-v3.d.ts +12 -0
- package/dist/rules/security-v3.js +397 -0
- package/dist/rules/security-v3.js.map +1 -0
- package/dist/rules/security-v4.d.ts +22 -0
- package/dist/rules/security-v4.js +688 -0
- package/dist/rules/security-v4.js.map +1 -0
- package/dist/rules/security.d.ts +12 -0
- package/dist/rules/security.js +286 -0
- package/dist/rules/security.js.map +1 -0
- package/dist/rules/utils.d.ts +7 -0
- package/dist/rules/utils.js +21 -0
- package/dist/rules/utils.js.map +1 -0
- package/dist/rules/vue.js +1 -1
- package/dist/rules/vue.js.map +1 -1
- package/dist/spec-checker.d.ts +83 -0
- package/dist/spec-checker.js +405 -0
- package/dist/spec-checker.js.map +1 -0
- package/dist/suppression/apply-suppression.d.ts +17 -0
- package/dist/suppression/apply-suppression.js +94 -0
- package/dist/suppression/apply-suppression.js.map +1 -0
- package/dist/suppression/index.d.ts +6 -0
- package/dist/suppression/index.js +6 -0
- package/dist/suppression/index.js.map +1 -0
- package/dist/suppression/parse-directives.d.ts +25 -0
- package/dist/suppression/parse-directives.js +161 -0
- package/dist/suppression/parse-directives.js.map +1 -0
- package/dist/suppression/types.d.ts +32 -0
- package/dist/suppression/types.js +5 -0
- package/dist/suppression/types.js.map +1 -0
- package/dist/taint.d.ts +115 -0
- package/dist/taint.js +1052 -0
- package/dist/taint.js.map +1 -0
- package/dist/types.d.ts +71 -0
- package/dist/types.js.map +1 -1
- package/package.json +7 -4
package/dist/reporter.d.ts
CHANGED
|
@@ -6,10 +6,26 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { ReviewReport, ReviewStats, ReviewFinding, InferResult, TemplateMatch, EnforceResult, ReviewConfig } from './types.js';
|
|
8
8
|
export declare function calculateStats(inferred: InferResult[], templateMatches: TemplateMatch[], findings: ReviewFinding[], totalLines: number): ReviewStats;
|
|
9
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Deduplicate findings using fingerprint + message hash.
|
|
11
|
+
* Fingerprint alone can collide when a rule emits multiple findings at the same location
|
|
12
|
+
* (e.g., machine-gap fires once per unreachable state on the same type declaration line).
|
|
13
|
+
*/
|
|
10
14
|
export declare function dedup(findings: ReviewFinding[]): ReviewFinding[];
|
|
15
|
+
/** Sort findings by severity (error > warning > info) then by line. Shared utility. */
|
|
16
|
+
export declare function sortFindings(findings: ReviewFinding[]): void;
|
|
17
|
+
/** Dedup + sort in one call. Replaces the 5 duplicated sort/dedup blocks. */
|
|
18
|
+
export declare function sortAndDedup(findings: ReviewFinding[]): ReviewFinding[];
|
|
11
19
|
export declare function checkEnforcement(report: ReviewReport, config: ReviewConfig): EnforceResult;
|
|
12
|
-
export declare function formatReport(report: ReviewReport): string;
|
|
20
|
+
export declare function formatReport(report: ReviewReport, config?: ReviewConfig): string;
|
|
13
21
|
export declare function formatEnforcement(result: EnforceResult): string;
|
|
14
|
-
export declare function formatReportJSON(report: ReviewReport
|
|
22
|
+
export declare function formatReportJSON(report: ReviewReport, options?: {
|
|
23
|
+
includeLLMPrompt?: boolean;
|
|
24
|
+
}): string;
|
|
25
|
+
export declare function formatSARIF(reports: ReviewReport[]): string;
|
|
26
|
+
/**
|
|
27
|
+
* Format SARIF with suppression metadata.
|
|
28
|
+
* Suppressed findings appear with a `suppressions` array per SARIF v2.1.0 section 3.35.
|
|
29
|
+
*/
|
|
30
|
+
export declare function formatSARIFWithSuppressions(reports: ReviewReport[], suppressedFindings?: ReviewFinding[]): string;
|
|
15
31
|
export declare function formatSummary(reports: ReviewReport[]): string;
|
package/dist/reporter.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* v2: Unified multi-source report with source tags [kern] [eslint] [tsc] [llm].
|
|
5
5
|
* Dedup across sources. Fingerprint-based cross-run stability.
|
|
6
6
|
*/
|
|
7
|
+
import { buildLLMPrompt, exportKernIR } from './llm-review.js';
|
|
7
8
|
// ── Stats Calculation ────────────────────────────────────────────────────
|
|
8
9
|
export function calculateStats(inferred, templateMatches, findings, totalLines) {
|
|
9
10
|
const coveredLineSet = new Set();
|
|
@@ -45,13 +46,16 @@ export function calculateStats(inferred, templateMatches, findings, totalLines)
|
|
|
45
46
|
};
|
|
46
47
|
}
|
|
47
48
|
// ── Dedup ────────────────────────────────────────────────────────────────
|
|
48
|
-
/**
|
|
49
|
+
/**
|
|
50
|
+
* Deduplicate findings using fingerprint + message hash.
|
|
51
|
+
* Fingerprint alone can collide when a rule emits multiple findings at the same location
|
|
52
|
+
* (e.g., machine-gap fires once per unreachable state on the same type declaration line).
|
|
53
|
+
*/
|
|
49
54
|
export function dedup(findings) {
|
|
50
55
|
const seen = new Map();
|
|
51
56
|
for (const f of findings) {
|
|
52
|
-
//
|
|
53
|
-
|
|
54
|
-
const key = `${f.primarySpan.startLine}:${f.message.substring(0, 60)}`;
|
|
57
|
+
// Combine fingerprint with message prefix to avoid false merges
|
|
58
|
+
const key = `${f.fingerprint}:${f.message.substring(0, 40)}`;
|
|
55
59
|
const existing = seen.get(key);
|
|
56
60
|
if (existing) {
|
|
57
61
|
// Keep the higher-severity finding
|
|
@@ -64,7 +68,35 @@ export function dedup(findings) {
|
|
|
64
68
|
seen.set(key, f);
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
|
-
|
|
71
|
+
// Suppress empty-catch when ignored-error fires on the same line (concept rule is more semantic)
|
|
72
|
+
const ignoredErrorLines = new Set();
|
|
73
|
+
for (const f of seen.values()) {
|
|
74
|
+
if (f.ruleId === 'ignored-error')
|
|
75
|
+
ignoredErrorLines.add(f.primarySpan.startLine);
|
|
76
|
+
}
|
|
77
|
+
const result = [];
|
|
78
|
+
for (const f of seen.values()) {
|
|
79
|
+
if (f.ruleId === 'empty-catch' && ignoredErrorLines.has(f.primarySpan.startLine))
|
|
80
|
+
continue;
|
|
81
|
+
result.push(f);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
/** Sort findings by severity (error > warning > info) then by line. Shared utility. */
|
|
86
|
+
export function sortFindings(findings) {
|
|
87
|
+
const severityOrder = { error: 0, warning: 1, info: 2 };
|
|
88
|
+
findings.sort((a, b) => {
|
|
89
|
+
const sd = severityOrder[a.severity] - severityOrder[b.severity];
|
|
90
|
+
if (sd !== 0)
|
|
91
|
+
return sd;
|
|
92
|
+
return a.primarySpan.startLine - b.primarySpan.startLine;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/** Dedup + sort in one call. Replaces the 5 duplicated sort/dedup blocks. */
|
|
96
|
+
export function sortAndDedup(findings) {
|
|
97
|
+
const result = dedup(findings);
|
|
98
|
+
sortFindings(result);
|
|
99
|
+
return result;
|
|
68
100
|
}
|
|
69
101
|
// ── Enforcement ──────────────────────────────────────────────────────────
|
|
70
102
|
export function checkEnforcement(report, config) {
|
|
@@ -79,8 +111,37 @@ export function checkEnforcement(report, config) {
|
|
|
79
111
|
}
|
|
80
112
|
}
|
|
81
113
|
}
|
|
82
|
-
|
|
83
|
-
|
|
114
|
+
// Filter findings by minConfidence — findings without confidence default to 1.0 (fully trusted)
|
|
115
|
+
const minConf = config.minConfidence ?? 0;
|
|
116
|
+
const countable = report.findings.filter(f => (f.confidence ?? 1.0) >= minConf);
|
|
117
|
+
const errors = countable.filter(f => f.severity === 'error').length;
|
|
118
|
+
const warnings = countable.filter(f => f.severity === 'warning').length;
|
|
119
|
+
const maxErrors = config.maxErrors ?? 0;
|
|
120
|
+
const maxWarnings = config.maxWarnings ?? Number.MAX_SAFE_INTEGER;
|
|
121
|
+
let maxComplexity = 0;
|
|
122
|
+
for (const f of report.findings) {
|
|
123
|
+
if (f.ruleId === 'cognitive-complexity') {
|
|
124
|
+
const match = f.message.match(/complexity of (\d+)/);
|
|
125
|
+
if (match) {
|
|
126
|
+
maxComplexity = Math.max(maxComplexity, parseInt(match[1]));
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const allowedComplexity = config.maxComplexity ?? 15;
|
|
131
|
+
const passed = actualCoverage >= minCoverage &&
|
|
132
|
+
templateViolations.length === 0 &&
|
|
133
|
+
errors <= maxErrors &&
|
|
134
|
+
warnings <= maxWarnings &&
|
|
135
|
+
maxComplexity <= allowedComplexity;
|
|
136
|
+
return {
|
|
137
|
+
passed,
|
|
138
|
+
minCoverage,
|
|
139
|
+
actualCoverage,
|
|
140
|
+
templateViolations,
|
|
141
|
+
errors: { actual: errors, max: maxErrors },
|
|
142
|
+
warnings: { actual: warnings, max: maxWarnings },
|
|
143
|
+
complexity: { actual: maxComplexity, max: allowedComplexity }
|
|
144
|
+
};
|
|
84
145
|
}
|
|
85
146
|
// ── CLI Format ───────────────────────────────────────────────────────────
|
|
86
147
|
const SOURCE_TAGS = {
|
|
@@ -89,7 +150,7 @@ const SOURCE_TAGS = {
|
|
|
89
150
|
tsc: '[tsc]',
|
|
90
151
|
llm: '[llm]',
|
|
91
152
|
};
|
|
92
|
-
export function formatReport(report) {
|
|
153
|
+
export function formatReport(report, config) {
|
|
93
154
|
const lines = [];
|
|
94
155
|
lines.push(` @kernlang/review — analyzing ${report.filePath}`);
|
|
95
156
|
lines.push('');
|
|
@@ -128,16 +189,19 @@ export function formatReport(report) {
|
|
|
128
189
|
}
|
|
129
190
|
}
|
|
130
191
|
// Unified findings — sorted by severity, with source tags
|
|
192
|
+
const showConf = config?.showConfidence === true;
|
|
131
193
|
const allFindings = dedup(report.findings);
|
|
132
194
|
if (allFindings.length > 0) {
|
|
133
195
|
const errors = allFindings.filter(f => f.severity === 'error');
|
|
134
196
|
const warnings = allFindings.filter(f => f.severity === 'warning');
|
|
135
197
|
const infos = allFindings.filter(f => f.severity === 'info');
|
|
198
|
+
const confPrefix = (f) => showConf && f.confidence !== undefined ? ` [${f.confidence.toFixed(2)}]` : '';
|
|
136
199
|
if (errors.length > 0) {
|
|
137
200
|
lines.push(` BUGS (${errors.length}):`);
|
|
138
201
|
for (const f of errors) {
|
|
139
202
|
const tag = SOURCE_TAGS[f.source] || '';
|
|
140
|
-
|
|
203
|
+
const upstream = f.origin === 'upstream' ? ' [upstream]' : '';
|
|
204
|
+
lines.push(` ! L${f.primarySpan.startLine}: ${tag}${confPrefix(f)} [${f.ruleId}]${upstream} ${f.message}`);
|
|
141
205
|
if (f.suggestion)
|
|
142
206
|
lines.push(` Fix: ${f.suggestion}`);
|
|
143
207
|
}
|
|
@@ -147,7 +211,8 @@ export function formatReport(report) {
|
|
|
147
211
|
lines.push(` WARNINGS (${warnings.length}):`);
|
|
148
212
|
for (const f of warnings) {
|
|
149
213
|
const tag = SOURCE_TAGS[f.source] || '';
|
|
150
|
-
|
|
214
|
+
const upstream = f.origin === 'upstream' ? ' [upstream]' : '';
|
|
215
|
+
lines.push(` ~ L${f.primarySpan.startLine}: ${tag}${confPrefix(f)} [${f.ruleId}]${upstream} ${f.message}`);
|
|
151
216
|
if (f.suggestion)
|
|
152
217
|
lines.push(` Suggestion: ${f.suggestion}`);
|
|
153
218
|
}
|
|
@@ -157,35 +222,182 @@ export function formatReport(report) {
|
|
|
157
222
|
lines.push(` INFO (${infos.length}):`);
|
|
158
223
|
for (const f of infos) {
|
|
159
224
|
const tag = SOURCE_TAGS[f.source] || '';
|
|
160
|
-
|
|
225
|
+
const upstream = f.origin === 'upstream' ? ` [upstream d=${f.distance ?? '?'}]` : '';
|
|
226
|
+
lines.push(` - L${f.primarySpan.startLine}: ${tag}${confPrefix(f)} [${f.ruleId}]${upstream} ${f.message}`);
|
|
161
227
|
}
|
|
162
228
|
lines.push('');
|
|
163
229
|
}
|
|
164
230
|
}
|
|
165
231
|
const s = report.stats;
|
|
166
232
|
lines.push(` Summary: ${s.coveragePct}% KERN coverage, ~${s.totalTsTokens} → ${s.totalKernTokens} KERN tokens (${s.reductionPct}% reduction)`);
|
|
233
|
+
// Confidence summary (when present)
|
|
234
|
+
if (showConf && report.confidenceSummary) {
|
|
235
|
+
const cs = report.confidenceSummary;
|
|
236
|
+
lines.push(` Confidence: ${cs.high} high (>0.9), ${cs.medium} medium (0.7-0.9), ${cs.low} low (<0.7)`);
|
|
237
|
+
if (cs.unresolvedNeeds > 0) {
|
|
238
|
+
lines.push(` Unresolved needs: ${cs.unresolvedNeeds}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
167
241
|
return lines.join('\n');
|
|
168
242
|
}
|
|
169
243
|
// ── Enforcement Format ───────────────────────────────────────────────────
|
|
170
244
|
export function formatEnforcement(result) {
|
|
171
245
|
const lines = [];
|
|
172
246
|
if (result.passed) {
|
|
173
|
-
lines.push(` Enforcement: PASS
|
|
247
|
+
lines.push(` Enforcement: PASS`);
|
|
174
248
|
}
|
|
175
249
|
else {
|
|
176
250
|
lines.push(` Enforcement: FAIL`);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
251
|
+
}
|
|
252
|
+
lines.push(` Coverage: ${result.actualCoverage}% (min: ${result.minCoverage}%)`);
|
|
253
|
+
lines.push(` Complexity: ${result.complexity.actual} (max: ${result.complexity.max})`);
|
|
254
|
+
lines.push(` Errors: ${result.errors.actual} (max: ${result.errors.max})`);
|
|
255
|
+
lines.push(` Warnings: ${result.warnings.actual} (max: ${result.warnings.max === Number.MAX_SAFE_INTEGER ? 'unlimited' : result.warnings.max})`);
|
|
256
|
+
for (const v of result.templateViolations) {
|
|
257
|
+
lines.push(` Template: ${v}`);
|
|
183
258
|
}
|
|
184
259
|
return lines.join('\n');
|
|
185
260
|
}
|
|
186
261
|
// ── JSON Format ──────────────────────────────────────────────────────────
|
|
187
|
-
export function formatReportJSON(report) {
|
|
188
|
-
|
|
262
|
+
export function formatReportJSON(report, options) {
|
|
263
|
+
if (!options?.includeLLMPrompt) {
|
|
264
|
+
return JSON.stringify(report, null, 2);
|
|
265
|
+
}
|
|
266
|
+
// Include KERN IR and LLM prompt so the calling AI can review
|
|
267
|
+
const llmPrompt = buildLLMPrompt(report.inferred, report.templateMatches);
|
|
268
|
+
const kernIR = exportKernIR(report.inferred, report.templateMatches);
|
|
269
|
+
return JSON.stringify({
|
|
270
|
+
...report,
|
|
271
|
+
kernIR,
|
|
272
|
+
llmPrompt,
|
|
273
|
+
}, null, 2);
|
|
274
|
+
}
|
|
275
|
+
// ── SARIF Format ─────────────────────────────────────────────────────────
|
|
276
|
+
export function formatSARIF(reports) {
|
|
277
|
+
const sarif = {
|
|
278
|
+
$schema: 'https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json',
|
|
279
|
+
version: '2.1.0',
|
|
280
|
+
runs: [
|
|
281
|
+
{
|
|
282
|
+
tool: {
|
|
283
|
+
driver: {
|
|
284
|
+
name: '@kernlang/review',
|
|
285
|
+
version: '2.0.0',
|
|
286
|
+
rules: []
|
|
287
|
+
}
|
|
288
|
+
},
|
|
289
|
+
results: []
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
};
|
|
293
|
+
const rules = new Set();
|
|
294
|
+
for (const report of reports) {
|
|
295
|
+
for (const f of report.findings) {
|
|
296
|
+
if (!rules.has(f.ruleId)) {
|
|
297
|
+
rules.add(f.ruleId);
|
|
298
|
+
sarif.runs[0].tool.driver.rules.push({
|
|
299
|
+
id: f.ruleId,
|
|
300
|
+
shortDescription: { text: f.ruleId },
|
|
301
|
+
helpUri: `https://github.com/kern-lang/kern-lang/blob/main/docs/rules.md#${f.ruleId}`
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
const sarifLevel = f.severity === 'error' ? 'error' : (f.severity === 'warning' ? 'warning' : 'note');
|
|
305
|
+
const result = {
|
|
306
|
+
ruleId: f.ruleId,
|
|
307
|
+
level: sarifLevel,
|
|
308
|
+
message: { text: f.message },
|
|
309
|
+
locations: [
|
|
310
|
+
{
|
|
311
|
+
physicalLocation: {
|
|
312
|
+
artifactLocation: { uri: f.primarySpan.file },
|
|
313
|
+
region: {
|
|
314
|
+
startLine: f.primarySpan.startLine,
|
|
315
|
+
startColumn: f.primarySpan.startCol,
|
|
316
|
+
endLine: f.primarySpan.endLine,
|
|
317
|
+
endColumn: f.primarySpan.endCol
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
],
|
|
322
|
+
};
|
|
323
|
+
// SARIF result.rank is 0.0–100.0 per spec; kern/confidence stays 0–1
|
|
324
|
+
if (f.confidence !== undefined) {
|
|
325
|
+
result.rank = f.confidence * 100;
|
|
326
|
+
result.properties = { 'kern/confidence': f.confidence };
|
|
327
|
+
}
|
|
328
|
+
sarif.runs[0].results.push(result);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
return JSON.stringify(sarif, null, 2);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Format SARIF with suppression metadata.
|
|
335
|
+
* Suppressed findings appear with a `suppressions` array per SARIF v2.1.0 section 3.35.
|
|
336
|
+
*/
|
|
337
|
+
export function formatSARIFWithSuppressions(reports, suppressedFindings) {
|
|
338
|
+
const sarif = {
|
|
339
|
+
$schema: 'https://schemastore.azurewebsites.net/schemas/json/sarif-2.1.0-rtm.5.json',
|
|
340
|
+
version: '2.1.0',
|
|
341
|
+
runs: [
|
|
342
|
+
{
|
|
343
|
+
tool: {
|
|
344
|
+
driver: {
|
|
345
|
+
name: '@kernlang/review',
|
|
346
|
+
version: '2.0.0',
|
|
347
|
+
rules: []
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
results: []
|
|
351
|
+
}
|
|
352
|
+
]
|
|
353
|
+
};
|
|
354
|
+
const rules = new Set();
|
|
355
|
+
const suppressedSet = new Set(suppressedFindings?.map(f => f.fingerprint) ?? []);
|
|
356
|
+
const allFindings = [
|
|
357
|
+
...reports.flatMap(r => r.findings),
|
|
358
|
+
...(suppressedFindings ?? []),
|
|
359
|
+
];
|
|
360
|
+
for (const f of allFindings) {
|
|
361
|
+
if (!rules.has(f.ruleId)) {
|
|
362
|
+
rules.add(f.ruleId);
|
|
363
|
+
sarif.runs[0].tool.driver.rules.push({
|
|
364
|
+
id: f.ruleId,
|
|
365
|
+
shortDescription: { text: f.ruleId },
|
|
366
|
+
helpUri: `https://github.com/kern-lang/kern-lang/blob/main/docs/rules.md#${f.ruleId}`
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
const sarifLevel = f.severity === 'error' ? 'error' : (f.severity === 'warning' ? 'warning' : 'note');
|
|
370
|
+
const result = {
|
|
371
|
+
ruleId: f.ruleId,
|
|
372
|
+
level: sarifLevel,
|
|
373
|
+
message: { text: f.message },
|
|
374
|
+
locations: [
|
|
375
|
+
{
|
|
376
|
+
physicalLocation: {
|
|
377
|
+
artifactLocation: { uri: f.primarySpan.file },
|
|
378
|
+
region: {
|
|
379
|
+
startLine: f.primarySpan.startLine,
|
|
380
|
+
startColumn: f.primarySpan.startCol,
|
|
381
|
+
endLine: f.primarySpan.endLine,
|
|
382
|
+
endColumn: f.primarySpan.endCol
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
],
|
|
387
|
+
};
|
|
388
|
+
if (f.confidence !== undefined) {
|
|
389
|
+
result.rank = f.confidence * 100;
|
|
390
|
+
result.properties = { 'kern/confidence': f.confidence };
|
|
391
|
+
}
|
|
392
|
+
if (suppressedSet.has(f.fingerprint)) {
|
|
393
|
+
result.suppressions = [{
|
|
394
|
+
kind: 'inSource',
|
|
395
|
+
justification: `kern-ignore directive`,
|
|
396
|
+
}];
|
|
397
|
+
}
|
|
398
|
+
sarif.runs[0].results.push(result);
|
|
399
|
+
}
|
|
400
|
+
return JSON.stringify(sarif, null, 2);
|
|
189
401
|
}
|
|
190
402
|
// ── Multi-file Summary ───────────────────────────────────────────────────
|
|
191
403
|
export function formatSummary(reports) {
|
package/dist/reporter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"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"}
|
package/dist/rules/base.js
CHANGED
|
@@ -61,7 +61,8 @@ function floatingPromise(ctx) {
|
|
|
61
61
|
const fnName = calleeExpr.getText();
|
|
62
62
|
if (asyncFns.has(fnName)) {
|
|
63
63
|
const matchingNode = ctx.inferred.find(r => r.node.type === 'fn' && r.node.props?.name === fnName);
|
|
64
|
-
|
|
64
|
+
const nodeRef = matchingNode != null ? { nodeIds: [matchingNode.nodeId] } : undefined;
|
|
65
|
+
findings.push(finding('floating-promise', 'error', 'bug', `Async function '${fnName}()' called without await — floating promise`, ctx.filePath, exprStmt.getStartLineNumber(), 1, nodeRef));
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
}
|
|
@@ -127,6 +128,9 @@ function emptyCatch(ctx) {
|
|
|
127
128
|
const block = stmt.getBlock();
|
|
128
129
|
const stmts = block.getStatements();
|
|
129
130
|
if (stmts.length === 0) {
|
|
131
|
+
const blockText = block.getText();
|
|
132
|
+
if (/\/[/*]\s*(Intentional|Expected|@suppress|eslint-disable)/.test(blockText))
|
|
133
|
+
continue;
|
|
130
134
|
const line = stmt.getStartLineNumber();
|
|
131
135
|
findings.push(finding('empty-catch', 'warning', 'bug', 'Empty catch block swallows exception — at minimum log or rethrow', ctx.filePath, line));
|
|
132
136
|
}
|
|
@@ -292,7 +296,6 @@ function eventMapMismatch(ctx) {
|
|
|
292
296
|
// Switch over union/machine state that misses cases
|
|
293
297
|
function nonExhaustiveSwitch(ctx) {
|
|
294
298
|
const findings = [];
|
|
295
|
-
const fullText = ctx.sourceFile.getFullText();
|
|
296
299
|
// Collect known union types from inferred results
|
|
297
300
|
const unionTypes = new Map();
|
|
298
301
|
for (const r of ctx.inferred) {
|
|
@@ -351,20 +354,139 @@ function nonExhaustiveSwitch(ctx) {
|
|
|
351
354
|
}
|
|
352
355
|
return findings;
|
|
353
356
|
}
|
|
354
|
-
// ── Rule 8: complexity
|
|
355
|
-
//
|
|
356
|
-
|
|
357
|
+
// ── Rule 8: cognitive-complexity ─────────────────────────────────────────
|
|
358
|
+
// Sonar-compatible cognitive complexity metric (S3776)
|
|
359
|
+
//
|
|
360
|
+
// Codex review fixes applied:
|
|
361
|
+
// - Nested functions scored independently (not leaked into parent)
|
|
362
|
+
// - else if handled as flat chain (+1 only), not nested
|
|
363
|
+
// - .then()/.catch() not counted (callbacks are separate functions)
|
|
364
|
+
// - ?? included alongside && and ||
|
|
365
|
+
// - Recursion via text match (good enough for single-file scope)
|
|
366
|
+
const NESTING_STRUCTURES = new Set([
|
|
367
|
+
SyntaxKind.IfStatement,
|
|
368
|
+
SyntaxKind.SwitchStatement,
|
|
369
|
+
SyntaxKind.ForStatement,
|
|
370
|
+
SyntaxKind.ForInStatement,
|
|
371
|
+
SyntaxKind.ForOfStatement,
|
|
372
|
+
SyntaxKind.WhileStatement,
|
|
373
|
+
SyntaxKind.DoStatement,
|
|
374
|
+
SyntaxKind.CatchClause,
|
|
375
|
+
SyntaxKind.ConditionalExpression,
|
|
376
|
+
]);
|
|
377
|
+
const NESTED_FUNCTION_KINDS = new Set([
|
|
378
|
+
SyntaxKind.ArrowFunction,
|
|
379
|
+
SyntaxKind.FunctionExpression,
|
|
380
|
+
SyntaxKind.FunctionDeclaration,
|
|
381
|
+
SyntaxKind.MethodDeclaration,
|
|
382
|
+
]);
|
|
383
|
+
const LOGICAL_OPS = new Set([
|
|
384
|
+
SyntaxKind.AmpersandAmpersandToken,
|
|
385
|
+
SyntaxKind.BarBarToken,
|
|
386
|
+
SyntaxKind.QuestionQuestionToken,
|
|
387
|
+
]);
|
|
388
|
+
function calculateCognitiveComplexity(body, fnName) {
|
|
389
|
+
let complexity = 0;
|
|
390
|
+
function walk(n, nesting) {
|
|
391
|
+
const kind = n.getKind();
|
|
392
|
+
// Stop at nested function boundaries — they are scored independently
|
|
393
|
+
if (NESTED_FUNCTION_KINDS.has(kind) && n !== body && n.getParent() !== body.getParent()) {
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
// Handle if/else-if/else chains specially
|
|
397
|
+
if (kind === SyntaxKind.IfStatement) {
|
|
398
|
+
const ifStmt = n;
|
|
399
|
+
// +1 + nesting for the if itself
|
|
400
|
+
complexity += 1 + nesting;
|
|
401
|
+
// Walk the then-block at nesting+1
|
|
402
|
+
const thenStmt = ifStmt.getThenStatement();
|
|
403
|
+
thenStmt.forEachChild(child => walk(child, nesting + 1));
|
|
404
|
+
// Handle else / else-if
|
|
405
|
+
const elseStmt = ifStmt.getElseStatement();
|
|
406
|
+
if (elseStmt) {
|
|
407
|
+
if (elseStmt.getKind() === SyntaxKind.IfStatement) {
|
|
408
|
+
// else if: +1 only (flat chain, no nesting increment)
|
|
409
|
+
complexity += 1;
|
|
410
|
+
const elseIf = elseStmt;
|
|
411
|
+
const elseThen = elseIf.getThenStatement();
|
|
412
|
+
elseThen.forEachChild(child => walk(child, nesting + 1));
|
|
413
|
+
// Continue the chain
|
|
414
|
+
const nextElse = elseIf.getElseStatement();
|
|
415
|
+
if (nextElse) {
|
|
416
|
+
if (nextElse.getKind() === SyntaxKind.IfStatement) {
|
|
417
|
+
// Recurse for further else-if
|
|
418
|
+
walk(nextElse, nesting);
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
// plain else at end of chain
|
|
422
|
+
complexity += 1;
|
|
423
|
+
nextElse.forEachChild(child => walk(child, nesting + 1));
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
else {
|
|
428
|
+
// plain else: +1 only
|
|
429
|
+
complexity += 1;
|
|
430
|
+
elseStmt.forEachChild(child => walk(child, nesting + 1));
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
// Other nesting structures: +1 + nesting, increase depth
|
|
436
|
+
if (NESTING_STRUCTURES.has(kind)) {
|
|
437
|
+
complexity += 1 + nesting;
|
|
438
|
+
n.forEachChild(child => walk(child, nesting + 1));
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
// Logical operator sequences: +1 when operator type changes
|
|
442
|
+
if (kind === SyntaxKind.BinaryExpression) {
|
|
443
|
+
const binExpr = n;
|
|
444
|
+
const op = binExpr.getOperatorToken().getKind();
|
|
445
|
+
if (LOGICAL_OPS.has(op)) {
|
|
446
|
+
const parent = n.getParent();
|
|
447
|
+
let sameAsParent = false;
|
|
448
|
+
if (parent?.getKind() === SyntaxKind.BinaryExpression) {
|
|
449
|
+
const parentOp = parent.getOperatorToken().getKind();
|
|
450
|
+
if (parentOp === op)
|
|
451
|
+
sameAsParent = true;
|
|
452
|
+
}
|
|
453
|
+
if (!sameAsParent)
|
|
454
|
+
complexity += 1;
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
// Recursion: direct call to own name
|
|
458
|
+
if (kind === SyntaxKind.CallExpression && fnName) {
|
|
459
|
+
const callText = n.getExpression().getText();
|
|
460
|
+
if (callText === fnName || callText === `this.${fnName}`) {
|
|
461
|
+
complexity += 1;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
n.forEachChild(child => walk(child, nesting));
|
|
465
|
+
}
|
|
466
|
+
body.forEachChild(child => walk(child, 0));
|
|
467
|
+
return complexity;
|
|
468
|
+
}
|
|
469
|
+
function cognitiveComplexity(ctx) {
|
|
357
470
|
const findings = [];
|
|
358
|
-
|
|
359
|
-
|
|
471
|
+
const threshold = ctx.config?.maxComplexity ?? 15;
|
|
472
|
+
// Score every function-like body independently
|
|
473
|
+
const functions = [
|
|
474
|
+
...ctx.sourceFile.getFunctions(),
|
|
475
|
+
...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.MethodDeclaration),
|
|
476
|
+
...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction),
|
|
477
|
+
...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression),
|
|
478
|
+
...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.GetAccessor),
|
|
479
|
+
...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.SetAccessor),
|
|
480
|
+
...ctx.sourceFile.getDescendantsOfKind(SyntaxKind.Constructor),
|
|
481
|
+
];
|
|
482
|
+
for (const fn of functions) {
|
|
483
|
+
const body = fn.getBody();
|
|
484
|
+
if (!body)
|
|
360
485
|
continue;
|
|
361
|
-
const
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
const tokens = countTokens(code);
|
|
366
|
-
if (tokens > 200) {
|
|
367
|
-
findings.push(finding('complexity-spike', 'info', 'structure', `Function '${r.node.props?.name}' has ${tokens} tokens in handler body — consider splitting`, ctx.filePath, r.startLine, 1, { nodeIds: [r.nodeId] }));
|
|
486
|
+
const name = fn.getName?.() || undefined;
|
|
487
|
+
const score = calculateCognitiveComplexity(body, name);
|
|
488
|
+
if (score > threshold) {
|
|
489
|
+
findings.push(finding('cognitive-complexity', 'warning', 'structure', `Function '${name || 'anonymous'}' has cognitive complexity of ${score} (threshold: ${threshold})`, ctx.filePath, fn.getStartLineNumber()));
|
|
368
490
|
}
|
|
369
491
|
}
|
|
370
492
|
return findings;
|
|
@@ -539,6 +661,35 @@ function unhandledAsync(ctx) {
|
|
|
539
661
|
return findings;
|
|
540
662
|
}
|
|
541
663
|
// ── Exported Base Rules ──────────────────────────────────────────────────
|
|
664
|
+
// ── Rule: sync-in-async ──────────────────────────────────────────────────
|
|
665
|
+
// Blocking I/O (readFileSync, writeFileSync, execSync) inside async functions
|
|
666
|
+
const SYNC_BLOCKERS = new Set([
|
|
667
|
+
'readFileSync', 'writeFileSync', 'appendFileSync', 'mkdirSync', 'rmdirSync',
|
|
668
|
+
'unlinkSync', 'renameSync', 'copyFileSync', 'readdirSync', 'statSync',
|
|
669
|
+
'existsSync', 'execSync', 'spawnSync', 'execFileSync',
|
|
670
|
+
]);
|
|
671
|
+
function syncInAsync(ctx) {
|
|
672
|
+
const findings = [];
|
|
673
|
+
const fns = ctx.sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration)
|
|
674
|
+
.filter(f => f.isAsync());
|
|
675
|
+
const arrows = ctx.sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction)
|
|
676
|
+
.filter(f => f.isAsync());
|
|
677
|
+
const methods = ctx.sourceFile.getDescendantsOfKind(SyntaxKind.MethodDeclaration)
|
|
678
|
+
.filter(f => f.isAsync());
|
|
679
|
+
for (const fn of [...fns, ...arrows, ...methods]) {
|
|
680
|
+
const calls = fn.getDescendantsOfKind(SyntaxKind.CallExpression);
|
|
681
|
+
for (const call of calls) {
|
|
682
|
+
const callee = call.getExpression().getText();
|
|
683
|
+
const calleeName = callee.split('.').pop() || callee;
|
|
684
|
+
if (SYNC_BLOCKERS.has(calleeName)) {
|
|
685
|
+
const line = call.getStartLineNumber();
|
|
686
|
+
const fnName = 'getName' in fn && typeof fn.getName === 'function' ? fn.getName() || '<anonymous>' : '<arrow>';
|
|
687
|
+
findings.push(finding('sync-in-async', 'warning', 'bug', `'${calleeName}' blocks the event loop inside async function '${fnName}' — use the async variant`, ctx.filePath, line, 1, { suggestion: `Replace ${calleeName} with its async counterpart (e.g., readFile, writeFile, exec)` }));
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
return findings;
|
|
692
|
+
}
|
|
542
693
|
export const baseRules = [
|
|
543
694
|
floatingPromise,
|
|
544
695
|
stateMutation,
|
|
@@ -547,10 +698,11 @@ export const baseRules = [
|
|
|
547
698
|
configDefaultMismatch,
|
|
548
699
|
eventMapMismatch,
|
|
549
700
|
nonExhaustiveSwitch,
|
|
550
|
-
|
|
701
|
+
cognitiveComplexity,
|
|
551
702
|
templateAvailable,
|
|
552
703
|
handlerExtraction,
|
|
553
704
|
memoryLeak,
|
|
554
705
|
unhandledAsync,
|
|
706
|
+
syncInAsync,
|
|
555
707
|
];
|
|
556
708
|
//# sourceMappingURL=base.js.map
|