sh-ast 0.6.1 → 0.8.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/README.md +147 -15
- package/dist/analyze/enumerate-commands.d.ts +5 -1
- package/dist/analyze/enumerate-commands.d.ts.map +1 -1
- package/dist/analyze/enumerate-commands.js.map +1 -1
- package/dist/analyze/index.d.ts +10 -2
- package/dist/analyze/index.d.ts.map +1 -1
- package/dist/analyze/index.js +11 -1
- package/dist/analyze/index.js.map +1 -1
- package/dist/analyze/resolve-argv0.d.ts +225 -16
- package/dist/analyze/resolve-argv0.d.ts.map +1 -1
- package/dist/analyze/resolve-argv0.js +372 -11
- package/dist/analyze/resolve-argv0.js.map +1 -1
- package/dist/analyze.d.ts +380 -157
- package/dist/errors.d.ts +14 -27
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +15 -28
- package/dist/errors.js.map +1 -1
- package/dist/sh-ast.d.ts +28 -32
- package/dist/syntax-operator.d.ts +9 -0
- package/dist/syntax-operator.d.ts.map +1 -0
- package/dist/syntax-operator.js +22 -0
- package/dist/syntax-operator.js.map +1 -0
- package/dist/syntax-print.d.ts +3 -1
- package/dist/syntax-print.d.ts.map +1 -1
- package/dist/syntax-print.js +3 -1
- package/dist/syntax-print.js.map +1 -1
- package/dist/syntax-snapshot.d.ts +4 -1
- package/dist/syntax-snapshot.d.ts.map +1 -1
- package/dist/syntax-snapshot.js +18 -3
- package/dist/syntax-snapshot.js.map +1 -1
- package/dist/syntax-wire.d.ts +12 -0
- package/dist/syntax-wire.d.ts.map +1 -1
- package/dist/syntax-wire.js +99 -15
- package/dist/syntax-wire.js.map +1 -1
- package/dist/syntax.d.ts +12 -10
- package/dist/syntax.d.ts.map +1 -1
- package/dist/syntax.js +46 -33
- package/dist/syntax.js.map +1 -1
- package/dist/wasm-instance.d.ts +8 -0
- package/dist/wasm-instance.d.ts.map +1 -1
- package/dist/wasm-instance.js +36 -8
- package/dist/wasm-instance.js.map +1 -1
- package/package.json +1 -1
- package/shim/sh-ast.wasm +0 -0
- package/dist/parse-depth-guard.d.ts +0 -11
- package/dist/parse-depth-guard.d.ts.map +0 -1
- package/dist/parse-depth-guard.js +0 -633
- package/dist/parse-depth-guard.js.map +0 -1
package/dist/errors.d.ts
CHANGED
|
@@ -50,41 +50,28 @@ export declare class ShAnalyzeMaxDepthError extends ShAstError {
|
|
|
50
50
|
constructor(maxDepth: number);
|
|
51
51
|
}
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* `parse-depth-guard.ts`'s module doc for the exact heuristic) exceeds the
|
|
58
|
-
* limit `parseSync` accepts. Thrown *before* `text` is ever handed to the
|
|
59
|
-
* WASM shim: mvdan/sh's own recursive-descent parser has no recovery path
|
|
60
|
-
* for exhausting its call stack on pathologically deep input (a stack
|
|
61
|
-
* overflow deep inside the shared WASM instance is not a normal, catchable
|
|
62
|
-
* JS error the way a parse syntax error is), so this bridge estimates the
|
|
63
|
-
* risk up front and fails closed with a typed error instead of ever making
|
|
64
|
-
* that call — the shared WASM instance is therefore never put at risk of
|
|
65
|
-
* wedging on this class of input; a `parseSync` call right after catching
|
|
66
|
-
* this error works exactly as it would if this input had never been
|
|
67
|
-
* attempted.
|
|
53
|
+
* A whole-file parse operation exceeded the binding's native node-nesting budget.
|
|
54
|
+
* The maintained parser counts statement, word, and expression work, including
|
|
55
|
+
* iterative construction of deep operator trees. A refusal returns no partial
|
|
56
|
+
* File or position snapshot and leaves subsequent parse calls available.
|
|
68
57
|
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* trades off against ever letting a genuinely crash-inducing input
|
|
76
|
-
* through.
|
|
58
|
+
* This is a binding resource constraint, not an upstream grammar restriction.
|
|
59
|
+
* The fixed 128-unit policy can refuse valid deeply nested input. Units describe
|
|
60
|
+
* native node work, not actual Go/JavaScript frames or necessarily final AST
|
|
61
|
+
* depth. The empirical margin assumes an ordinary caller stack; arbitrary
|
|
62
|
+
* pre-existing JavaScript recursion can exhaust it. This does not establish
|
|
63
|
+
* safety for arbitrary caller-constructed trees or other recursive operations.
|
|
77
64
|
*
|
|
78
65
|
* @public
|
|
79
66
|
*/
|
|
80
67
|
export declare class ShParseMaxDepthError extends ShAstError {
|
|
81
68
|
readonly code = "SH_AST_PARSE_MAX_DEPTH";
|
|
82
|
-
/**
|
|
69
|
+
/** Fixed maximum native node-nesting units; not caller-configurable. */
|
|
83
70
|
readonly maxDepth: number;
|
|
84
71
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
72
|
+
* Native node work at the rejected entry, greater than {@link ShParseMaxDepthError.maxDepth}.
|
|
73
|
+
* The historical field name is retained for compatibility; the value is no
|
|
74
|
+
* longer a lexical estimate and is not a count of runtime stack frames.
|
|
88
75
|
*/
|
|
89
76
|
readonly estimatedDepth: number;
|
|
90
77
|
constructor(maxDepth: number, estimatedDepth: number);
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAE9F;;;;;GAKG;AACH,8BAAsB,UAAW,SAAQ,KAAK;IAC5C,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,QAAQ,CAAC,IAAI,qBAAqB;gBAEtB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,sBAAuB,SAAQ,UAAU;IACpD,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,mHAAmH;IACnH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;CAO7B;AAED
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAE9F;;;;;GAKG;AACH,8BAAsB,UAAW,SAAQ,KAAK;IAC5C,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CAChC;AAED;;;;;;;;;GASG;AACH,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,QAAQ,CAAC,IAAI,qBAAqB;gBAEtB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,sBAAuB,SAAQ,UAAU;IACpD,QAAQ,CAAC,IAAI,8BAA8B;IAC3C,mHAAmH;IACnH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;gBAEd,QAAQ,EAAE,MAAM;CAO7B;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,oBAAqB,SAAQ,UAAU;IAClD,QAAQ,CAAC,IAAI,4BAA4B;IACzC,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;gBAEpB,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM;CAQrD;AAED;;;;;;;;;;GAUG;AACH,qBAAa,gCAAiC,SAAQ,UAAU;IAC9D,QAAQ,CAAC,IAAI,yCAAyC;gBAE1C,OAAO,EAAE,MAAM;CAI5B"}
|
package/dist/errors.js
CHANGED
|
@@ -55,45 +55,32 @@ export class ShAnalyzeMaxDepthError extends ShAstError {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* `parse-depth-guard.ts`'s module doc for the exact heuristic) exceeds the
|
|
63
|
-
* limit `parseSync` accepts. Thrown *before* `text` is ever handed to the
|
|
64
|
-
* WASM shim: mvdan/sh's own recursive-descent parser has no recovery path
|
|
65
|
-
* for exhausting its call stack on pathologically deep input (a stack
|
|
66
|
-
* overflow deep inside the shared WASM instance is not a normal, catchable
|
|
67
|
-
* JS error the way a parse syntax error is), so this bridge estimates the
|
|
68
|
-
* risk up front and fails closed with a typed error instead of ever making
|
|
69
|
-
* that call — the shared WASM instance is therefore never put at risk of
|
|
70
|
-
* wedging on this class of input; a `parseSync` call right after catching
|
|
71
|
-
* this error works exactly as it would if this input had never been
|
|
72
|
-
* attempted.
|
|
58
|
+
* A whole-file parse operation exceeded the binding's native node-nesting budget.
|
|
59
|
+
* The maintained parser counts statement, word, and expression work, including
|
|
60
|
+
* iterative construction of deep operator trees. A refusal returns no partial
|
|
61
|
+
* File or position snapshot and leaves subsequent parse calls available.
|
|
73
62
|
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* trades off against ever letting a genuinely crash-inducing input
|
|
81
|
-
* through.
|
|
63
|
+
* This is a binding resource constraint, not an upstream grammar restriction.
|
|
64
|
+
* The fixed 128-unit policy can refuse valid deeply nested input. Units describe
|
|
65
|
+
* native node work, not actual Go/JavaScript frames or necessarily final AST
|
|
66
|
+
* depth. The empirical margin assumes an ordinary caller stack; arbitrary
|
|
67
|
+
* pre-existing JavaScript recursion can exhaust it. This does not establish
|
|
68
|
+
* safety for arbitrary caller-constructed trees or other recursive operations.
|
|
82
69
|
*
|
|
83
70
|
* @public
|
|
84
71
|
*/
|
|
85
72
|
export class ShParseMaxDepthError extends ShAstError {
|
|
86
73
|
code = 'SH_AST_PARSE_MAX_DEPTH';
|
|
87
|
-
/**
|
|
74
|
+
/** Fixed maximum native node-nesting units; not caller-configurable. */
|
|
88
75
|
maxDepth;
|
|
89
76
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
77
|
+
* Native node work at the rejected entry, greater than {@link ShParseMaxDepthError.maxDepth}.
|
|
78
|
+
* The historical field name is retained for compatibility; the value is no
|
|
79
|
+
* longer a lexical estimate and is not a count of runtime stack frames.
|
|
93
80
|
*/
|
|
94
81
|
estimatedDepth;
|
|
95
82
|
constructor(maxDepth, estimatedDepth) {
|
|
96
|
-
super(`parseSync:
|
|
83
|
+
super(`parseSync: native parser node work (${String(estimatedDepth)} units) exceeds the maximum this bridge accepts (${String(maxDepth)}) — refusing this input without a partial result.`);
|
|
97
84
|
this.name = 'ShParseMaxDepthError';
|
|
98
85
|
this.maxDepth = maxDepth;
|
|
99
86
|
this.estimatedDepth = estimatedDepth;
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAE9F;;;;;GAKG;AACH,MAAM,OAAgB,UAAW,SAAQ,KAAK;CAG7C;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,eAAgB,SAAQ,UAAU;IACpC,IAAI,GAAG,iBAAiB,CAAC;IAElC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,sBAAuB,SAAQ,UAAU;IAC3C,IAAI,GAAG,0BAA0B,CAAC;IAC3C,mHAAmH;IAC1G,QAAQ,CAAS;IAE1B,YAAY,QAAgB;QAC1B,KAAK,CACH,+EAA+E,MAAM,CAAC,QAAQ,CAAC,uGAAuG,CACvM,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAE9F;;;;;GAKG;AACH,MAAM,OAAgB,UAAW,SAAQ,KAAK;CAG7C;AAED;;;;;;;;;GASG;AACH,MAAM,OAAO,eAAgB,SAAQ,UAAU;IACpC,IAAI,GAAG,iBAAiB,CAAC;IAElC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,OAAO,sBAAuB,SAAQ,UAAU;IAC3C,IAAI,GAAG,0BAA0B,CAAC;IAC3C,mHAAmH;IAC1G,QAAQ,CAAS;IAE1B,YAAY,QAAgB;QAC1B,KAAK,CACH,+EAA+E,MAAM,CAAC,QAAQ,CAAC,uGAAuG,CACvM,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,oBAAqB,SAAQ,UAAU;IACzC,IAAI,GAAG,wBAAwB,CAAC;IACzC,wEAAwE;IAC/D,QAAQ,CAAS;IAC1B;;;;OAIG;IACM,cAAc,CAAS;IAEhC,YAAY,QAAgB,EAAE,cAAsB;QAClD,KAAK,CACH,uCAAuC,MAAM,CAAC,cAAc,CAAC,oDAAoD,MAAM,CAAC,QAAQ,CAAC,mDAAmD,CACrL,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,sBAAsB,CAAC;QACnC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;IACvC,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,gCAAiC,SAAQ,UAAU;IACrD,IAAI,GAAG,qCAAqC,CAAC;IAEtD,YAAY,OAAe;QACzB,KAAK,CAAC,qDAAqD,OAAO,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,IAAI,GAAG,kCAAkC,CAAC;IACjD,CAAC;CACF"}
|
package/dist/sh-ast.d.ts
CHANGED
|
@@ -2263,8 +2263,12 @@ export declare interface ParseOptions {
|
|
|
2263
2263
|
|
|
2264
2264
|
/**
|
|
2265
2265
|
* Parses exact source bytes, or well-formed Unicode text encoded as UTF-8. First
|
|
2266
|
-
* use synchronously initializes WASM.
|
|
2267
|
-
*
|
|
2266
|
+
* use synchronously initializes WASM. Native node-nesting work has a fixed binding
|
|
2267
|
+
* resource budget; exceeding it throws {@link ShParseMaxDepthError}. Subsequent
|
|
2268
|
+
* parse calls remain usable after that refusal.
|
|
2269
|
+
* The returned File and its Node subtrees are plain syntax data: ordinary
|
|
2270
|
+
* structuredClone(node), without transfers, makes an independent editable copy
|
|
2271
|
+
* while retaining position values, byte strings, typed nils and internal aliases.
|
|
2268
2272
|
* @public
|
|
2269
2273
|
*/
|
|
2270
2274
|
export declare function parseSync(source: string | Uint8Array, options?: ParseOptions): File_2;
|
|
@@ -2307,7 +2311,10 @@ export declare const Plus: 81;
|
|
|
2307
2311
|
|
|
2308
2312
|
/**
|
|
2309
2313
|
* Identity-based lookup of the original parse's bounds. A new or copied node has
|
|
2310
|
-
* no observation
|
|
2314
|
+
* no observation, including every node in a structuredClone of the syntax tree.
|
|
2315
|
+
* Clone File or a Node subtree, not this function-bearing lookup. Copied position
|
|
2316
|
+
* fields retain their values but do not transfer snapshot identity.
|
|
2317
|
+
* The index never calls WASM or recalculates edited node bounds.
|
|
2311
2318
|
* @public
|
|
2312
2319
|
*/
|
|
2313
2320
|
export declare interface PositionSnapshot {
|
|
@@ -2398,7 +2405,9 @@ export declare class PrintPanicError extends ShAstError {
|
|
|
2398
2405
|
/**
|
|
2399
2406
|
* Formats the current tree with a fresh upstream printer and collects all output.
|
|
2400
2407
|
* Supported roots are File, Stmt, Word, Assign, Command and WordPart; other Nodes
|
|
2401
|
-
* produce PrintError.
|
|
2408
|
+
* produce PrintError. An ordinary structuredClone of a supported syntax subtree
|
|
2409
|
+
* is accepted under the same input and failure rules; copying does not make nil
|
|
2410
|
+
* or unsupported roots printable. Only File output has upstream's trailing-newline behavior.
|
|
2402
2411
|
* Invalid UTF-8 output remains bytes. Upstream formatting can itself consume
|
|
2403
2412
|
* input bytes, including its tabwriter escape byte, so this is not source replay.
|
|
2404
2413
|
*
|
|
@@ -2827,41 +2836,28 @@ export declare const Shl: 71;
|
|
|
2827
2836
|
export declare const ShlAssgn: 57;
|
|
2828
2837
|
|
|
2829
2838
|
/**
|
|
2830
|
-
*
|
|
2831
|
-
*
|
|
2832
|
-
*
|
|
2833
|
-
*
|
|
2834
|
-
*
|
|
2835
|
-
*
|
|
2836
|
-
*
|
|
2837
|
-
*
|
|
2838
|
-
*
|
|
2839
|
-
*
|
|
2840
|
-
*
|
|
2841
|
-
* that call — the shared WASM instance is therefore never put at risk of
|
|
2842
|
-
* wedging on this class of input; a `parseSync` call right after catching
|
|
2843
|
-
* this error works exactly as it would if this input had never been
|
|
2844
|
-
* attempted.
|
|
2845
|
-
*
|
|
2846
|
-
* Like {@link ShAnalyzeMaxDepthError}, this is pathological-input
|
|
2847
|
-
* protection, not a normal-usage ceiling: a legitimately deep (but
|
|
2848
|
-
* realistic) script parses fine. The estimate can *over*-count relative to
|
|
2849
|
-
* mvdan/sh's real grammar (rejecting some legitimate-but-unusually-deep
|
|
2850
|
-
* input) but is designed to never *under*-count relative to it — see
|
|
2851
|
-
* `parse-depth-guard.ts` for the documented false-positive sources this
|
|
2852
|
-
* trades off against ever letting a genuinely crash-inducing input
|
|
2853
|
-
* through.
|
|
2839
|
+
* A whole-file parse operation exceeded the binding's native node-nesting budget.
|
|
2840
|
+
* The maintained parser counts statement, word, and expression work, including
|
|
2841
|
+
* iterative construction of deep operator trees. A refusal returns no partial
|
|
2842
|
+
* File or position snapshot and leaves subsequent parse calls available.
|
|
2843
|
+
*
|
|
2844
|
+
* This is a binding resource constraint, not an upstream grammar restriction.
|
|
2845
|
+
* The fixed 128-unit policy can refuse valid deeply nested input. Units describe
|
|
2846
|
+
* native node work, not actual Go/JavaScript frames or necessarily final AST
|
|
2847
|
+
* depth. The empirical margin assumes an ordinary caller stack; arbitrary
|
|
2848
|
+
* pre-existing JavaScript recursion can exhaust it. This does not establish
|
|
2849
|
+
* safety for arbitrary caller-constructed trees or other recursive operations.
|
|
2854
2850
|
*
|
|
2855
2851
|
* @public
|
|
2856
2852
|
*/
|
|
2857
2853
|
export declare class ShParseMaxDepthError extends ShAstError {
|
|
2858
2854
|
readonly code = "SH_AST_PARSE_MAX_DEPTH";
|
|
2859
|
-
/**
|
|
2855
|
+
/** Fixed maximum native node-nesting units; not caller-configurable. */
|
|
2860
2856
|
readonly maxDepth: number;
|
|
2861
2857
|
/**
|
|
2862
|
-
*
|
|
2863
|
-
*
|
|
2864
|
-
*
|
|
2858
|
+
* Native node work at the rejected entry, greater than {@link ShParseMaxDepthError.maxDepth}.
|
|
2859
|
+
* The historical field name is retained for compatibility; the value is no
|
|
2860
|
+
* longer a lexical estimate and is not a count of runtime stack frames.
|
|
2865
2861
|
*/
|
|
2866
2862
|
readonly estimatedDepth: number;
|
|
2867
2863
|
constructor(maxDepth: number, estimatedDepth: number);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { OperatorFamily, RawOperator } from '../generated/syntax-constants.js';
|
|
2
|
+
/**
|
|
3
|
+
* Represents an unnamed value in an upstream uint32 operator family. Named
|
|
4
|
+
* constants remain precise literal unions; this explicit path preserves other Go
|
|
5
|
+
* values without claiming an operation such as Print accepts them.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export declare function rawOperator<Family extends OperatorFamily>(family: Family, value: number): RawOperator<Family>;
|
|
9
|
+
//# sourceMappingURL=syntax-operator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntax-operator.d.ts","sourceRoot":"","sources":["../src/syntax-operator.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAGpF;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,SAAS,cAAc,EACvD,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,WAAW,CAAC,MAAM,CAAC,CAarB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validates unnamed operator values against the faithful field domains. This
|
|
3
|
+
* shared constructor owns numeric branding only; it does not parse syntax or
|
|
4
|
+
* promise that an upstream operation accepts every representable operator.
|
|
5
|
+
*/
|
|
6
|
+
import { SYNTAX_SCHEMA } from '../generated/syntax-schema.js';
|
|
7
|
+
import { InputError } from './syntax-errors.js';
|
|
8
|
+
/**
|
|
9
|
+
* Represents an unnamed value in an upstream uint32 operator family. Named
|
|
10
|
+
* constants remain precise literal unions; this explicit path preserves other Go
|
|
11
|
+
* values without claiming an operation such as Print accepts them.
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export function rawOperator(family, value) {
|
|
15
|
+
const knownFamily = Object.values(SYNTAX_SCHEMA).some((record) => Object.values(record.fields).some((field) => field.kind === 'operator' && field.type === family));
|
|
16
|
+
if (!knownFamily || !Number.isInteger(value) || value < 0 || value > 0xffff_ffff) {
|
|
17
|
+
throw new InputError('An operator value must belong to a known family and be an integral uint32');
|
|
18
|
+
}
|
|
19
|
+
// The runtime check establishes the opaque numeric brand; no value is changed.
|
|
20
|
+
return value;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=syntax-operator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"syntax-operator.js","sourceRoot":"","sources":["../src/syntax-operator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAE9D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,KAAa;IAEb,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAC/D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAC/B,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,CAC9D,CACF,CAAC;IACF,IAAI,CAAC,WAAW,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,WAAW,EAAE,CAAC;QACjF,MAAM,IAAI,UAAU,CAClB,2EAA2E,CAC5E,CAAC;IACJ,CAAC;IACD,+EAA+E;IAC/E,OAAO,KAA4B,CAAC;AACtC,CAAC"}
|
package/dist/syntax-print.d.ts
CHANGED
|
@@ -34,7 +34,9 @@ export interface PrintOptions {
|
|
|
34
34
|
/**
|
|
35
35
|
* Formats the current tree with a fresh upstream printer and collects all output.
|
|
36
36
|
* Supported roots are File, Stmt, Word, Assign, Command and WordPart; other Nodes
|
|
37
|
-
* produce PrintError.
|
|
37
|
+
* produce PrintError. An ordinary structuredClone of a supported syntax subtree
|
|
38
|
+
* is accepted under the same input and failure rules; copying does not make nil
|
|
39
|
+
* or unsupported roots printable. Only File output has upstream's trailing-newline behavior.
|
|
38
40
|
* Invalid UTF-8 output remains bytes. Upstream formatting can itself consume
|
|
39
41
|
* input bytes, including its tabwriter escape byte, so this is not source replay.
|
|
40
42
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syntax-print.d.ts","sourceRoot":"","sources":["../src/syntax-print.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAOnE;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,wFAAwF;IACxF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yFAAyF;IACzF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oFAAoF;IACpF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED
|
|
1
|
+
{"version":3,"file":"syntax-print.d.ts","sourceRoot":"","sources":["../src/syntax-print.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAOnE;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,wFAAwF;IACxF,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,+EAA+E;IAC/E,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yFAAyF;IACzF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,oFAAoF;IACpF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,0DAA0D;IAC1D,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,GAAE,YAAiB,GAAG,QAAQ,CAoC1E"}
|
package/dist/syntax-print.js
CHANGED
|
@@ -6,7 +6,9 @@ import { callSyntax } from './wasm-instance.js';
|
|
|
6
6
|
/**
|
|
7
7
|
* Formats the current tree with a fresh upstream printer and collects all output.
|
|
8
8
|
* Supported roots are File, Stmt, Word, Assign, Command and WordPart; other Nodes
|
|
9
|
-
* produce PrintError.
|
|
9
|
+
* produce PrintError. An ordinary structuredClone of a supported syntax subtree
|
|
10
|
+
* is accepted under the same input and failure rules; copying does not make nil
|
|
11
|
+
* or unsupported roots printable. Only File output has upstream's trailing-newline behavior.
|
|
10
12
|
* Invalid UTF-8 output remains bytes. Upstream formatting can itself consume
|
|
11
13
|
* input bytes, including its tabwriter escape byte, so this is not source replay.
|
|
12
14
|
*
|
package/dist/syntax-print.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syntax-print.js","sourceRoot":"","sources":["../src/syntax-print.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AA8BhD
|
|
1
|
+
{"version":3,"file":"syntax-print.js","sourceRoot":"","sources":["../src/syntax-print.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC9F,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AA8BhD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,SAAS,CAAC,IAAU,EAAE,UAAwB,EAAE;IAC9D,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,UAAU,CAAC,mDAAmD,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3D,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC7E,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,eAAe,CAAC,mDAAmD,CAAC,CAAC;IACjF,CAAC;IACD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,eAAe,CAAC,+CAA+C,CAAC,CAAC;QAC7E,CAAC;QACD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;YACnB,KAAK,YAAY;gBACf,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACtC,KAAK,iBAAiB;gBACpB,MAAM,IAAI,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC3C,KAAK,YAAY;gBACf,MAAM,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACtC,KAAK,eAAe;gBAClB,MAAM,IAAI,eAAe,CACvB,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;oBAC/B,CAAC,CAAC,KAAK,CAAC,OAAO;oBACf,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAC5C,CAAC;YACJ;gBACE,MAAM,IAAI,eAAe,CAAC,mDAAmD,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,eAAe,CAAC,qDAAqD,CAAC,CAAC;IACnF,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED,0FAA0F;AAC1F,SAAS,oBAAoB,CAAC,OAAqB;IACjD,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,UAAU,CAAC,uCAAuC,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC;QACpB,gBAAgB;QAChB,kBAAkB;QAClB,gBAAgB;QAChB,aAAa;QACb,QAAQ;QACR,YAAY;QACZ,kBAAkB;KACnB,CAAC,CAAC;IACH,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACpD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,MAAM,KAAK,GACT,OAAO,KAAK,KAAK,QAAQ;gBACvB,CAAC,CAAC,KAAK,IAAI,EAAE,IAAI,KAAK,IAAI,mBAAsB;gBAChD,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;YAC7E,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,UAAU,CAAC,4DAA4D,CAAC,CAAC;YACrF,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,UAAU,CAAC,2BAA2B,IAAI,EAAE,CAAC,CAAC;QAC1D,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YACtC,MAAM,IAAI,UAAU,CAAC,GAAG,IAAI,kBAAkB,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -12,7 +12,10 @@ export interface NodePositions {
|
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Identity-based lookup of the original parse's bounds. A new or copied node has
|
|
15
|
-
* no observation
|
|
15
|
+
* no observation, including every node in a structuredClone of the syntax tree.
|
|
16
|
+
* Clone File or a Node subtree, not this function-bearing lookup. Copied position
|
|
17
|
+
* fields retain their values but do not transfer snapshot identity.
|
|
18
|
+
* The index never calls WASM or recalculates edited node bounds.
|
|
16
19
|
* @public
|
|
17
20
|
*/
|
|
18
21
|
export interface PositionSnapshot {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syntax-snapshot.d.ts","sourceRoot":"","sources":["../src/syntax-snapshot.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAY,IAAI,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAKpF;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;CACnC;AAED
|
|
1
|
+
{"version":3,"file":"syntax-snapshot.d.ts","sourceRoot":"","sources":["../src/syntax-snapshot.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,IAAI,EAAY,IAAI,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAKpF;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,oEAAoE;IACpE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;CACnC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,aAAa,GAAG,SAAS,CAAC;CAC5C;AAED;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,kFAAkF;IAClF,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;CACtC;AAyFD;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,IAAI,EACV,GAAG,EAAE,OAAO,EACZ,SAAS,EAAE,OAAO,GACjB,gBAAgB,CA4DlB"}
|
package/dist/syntax-snapshot.js
CHANGED
|
@@ -31,9 +31,7 @@ function visitNodes(file, observe) {
|
|
|
31
31
|
observe(value);
|
|
32
32
|
if (!Object.hasOwn(SYNTAX_SCHEMA, value.Type))
|
|
33
33
|
return;
|
|
34
|
-
for (const
|
|
35
|
-
if (field.kind !== 'struct' && field.kind !== 'interface')
|
|
36
|
-
continue;
|
|
34
|
+
for (const name of childFields(value.Type)) {
|
|
37
35
|
const child = value[name];
|
|
38
36
|
if (Array.isArray(child))
|
|
39
37
|
child.forEach(visit);
|
|
@@ -43,6 +41,23 @@ function visitNodes(file, observe) {
|
|
|
43
41
|
};
|
|
44
42
|
visit(file);
|
|
45
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Child-bearing (struct or interface) field names per record type, in schema
|
|
46
|
+
* order. The generated schema is immutable, so each list is derived once rather
|
|
47
|
+
* than re-filtering every field of every visited record.
|
|
48
|
+
*/
|
|
49
|
+
const CHILD_FIELDS = new Map();
|
|
50
|
+
/** Returns the cached child field names for a type known to be in the schema. */
|
|
51
|
+
function childFields(type) {
|
|
52
|
+
let names = CHILD_FIELDS.get(type);
|
|
53
|
+
if (names === undefined) {
|
|
54
|
+
names = Object.entries(SYNTAX_SCHEMA[type].fields)
|
|
55
|
+
.filter(([, field]) => field.kind === 'struct' || field.kind === 'interface')
|
|
56
|
+
.map(([name]) => name);
|
|
57
|
+
CHILD_FIELDS.set(type, names);
|
|
58
|
+
}
|
|
59
|
+
return names;
|
|
60
|
+
}
|
|
46
61
|
/** Own byte-bearing failures so neither transport holders nor catchers can alter captures. */
|
|
47
62
|
function copyError(error) {
|
|
48
63
|
return typeof error === 'string' ? error : error.slice();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syntax-snapshot.js","sourceRoot":"","sources":["../src/syntax-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"syntax-snapshot.js","sourceRoot":"","sources":["../src/syntax-snapshot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAkDrE;;;GAGG;AACH,SAAS,cAAc,CAAC,KAA8B;IACpD,OAAO,CACL,CAAC,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/E,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU;YACxB,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;YAC9B,iBAAiB,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAC/C,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,UAAU,CAAC,IAAU,EAAE,OAA6B;IAC3D,MAAM,KAAK,GAAG,CAAC,KAAc,EAAQ,EAAE;QACrC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO;QAC/D,IAAI,cAAc,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QAC1C,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC;YAAE,OAAO;QACtD,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;gBAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;;gBAC1C,KAAK,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,YAAY,GAAG,IAAI,GAAG,EAA6B,CAAC;AAE1D,iFAAiF;AACjF,SAAS,WAAW,CAAC,IAAY;IAC/B,IAAI,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;aAC/C,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC;aAC5E,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QACzB,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,8FAA8F;AAC9F,SAAS,SAAS,CAAC,KAAe;IAChC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;AAC3D,CAAC;AAED,0FAA0F;AAC1F,SAAS,SAAS,CAAC,GAAuB,EAAE,MAAc,EAAE,MAAe;IACzE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACpF,MAAM,IAAI,eAAe,CAAC,qDAAqD,CAAC,CAAC;IACnF,CAAC;IACD,MAAM,QAAQ,GAAG;QACf,MAAM;QACN,IAAI;QACJ,GAAG;QACH,OAAO,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QAC1B,WAAW,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;QAC9B,cAAc,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;KAClC,CAAC;IACF,IACE,CAAC,WAAW,CAAC,QAAQ,CAAC;QACtB,CAAC,MAAM,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,EACpE,CAAC;QACD,MAAM,IAAI,eAAe,CAAC,8DAA8D,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAU,EACV,GAAY,EACZ,SAAkB;IAElB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;QAC7E,MAAM,IAAI,eAAe,CAAC,kDAAkD,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAChD,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5C,MAAM,IAAI,eAAe,CAAC,qDAAqD,CAAC,CAAC;QACnF,CAAC;QACD,MAAM,MAAM,GAAuB,GAAG,CAAC;QACvC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,MAAM,CAAC;QACjC,IACE,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;YACxB,KAAK,GAAG,CAAC;YACT,KAAK,IAAI,KAAK;YACd,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;YACnB,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC,CAAC,GAAG,KAAK,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,CAAC,EAC9B,CAAC;YACD,MAAM,IAAI,eAAe,CAAC,6DAA6D,CAAC,CAAC;QAC3F,CAAC;QACD,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE;YAClB,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC;YACpC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC;SACrC,CAAC,CAAC;IACL,CAAC;IACD,MAAM,YAAY,GAAG,IAAI,OAAO,EAA2B,CAAC;IAC5D,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,UAAU,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE;QACxB,IAAI,KAAK,IAAI,KAAK;YAAE,MAAM,IAAI,eAAe,CAAC,0CAA0C,CAAC,CAAC;QAC1F,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QACrC,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;QACrC,+EAA+E;QAC/E,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC;QACzD,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,GAAG,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,QAAQ,IAAI,QAAQ,CAAC;QACnC,YAAY,CAAC,GAAG,CACd,IAAI,EACJ,KAAK,KAAK,IAAI;YACZ,CAAC,CAAC,EAAE,KAAK,EAAE;YACX,CAAC,CAAC;gBACE,SAAS,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;aAC/E,CACN,CAAC;QACF,KAAK,EAAE,CAAC;IACV,CAAC,CAAC,CAAC;IACH,IAAI,KAAK,KAAK,KAAK;QACjB,MAAM,IAAI,eAAe,CAAC,kDAAkD,CAAC,CAAC;IAChF,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,GAAG,CAAC,IAAU;YACZ,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,WAAW,KAAK,SAAS;gBAAE,OAAO,SAAS,CAAC;YAChD,IAAI,OAAO,IAAI,WAAW;gBAAE,MAAM,IAAI,UAAU,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/E,OAAO,WAAW,CAAC,SAAS,CAAC;QAC/B,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
package/dist/syntax-wire.d.ts
CHANGED
|
@@ -30,4 +30,16 @@ export declare function isSyntaxPos(value: unknown): value is SyntaxPos;
|
|
|
30
30
|
export declare function isSyntaxNode(value: unknown): value is Node;
|
|
31
31
|
/** The public parser's root is the precise upstream File representation. @internal */
|
|
32
32
|
export declare function isSyntaxFile(value: unknown): value is File;
|
|
33
|
+
/**
|
|
34
|
+
* Validates a parse response's File exactly as isSyntaxFile does while rebuilding
|
|
35
|
+
* its positions. The bridge spells each File position as a compact
|
|
36
|
+
* [Offset, Line, Col, Flags] tuple (flags: bit 0 IsValid, bit 1 IsRecovered,
|
|
37
|
+
* bit 2 OffsetOverflow) because positions are most of a parse response. Each
|
|
38
|
+
* tuple is replaced in place by the identical six-member SyntaxPos record, in
|
|
39
|
+
* its usual member order, and then checked like any other position. Only a
|
|
40
|
+
* freshly decoded response may be passed: the graph is mutated, and a false
|
|
41
|
+
* result can leave it partly restored, so callers must discard it.
|
|
42
|
+
* @internal
|
|
43
|
+
*/
|
|
44
|
+
export declare function restoreSyntaxFile(value: unknown): value is File;
|
|
33
45
|
//# sourceMappingURL=syntax-wire.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syntax-wire.d.ts","sourceRoot":"","sources":["../src/syntax-wire.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEpF,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CASvD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAgCjD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"syntax-wire.d.ts","sourceRoot":"","sources":["../src/syntax-wire.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,8BAA8B,CAAC;AAEpF,kFAAkF;AAClF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CASvD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAgCjD;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CA0ChD;AAsCD,kFAAkF;AAClF,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,QAAQ,CAE5D;AAED,6FAA6F;AAC7F,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,SAAS,CAwB9D;AA+GD,sGAAsG;AACtG,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAS1D;AAED,sFAAsF;AACtF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAE1D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,IAAI,CAE/D"}
|
package/dist/syntax-wire.js
CHANGED
|
@@ -80,6 +80,8 @@ export function decodeWire(text) {
|
|
|
80
80
|
catch (cause) {
|
|
81
81
|
throw new ShInternalError(`Invalid syntax bridge JSON: ${String(cause)}`);
|
|
82
82
|
}
|
|
83
|
+
if (!mayContainBytesTag(text))
|
|
84
|
+
return parsed;
|
|
83
85
|
const visit = (item) => {
|
|
84
86
|
if (Array.isArray(item)) {
|
|
85
87
|
for (let index = 0; index < item.length; index++) {
|
|
@@ -117,6 +119,39 @@ export function decodeWire(text) {
|
|
|
117
119
|
};
|
|
118
120
|
return visit(parsed);
|
|
119
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Reports whether bridge JSON can contain a Bytes member. The Go producer spells
|
|
124
|
+
* every ASCII key literally (encoding/json escapes only quotes, backslashes,
|
|
125
|
+
* controls, HTML metacharacters and line separators), so a Bytes key always
|
|
126
|
+
* appears as the exact characters `"Bytes"`. Their absence therefore proves no
|
|
127
|
+
* record needs byte restoration. Their presence, including an ordinary string
|
|
128
|
+
* value spelled Bytes, only selects the complete restoration walk.
|
|
129
|
+
*/
|
|
130
|
+
function mayContainBytesTag(text) {
|
|
131
|
+
return text.includes('"Bytes"');
|
|
132
|
+
}
|
|
133
|
+
/** Decodes one compact position tuple, or returns undefined when it is malformed. */
|
|
134
|
+
function positionFromTuple(tuple) {
|
|
135
|
+
if (tuple.length !== 4)
|
|
136
|
+
return undefined;
|
|
137
|
+
const [Offset, Line, Col, flags] = tuple;
|
|
138
|
+
if (typeof Offset !== 'number' ||
|
|
139
|
+
typeof Line !== 'number' ||
|
|
140
|
+
typeof Col !== 'number' ||
|
|
141
|
+
typeof flags !== 'number' ||
|
|
142
|
+
!Number.isInteger(flags) ||
|
|
143
|
+
flags < 0 ||
|
|
144
|
+
flags > 7)
|
|
145
|
+
return undefined;
|
|
146
|
+
return {
|
|
147
|
+
Offset,
|
|
148
|
+
Line,
|
|
149
|
+
Col,
|
|
150
|
+
IsValid: (flags & 1) !== 0,
|
|
151
|
+
IsRecovered: (flags & 2) !== 0,
|
|
152
|
+
OffsetOverflow: (flags & 4) !== 0,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
120
155
|
/** A Go string is text only when every original byte is valid UTF-8. @internal */
|
|
121
156
|
export function isGoString(value) {
|
|
122
157
|
return typeof value === 'string' || value instanceof Uint8Array;
|
|
@@ -161,34 +196,67 @@ function isTypedNil(value, implementers) {
|
|
|
161
196
|
* Validates complete records against the pinned schema, including nil-bearing
|
|
162
197
|
* boundaries. This is a boundary check, not a semantic shell interpretation.
|
|
163
198
|
*/
|
|
164
|
-
function matchesRecord(value,
|
|
165
|
-
if (!isRecord(value) || typeof value.Type !== 'string' || active
|
|
199
|
+
function matchesRecord(value, check) {
|
|
200
|
+
if (!isRecord(value) || typeof value.Type !== 'string' || check.active?.has(value))
|
|
166
201
|
return false;
|
|
167
202
|
if (!Object.hasOwn(SYNTAX_SCHEMA, value.Type))
|
|
168
203
|
return false;
|
|
169
|
-
const
|
|
170
|
-
if (Object.keys(value).length !==
|
|
204
|
+
const fields = fieldEntries(value.Type);
|
|
205
|
+
if (Object.keys(value).length !== fields.length + 1)
|
|
171
206
|
return false;
|
|
172
|
-
active
|
|
207
|
+
check.active?.add(value);
|
|
173
208
|
try {
|
|
174
|
-
|
|
209
|
+
for (const [name, field] of fields) {
|
|
210
|
+
if (!Object.hasOwn(value, name))
|
|
211
|
+
return false;
|
|
212
|
+
let child = value[name];
|
|
213
|
+
if (check.restore && field.kind === 'position' && Array.isArray(child)) {
|
|
214
|
+
const position = positionFromTuple(child);
|
|
215
|
+
if (position === undefined)
|
|
216
|
+
return false;
|
|
217
|
+
value[name] = child = position;
|
|
218
|
+
}
|
|
219
|
+
if (!matchesField(child, field, check))
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
return true;
|
|
175
223
|
}
|
|
176
224
|
finally {
|
|
177
|
-
active
|
|
225
|
+
check.active?.delete(value);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Field descriptors in schema order for each record type. The generated schema
|
|
230
|
+
* is immutable, so listing its entries once per type avoids rebuilding the same
|
|
231
|
+
* arrays for every record a large File contains.
|
|
232
|
+
*/
|
|
233
|
+
const FIELD_ENTRIES = new Map();
|
|
234
|
+
/** Returns the cached field list for a type already known to be in the schema. */
|
|
235
|
+
function fieldEntries(type) {
|
|
236
|
+
let entries = FIELD_ENTRIES.get(type);
|
|
237
|
+
if (entries === undefined) {
|
|
238
|
+
entries = Object.entries(SYNTAX_SCHEMA[type].fields);
|
|
239
|
+
FIELD_ENTRIES.set(type, entries);
|
|
178
240
|
}
|
|
241
|
+
return entries;
|
|
179
242
|
}
|
|
180
243
|
/** Checks one upstream field without conflating a nil slice with an empty one. */
|
|
181
|
-
function matchesField(value, field,
|
|
244
|
+
function matchesField(value, field, check) {
|
|
182
245
|
if (value === null)
|
|
183
246
|
return field.nullable;
|
|
184
247
|
if (field.slice) {
|
|
185
|
-
|
|
186
|
-
|
|
248
|
+
if (!Array.isArray(value))
|
|
249
|
+
return false;
|
|
250
|
+
for (const item of value) {
|
|
251
|
+
if (item === null ? !field.elementNullable : !matchesScalar(item, field, check))
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
return true;
|
|
187
255
|
}
|
|
188
|
-
return matchesScalar(value, field,
|
|
256
|
+
return matchesScalar(value, field, check);
|
|
189
257
|
}
|
|
190
258
|
/** Each scalar category retains its upstream domain rather than JS coercions. */
|
|
191
|
-
function matchesScalar(value, field,
|
|
259
|
+
function matchesScalar(value, field, check) {
|
|
192
260
|
switch (field.kind) {
|
|
193
261
|
case 'boolean':
|
|
194
262
|
return typeof value === 'boolean';
|
|
@@ -199,14 +267,14 @@ function matchesScalar(value, field, active) {
|
|
|
199
267
|
case 'operator':
|
|
200
268
|
return (typeof value === 'number' && Number.isInteger(value) && value >= 0 && value <= 0xffff_ffff);
|
|
201
269
|
case 'struct':
|
|
202
|
-
return isRecord(value) && value.Type === field.type && matchesRecord(value,
|
|
270
|
+
return isRecord(value) && value.Type === field.type && matchesRecord(value, check);
|
|
203
271
|
case 'interface':
|
|
204
272
|
return (isRecord(value) &&
|
|
205
273
|
typeof value.Type === 'string' &&
|
|
206
274
|
field.type !== null &&
|
|
207
275
|
Object.hasOwn(SYNTAX_INTERFACES, field.type) &&
|
|
208
276
|
(isTypedNil(value, SYNTAX_INTERFACES[field.type]) ||
|
|
209
|
-
(SYNTAX_INTERFACES[field.type].includes(value.Type) && matchesRecord(value,
|
|
277
|
+
(SYNTAX_INTERFACES[field.type].includes(value.Type) && matchesRecord(value, check))));
|
|
210
278
|
}
|
|
211
279
|
}
|
|
212
280
|
/** Narrows complete syntax.Nodes or typed nil Node interfaces; auxiliaries are excluded. @internal */
|
|
@@ -217,10 +285,26 @@ export function isSyntaxNode(value) {
|
|
|
217
285
|
typeof value.Type === 'string' &&
|
|
218
286
|
Object.hasOwn(SYNTAX_SCHEMA, value.Type) &&
|
|
219
287
|
SYNTAX_SCHEMA[value.Type].node &&
|
|
220
|
-
matchesRecord(value, new Set()));
|
|
288
|
+
matchesRecord(value, { active: new Set(), restore: false }));
|
|
221
289
|
}
|
|
222
290
|
/** The public parser's root is the precise upstream File representation. @internal */
|
|
223
291
|
export function isSyntaxFile(value) {
|
|
224
292
|
return isSyntaxNode(value) && value.Type === 'File';
|
|
225
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Validates a parse response's File exactly as isSyntaxFile does while rebuilding
|
|
296
|
+
* its positions. The bridge spells each File position as a compact
|
|
297
|
+
* [Offset, Line, Col, Flags] tuple (flags: bit 0 IsValid, bit 1 IsRecovered,
|
|
298
|
+
* bit 2 OffsetOverflow) because positions are most of a parse response. Each
|
|
299
|
+
* tuple is replaced in place by the identical six-member SyntaxPos record, in
|
|
300
|
+
* its usual member order, and then checked like any other position. Only a
|
|
301
|
+
* freshly decoded response may be passed: the graph is mutated, and a false
|
|
302
|
+
* result can leave it partly restored, so callers must discard it.
|
|
303
|
+
* @internal
|
|
304
|
+
*/
|
|
305
|
+
export function restoreSyntaxFile(value) {
|
|
306
|
+
return isRecord(value) && value.Type === 'File' && matchesRecord(value, RESTORING);
|
|
307
|
+
}
|
|
308
|
+
/** Restoring validation state; it carries no per-call data and is shared. */
|
|
309
|
+
const RESTORING = { active: null, restore: true };
|
|
226
310
|
//# sourceMappingURL=syntax-wire.js.map
|