sh-ast 0.1.0 → 0.2.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/analyze/enumerate-commands.d.ts +7 -1
- package/dist/analyze/enumerate-commands.d.ts.map +1 -1
- package/dist/analyze/enumerate-commands.js +7 -1
- package/dist/analyze/enumerate-commands.js.map +1 -1
- package/dist/analyze/index.d.ts +12 -4
- package/dist/analyze/index.d.ts.map +1 -1
- package/dist/analyze/index.js +18 -15
- package/dist/analyze/index.js.map +1 -1
- package/dist/analyze/resolve-argv0.d.ts +335 -0
- package/dist/analyze/resolve-argv0.d.ts.map +1 -0
- package/dist/analyze/resolve-argv0.js +510 -0
- package/dist/analyze/resolve-argv0.js.map +1 -0
- package/dist/analyze/resolve-word.d.ts +5 -0
- package/dist/analyze/resolve-word.d.ts.map +1 -1
- package/dist/analyze/resolve-word.js +5 -0
- package/dist/analyze/resolve-word.js.map +1 -1
- package/dist/analyze.d.ts +592 -211
- package/dist/errors.d.ts +81 -16
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +90 -17
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/parse-depth-guard.d.ts +11 -0
- package/dist/parse-depth-guard.d.ts.map +1 -0
- package/dist/parse-depth-guard.js +633 -0
- package/dist/parse-depth-guard.js.map +1 -0
- package/dist/parse.d.ts +7 -2
- package/dist/parse.d.ts.map +1 -1
- package/dist/parse.js +15 -8
- package/dist/parse.js.map +1 -1
- package/dist/sh-ast.d.ts +121 -45
- package/dist/types.d.ts +5 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/wasm-instance.js +3 -3
- package/dist/wasm-instance.js.map +1 -1
- package/package.json +1 -1
package/dist/parse.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG1E,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,EAAE,MAAM,YAAY,CAAC;AAcrE,UAAU,iBAAiB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,YAAY;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,UAAU,cAAc;IACtB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAoCD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAKxE;AAYD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAsCtE"}
|
package/dist/parse.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ShInternalError, ShInvalidDialectError, ShParseError } from './errors.js';
|
|
2
2
|
import { normalize, toUtf16Column } from './normalize.js';
|
|
3
|
+
import { assertParseDepthWithinLimit } from './parse-depth-guard.js';
|
|
3
4
|
import { callParse } from './wasm-instance.js';
|
|
4
5
|
/**
|
|
5
6
|
* The full set of dialects {@link parseSync} accepts, in the order surfaced
|
|
@@ -52,10 +53,10 @@ export function isResultEnvelope(value) {
|
|
|
52
53
|
}
|
|
53
54
|
function asShFile(node) {
|
|
54
55
|
if (node.type !== 'File') {
|
|
55
|
-
throw new
|
|
56
|
+
throw new ShInternalError(`bridge: expected root node of type "File", got "${node.type}"`);
|
|
56
57
|
}
|
|
57
58
|
if (!Array.isArray(node.stmts)) {
|
|
58
|
-
throw new
|
|
59
|
+
throw new ShInternalError('bridge: expected root node to have an array "stmts" field');
|
|
59
60
|
}
|
|
60
61
|
return node;
|
|
61
62
|
}
|
|
@@ -74,9 +75,14 @@ function asShFile(node) {
|
|
|
74
75
|
* position appears only inside `.message`, which is mvdan/sh's own
|
|
75
76
|
* formatted string, verbatim. Throws {@link ShInvalidDialectError} when
|
|
76
77
|
* {@link ParseOptions.dialect} is not a supported dialect. Throws
|
|
77
|
-
* {@link
|
|
78
|
+
* {@link ShInternalError} for failures that should never happen given
|
|
78
79
|
* a correctly-behaving shim (malformed envelope, unexpected root node
|
|
79
|
-
* type, shim contract violations).
|
|
80
|
+
* type, shim contract violations). Throws {@link ShParseMaxDepthError} if
|
|
81
|
+
* `text`'s conservatively estimated structural nesting depth exceeds the
|
|
82
|
+
* limit this bridge accepts — checked, and thrown, *before* `text` is ever
|
|
83
|
+
* handed to the WASM shim, since mvdan/sh's own parser has no recovery path
|
|
84
|
+
* for exhausting its stack on pathological nesting (see that error's doc
|
|
85
|
+
* comment and `parse-depth-guard.ts`).
|
|
80
86
|
*
|
|
81
87
|
* @public
|
|
82
88
|
*/
|
|
@@ -86,10 +92,11 @@ export function parseSync(text, options) {
|
|
|
86
92
|
if (!isSupportedShellDialect(dialect)) {
|
|
87
93
|
throw new ShInvalidDialectError(dialect, SUPPORTED_SHELL_DIALECTS);
|
|
88
94
|
}
|
|
95
|
+
assertParseDepthWithinLimit(text);
|
|
89
96
|
const raw = callParse(text, dialect, filename);
|
|
90
97
|
const result = JSON.parse(raw);
|
|
91
98
|
if (!isResultEnvelope(result)) {
|
|
92
|
-
throw new
|
|
99
|
+
throw new ShInternalError('bridge: WASM shim returned an unexpected payload shape');
|
|
93
100
|
}
|
|
94
101
|
if (result.parseError) {
|
|
95
102
|
// mvdan/sh reports `column` as a byte count on the source line, not a
|
|
@@ -108,10 +115,10 @@ export function parseSync(text, options) {
|
|
|
108
115
|
});
|
|
109
116
|
}
|
|
110
117
|
if (result.error) {
|
|
111
|
-
throw new
|
|
118
|
+
throw new ShInternalError(result.error.message);
|
|
112
119
|
}
|
|
113
120
|
if (result.file === undefined) {
|
|
114
|
-
throw new
|
|
121
|
+
throw new ShInternalError('bridge: WASM shim returned neither a file nor an error');
|
|
115
122
|
}
|
|
116
123
|
return asShFile(normalize(result.file, text));
|
|
117
124
|
}
|
package/dist/parse.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"parse.js","sourceRoot":"","sources":["../src/parse.ts"],"names":[],"mappings":"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"}
|
package/dist/sh-ast.d.ts
CHANGED
|
@@ -32,9 +32,14 @@ export declare interface ParseOptions {
|
|
|
32
32
|
* position appears only inside `.message`, which is mvdan/sh's own
|
|
33
33
|
* formatted string, verbatim. Throws {@link ShInvalidDialectError} when
|
|
34
34
|
* {@link ParseOptions.dialect} is not a supported dialect. Throws
|
|
35
|
-
* {@link
|
|
35
|
+
* {@link ShInternalError} for failures that should never happen given
|
|
36
36
|
* a correctly-behaving shim (malformed envelope, unexpected root node
|
|
37
|
-
* type, shim contract violations).
|
|
37
|
+
* type, shim contract violations). Throws {@link ShParseMaxDepthError} if
|
|
38
|
+
* `text`'s conservatively estimated structural nesting depth exceeds the
|
|
39
|
+
* limit this bridge accepts — checked, and thrown, *before* `text` is ever
|
|
40
|
+
* handed to the WASM shim, since mvdan/sh's own parser has no recovery path
|
|
41
|
+
* for exhausting its stack on pathological nesting (see that error's doc
|
|
42
|
+
* comment and `parse-depth-guard.ts`).
|
|
38
43
|
*
|
|
39
44
|
* @public
|
|
40
45
|
*/
|
|
@@ -51,6 +56,22 @@ export declare interface Position {
|
|
|
51
56
|
readonly column: number;
|
|
52
57
|
}
|
|
53
58
|
|
|
59
|
+
/**
|
|
60
|
+
* Thrown by `sh-ast/analyze`'s `resolveArgv0` when a caller-supplied
|
|
61
|
+
* `options.transparentWrappers` array contains a malformed `WrapperSpec`
|
|
62
|
+
* entry — e.g. a non-array or empty `names`, or a flag field that isn't an
|
|
63
|
+
* array of strings. Fails closed with a clear, specific message at the
|
|
64
|
+
* point the malformed table is supplied, rather than letting the bad shape
|
|
65
|
+
* reach flag-matching logic and surface as a confusing native `TypeError`
|
|
66
|
+
* (or, worse, a silently wrong match) far from its actual cause.
|
|
67
|
+
*
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
70
|
+
export declare class ShAnalyzeInvalidWrapperSpecError extends ShAstError {
|
|
71
|
+
readonly code = "SH_AST_ANALYZE_INVALID_WRAPPER_SPEC";
|
|
72
|
+
constructor(message: string);
|
|
73
|
+
}
|
|
74
|
+
|
|
54
75
|
/**
|
|
55
76
|
* Thrown by `sh-ast/analyze`'s `enumerateCommands` when a tree's genuinely
|
|
56
77
|
* nested structure — subshells within subshells, chained command/process
|
|
@@ -71,8 +92,8 @@ export declare interface Position {
|
|
|
71
92
|
*
|
|
72
93
|
* @public
|
|
73
94
|
*/
|
|
74
|
-
export declare class ShAnalyzeMaxDepthError extends
|
|
75
|
-
readonly code = "
|
|
95
|
+
export declare class ShAnalyzeMaxDepthError extends ShAstError {
|
|
96
|
+
readonly code = "SH_AST_ANALYZE_MAX_DEPTH";
|
|
76
97
|
/** The maximum nesting depth `enumerateCommands` supports; the same value every time (not caller-configurable). */
|
|
77
98
|
readonly maxDepth: number;
|
|
78
99
|
constructor(maxDepth: number);
|
|
@@ -226,6 +247,37 @@ declare interface ShAssignNode {
|
|
|
226
247
|
readonly value?: ShWordNode;
|
|
227
248
|
}
|
|
228
249
|
|
|
250
|
+
/**
|
|
251
|
+
* Common base class for every error this package throws — originally just
|
|
252
|
+
* {@link sh-ast#parseSync | parseSync}'s errors, now also the
|
|
253
|
+
* `sh-ast/analyze` layer's (see {@link ShAnalyzeMaxDepthError},
|
|
254
|
+
* {@link ShAnalyzeInvalidWrapperSpecError}). Provides a stable, documented
|
|
255
|
+
* `code` discriminator (e.g. `"SH_AST_PARSE_ERROR"`) alongside the usual
|
|
256
|
+
* `instanceof` narrowing, so consumers can branch on failure kind
|
|
257
|
+
* programmatically without parsing `.message` strings. Never thrown directly
|
|
258
|
+
* — only via its concrete subclasses
|
|
259
|
+
* ({@link sh-ast#ShParseError | ShParseError},
|
|
260
|
+
* {@link sh-ast#ShInvalidDialectError | ShInvalidDialectError},
|
|
261
|
+
* {@link sh-ast#ShInternalError | ShInternalError},
|
|
262
|
+
* {@link ShAnalyzeMaxDepthError},
|
|
263
|
+
* {@link sh-ast#ShParseMaxDepthError | ShParseMaxDepthError},
|
|
264
|
+
* {@link ShAnalyzeInvalidWrapperSpecError}).
|
|
265
|
+
*
|
|
266
|
+
* Re-exported from `sh-ast/analyze` as well as the root `sh-ast` entry
|
|
267
|
+
* point (see #23) — every subclass thrown by `sh-ast/analyze`'s own
|
|
268
|
+
* functions extends this, so a consumer of that subpath alone can
|
|
269
|
+
* `catch`/reference the base without also importing from root.
|
|
270
|
+
*
|
|
271
|
+
* @public
|
|
272
|
+
*/
|
|
273
|
+
export declare abstract class ShAstError extends Error {
|
|
274
|
+
/**
|
|
275
|
+
* Stable, machine-readable discriminator for this error kind. Distinct
|
|
276
|
+
* per subclass and will not change once published.
|
|
277
|
+
*/
|
|
278
|
+
abstract readonly code: string;
|
|
279
|
+
}
|
|
280
|
+
|
|
229
281
|
/**
|
|
230
282
|
* mvdan/sh's `syntax.BinaryArithm`, normalized.
|
|
231
283
|
*
|
|
@@ -310,42 +362,6 @@ declare interface ShBraceExpNode {
|
|
|
310
362
|
readonly elems: readonly ShWordNode[];
|
|
311
363
|
}
|
|
312
364
|
|
|
313
|
-
/**
|
|
314
|
-
* Common base class for every error this package throws — originally just
|
|
315
|
-
* {@link parseSync}'s errors, now also the `sh-ast/analyze` layer's (see
|
|
316
|
-
* {@link ShAnalyzeMaxDepthError}). Provides a stable, documented `code`
|
|
317
|
-
* discriminator (e.g. `"ESLINT_SH_PARSE_ERROR"`) alongside the usual
|
|
318
|
-
* `instanceof` narrowing, so consumers can branch on failure kind
|
|
319
|
-
* programmatically without parsing `.message` strings. Never thrown
|
|
320
|
-
* directly — only via its concrete subclasses ({@link ShParseError},
|
|
321
|
-
* {@link ShInvalidDialectError}, {@link ShBridgeInternalError},
|
|
322
|
-
* {@link ShAnalyzeMaxDepthError}).
|
|
323
|
-
*
|
|
324
|
-
* @public
|
|
325
|
-
*/
|
|
326
|
-
export declare abstract class ShBridgeError extends Error {
|
|
327
|
-
/**
|
|
328
|
-
* Stable, machine-readable discriminator for this error kind. Distinct
|
|
329
|
-
* per subclass and will not change once published.
|
|
330
|
-
*/
|
|
331
|
-
abstract readonly code: string;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
/**
|
|
335
|
-
* Thrown by {@link parseSync} for failures that should never happen given a
|
|
336
|
-
* correctly-behaving WASM shim: a malformed result envelope, an unexpected
|
|
337
|
-
* root node type, or any other shim contract violation. Distinct from
|
|
338
|
-
* {@link ShInvalidDialectError} and {@link ShParseError}, both of which
|
|
339
|
-
* indicate a foreseeable, actionable user mistake rather than an internal
|
|
340
|
-
* defect.
|
|
341
|
-
*
|
|
342
|
-
* @public
|
|
343
|
-
*/
|
|
344
|
-
export declare class ShBridgeInternalError extends ShBridgeError {
|
|
345
|
-
readonly code = "ESLINT_SH_BRIDGE_INTERNAL";
|
|
346
|
-
constructor(message: string);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
365
|
/**
|
|
350
366
|
* mvdan/sh's `syntax.CallExpr`, normalized.
|
|
351
367
|
*
|
|
@@ -668,6 +684,21 @@ declare interface ShIfClauseNode {
|
|
|
668
684
|
readonly thenlast: readonly ShCommentNode[];
|
|
669
685
|
}
|
|
670
686
|
|
|
687
|
+
/**
|
|
688
|
+
* Thrown by {@link parseSync} for failures that should never happen given a
|
|
689
|
+
* correctly-behaving WASM shim: a malformed result envelope, an unexpected
|
|
690
|
+
* root node type, or any other shim contract violation. Distinct from
|
|
691
|
+
* {@link ShInvalidDialectError} and {@link ShParseError}, both of which
|
|
692
|
+
* indicate a foreseeable, actionable user mistake rather than an internal
|
|
693
|
+
* defect.
|
|
694
|
+
*
|
|
695
|
+
* @public
|
|
696
|
+
*/
|
|
697
|
+
export declare class ShInternalError extends ShAstError {
|
|
698
|
+
readonly code = "SH_AST_INTERNAL";
|
|
699
|
+
constructor(message: string);
|
|
700
|
+
}
|
|
701
|
+
|
|
671
702
|
/**
|
|
672
703
|
* Thrown by {@link parseSync} when {@link ParseOptions.dialect} is not one
|
|
673
704
|
* of the supported {@link ShellDialect} values. Carries the rejected value
|
|
@@ -676,8 +707,8 @@ declare interface ShIfClauseNode {
|
|
|
676
707
|
*
|
|
677
708
|
* @public
|
|
678
709
|
*/
|
|
679
|
-
export declare class ShInvalidDialectError extends
|
|
680
|
-
readonly code = "
|
|
710
|
+
export declare class ShInvalidDialectError extends ShAstError {
|
|
711
|
+
readonly code = "SH_AST_INVALID_DIALECT";
|
|
681
712
|
/** The rejected dialect value, exactly as passed to {@link parseSync}. */
|
|
682
713
|
readonly dialect: string;
|
|
683
714
|
constructor(dialect: string, supportedDialects: readonly ShellDialect[]);
|
|
@@ -723,7 +754,7 @@ declare interface ShLitNode {
|
|
|
723
754
|
declare type ShLoopNode = ShCStyleLoopNode | ShWordIterNode;
|
|
724
755
|
|
|
725
756
|
/**
|
|
726
|
-
* A normalized AST node produced by {@link parseSync}.
|
|
757
|
+
* A normalized AST node produced by {@link sh-ast#parseSync | parseSync}.
|
|
727
758
|
*
|
|
728
759
|
* `range` and `loc` are expressed in UTF-16 code units, so
|
|
729
760
|
* `code.slice(node.range[0], node.range[1])` reproduces the node's exact
|
|
@@ -733,6 +764,10 @@ declare type ShLoopNode = ShCStyleLoopNode | ShWordIterNode;
|
|
|
733
764
|
* typedjson tree keeps its original value but with the field name
|
|
734
765
|
* lowercased (`Stmts` becomes `stmts`, `CondLast` becomes `condlast`, etc.).
|
|
735
766
|
*
|
|
767
|
+
* Also re-exported from `sh-ast/analyze` (see #23) — the subpath's public
|
|
768
|
+
* surface consumes and exposes `ShNode`, so a consumer can reference the type
|
|
769
|
+
* without also importing from the root `sh-ast` entry point.
|
|
770
|
+
*
|
|
736
771
|
* @public
|
|
737
772
|
*/
|
|
738
773
|
export declare interface ShNode {
|
|
@@ -923,8 +958,8 @@ declare interface ShParenTestNode {
|
|
|
923
958
|
*
|
|
924
959
|
* @public
|
|
925
960
|
*/
|
|
926
|
-
export declare class ShParseError extends
|
|
927
|
-
readonly code = "
|
|
961
|
+
export declare class ShParseError extends ShAstError {
|
|
962
|
+
readonly code = "SH_AST_PARSE_ERROR";
|
|
928
963
|
readonly line: number;
|
|
929
964
|
readonly column: number;
|
|
930
965
|
readonly filename: string;
|
|
@@ -952,6 +987,47 @@ export declare interface ShParseErrorInfo {
|
|
|
952
987
|
filename: string;
|
|
953
988
|
}
|
|
954
989
|
|
|
990
|
+
/**
|
|
991
|
+
* Thrown by {@link parseSync} when `text`'s conservatively estimated
|
|
992
|
+
* structural nesting depth (subshells, command/process substitutions,
|
|
993
|
+
* `if`/`case`/loop/function bodies, `{ }` blocks, backtick or `$(...)`
|
|
994
|
+
* command substitution, `$((...))` arithmetic — see
|
|
995
|
+
* `parse-depth-guard.ts`'s module doc for the exact heuristic) exceeds the
|
|
996
|
+
* limit `parseSync` accepts. Thrown *before* `text` is ever handed to the
|
|
997
|
+
* WASM shim: mvdan/sh's own recursive-descent parser has no recovery path
|
|
998
|
+
* for exhausting its call stack on pathologically deep input (a stack
|
|
999
|
+
* overflow deep inside the shared WASM instance is not a normal, catchable
|
|
1000
|
+
* JS error the way a parse syntax error is), so this bridge estimates the
|
|
1001
|
+
* risk up front and fails closed with a typed error instead of ever making
|
|
1002
|
+
* that call — the shared WASM instance is therefore never put at risk of
|
|
1003
|
+
* wedging on this class of input; a `parseSync` call right after catching
|
|
1004
|
+
* this error works exactly as it would if this input had never been
|
|
1005
|
+
* attempted.
|
|
1006
|
+
*
|
|
1007
|
+
* Like {@link ShAnalyzeMaxDepthError}, this is pathological-input
|
|
1008
|
+
* protection, not a normal-usage ceiling: a legitimately deep (but
|
|
1009
|
+
* realistic) script parses fine. The estimate can *over*-count relative to
|
|
1010
|
+
* mvdan/sh's real grammar (rejecting some legitimate-but-unusually-deep
|
|
1011
|
+
* input) but is designed to never *under*-count relative to it — see
|
|
1012
|
+
* `parse-depth-guard.ts` for the documented false-positive sources this
|
|
1013
|
+
* trades off against ever letting a genuinely crash-inducing input
|
|
1014
|
+
* through.
|
|
1015
|
+
*
|
|
1016
|
+
* @public
|
|
1017
|
+
*/
|
|
1018
|
+
export declare class ShParseMaxDepthError extends ShAstError {
|
|
1019
|
+
readonly code = "SH_AST_PARSE_MAX_DEPTH";
|
|
1020
|
+
/** The maximum structural nesting depth `parseSync` accepts; the same value every time (not caller-configurable). */
|
|
1021
|
+
readonly maxDepth: number;
|
|
1022
|
+
/**
|
|
1023
|
+
* The conservatively estimated nesting depth that tripped the guard.
|
|
1024
|
+
* Not necessarily `text`'s "true" nesting depth under a real parse — see
|
|
1025
|
+
* {@link ShParseMaxDepthError}'s doc comment — only ever `> maxDepth`.
|
|
1026
|
+
*/
|
|
1027
|
+
readonly estimatedDepth: number;
|
|
1028
|
+
constructor(maxDepth: number, estimatedDepth: number);
|
|
1029
|
+
}
|
|
1030
|
+
|
|
955
1031
|
/**
|
|
956
1032
|
* mvdan/sh's `syntax.ProcSubst`, normalized.
|
|
957
1033
|
*
|
package/dist/types.d.ts
CHANGED
|
@@ -37,7 +37,7 @@ export interface Position {
|
|
|
37
37
|
readonly column: number;
|
|
38
38
|
}
|
|
39
39
|
/**
|
|
40
|
-
* A normalized AST node produced by {@link parseSync}.
|
|
40
|
+
* A normalized AST node produced by {@link sh-ast#parseSync | parseSync}.
|
|
41
41
|
*
|
|
42
42
|
* `range` and `loc` are expressed in UTF-16 code units, so
|
|
43
43
|
* `code.slice(node.range[0], node.range[1])` reproduces the node's exact
|
|
@@ -47,6 +47,10 @@ export interface Position {
|
|
|
47
47
|
* typedjson tree keeps its original value but with the field name
|
|
48
48
|
* lowercased (`Stmts` becomes `stmts`, `CondLast` becomes `condlast`, etc.).
|
|
49
49
|
*
|
|
50
|
+
* Also re-exported from `sh-ast/analyze` (see #23) — the subpath's public
|
|
51
|
+
* surface consumes and exposes `ShNode`, so a consumer can reference the type
|
|
52
|
+
* without also importing from the root `sh-ast` entry point.
|
|
53
|
+
*
|
|
50
54
|
* @public
|
|
51
55
|
*/
|
|
52
56
|
export interface ShNode {
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAEtE;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAEhC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAEtE;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC;IAEhC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,CAAC,GAAG,EAAE;QAAE,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAA;KAAE,CAAC;IACnE,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,WAAW,MAAO,SAAQ,MAAM;IACpC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC"}
|
package/dist/wasm-instance.js
CHANGED
|
@@ -2,7 +2,7 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { fileURLToPath } from 'node:url';
|
|
4
4
|
import '../shim/wasm_exec.js';
|
|
5
|
-
import {
|
|
5
|
+
import { ShInternalError } from './errors.js';
|
|
6
6
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
7
7
|
// `shim/` is a sibling of both `src/` (test-time) and `dist/` (build-time).
|
|
8
8
|
const wasmPath = path.join(here, '..', 'shim', 'sh-ast.wasm');
|
|
@@ -30,7 +30,7 @@ function ensureInstance() {
|
|
|
30
30
|
const instance = new WebAssembly.Instance(wasmModule, go.importObject);
|
|
31
31
|
void go.run(instance);
|
|
32
32
|
if (!isShimExports(instance.exports)) {
|
|
33
|
-
throw new
|
|
33
|
+
throw new ShInternalError('bridge: WASM shim did not export the expected alloc/process/free/mem linear-memory ABI');
|
|
34
34
|
}
|
|
35
35
|
shimExports = instance.exports;
|
|
36
36
|
return shimExports;
|
|
@@ -72,7 +72,7 @@ export function callParse(text, dialect, filename) {
|
|
|
72
72
|
exports.free(d.ptr);
|
|
73
73
|
exports.free(f.ptr);
|
|
74
74
|
if (resultPtr === 0) {
|
|
75
|
-
throw new
|
|
75
|
+
throw new ShInternalError('bridge: WASM shim returned a null result pointer');
|
|
76
76
|
}
|
|
77
77
|
// Re-read `mem.buffer` fresh (see `writeString`'s comment) and scan for the
|
|
78
78
|
// shim's NUL sentinel — valid JSON from Go's encoding/json never contains
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wasm-instance.js","sourceRoot":"","sources":["../src/wasm-instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,sBAAsB,CAAC;AAM9B,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"wasm-instance.js","sourceRoot":"","sources":["../src/wasm-instance.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED