Skip to content

Commit 3ee9785

Browse files
committed
conformance-matrix: classify over-accepts by TS diagnostic (diag mode)
1 parent 11007fa commit 3ee9785

1 file changed

Lines changed: 31 additions & 2 deletions

File tree

test/conformance-matrix.ts

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,26 @@ const isMulti = (t: string) => /^\s*\/\/\s*@filename:/im.test(t);
2525

2626
let TP = 0, FN = 0, FP = 0, TN = 0;
2727
const fns: string[] = [], fps: string[] = [];
28+
// For each over-accept, remember WHY TS rejected (its first parse diagnostic) so we
29+
// can classify FPs by error kind, not just by directory — `diag` mode prints this.
30+
const fpDiag = new Map<string, { code: number; msg: string }>();
2831
for (const f of walk(base)) {
2932
const code = readFileSync(f, 'utf8');
3033
if (isMulti(code)) continue;
3134
const sf = ts.createSourceFile('t.ts', code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
32-
const tsAccept = ((sf as any).parseDiagnostics?.length ?? 0) === 0;
35+
const diags = (sf as any).parseDiagnostics as ts.Diagnostic[] | undefined;
36+
const tsAccept = (diags?.length ?? 0) === 0;
3337
let weAccept = true;
3438
try { parse(code); } catch { weAccept = false; }
3539
if (tsAccept && weAccept) TP++;
3640
else if (tsAccept && !weAccept) { FN++; fns.push(f.replace(base + '/', '')); }
37-
else if (!tsAccept && weAccept) { FP++; fps.push(f.replace(base + '/', '')); }
41+
else if (!tsAccept && weAccept) {
42+
FP++;
43+
const rel = f.replace(base + '/', '');
44+
fps.push(rel);
45+
const d = diags![0];
46+
fpDiag.set(rel, { code: d.code, msg: ts.flattenDiagnosticMessageText(d.messageText, ' ') });
47+
}
3848
else TN++;
3949
}
4050
const total = TP + FN + FP + TN;
@@ -62,3 +72,22 @@ for (const [dir, files] of groups) {
6272
if (showFiles) for (const f of files) console.log(` ${f.split('/').pop()}`);
6373
}
6474
if (!showFiles) console.log(`\n (re-run with \`fp\` to list every file: node test/conformance-matrix.ts fp)`);
75+
76+
// Over-accepts grouped by TS's OWN reason for rejecting (parse-diagnostic code) → the
77+
// error *kinds* we wave through. This is the classification to triage against: a single
78+
// lexical rule ("digit expected", "invalid escape") often spans many directories, while
79+
// a directory can mix several kinds. `node test/conformance-matrix.ts diag`.
80+
if (process.argv.includes('diag')) {
81+
const byCode = new Map<number, { msg: string; files: string[] }>();
82+
for (const f of fps) {
83+
const { code, msg } = fpDiag.get(f)!;
84+
const e = byCode.get(code) ?? byCode.set(code, { msg, files: [] }).get(code)!;
85+
e.files.push(f);
86+
}
87+
const diagGroups = [...byCode.entries()].sort((a, b) => b[1].files.length - a[1].files.length);
88+
console.log(`\n OVER-ACCEPTS by TS diagnostic (${FP} files, ${diagGroups.length} distinct reasons):`);
89+
for (const [code, { msg, files }] of diagGroups) {
90+
console.log(`\n ${String(files.length).padStart(3)} TS${code}: ${msg}`);
91+
for (const f of files) console.log(` ${f}`);
92+
}
93+
}

0 commit comments

Comments
 (0)