parseman 0.45.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.
- package/dist/analysis/choice-cost-gate.d.ts +158 -0
- package/dist/analysis/choice-cost-gate.d.ts.map +1 -0
- package/dist/analysis/choice-cost-render.d.ts +88 -0
- package/dist/analysis/choice-cost-render.d.ts.map +1 -0
- package/dist/analysis/choice-cost.d.ts +383 -0
- package/dist/analysis/choice-cost.d.ts.map +1 -0
- package/dist/analysis/corpus.d.ts +73 -0
- package/dist/analysis/corpus.d.ts.map +1 -0
- package/dist/analysis/diagnose-render.d.ts +65 -0
- package/dist/analysis/diagnose-render.d.ts.map +1 -0
- package/dist/analysis/diagnose.d.ts +15 -0
- package/dist/analysis/diagnose.d.ts.map +1 -1
- package/dist/analysis/diagnostics.cjs +11272 -0
- package/dist/analysis/diagnostics.cjs.map +7 -0
- package/dist/analysis/diagnostics.d.ts +27 -0
- package/dist/analysis/diagnostics.d.ts.map +1 -0
- package/dist/analysis/diagnostics.js +11249 -0
- package/dist/analysis/diagnostics.js.map +7 -0
- package/dist/analysis/fix-render.d.ts +43 -0
- package/dist/analysis/fix-render.d.ts.map +1 -0
- package/dist/analysis/fix.d.ts +172 -0
- package/dist/analysis/fix.d.ts.map +1 -0
- package/dist/analysis/gating.d.ts +8 -0
- package/dist/analysis/gating.d.ts.map +1 -1
- package/dist/analysis/rebuild.d.ts +61 -0
- package/dist/analysis/rebuild.d.ts.map +1 -0
- package/dist/analysis/terminal.d.ts +142 -0
- package/dist/analysis/terminal.d.ts.map +1 -0
- package/dist/cli/index.cjs +12507 -0
- package/dist/cli/index.cjs.map +7 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +12484 -0
- package/dist/cli/index.js.map +7 -0
- package/dist/compiler/build-arity.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +44 -6
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/compiler/module-hoist.d.ts +106 -0
- package/dist/compiler/module-hoist.d.ts.map +1 -0
- package/dist/index.cjs +1297 -297
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1297 -297
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs.map +2 -2
- package/dist/language-service/index.js.map +2 -2
- package/dist/plugin/evaluator.d.ts +1 -1
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/free-identifiers.d.ts +23 -0
- package/dist/plugin/free-identifiers.d.ts.map +1 -0
- package/dist/plugin/index.cjs +429 -43
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +429 -43
- package/dist/plugin/index.js.map +4 -4
- package/dist/plugin/reducer-resolver.d.ts +17 -1
- package/dist/plugin/reducer-resolver.d.ts.map +1 -1
- package/dist/spec/index.cjs +2 -1
- package/dist/spec/index.cjs.map +2 -2
- package/dist/spec/index.js +2 -1
- package/dist/spec/index.js.map +2 -2
- package/dist/version.d.ts +1 -1
- package/package.json +18 -3
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The human layer over `FixReport`.
|
|
3
|
+
*
|
|
4
|
+
* The claim this rendering has to carry is unusual, so it is made explicitly and never
|
|
5
|
+
* by implication: a fix shown here was APPLIED to the grammar, the grammar was
|
|
6
|
+
* RECOMPILED, the corpus was RE-PARSED, and the output did not move. Every offered
|
|
7
|
+
* rewrite prints that evidence next to it, with the sample and byte counts, because
|
|
8
|
+
* "proven" without a corpus size is a word, not a fact.
|
|
9
|
+
*
|
|
10
|
+
* The diff is the primary interface. `--apply` writing to a file is a second, explicit
|
|
11
|
+
* step; what a reader gets by default is what would change, in the form they would read
|
|
12
|
+
* it in a review.
|
|
13
|
+
*
|
|
14
|
+
* TWO STATES, MADE VISUALLY DISTINCT
|
|
15
|
+
* ----------------------------------
|
|
16
|
+
* ACTIONABLE and LOCATED are the whole model, and in the first cut they were two words
|
|
17
|
+
* in the same colour — which is to say, not a distinction at all until you read them.
|
|
18
|
+
* They now differ in glyph, colour and weight, so a reader triages the report by
|
|
19
|
+
* scanning the left margin rather than by parsing it. LOCATED prints the REASON and
|
|
20
|
+
* never advice: a site that cannot be rewritten is still worth knowing about, and that
|
|
21
|
+
* is the difference between "here is exactly where the problem is" and silence.
|
|
22
|
+
*
|
|
23
|
+
* Like `diagnose-render.ts`, this emits LINES OF SPANS and never an escape byte;
|
|
24
|
+
* `terminal.ts` owns every interaction with a terminal.
|
|
25
|
+
*/
|
|
26
|
+
import type { FixReport } from './fix.ts';
|
|
27
|
+
import { type Line, type RenderTarget } from './terminal.ts';
|
|
28
|
+
export type FixRenderOptions = RenderTarget & {
|
|
29
|
+
name?: string;
|
|
30
|
+
/**
|
|
31
|
+
* How many edits were WRITTEN to disk. A count, not a flag: `applyFixEdits` skips an
|
|
32
|
+
* edit whose span moved under it, so a run can write some of `r.verified` and skip the
|
|
33
|
+
* rest. A boolean here made the report say every verified change had been written
|
|
34
|
+
* whenever any one of them had been — the one number a reader checks after `--apply`,
|
|
35
|
+
* wrong in exactly the case that matters. Absent (or 0) means nothing was written.
|
|
36
|
+
*/
|
|
37
|
+
applied?: number;
|
|
38
|
+
/** Absolute path of the edited source, used ONLY for the frame's terminal hyperlink. */
|
|
39
|
+
sourceRoot?: string;
|
|
40
|
+
};
|
|
41
|
+
export declare function fixReportLines(r: FixReport, opts?: FixRenderOptions): Line[];
|
|
42
|
+
export declare function renderFixReport(r: FixReport, opts?: FixRenderOptions): string;
|
|
43
|
+
//# sourceMappingURL=fix-render.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix-render.d.ts","sourceRoot":"","sources":["../../src/analysis/fix-render.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EAAE,SAAS,EAA+B,MAAM,UAAU,CAAA;AACtE,OAAO,EAEL,KAAK,IAAI,EAAE,KAAK,YAAY,EAC7B,MAAM,eAAe,CAAA;AAEtB,MAAM,MAAM,gBAAgB,GAAG,YAAY,GAAG;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wFAAwF;IACxF,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,GAAE,gBAAqB,GAAG,IAAI,EAAE,CA6EhF;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,GAAE,gBAAqB,GAAG,MAAM,CAEjF"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VERIFIED grammar fixes — the propose → apply → recompile → compare loop.
|
|
3
|
+
*
|
|
4
|
+
* rustc can tell you a suggestion is machine-applicable. It cannot tell you the
|
|
5
|
+
* suggestion is CORRECT: there is no cheap oracle for "this rewrite of your program
|
|
6
|
+
* means the same thing". A parser generator has one. A grammar's whole observable
|
|
7
|
+
* behaviour is the tree it produces for an input, so a rewrite can be applied, the
|
|
8
|
+
* grammar recompiled, a corpus re-parsed, and the two outputs compared byte for byte.
|
|
9
|
+
* Unchanged output is not a heuristic that the rewrite was safe; it is the evidence.
|
|
10
|
+
*
|
|
11
|
+
* propose → apply → recompile → compare parse output
|
|
12
|
+
* unchanged → PROVEN over this corpus; offer it
|
|
13
|
+
* changed → WRONG; discard, never show it
|
|
14
|
+
*
|
|
15
|
+
* TWO STATES, NEVER A THIRD
|
|
16
|
+
* -------------------------
|
|
17
|
+
* Every candidate site ends as ACTIONABLE (here is the rewrite, here is the evidence,
|
|
18
|
+
* here is the measured benefit) or LOCATED (here is the exact site and the exact reason
|
|
19
|
+
* no rewrite can be offered). There is no "consider refactoring": a sentence of advice
|
|
20
|
+
* with no location and no rewrite is the thing this module exists to replace. A rewrite
|
|
21
|
+
* that moved the output is reported as LOCATED with the rejection as its reason — the
|
|
22
|
+
* site is real, the rewrite is not shown, and the reader is never handed a wrong fix.
|
|
23
|
+
*
|
|
24
|
+
* WHAT "PROVEN" MEANS HERE, EXACTLY
|
|
25
|
+
* ---------------------------------
|
|
26
|
+
* Proven OVER THE SUPPLIED CORPUS, on every engine the grammar supports — both when it
|
|
27
|
+
* compiles, the interpreted one alone when it does not — and that is stated in every
|
|
28
|
+
* rendering rather than implied. A corpus that never reaches the rewritten arm proves
|
|
29
|
+
* nothing about it, so the evidence carries the sample and byte counts and the caller
|
|
30
|
+
* can judge. Two deliberate exclusions from the comparison:
|
|
31
|
+
*
|
|
32
|
+
* - FAILURE `expected` LABELS are compared as position only, not text. A keyword
|
|
33
|
+
* rewrite changes `/\@media/` to `keyword` by design; that is diagnostic text, not
|
|
34
|
+
* parse output. Values, spans, and WHERE a parse failed are compared exactly.
|
|
35
|
+
* - The rebuild itself is not trusted, it is CHECKED: before any candidate is
|
|
36
|
+
* considered, the grammar is rebuilt with NO substitution and that identity rebuild
|
|
37
|
+
* must reproduce the corpus output exactly. If `rebuild.ts` threads any option
|
|
38
|
+
* wrongly, this check fails and NO fix is offered. Wrong makes the tool silent.
|
|
39
|
+
*
|
|
40
|
+
* BENEFIT IS MEASURED TOO
|
|
41
|
+
* -----------------------
|
|
42
|
+
* A verified-but-pointless rewrite is not offered either. Benefit is read off the same
|
|
43
|
+
* analysis a CI gate reads — ungated choices, anti-patterns — plus the compiled artifact
|
|
44
|
+
* size, which is deterministic and therefore safe to print. No timings: this must be
|
|
45
|
+
* diffable.
|
|
46
|
+
*/
|
|
47
|
+
import type { Combinator } from '../types.ts';
|
|
48
|
+
import { type FrozenSubtree } from './rebuild.ts';
|
|
49
|
+
/** One corpus document. `name` is a label for the report; it is never a path lookup. */
|
|
50
|
+
export type FixSample = {
|
|
51
|
+
name: string;
|
|
52
|
+
text: string;
|
|
53
|
+
};
|
|
54
|
+
/** Stable, greppable fix class. Mirrors the `anti-pattern` kinds `diagnoseGrammar` reports. */
|
|
55
|
+
export type FixCode = 'keyword-regex' | 'double-not';
|
|
56
|
+
/** The engines a comparison ran on. `compiled` is absent when the grammar does not compile. */
|
|
57
|
+
export type FixEngine = 'interpreted' | 'compiled';
|
|
58
|
+
export type FixEvidence = {
|
|
59
|
+
samples: number;
|
|
60
|
+
bytes: number;
|
|
61
|
+
engines: FixEngine[];
|
|
62
|
+
/** Always true on a VERIFIED fix — the field exists so the JSON states the claim. */
|
|
63
|
+
outputUnchanged: true;
|
|
64
|
+
};
|
|
65
|
+
export type FixBenefit = {
|
|
66
|
+
ungatedChoicesBefore: number;
|
|
67
|
+
ungatedChoicesAfter: number;
|
|
68
|
+
antiPatternsBefore: number;
|
|
69
|
+
antiPatternsAfter: number;
|
|
70
|
+
gatedChoicesBefore: number;
|
|
71
|
+
gatedChoicesAfter: number;
|
|
72
|
+
/** Bytes of `compile().source`. Deterministic. `null` when the grammar does not compile. */
|
|
73
|
+
codegenBytesBefore: number | null;
|
|
74
|
+
codegenBytesAfter: number | null;
|
|
75
|
+
};
|
|
76
|
+
/** A source edit, offered only when the site is UNAMBIGUOUS in the supplied text. */
|
|
77
|
+
export type FixEdit = {
|
|
78
|
+
path: string;
|
|
79
|
+
/** 1-based, for a diagnostic header. */
|
|
80
|
+
line: number;
|
|
81
|
+
column: number;
|
|
82
|
+
start: number;
|
|
83
|
+
end: number;
|
|
84
|
+
oldText: string;
|
|
85
|
+
newText: string;
|
|
86
|
+
/** The whole source line the edit sits on, so a renderer can draw a real code frame. */
|
|
87
|
+
lineText: string;
|
|
88
|
+
};
|
|
89
|
+
export type VerifiedFix = {
|
|
90
|
+
id: string;
|
|
91
|
+
code: FixCode;
|
|
92
|
+
rule: string;
|
|
93
|
+
armIndex: number;
|
|
94
|
+
/** How the site reads now, and how it would read. Rendering, not source text. */
|
|
95
|
+
before: string;
|
|
96
|
+
after: string;
|
|
97
|
+
/** The arm's deep first-set before and after — the number that makes the fix self-evident. */
|
|
98
|
+
armFirstSetBefore: string;
|
|
99
|
+
armFirstSetAfter: string;
|
|
100
|
+
/** The enclosing choice's gating verdict, before and after. */
|
|
101
|
+
choiceId: string;
|
|
102
|
+
choiceGatesBefore: 'yes' | 'recoverable' | 'no';
|
|
103
|
+
choiceGatesAfter: 'yes' | 'recoverable' | 'no';
|
|
104
|
+
benefit: FixBenefit;
|
|
105
|
+
evidence: FixEvidence;
|
|
106
|
+
/** Present only when the site was located unambiguously in a supplied source file. */
|
|
107
|
+
edit?: FixEdit;
|
|
108
|
+
};
|
|
109
|
+
export type LocatedFinding = {
|
|
110
|
+
id: string;
|
|
111
|
+
code: FixCode;
|
|
112
|
+
rule: string;
|
|
113
|
+
armIndex: number;
|
|
114
|
+
/** How the site reads now. */
|
|
115
|
+
site: string;
|
|
116
|
+
/** The exact reason no rewrite can be offered. Never advice. */
|
|
117
|
+
reason: string;
|
|
118
|
+
};
|
|
119
|
+
export type FixReport = {
|
|
120
|
+
schema: 'parseman.fix/1';
|
|
121
|
+
/**
|
|
122
|
+
* True when every candidate site got a verdict — i.e. the corpus was usable and the
|
|
123
|
+
* identity rebuild held. FALSE IS NOT "no fixes": it means the loop could not run, and
|
|
124
|
+
* an empty `verified` list under it proves nothing. Fails closed.
|
|
125
|
+
*/
|
|
126
|
+
ok: boolean;
|
|
127
|
+
/** Why `ok` is false, or `null`. */
|
|
128
|
+
blocked: string | null;
|
|
129
|
+
corpus: {
|
|
130
|
+
samples: number;
|
|
131
|
+
bytes: number;
|
|
132
|
+
};
|
|
133
|
+
engines: FixEngine[];
|
|
134
|
+
verified: VerifiedFix[];
|
|
135
|
+
located: LocatedFinding[];
|
|
136
|
+
/** Subtrees `rebuild.ts` reused verbatim; a candidate inside one cannot be applied. */
|
|
137
|
+
frozen: FrozenSubtree[];
|
|
138
|
+
};
|
|
139
|
+
export type ProposeFixOptions = {
|
|
140
|
+
/**
|
|
141
|
+
* The documents the before/after comparison runs over. REQUIRED and non-empty: with no
|
|
142
|
+
* corpus there is no evidence, and this module does not offer unverified rewrites.
|
|
143
|
+
*/
|
|
144
|
+
corpus: readonly FixSample[];
|
|
145
|
+
/** Grammar source, to locate edits in. Without it, fixes carry no `edit`. */
|
|
146
|
+
source?: {
|
|
147
|
+
path: string;
|
|
148
|
+
text: string;
|
|
149
|
+
};
|
|
150
|
+
/** Passed through to `analyzeGating` when measuring benefit. */
|
|
151
|
+
accept?: Iterable<string>;
|
|
152
|
+
entryName?: string;
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Propose fixes, and offer only the ones proven output-neutral over `opts.corpus`.
|
|
156
|
+
*
|
|
157
|
+
* Never throws: a loop that cannot run reports `ok: false` with the reason, because a
|
|
158
|
+
* thrown proposal and a grammar with nothing to fix must not look the same.
|
|
159
|
+
*/
|
|
160
|
+
export declare function proposeFixes(root: Combinator<unknown>, opts: ProposeFixOptions): FixReport;
|
|
161
|
+
/**
|
|
162
|
+
* Apply verified edits to a source text, right-to-left so earlier offsets stay valid.
|
|
163
|
+
*
|
|
164
|
+
* Pure: it returns the new text and never touches the filesystem. Writing is the
|
|
165
|
+
* caller's explicit second step, which is what keeps `--apply` from being something that
|
|
166
|
+
* happens to you.
|
|
167
|
+
*/
|
|
168
|
+
export declare function applyFixEdits(sourceText: string, fixes: readonly VerifiedFix[]): {
|
|
169
|
+
text: string;
|
|
170
|
+
applied: number;
|
|
171
|
+
};
|
|
172
|
+
//# sourceMappingURL=fix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fix.d.ts","sourceRoot":"","sources":["../../src/analysis/fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -109,6 +109,12 @@ export type ChoiceGating = {
|
|
|
109
109
|
anyArms: AnyArm[];
|
|
110
110
|
overlaps: Overlap[];
|
|
111
111
|
};
|
|
112
|
+
/**
|
|
113
|
+
* The arms a `ChoiceGating` describes, in arm order — or `undefined` when the report did
|
|
114
|
+
* not come from a live walk (a deserialized snapshot). Carried non-enumerably, so it
|
|
115
|
+
* never reaches the JSON a CI snapshot diffs.
|
|
116
|
+
*/
|
|
117
|
+
export declare const choiceArms: (c: ChoiceGating) => readonly Combinator<unknown>[] | undefined;
|
|
112
118
|
/** Options for `analyzeGating` — the accepted-snapshot allowlist. */
|
|
113
119
|
export type AnalyzeGatingOptions = {
|
|
114
120
|
/**
|
|
@@ -181,6 +187,8 @@ export type GatingReport = {
|
|
|
181
187
|
antiPatterns: AntiPattern[];
|
|
182
188
|
};
|
|
183
189
|
export declare function firstSetToString(fs: FirstSet): string;
|
|
190
|
+
/** Peel non-consuming wrappers to the arm's leading term (mirrors leadingTermOfArm). */
|
|
191
|
+
export declare function peelToLeading(arm: Combinator<unknown>): Combinator<unknown>;
|
|
184
192
|
export declare function analyzeGating(entry: Combinator<unknown>, opts?: AnalyzeGatingOptions): GatingReport;
|
|
185
193
|
/**
|
|
186
194
|
* Multi-root variant: analyze a WHOLE `rules()` map in one walk, so every choice
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gating.d.ts","sourceRoot":"","sources":["../../src/analysis/gating.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"gating.d.ts","sourceRoot":"","sources":["../../src/analysis/gating.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rebuild a combinator graph THROUGH THE PUBLIC FACTORIES, substituting selected nodes.
|
|
3
|
+
*
|
|
4
|
+
* This exists so a proposed grammar fix can be APPLIED and then MEASURED, rather than
|
|
5
|
+
* printed and hoped for. Everything downstream — `proposeFixes()` — depends on one
|
|
6
|
+
* property: a rewritten grammar must be a real grammar, built the same way the author's
|
|
7
|
+
* was, so that compiling it and parsing with it means the same thing.
|
|
8
|
+
*
|
|
9
|
+
* WHY THE FACTORIES AND NOT A `_def` DEEP-COPY
|
|
10
|
+
* --------------------------------------------
|
|
11
|
+
* A combinator is two things at once: a `_def` descriptor the COMPILER reads, and a
|
|
12
|
+
* `parse` closure the INTERPRETER runs, which captured its children when the factory
|
|
13
|
+
* ran. Patching `_def.parser` moves the compiled engine and leaves the interpreted one
|
|
14
|
+
* on the old graph — the two engines would then disagree, and a verification that runs
|
|
15
|
+
* either one would certify a rewrite that does not exist in the other. Re-running the
|
|
16
|
+
* factory produces both halves from the same inputs, and also recomputes everything
|
|
17
|
+
* DERIVED that the fix is trying to move in the first place: `_meta.firstSet`,
|
|
18
|
+
* `choice._def.disjoint`, and the choice strategy.
|
|
19
|
+
*
|
|
20
|
+
* FROZEN SUBTREES, NOT A FAILED REBUILD
|
|
21
|
+
* -------------------------------------
|
|
22
|
+
* Some node kinds have no faithful public reconstruction — `dispatch` (its arms carry
|
|
23
|
+
* matcher objects), `recover`, `scanTo`, `guard`, `withCtx`, `trivia` (classified
|
|
24
|
+
* trivia carries labels derived at construction). Refusing to rebuild a whole grammar
|
|
25
|
+
* because it contains one of them would make this useless on every real grammar. So
|
|
26
|
+
* such a node is REUSED VERBATIM: nothing inside it changed, so reusing it is exact.
|
|
27
|
+
* The cost is precise and reported — a rewrite target that sits inside a frozen subtree
|
|
28
|
+
* cannot be applied, and comes back in `unapplied` so the caller can say WHY rather
|
|
29
|
+
* than silently dropping it.
|
|
30
|
+
*
|
|
31
|
+
* THE HONESTY BACKSTOP
|
|
32
|
+
* --------------------
|
|
33
|
+
* This module does not claim to be faithful; it is CHECKED. `proposeFixes()` first
|
|
34
|
+
* rebuilds with NO substitutions and requires that identity rebuild to produce
|
|
35
|
+
* byte-identical parse output over the caller's corpus. If any option threading below
|
|
36
|
+
* is wrong, that check fails and NO fix is offered for that grammar. A rebuilder that
|
|
37
|
+
* is wrong makes the tool silent, never wrong.
|
|
38
|
+
*/
|
|
39
|
+
import type { Combinator } from '../types.ts';
|
|
40
|
+
/** A subtree that was reused verbatim instead of rebuilt. */
|
|
41
|
+
export type FrozenSubtree = {
|
|
42
|
+
tag: string;
|
|
43
|
+
/** Nearest enclosing rule name, so the report can point at it. */
|
|
44
|
+
rule: string;
|
|
45
|
+
};
|
|
46
|
+
export type RebuildResult = {
|
|
47
|
+
root: Combinator<unknown>;
|
|
48
|
+
/** Reused-verbatim subtrees, deduplicated by (rule, tag) and sorted. */
|
|
49
|
+
frozen: FrozenSubtree[];
|
|
50
|
+
/**
|
|
51
|
+
* Substitutions that could NOT be applied because their target sits inside a frozen
|
|
52
|
+
* subtree. Non-empty means the returned graph is NOT the graph the caller asked for.
|
|
53
|
+
*/
|
|
54
|
+
unapplied: Combinator<unknown>[];
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Rebuild `root`, replacing every combinator that is a key of `replacements` with its
|
|
58
|
+
* value. The replacement is spliced WITHOUT descending into the original target.
|
|
59
|
+
*/
|
|
60
|
+
export declare function rebuildCombinator(root: Combinator<unknown>, replacements: ReadonlyMap<Combinator<unknown>, Combinator<unknown>>): RebuildResult;
|
|
61
|
+
//# sourceMappingURL=rebuild.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rebuild.d.ts","sourceRoot":"","sources":["../../src/analysis/rebuild.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAA;AAsBxD,6DAA6D;AAC7D,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IACzB,wEAAwE;IACxE,MAAM,EAAE,aAAa,EAAE,CAAA;IACvB;;;OAGG;IACH,SAAS,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAA;CACjC,CAAA;AA0CD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,EACzB,YAAY,EAAE,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,GAClE,aAAa,CA2Jf"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONLY module in parseman that talks to a terminal.
|
|
3
|
+
*
|
|
4
|
+
* Everything above it produces DATA — lines made of spans, each span carrying text and a
|
|
5
|
+
* semantic tone — and this file turns lines into bytes. That split is not tidiness; it is
|
|
6
|
+
* what makes the rendering diffable. A renderer that emits escape sequences inline has
|
|
7
|
+
* two outputs (styled and plain) that can drift apart, and the plain one is what a
|
|
8
|
+
* snapshot, a CI log and `docs/samples/` all read.
|
|
9
|
+
*
|
|
10
|
+
* WHY LINECRAFT AND NOT HAND-ROLLED ANSI
|
|
11
|
+
* --------------------------------------
|
|
12
|
+
* The first cut of this CLI carried its own `ANSI` constant table. Writing that file
|
|
13
|
+
* silently dropped the ESC bytes, so colour was dead for an entire session and nothing
|
|
14
|
+
* said so — the output still looked structured, because an escape-less `[2m` prints as
|
|
15
|
+
* `[2m`. Escape sequences are invisible failure surface, and a library that owns them
|
|
16
|
+
* removes the surface. jess already renders its diagnostics through linecraft
|
|
17
|
+
* (`packages/compiler/src/diagnostics.ts`, `packages/lint/src/index.ts`), so following
|
|
18
|
+
* the same idiom also means a jess user and a parseman user see the same shape of output
|
|
19
|
+
* rather than two parallel inventions. Pinned to `0.2.6`, exactly matching jess's pins.
|
|
20
|
+
*
|
|
21
|
+
* SPANS, NOT WHOLE-LINE STYLES
|
|
22
|
+
* ----------------------------
|
|
23
|
+
* jess's lint table styles a whole row at a time, which is right for a table of one
|
|
24
|
+
* thing per line. A grammar finding is not that: within one line the arm index, the
|
|
25
|
+
* production, its first set and the annotation all mean different things, and the
|
|
26
|
+
* annotation is the part that should be shouting. So a line here is a list of SPANS, and
|
|
27
|
+
* a styled line is a linecraft `Grid` of `Styled` cells — which also gives the columns
|
|
28
|
+
* their alignment for free.
|
|
29
|
+
*
|
|
30
|
+
* THE INVARIANT THAT MUST NOT BREAK
|
|
31
|
+
* ---------------------------------
|
|
32
|
+
* Padding happens in ONE place, before either path sees it, and the plain form is the
|
|
33
|
+
* concatenation of the padded span texts. So the two paths differ in styling and in
|
|
34
|
+
* nothing else — not in width, not in alignment, not in content. No escape byte is
|
|
35
|
+
* produced at all when colour is off, so the diffable output is byte-stable by
|
|
36
|
+
* construction rather than by stripping. `width` is passed explicitly and defaults to 80
|
|
37
|
+
* off-TTY, so a piped run cannot vary with the terminal it was piped from.
|
|
38
|
+
*/
|
|
39
|
+
import { type TextStyle } from 'linecraft';
|
|
40
|
+
export type Tone = TextStyle;
|
|
41
|
+
/**
|
|
42
|
+
* Semantic tones, named once so the two renderers cannot drift apart.
|
|
43
|
+
*
|
|
44
|
+
* The ladder matters more than the individual colours: within a finding, exactly one
|
|
45
|
+
* thing should be the brightest, and provenance / accept keys / byte costs should
|
|
46
|
+
* recede. A report where everything is emphasised is a report where nothing is.
|
|
47
|
+
*/
|
|
48
|
+
export declare const TONE: {
|
|
49
|
+
/** The single most important thing in its block. */
|
|
50
|
+
readonly loud: Tone;
|
|
51
|
+
/** A heading, a count, the thing being named. */
|
|
52
|
+
readonly strong: Tone;
|
|
53
|
+
/** Supporting detail — never the finding itself. */
|
|
54
|
+
readonly quiet: Tone;
|
|
55
|
+
/** Recedes furthest: provenance, snapshot keys, byte costs. */
|
|
56
|
+
readonly faint: Tone;
|
|
57
|
+
/** This span IS the problem. */
|
|
58
|
+
readonly bad: Tone;
|
|
59
|
+
/** Real, but not blocking. */
|
|
60
|
+
readonly warn: Tone;
|
|
61
|
+
/** A location or an identifier the reader will search for. */
|
|
62
|
+
readonly ident: Tone;
|
|
63
|
+
/** Clean, or the thing to do. */
|
|
64
|
+
readonly good: Tone;
|
|
65
|
+
/** Structure: rules, box drawing, group frames. */
|
|
66
|
+
readonly frame: Tone;
|
|
67
|
+
};
|
|
68
|
+
/** One styled run of text. `width` pads it, in BOTH paths, so columns line up. */
|
|
69
|
+
export type Span = {
|
|
70
|
+
text: string;
|
|
71
|
+
style?: Tone;
|
|
72
|
+
/** Pad to this column width. Applied once, before either path renders. */
|
|
73
|
+
width?: number;
|
|
74
|
+
/** Text that ALREADY contains escapes (a linecraft component's own output). */
|
|
75
|
+
raw?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Absolute path this span points at. In the STYLED path it becomes a clickable
|
|
78
|
+
* terminal hyperlink; the plain path ignores it entirely, which is what keeps the
|
|
79
|
+
* diffable output free of escapes and of absolute paths.
|
|
80
|
+
*/
|
|
81
|
+
link?: string;
|
|
82
|
+
};
|
|
83
|
+
/** A line is its spans. An empty array is a blank line. */
|
|
84
|
+
export type Line = Span[];
|
|
85
|
+
export declare const t: (text: string, style?: Tone, width?: number) => Span;
|
|
86
|
+
export declare const blank: () => Line;
|
|
87
|
+
/** A horizontal rule. Segmentation is what turns eighty undifferentiated lines into a
|
|
88
|
+
* handful of blocks a reader can skip between. */
|
|
89
|
+
export declare const rule: (width: number, style?: Tone, char?: string) => Line;
|
|
90
|
+
export type RenderTarget = {
|
|
91
|
+
/** Emit ANSI. Default false — never sniffed here; the CLI decides. */
|
|
92
|
+
color?: boolean;
|
|
93
|
+
/** Columns. Default 80, which is also what an off-TTY stream reports as nothing. */
|
|
94
|
+
width?: number;
|
|
95
|
+
/**
|
|
96
|
+
* Emit OSC-8 terminal hyperlinks on file locations. Only meaningful with `color`,
|
|
97
|
+
* since both are escape sequences. Default: on when colouring. A terminal without
|
|
98
|
+
* OSC-8 support prints the URL as visible junk, so this is the escape hatch.
|
|
99
|
+
*/
|
|
100
|
+
links?: boolean;
|
|
101
|
+
};
|
|
102
|
+
export declare const DEFAULT_WIDTH = 80;
|
|
103
|
+
/** Plain text of a line list — the byte-stable form, produced without a terminal. */
|
|
104
|
+
export declare const plain: (lines: readonly Line[]) => string;
|
|
105
|
+
/**
|
|
106
|
+
* Lines → a string. Without colour this never constructs a Region at all, so nothing on
|
|
107
|
+
* the diffable path depends on linecraft's environment detection.
|
|
108
|
+
*/
|
|
109
|
+
export declare function render(lines: readonly Line[], target?: RenderTarget): string;
|
|
110
|
+
export type CodeFrame = {
|
|
111
|
+
/** Path as the reader should see it — relative, so no absolute path can be diffed. */
|
|
112
|
+
path: string;
|
|
113
|
+
/** Absolute path, used ONLY for the terminal hyperlink, which the plain form strips. */
|
|
114
|
+
fullPath: string;
|
|
115
|
+
line: number;
|
|
116
|
+
column: number;
|
|
117
|
+
endLine?: number;
|
|
118
|
+
endColumn?: number;
|
|
119
|
+
lineBefore?: string | null;
|
|
120
|
+
lineText: string;
|
|
121
|
+
lineAfter?: string | null;
|
|
122
|
+
message: string;
|
|
123
|
+
/** Short label attached to the underline — the one sentence the caret is making. */
|
|
124
|
+
shortMessage?: string;
|
|
125
|
+
type?: 'error' | 'warning' | 'info';
|
|
126
|
+
};
|
|
127
|
+
/**
|
|
128
|
+
* A source frame with the caret under the offending span — linecraft's `CodeDebug`, the
|
|
129
|
+
* same component jess renders its compiler errors with.
|
|
130
|
+
*
|
|
131
|
+
* Its lines come back as RAW spans: the component styles per token, which a span list
|
|
132
|
+
* cannot describe, and it is already the shape a reader wants. The plain form is
|
|
133
|
+
* recovered by stripping — the one place in this file that has to — and is asserted
|
|
134
|
+
* escape-free and absolute-path-free by test.
|
|
135
|
+
*/
|
|
136
|
+
export declare function codeFrame(frame: CodeFrame, target?: RenderTarget, indent?: string): Line[];
|
|
137
|
+
/** Deterministic thousands grouping — `toLocaleString()` differs between machines. */
|
|
138
|
+
export declare function groupDigits(n: number): string;
|
|
139
|
+
export declare const pad: (s: string, w: number) => string;
|
|
140
|
+
/** Hard-wrap on spaces at `width`, prefixing every line with `indent`. */
|
|
141
|
+
export declare function wrap(text: string, width: number, indent: string): string[];
|
|
142
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/analysis/terminal.ts"],"names":[],"mappings":"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"}
|