parseman 0.44.0 → 0.46.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.
Files changed (111) hide show
  1. package/dist/analysis/choice-cost-gate.d.ts +158 -0
  2. package/dist/analysis/choice-cost-gate.d.ts.map +1 -0
  3. package/dist/analysis/choice-cost-render.d.ts +88 -0
  4. package/dist/analysis/choice-cost-render.d.ts.map +1 -0
  5. package/dist/analysis/choice-cost.d.ts +383 -0
  6. package/dist/analysis/choice-cost.d.ts.map +1 -0
  7. package/dist/analysis/corpus.d.ts +73 -0
  8. package/dist/analysis/corpus.d.ts.map +1 -0
  9. package/dist/analysis/diagnose-render.d.ts +65 -0
  10. package/dist/analysis/diagnose-render.d.ts.map +1 -0
  11. package/dist/analysis/diagnose.d.ts +133 -0
  12. package/dist/analysis/diagnose.d.ts.map +1 -0
  13. package/dist/analysis/diagnostics.cjs +11272 -0
  14. package/dist/analysis/diagnostics.cjs.map +7 -0
  15. package/dist/analysis/diagnostics.d.ts +27 -0
  16. package/dist/analysis/diagnostics.d.ts.map +1 -0
  17. package/dist/analysis/diagnostics.js +11249 -0
  18. package/dist/analysis/diagnostics.js.map +7 -0
  19. package/dist/analysis/fix-render.d.ts +43 -0
  20. package/dist/analysis/fix-render.d.ts.map +1 -0
  21. package/dist/analysis/fix.d.ts +172 -0
  22. package/dist/analysis/fix.d.ts.map +1 -0
  23. package/dist/analysis/gating.d.ts +17 -9
  24. package/dist/analysis/gating.d.ts.map +1 -1
  25. package/dist/analysis/grammar.d.ts.map +1 -1
  26. package/dist/analysis/rebuild.d.ts +61 -0
  27. package/dist/analysis/rebuild.d.ts.map +1 -0
  28. package/dist/analysis/terminal.d.ts +142 -0
  29. package/dist/analysis/terminal.d.ts.map +1 -0
  30. package/dist/cli/index.cjs +12507 -0
  31. package/dist/cli/index.cjs.map +7 -0
  32. package/dist/cli/index.d.ts +3 -0
  33. package/dist/cli/index.d.ts.map +1 -0
  34. package/dist/cli/index.js +12484 -0
  35. package/dist/cli/index.js.map +7 -0
  36. package/dist/combinators/choice.d.ts.map +1 -1
  37. package/dist/combinators/dispatch.d.ts +19 -1
  38. package/dist/combinators/dispatch.d.ts.map +1 -1
  39. package/dist/combinators/expect.d.ts.map +1 -1
  40. package/dist/combinators/first-set.d.ts.map +1 -1
  41. package/dist/combinators/node.d.ts +19 -0
  42. package/dist/combinators/node.d.ts.map +1 -1
  43. package/dist/compiler/build-arity.d.ts +28 -0
  44. package/dist/compiler/build-arity.d.ts.map +1 -1
  45. package/dist/compiler/codegen.d.ts +80 -60
  46. package/dist/compiler/codegen.d.ts.map +1 -1
  47. package/dist/compiler/degradation.d.ts +123 -0
  48. package/dist/compiler/degradation.d.ts.map +1 -0
  49. package/dist/compiler/fields.d.ts.map +1 -1
  50. package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
  51. package/dist/compiler/inline-build.d.ts.map +1 -1
  52. package/dist/compiler/ir-serialize.d.ts.map +1 -1
  53. package/dist/compiler/linker.d.ts +45 -7
  54. package/dist/compiler/linker.d.ts.map +1 -1
  55. package/dist/compiler/module-hoist.d.ts +106 -0
  56. package/dist/compiler/module-hoist.d.ts.map +1 -0
  57. package/dist/coverage.d.ts +13 -0
  58. package/dist/coverage.d.ts.map +1 -1
  59. package/dist/cst/reflection.d.ts.map +1 -1
  60. package/dist/functional/run.d.ts.map +1 -1
  61. package/dist/index.cjs +1846 -610
  62. package/dist/index.cjs.map +4 -4
  63. package/dist/index.d.ts +11 -7
  64. package/dist/index.d.ts.map +1 -1
  65. package/dist/index.js +1846 -610
  66. package/dist/index.js.map +4 -4
  67. package/dist/language-service/index.cjs +40 -30
  68. package/dist/language-service/index.cjs.map +3 -3
  69. package/dist/language-service/index.js +40 -30
  70. package/dist/language-service/index.js.map +3 -3
  71. package/dist/oracle/digest.d.ts +132 -6
  72. package/dist/oracle/digest.d.ts.map +1 -1
  73. package/dist/oracle/index.cjs +136 -305
  74. package/dist/oracle/index.cjs.map +4 -4
  75. package/dist/oracle/index.d.ts +43 -31
  76. package/dist/oracle/index.d.ts.map +1 -1
  77. package/dist/oracle/index.js +136 -305
  78. package/dist/oracle/index.js.map +4 -4
  79. package/dist/plugin/evaluator.d.ts +3 -0
  80. package/dist/plugin/evaluator.d.ts.map +1 -1
  81. package/dist/plugin/free-identifiers.d.ts +23 -0
  82. package/dist/plugin/free-identifiers.d.ts.map +1 -0
  83. package/dist/plugin/index.cjs +1529 -763
  84. package/dist/plugin/index.cjs.map +4 -4
  85. package/dist/plugin/index.d.ts +18 -0
  86. package/dist/plugin/index.d.ts.map +1 -1
  87. package/dist/plugin/index.js +1529 -763
  88. package/dist/plugin/index.js.map +4 -4
  89. package/dist/plugin/reducer-resolver.d.ts +57 -0
  90. package/dist/plugin/reducer-resolver.d.ts.map +1 -0
  91. package/dist/run/index.cjs +33 -30
  92. package/dist/run/index.cjs.map +2 -2
  93. package/dist/run/index.js +33 -30
  94. package/dist/run/index.js.map +2 -2
  95. package/dist/spec/index.cjs +222 -34
  96. package/dist/spec/index.cjs.map +4 -4
  97. package/dist/spec/index.js +222 -34
  98. package/dist/spec/index.js.map +4 -4
  99. package/dist/spec/model.d.ts.map +1 -1
  100. package/dist/types.d.ts +6 -1
  101. package/dist/types.d.ts.map +1 -1
  102. package/dist/version.d.ts +1 -1
  103. package/package.json +23 -4
  104. package/dist/combinators/guard.d.ts +0 -8
  105. package/dist/combinators/guard.d.ts.map +0 -1
  106. package/dist/cst/offset-model.d.ts +0 -119
  107. package/dist/cst/offset-model.d.ts.map +0 -1
  108. package/dist/oracle/corpus.d.ts +0 -32
  109. package/dist/oracle/corpus.d.ts.map +0 -1
  110. package/dist/oracle/identity.d.ts +0 -117
  111. package/dist/oracle/identity.d.ts.map +0 -1
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The SECOND world.
3
+ *
4
+ * A type error has one source to point at. A grammar finding has two — the ordered
5
+ * choice whose arms cost the time, and the input that pays for it — and relating them is
6
+ * the whole diagnostic. `gating.ts` owns the first world and is entirely static. This
7
+ * module owns the second, and it is deliberately the smallest honest thing that can be
8
+ * said about a corpus without instrumenting a parse.
9
+ *
10
+ * WHAT IS MEASURED, EXACTLY
11
+ * -------------------------
12
+ * For a choice, every corpus POSITION whose character is in some arm's first set. That
13
+ * is a count of characters, not of times the choice was reached, and the difference
14
+ * matters: a choice nested three rules deep is reached far less often than its first
15
+ * characters occur. So the number is reported as what it is — an upper bound on entries,
16
+ * derived from the same first sets the compiler dispatches on — and never as "this
17
+ * choice ran N times". Naming it precisely is what keeps it useful; a number that
18
+ * overstates itself is worse than no number, because the reader stops trusting all of
19
+ * them.
20
+ *
21
+ * The one thing this DOES settle, exactly and without any modelling: an arm whose first
22
+ * set is ANY is entered at every one of those positions, because no first character can
23
+ * exclude it. That is the cost the fix removes, and it is arithmetic, not a guess.
24
+ *
25
+ * Determinism: counts and the located example are a pure function of (report, corpus).
26
+ * No timings, no paths beyond the caller's own sample names.
27
+ */
28
+ import type { Combinator, FirstSet } from '../types.ts';
29
+ import type { ChoiceGating } from './gating.ts';
30
+ export type CorpusSample = {
31
+ name: string;
32
+ text: string;
33
+ };
34
+ /** A located input position: the caller's sample name plus 1-based line/column. */
35
+ export type CorpusSite = {
36
+ sample: string;
37
+ line: number;
38
+ column: number;
39
+ /** The source line, untrimmed, for a caret rendering. */
40
+ lineText: string;
41
+ };
42
+ export type ArmCorpusCost = {
43
+ index: number;
44
+ /** ANY first set — no character excludes this arm. */
45
+ any: boolean;
46
+ /**
47
+ * Corpus positions whose character this arm's first set accepts. For an `any` arm this
48
+ * equals the choice total, which is the point.
49
+ */
50
+ positions: number;
51
+ /** The first such position, for the two-world rendering. Absent when there are none. */
52
+ firstSite?: CorpusSite;
53
+ };
54
+ export type ChoiceCorpusCost = {
55
+ choiceId: string;
56
+ /** Positions whose character SOME arm accepts — the choice's own reach, bounded. */
57
+ positions: number;
58
+ /** Every position in the corpus, so a share can be read. */
59
+ corpusPositions: number;
60
+ arms: ArmCorpusCost[];
61
+ };
62
+ /**
63
+ * Measure one choice against a corpus. `choice.anyArms` already knows which arms are
64
+ * broad; this adds how much input that costs.
65
+ */
66
+ export declare function measureChoiceCost(c: ChoiceGating, samples: readonly CorpusSample[], arms: readonly {
67
+ firstSet: FirstSet;
68
+ }[]): ChoiceCorpusCost;
69
+ /** The per-arm first sets a choice dispatches on, in arm order. */
70
+ export declare function armFirstSets(choiceArms: readonly Combinator<unknown>[]): {
71
+ firstSet: FirstSet;
72
+ }[];
73
+ //# sourceMappingURL=corpus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus.d.ts","sourceRoot":"","sources":["../../src/analysis/corpus.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzD,mFAAmF;AACnF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAA;IACb,sDAAsD;IACtD,GAAG,EAAE,OAAO,CAAA;IACZ;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAA;IACjB,wFAAwF;IACxF,SAAS,CAAC,EAAE,UAAU,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,oFAAoF;IACpF,SAAS,EAAE,MAAM,CAAA;IACjB,4DAA4D;IAC5D,eAAe,EAAE,MAAM,CAAA;IACvB,IAAI,EAAE,aAAa,EAAE,CAAA;CACtB,CAAA;AAyBD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,EAAE,SAAS,YAAY,EAAE,EAAE,IAAI,EAAE,SAAS;IAAE,QAAQ,EAAE,QAAQ,CAAA;CAAE,EAAE,GAAG,gBAAgB,CAiC9I;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,UAAU,EAAE,SAAS,UAAU,CAAC,OAAO,CAAC,EAAE,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAA;CAAE,EAAE,CAEjG"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The human layer over `GrammarDiagnosis`.
3
+ *
4
+ * Three layers, not two: `gating.ts`/`corpus.ts` produce data, `diagnose.ts` decides
5
+ * `ok` (the CI verdict), and this file makes either readable. Nothing here computes a
6
+ * finding and nothing here decides pass or fail. A gate consumes the object; a person
7
+ * reads this. If a number appears below that is not in the report, that is a bug here.
8
+ *
9
+ * GROUPED BY CAUSE, NOT BY SITE
10
+ * -----------------------------
11
+ * The first version grouped by site: thirteen findings, each carrying its own copy of
12
+ * the explanation, the `do` line and the `ok as-is?` line. Measured on
13
+ * `examples/css/parser.ts`, that was three distinct explanations rendered nine times
14
+ * across 146 lines. Density that comes from repetition is not detail — it is the same
15
+ * sentence again, and it buries the arm tables, which are the part a reader acts on.
16
+ *
17
+ * A cause is now stated ONCE, given a glyph, and followed by its sites. That also
18
+ * disposes of the question a glossary would have answered: the glyph is defined at the
19
+ * head of the only group it labels, so there is nothing to look up. Shipping a glossary
20
+ * AND the inline explanations would just re-create the duplication this removes.
21
+ *
22
+ * WHAT CARRIES MEANING
23
+ * --------------------
24
+ * colour — severity, and importance WITHIN a finding. Exactly one span per block is
25
+ * the brightest thing in it; provenance and accept keys recede.
26
+ * glyph — the cause class, so sites are scannable without reading prose.
27
+ * rules — group boundaries, so the report is blocks rather than a paragraph.
28
+ * columns — the arm table is aligned, so an ANY arm or an overlap is visible as a
29
+ * shape before it is read as text.
30
+ *
31
+ * All of that lives in the STYLED path. The plain path is the same content with the same
32
+ * padding and no escapes, so `docs/samples/` stays diffable and the two cannot drift.
33
+ */
34
+ import { type GrammarDiagnosis } from './diagnose.ts';
35
+ import type { ChoiceCorpusCost } from './corpus.ts';
36
+ import { groupDigits, type Line, type RenderTarget } from './terminal.ts';
37
+ export type DiagnoseRenderOptions = RenderTarget & {
38
+ /** Grammar label for the header. The CLI passes a cwd-relative path. */
39
+ name?: string;
40
+ /** Sites to expand. Default 20; the report always holds all of them. */
41
+ limit?: number;
42
+ /** Corpus cost per choice id, from `measureChoiceCost`. */
43
+ cost?: ReadonlyMap<string, ChoiceCorpusCost>;
44
+ /** Per-arm first-set renderings per choice id, in arm order. */
45
+ armFirstSets?: ReadonlyMap<string, readonly string[]>;
46
+ /** Per-arm leading-term labels per choice id, in arm order. */
47
+ armLabels?: ReadonlyMap<string, readonly string[]>;
48
+ /** Absolute corpus root, used ONLY for the frame's terminal hyperlink. */
49
+ corpusRoot?: string;
50
+ /**
51
+ * Finding ids for which `proposeFixes` PROVED a rewrite — applied it, recompiled, and
52
+ * re-parsed the corpus with identical output. Only these may carry the wrench. A
53
+ * candidate that was proposed and rejected must never appear here: offering a fix that
54
+ * does not exist would destroy the one guarantee the feature has.
55
+ */
56
+ fixable?: ReadonlySet<string>;
57
+ /** The command that would apply them, printed verbatim so nobody has to guess it. */
58
+ fixCommand?: string;
59
+ };
60
+ export { groupDigits };
61
+ /** The lines a diagnosis renders to — data, so a caller can compose them into a larger
62
+ * report without going through a string. */
63
+ export declare function diagnosisLines(d: GrammarDiagnosis, opts?: DiagnoseRenderOptions): Line[];
64
+ export declare function renderDiagnosis(d: GrammarDiagnosis, opts?: DiagnoseRenderOptions): string;
65
+ //# sourceMappingURL=diagnose-render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnose-render.d.ts","sourceRoot":"","sources":["../../src/analysis/diagnose-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EAAmB,KAAK,gBAAgB,EAAyB,MAAM,eAAe,CAAA;AAC7F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AACnD,OAAO,EACkC,WAAW,EAClD,KAAK,IAAI,EAAE,KAAK,YAAY,EAC7B,MAAM,eAAe,CAAA;AAEtB,MAAM,MAAM,qBAAqB,GAAG,YAAY,GAAG;IACjD,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wEAAwE;IACxE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,2DAA2D;IAC3D,IAAI,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;IAC5C,gEAAgE;IAChE,YAAY,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAA;IACrD,+DAA+D;IAC/D,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAA;IAClD,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC7B,qFAAqF;IACrF,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,OAAO,EAAE,WAAW,EAAE,CAAA;AA8ItB;6CAC6C;AAC7C,wBAAgB,cAAc,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,GAAE,qBAA0B,GAAG,IAAI,EAAE,CAmL5F;AAuFD,wBAAgB,eAAe,CAAC,CAAC,EAAE,gBAAgB,EAAE,IAAI,GAAE,qBAA0B,GAAG,MAAM,CAE7F"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * The DELIBERATE grammar diagnostic — the one call that asks parseman "is anything
3
+ * wrong with this grammar?" and answers in a form a machine can gate on.
4
+ *
5
+ * Why this exists as its own entry point, and why nothing in `compile()` prints any
6
+ * more: a diagnostic that rides along with the thing that produces the artifact is a
7
+ * diagnostic nobody chose to run. Importing one example grammar used to print ~51
8
+ * lines of gating advice through `console.warn` before a single byte was parsed —
9
+ * advice that was correct, detailed, and read by no one, because it arrived unasked
10
+ * in the middle of an unrelated build log. The same principle is already settled one
11
+ * layer down for codegen ("anything 'diagnostic' doesn't end up in codegen"); this is
12
+ * that principle applied at build time. Compiling produces an artifact and says
13
+ * nothing. Asking for a diagnosis produces a diagnosis.
14
+ *
15
+ * Design rules this surface holds itself to:
16
+ *
17
+ * 1. MACHINE-READABLE FIRST. `diagnoseGrammar()` returns a plain, JSON-serializable
18
+ * object with a versioned `schema` tag. The human rendering is a separate,
19
+ * optional function over that object — never the primary product. A CI job gates
20
+ * on `ok`; a person reads `formatGrammarDiagnosis()`.
21
+ * 2. DETERMINISTIC. Findings are sorted by (severity, code, id). Two runs over the
22
+ * same grammar produce byte-identical JSON, so a diagnosis can be committed as a
23
+ * snapshot and diffed.
24
+ * 3. FAILS CLOSED. An analysis that could not run is NOT a pass. `unanalysable` stays
25
+ * authoritative (see `GatingReport.unanalysable`), it is a BLOCKING finding, and a
26
+ * diagnosis whose analysis THREW is reported as a blocking finding rather than as
27
+ * an empty, clean-looking report.
28
+ * 4. ONE ENTRY POINT. It accepts a combinator, a rule-name→combinator map, a `rules()`
29
+ * map, or a `compose()` result, and figures out which it got. Choosing between
30
+ * `analyzeGating` / `analyzeGatingRules` / `analyzeGrammarGating` is exactly the
31
+ * kind of decision that makes people not bother.
32
+ */
33
+ import type { Combinator } from '../types.ts';
34
+ import { type AnalyzeGatingOptions, type GatingReport } from './gating.ts';
35
+ import { type AnalysableGrammar } from './grammar.ts';
36
+ import { type Degradation } from '../compiler/degradation.ts';
37
+ /** Anything `diagnoseGrammar()` knows how to read. */
38
+ export type DiagnosableGrammar = Combinator<unknown> | AnalysableGrammar | ReadonlyArray<readonly [string, Combinator<unknown>]>;
39
+ /**
40
+ * `blocking` fails `ok` (and therefore a CI gate). `advisory` is reported but does not
41
+ * fail: the author either already acknowledged it (`accepted`) or has nothing to act on.
42
+ */
43
+ export type DiagnosisSeverity = 'blocking' | 'advisory';
44
+ /** Stable, greppable finding class. New codes may be added; existing ones are not renamed. */
45
+ export type DiagnosisCode =
46
+ /** A hot choice with no first-char dispatch — every position enters doomed arms. */
47
+ 'ungated-choice'
48
+ /** An API-misuse pattern in a choice's arms (double-not, leading-not, keyword-regex). */
49
+ | 'anti-pattern'
50
+ /** Part of the grammar could not be examined. A clean report over it is NOT a pass. */
51
+ | 'unanalysable'
52
+ /** The compiler took a correct-but-slower path. Mirrors the `[parseman] degraded` channel. */
53
+ | 'degraded'
54
+ /** An `accept` entry that matched no ungated choice — a stale snapshot line to prune. */
55
+ | 'stale-accept';
56
+ export type DiagnosisFinding = {
57
+ /** Stable identity: the choice id, `rule#arm`, the rule name, or the degradation code. */
58
+ id: string;
59
+ code: DiagnosisCode;
60
+ severity: DiagnosisSeverity;
61
+ /** Rule / node type the finding lands on. */
62
+ rule: string;
63
+ /** One-line statement of what is wrong. */
64
+ message: string;
65
+ /** Arm-level evidence and concrete fixes, one entry per contributing cause. */
66
+ details: string[];
67
+ /** The `accept` snapshot key that would silence this finding, when one exists. */
68
+ acceptKey?: string;
69
+ };
70
+ export type GrammarDiagnosis = {
71
+ /** Versioned so a committed snapshot can be migrated rather than silently reinterpreted. */
72
+ schema: 'parseman.diagnosis/1';
73
+ /**
74
+ * True only when there is no blocking finding. A CI gate is
75
+ * `process.exit(diagnoseGrammar(g).ok ? 0 : 1)` — nothing else to remember.
76
+ */
77
+ ok: boolean;
78
+ summary: {
79
+ totalChoices: number;
80
+ gated: number;
81
+ recoverable: number;
82
+ ungated: number;
83
+ accepted: number;
84
+ deferred: number;
85
+ antiPatterns: number;
86
+ unanalysable: number;
87
+ degraded: number;
88
+ staleAccepts: number;
89
+ };
90
+ /** Sorted (severity, code, id). Deterministic across runs. */
91
+ findings: DiagnosisFinding[];
92
+ /**
93
+ * Every blocking-choice id, sorted — paste straight into `{ accept: [...] }` to
94
+ * acknowledge the current state as intentional.
95
+ */
96
+ acceptSnapshot: string[];
97
+ /** The full underlying gating report, for callers that want the raw per-choice detail. */
98
+ gating: GatingReport;
99
+ /**
100
+ * Degradations recorded WHILE this analysis ran (e.g. an opaque composed artifact).
101
+ * NOT the compile-time set — compiling is a separate act; see `PARSEMAN_DEGRADATION`.
102
+ *
103
+ * Empty when `PARSEMAN_DEGRADATION=off`, because `recordDegradation` short-circuits on
104
+ * the level. That is not a blind spot: everything this analysis can record is ALSO
105
+ * present in `gating.unanalysable`, which no env var can switch off.
106
+ */
107
+ degradations: Degradation[];
108
+ };
109
+ export type DiagnoseOptions = Pick<AnalyzeGatingOptions, 'accept' | 'entryName'>;
110
+ /**
111
+ * Diagnose a grammar. Never throws: an analysis that cannot run is reported as a
112
+ * blocking `unanalysable` finding, because a thrown diagnostic and a clean grammar
113
+ * must not look the same to a caller that wrapped this in a try/catch.
114
+ */
115
+ export declare function diagnoseGrammar(grammar: DiagnosableGrammar, opts?: DiagnoseOptions): GrammarDiagnosis;
116
+ /**
117
+ * The analysis examined NOTHING: no choice was walked, and rules were skipped.
118
+ *
119
+ * This is NOT "problems were found" and must never be presented as a finding count. A
120
+ * diagnosis over a fully opaque grammar has one blocking finding per skipped rule, which
121
+ * `findings.length` then reports as "176 problems, 176 failing the check" — a sentence
122
+ * that reads as 176 discovered defects and actually means the tool inspected zero
123
+ * choices. `ok` is correctly false either way, so `ok` alone cannot tell the two apart;
124
+ * a caller that needs to distinguish "measured, and it is bad" from "could not measure"
125
+ * asks here. The CLI maps this to exit 2 (COULD NOT ANALYSE), not exit 1.
126
+ *
127
+ * `unanalysable > 0` is required, so a genuinely choice-free grammar (nothing to walk,
128
+ * nothing skipped) stays an ordinary clean pass rather than a measurement failure.
129
+ */
130
+ export declare function examinedNothing(d: GrammarDiagnosis): boolean;
131
+ /** Render a diagnosis for a human. The structured object stays the product of record. */
132
+ export declare function formatGrammarDiagnosis(d: GrammarDiagnosis): string[];
133
+ //# sourceMappingURL=diagnose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnose.d.ts","sourceRoot":"","sources":["../../src/analysis/diagnose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAC7C,OAAO,EAEL,KAAK,oBAAoB,EAAE,KAAK,YAAY,EAC7C,MAAM,aAAa,CAAA;AACpB,OAAO,EAAwB,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAEc,KAAK,WAAW,EACpC,MAAM,4BAA4B,CAAA;AAEnC,sDAAsD;AACtD,MAAM,MAAM,kBAAkB,GAC1B,UAAU,CAAC,OAAO,CAAC,GACnB,iBAAiB,GACjB,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;AAEzD;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,UAAU,CAAA;AAEvD,8FAA8F;AAC9F,MAAM,MAAM,aAAa;AACvB,oFAAoF;AAClF,gBAAgB;AAClB,yFAAyF;GACvF,cAAc;AAChB,uFAAuF;GACrF,cAAc;AAChB,8FAA8F;GAC5F,UAAU;AACZ,yFAAyF;GACvF,cAAc,CAAA;AAElB,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0FAA0F;IAC1F,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,aAAa,CAAA;IACnB,QAAQ,EAAE,iBAAiB,CAAA;IAC3B,6CAA6C;IAC7C,IAAI,EAAE,MAAM,CAAA;IACZ,2CAA2C;IAC3C,OAAO,EAAE,MAAM,CAAA;IACf,+EAA+E;IAC/E,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,4FAA4F;IAC5F,MAAM,EAAE,sBAAsB,CAAA;IAC9B;;;OAGG;IACH,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,EAAE;QACP,YAAY,EAAE,MAAM,CAAA;QACpB,KAAK,EAAE,MAAM,CAAA;QACb,WAAW,EAAE,MAAM,CAAA;QACnB,OAAO,EAAE,MAAM,CAAA;QACf,QAAQ,EAAE,MAAM,CAAA;QAChB,QAAQ,EAAE,MAAM,CAAA;QAChB,YAAY,EAAE,MAAM,CAAA;QACpB,YAAY,EAAE,MAAM,CAAA;QACpB,QAAQ,EAAE,MAAM,CAAA;QAChB,YAAY,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,8DAA8D;IAC9D,QAAQ,EAAE,gBAAgB,EAAE,CAAA;IAC5B;;;OAGG;IACH,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,0FAA0F;IAC1F,MAAM,EAAE,YAAY,CAAA;IACpB;;;;;;;OAOG;IACH,YAAY,EAAE,WAAW,EAAE,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,WAAW,CAAC,CAAA;AAQhF;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,gBAAgB,CAqBrG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAE5D;AAED,yFAAyF;AACzF,wBAAgB,sBAAsB,CAAC,CAAC,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAmCpE"}