sh-ast 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/README.md +147 -0
  2. package/dist/analyze/ansi-c-escapes.d.ts +53 -0
  3. package/dist/analyze/ansi-c-escapes.d.ts.map +1 -0
  4. package/dist/analyze/ansi-c-escapes.js +255 -0
  5. package/dist/analyze/ansi-c-escapes.js.map +1 -0
  6. package/dist/analyze/decode-lit.d.ts +74 -0
  7. package/dist/analyze/decode-lit.d.ts.map +1 -0
  8. package/dist/analyze/decode-lit.js +114 -0
  9. package/dist/analyze/decode-lit.js.map +1 -0
  10. package/dist/analyze/enumerate-commands.d.ts +159 -0
  11. package/dist/analyze/enumerate-commands.d.ts.map +1 -0
  12. package/dist/analyze/enumerate-commands.js +390 -0
  13. package/dist/analyze/enumerate-commands.js.map +1 -0
  14. package/dist/analyze/index.d.ts +18 -0
  15. package/dist/analyze/index.d.ts.map +1 -0
  16. package/dist/analyze/index.js +27 -0
  17. package/dist/analyze/index.js.map +1 -0
  18. package/dist/analyze/node-helpers.d.ts +28 -0
  19. package/dist/analyze/node-helpers.d.ts.map +1 -0
  20. package/dist/analyze/node-helpers.js +37 -0
  21. package/dist/analyze/node-helpers.js.map +1 -0
  22. package/dist/analyze/resolve-word.d.ts +146 -0
  23. package/dist/analyze/resolve-word.d.ts.map +1 -0
  24. package/dist/analyze/resolve-word.js +202 -0
  25. package/dist/analyze/resolve-word.js.map +1 -0
  26. package/dist/analyze.d.ts +390 -0
  27. package/dist/deep-freeze.d.ts +14 -0
  28. package/dist/deep-freeze.d.ts.map +1 -0
  29. package/dist/deep-freeze.js +25 -0
  30. package/dist/deep-freeze.js.map +1 -0
  31. package/dist/errors.d.ts +115 -0
  32. package/dist/errors.d.ts.map +1 -0
  33. package/dist/errors.js +106 -0
  34. package/dist/errors.js.map +1 -0
  35. package/dist/index.d.ts +18 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +5 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/normalize.d.ts +52 -0
  40. package/dist/normalize.d.ts.map +1 -0
  41. package/dist/normalize.js +260 -0
  42. package/dist/normalize.js.map +1 -0
  43. package/dist/parse.d.ts +45 -0
  44. package/dist/parse.d.ts.map +1 -0
  45. package/dist/parse.js +118 -0
  46. package/dist/parse.js.map +1 -0
  47. package/dist/sh-ast.d.ts +1270 -0
  48. package/dist/types.d.ts +70 -0
  49. package/dist/types.d.ts.map +1 -0
  50. package/dist/types.js +2 -0
  51. package/dist/types.js.map +1 -0
  52. package/dist/visitor-keys.d.ts +21 -0
  53. package/dist/visitor-keys.d.ts.map +1 -0
  54. package/dist/visitor-keys.js +23 -0
  55. package/dist/visitor-keys.js.map +1 -0
  56. package/dist/walk.d.ts +18 -0
  57. package/dist/walk.d.ts.map +1 -0
  58. package/dist/walk.js +40 -0
  59. package/dist/walk.js.map +1 -0
  60. package/dist/wasm-instance.d.ts +13 -0
  61. package/dist/wasm-instance.d.ts.map +1 -0
  62. package/dist/wasm-instance.js +88 -0
  63. package/dist/wasm-instance.js.map +1 -0
  64. package/generated/child-type-schema.d.ts +14 -0
  65. package/generated/child-type-schema.js +188 -0
  66. package/generated/node-types.d.ts +958 -0
  67. package/generated/position-fields.d.ts +21 -0
  68. package/generated/position-fields.js +50 -0
  69. package/generated/visitor-keys.d.ts +11 -0
  70. package/generated/visitor-keys.js +50 -0
  71. package/package.json +93 -10
  72. package/shim/sh-ast.wasm +0 -0
  73. package/shim/wasm_exec.js +654 -0
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Shell dialect (mvdan/sh `LangVariant`) to parse against. Mapped to
3
+ * `LangVariant` by string name via `LangVariant.Set()` — never by numeric
4
+ * value, since the bit-flag encoding of `LangVariant` is not a stable
5
+ * contract across mvdan/sh versions. See design/ARCHITECTURE.md, "Parse
6
+ * errors and dialects".
7
+ *
8
+ * @public
9
+ */
10
+ export type ShellDialect = 'bash' | 'posix' | 'mksh' | 'bats' | 'zsh';
11
+ /**
12
+ * Options accepted by {@link parseSync}.
13
+ *
14
+ * @public
15
+ */
16
+ export interface ParseOptions {
17
+ /**
18
+ * The shell dialect to parse against.
19
+ * @defaultValue `"bash"`
20
+ */
21
+ readonly dialect?: ShellDialect;
22
+ /**
23
+ * Filename used only to annotate error messages and positions; the source
24
+ * is never read from disk.
25
+ * @defaultValue `"input.sh"`
26
+ */
27
+ readonly filename?: string;
28
+ }
29
+ /**
30
+ * A 1-based line/column position. Columns are UTF-16 code units, matching
31
+ * JavaScript string indexing (see {@link ShNode.range}).
32
+ *
33
+ * @public
34
+ */
35
+ export interface Position {
36
+ readonly line: number;
37
+ readonly column: number;
38
+ }
39
+ /**
40
+ * A normalized AST node produced by {@link parseSync}.
41
+ *
42
+ * `range` and `loc` are expressed in UTF-16 code units, so
43
+ * `code.slice(node.range[0], node.range[1])` reproduces the node's exact
44
+ * source text — even though mvdan/sh itself reports byte offsets and
45
+ * byte-counting columns internally (see design/ARCHITECTURE.md's
46
+ * "Serialization contract"). Every other field copied over from mvdan/sh's
47
+ * typedjson tree keeps its original value but with the field name
48
+ * lowercased (`Stmts` becomes `stmts`, `CondLast` becomes `condlast`, etc.).
49
+ *
50
+ * @public
51
+ */
52
+ export interface ShNode {
53
+ readonly type: string;
54
+ readonly range: readonly [number, number];
55
+ readonly loc: {
56
+ readonly start: Position;
57
+ readonly end: Position;
58
+ };
59
+ [field: string]: unknown;
60
+ }
61
+ /**
62
+ * The root node of a parsed shell script.
63
+ *
64
+ * @public
65
+ */
66
+ export interface ShFile extends ShNode {
67
+ readonly type: 'File';
68
+ readonly stmts: readonly ShNode[];
69
+ }
70
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +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;;;;;;;;;;;;GAYG;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/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Maps each normalized node `type` to the field names (lowercased, matching
3
+ * the normalized node shape produced by `normalize`) whose values hold child
4
+ * nodes.
5
+ *
6
+ * Generated from mvdan/sh's `syntax` package struct definitions by
7
+ * `tools/gen-visitor-keys` (see design/ARCHITECTURE.md, "The schema table is
8
+ * generated, not hand-written") — this module only re-exports the generated
9
+ * table under the public name, frozen. {@link walk} does not depend on this
10
+ * table for correctness — it discovers children structurally — so any gap
11
+ * here (there shouldn't be one; the kitchen-sink golden test guards it)
12
+ * affects only external consumers that choose to traverse via this table.
13
+ *
14
+ * Frozen (including each per-type field-name array) so immutability of this
15
+ * shared, module-scoped table is a contract, not just a convention any
16
+ * importer happens to honor.
17
+ *
18
+ * @public
19
+ */
20
+ export declare const visitorKeys: Readonly<Record<string, readonly string[]>>;
21
+ //# sourceMappingURL=visitor-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visitor-keys.d.ts","sourceRoot":"","sources":["../src/visitor-keys.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAClC,CAAC"}
@@ -0,0 +1,23 @@
1
+ import { deepFreeze } from './deep-freeze.js';
2
+ import { visitorKeys as generatedVisitorKeys } from '../generated/visitor-keys.js';
3
+ /**
4
+ * Maps each normalized node `type` to the field names (lowercased, matching
5
+ * the normalized node shape produced by `normalize`) whose values hold child
6
+ * nodes.
7
+ *
8
+ * Generated from mvdan/sh's `syntax` package struct definitions by
9
+ * `tools/gen-visitor-keys` (see design/ARCHITECTURE.md, "The schema table is
10
+ * generated, not hand-written") — this module only re-exports the generated
11
+ * table under the public name, frozen. {@link walk} does not depend on this
12
+ * table for correctness — it discovers children structurally — so any gap
13
+ * here (there shouldn't be one; the kitchen-sink golden test guards it)
14
+ * affects only external consumers that choose to traverse via this table.
15
+ *
16
+ * Frozen (including each per-type field-name array) so immutability of this
17
+ * shared, module-scoped table is a contract, not just a convention any
18
+ * importer happens to honor.
19
+ *
20
+ * @public
21
+ */
22
+ export const visitorKeys = deepFreeze(generatedVisitorKeys);
23
+ //# sourceMappingURL=visitor-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visitor-keys.js","sourceRoot":"","sources":["../src/visitor-keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEnF;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,MAAM,WAAW,GACtB,UAAU,CAAC,oBAAoB,CAAC,CAAC"}
package/dist/walk.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ import type { ShNode } from './types.js';
2
+ /**
3
+ * Visits every node in a normalized tree, pre-order (parent before
4
+ * children), starting at `node`.
5
+ *
6
+ * Children are discovered structurally: any field on a visited node whose
7
+ * value is itself a normalized node (or an array of normalized nodes) is
8
+ * treated as a child. This is deliberately not driven off {@link
9
+ * visitorKeys} — the spike's hand-written visitor-keys table missed
10
+ * `DeclClause.Variant` (see design/ARCHITECTURE.md) and silently
11
+ * under-walked the tree, and `visitorKeys` remains hand-maintained pending a
12
+ * schema generator (tracked separately). Walking structurally means this
13
+ * function's completeness never depends on that table's accuracy.
14
+ *
15
+ * @public
16
+ */
17
+ export declare function walk(node: ShNode, visit: (node: ShNode, parent: ShNode | null) => void): void;
18
+ //# sourceMappingURL=walk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../src/walk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AA6BzC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,GAAG,IAAI,CAE7F"}
package/dist/walk.js ADDED
@@ -0,0 +1,40 @@
1
+ function isShNode(value) {
2
+ return (typeof value === 'object' &&
3
+ value !== null &&
4
+ !Array.isArray(value) &&
5
+ typeof value.type === 'string' &&
6
+ Array.isArray(value.range));
7
+ }
8
+ function walkNode(node, parent, visit) {
9
+ visit(node, parent);
10
+ for (const value of Object.values(node)) {
11
+ if (isShNode(value)) {
12
+ walkNode(value, node, visit);
13
+ }
14
+ else if (Array.isArray(value)) {
15
+ for (const item of value) {
16
+ if (isShNode(item))
17
+ walkNode(item, node, visit);
18
+ }
19
+ }
20
+ }
21
+ }
22
+ /**
23
+ * Visits every node in a normalized tree, pre-order (parent before
24
+ * children), starting at `node`.
25
+ *
26
+ * Children are discovered structurally: any field on a visited node whose
27
+ * value is itself a normalized node (or an array of normalized nodes) is
28
+ * treated as a child. This is deliberately not driven off {@link
29
+ * visitorKeys} — the spike's hand-written visitor-keys table missed
30
+ * `DeclClause.Variant` (see design/ARCHITECTURE.md) and silently
31
+ * under-walked the tree, and `visitorKeys` remains hand-maintained pending a
32
+ * schema generator (tracked separately). Walking structurally means this
33
+ * function's completeness never depends on that table's accuracy.
34
+ *
35
+ * @public
36
+ */
37
+ export function walk(node, visit) {
38
+ walkNode(node, null, visit);
39
+ }
40
+ //# sourceMappingURL=walk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"walk.js","sourceRoot":"","sources":["../src/walk.ts"],"names":[],"mappings":"AAEA,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,OAAQ,KAA4B,CAAC,IAAI,KAAK,QAAQ;QACtD,KAAK,CAAC,OAAO,CAAE,KAA6B,CAAC,KAAK,CAAC,CACpD,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CACf,IAAY,EACZ,MAAqB,EACrB,KAAoD;IAEpD,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpB,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpB,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChC,KAAK,MAAM,IAAI,IAAI,KAAkB,EAAE,CAAC;gBACtC,IAAI,QAAQ,CAAC,IAAI,CAAC;oBAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,IAAI,CAAC,IAAY,EAAE,KAAoD;IACrF,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,13 @@
1
+ import '../shim/wasm_exec.js';
2
+ /**
3
+ * Calls into the WASM shim's `process` export, instantiating the shim on
4
+ * first use. Encodes `text`/`dialect`/`filename` into shim-owned linear
5
+ * memory, reads the NUL-terminated JSON result back via `TextDecoder`
6
+ * (rather than syscall/js's `js.ValueOf(string)`, which dominated the parse
7
+ * cost — see design/ARCHITECTURE.md's "Performance"), and frees every buffer
8
+ * the call allocated.
9
+ *
10
+ * @internal
11
+ */
12
+ export declare function callParse(text: string, dialect: string, filename: string): string;
13
+ //# sourceMappingURL=wasm-instance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wasm-instance.d.ts","sourceRoot":"","sources":["../src/wasm-instance.ts"],"names":[],"mappings":"AAGA,OAAO,sBAAsB,CAAC;AA2F9B;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuBjF"}
@@ -0,0 +1,88 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ import '../shim/wasm_exec.js';
5
+ import { ShBridgeInternalError } from './errors.js';
6
+ const here = path.dirname(fileURLToPath(import.meta.url));
7
+ // `shim/` is a sibling of both `src/` (test-time) and `dist/` (build-time).
8
+ const wasmPath = path.join(here, '..', 'shim', 'sh-ast.wasm');
9
+ function isShimExports(value) {
10
+ const candidate = value;
11
+ return (candidate.mem instanceof WebAssembly.Memory &&
12
+ typeof candidate.alloc === 'function' &&
13
+ typeof candidate.free === 'function' &&
14
+ typeof candidate.process === 'function');
15
+ }
16
+ let wasmModule;
17
+ let shimExports;
18
+ /**
19
+ * Instantiates the WASM shim synchronously in Node, exactly once, and
20
+ * reuses the instance across parses (see design/ARCHITECTURE.md,
21
+ * "Synchronous parse: solved, two mechanisms"). Node imposes no size limit
22
+ * on synchronous `WebAssembly.Module` compilation — that restriction is
23
+ * browser-main-thread-only.
24
+ */
25
+ function ensureInstance() {
26
+ if (shimExports)
27
+ return shimExports;
28
+ wasmModule ??= new WebAssembly.Module(fs.readFileSync(wasmPath));
29
+ const go = new Go();
30
+ const instance = new WebAssembly.Instance(wasmModule, go.importObject);
31
+ void go.run(instance);
32
+ if (!isShimExports(instance.exports)) {
33
+ throw new ShBridgeInternalError('bridge: WASM shim did not export the expected alloc/process/free/mem linear-memory ABI');
34
+ }
35
+ shimExports = instance.exports;
36
+ return shimExports;
37
+ }
38
+ const encoder = new TextEncoder();
39
+ const decoder = new TextDecoder();
40
+ /**
41
+ * Writes `text` (UTF-8 encoded) into a freshly `alloc`ed buffer and returns
42
+ * its (pointer, length). The caller owns the buffer and must `free` it once
43
+ * `process` has consumed it.
44
+ */
45
+ function writeString(exports, text) {
46
+ const bytes = encoder.encode(text);
47
+ const ptr = exports.alloc(bytes.length);
48
+ // `exports.mem.buffer` is re-read here rather than cached across calls:
49
+ // a Go-side allocation can grow WASM linear memory, which detaches any
50
+ // previously created `ArrayBuffer` view (see `callParse` below for the
51
+ // same reasoning on the read side).
52
+ new Uint8Array(exports.mem.buffer, ptr, bytes.length).set(bytes);
53
+ return { ptr, len: bytes.length };
54
+ }
55
+ /**
56
+ * Calls into the WASM shim's `process` export, instantiating the shim on
57
+ * first use. Encodes `text`/`dialect`/`filename` into shim-owned linear
58
+ * memory, reads the NUL-terminated JSON result back via `TextDecoder`
59
+ * (rather than syscall/js's `js.ValueOf(string)`, which dominated the parse
60
+ * cost — see design/ARCHITECTURE.md's "Performance"), and frees every buffer
61
+ * the call allocated.
62
+ *
63
+ * @internal
64
+ */
65
+ export function callParse(text, dialect, filename) {
66
+ const exports = ensureInstance();
67
+ const t = writeString(exports, text);
68
+ const d = writeString(exports, dialect);
69
+ const f = writeString(exports, filename);
70
+ const resultPtr = exports.process(t.ptr, t.len, d.ptr, d.len, f.ptr, f.len);
71
+ exports.free(t.ptr);
72
+ exports.free(d.ptr);
73
+ exports.free(f.ptr);
74
+ if (resultPtr === 0) {
75
+ throw new ShBridgeInternalError('bridge: WASM shim returned a null result pointer');
76
+ }
77
+ // Re-read `mem.buffer` fresh (see `writeString`'s comment) and scan for the
78
+ // shim's NUL sentinel — valid JSON from Go's encoding/json never contains
79
+ // a raw 0x00 byte, since every control character is \u-escaped.
80
+ const memory = new Uint8Array(exports.mem.buffer);
81
+ let end = resultPtr;
82
+ while (memory[end] !== 0)
83
+ end++;
84
+ const json = decoder.decode(memory.subarray(resultPtr, end));
85
+ exports.free(resultPtr);
86
+ return json;
87
+ }
88
+ //# sourceMappingURL=wasm-instance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wasm-instance.js","sourceRoot":"","sources":["../src/wasm-instance.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ // Code generated by tools/gen-visitor-keys from mvdan.cc/sh/v3 v3.13.1. DO NOT EDIT.
2
+ // See design/ARCHITECTURE.md, "The schema table is generated, not hand-written".
3
+ /**
4
+ * `(parentType, fieldName) -> childType` for node fields whose static Go
5
+ * type is a concrete struct rather than an interface — typedjson only
6
+ * emits a "Type" discriminator for interface-typed fields, so these need
7
+ * the child type injected during normalization. A `null` value means the
8
+ * field's static type is a Node-derived interface (already
9
+ * self-discriminating). See design/ARCHITECTURE.md, "The schema table is
10
+ * generated, not hand-written".
11
+ *
12
+ * @internal
13
+ */
14
+ export declare const CHILD_TYPE_SCHEMA: Record<string, Record<string, string | null>>;
@@ -0,0 +1,188 @@
1
+ // Code generated by tools/gen-visitor-keys from mvdan.cc/sh/v3 v3.13.1. DO NOT EDIT.
2
+ // See design/ARCHITECTURE.md, "The schema table is generated, not hand-written".
3
+ export const CHILD_TYPE_SCHEMA = {
4
+ ArithmCmd: {
5
+ X: null,
6
+ },
7
+ ArithmExp: {
8
+ X: null,
9
+ },
10
+ ArrayElem: {
11
+ Comments: 'Comment',
12
+ Index: null,
13
+ Value: 'Word',
14
+ },
15
+ ArrayExpr: {
16
+ Elems: 'ArrayElem',
17
+ Last: 'Comment',
18
+ },
19
+ Assign: {
20
+ Array: 'ArrayExpr',
21
+ Index: null,
22
+ Name: 'Lit',
23
+ Value: 'Word',
24
+ },
25
+ BinaryArithm: {
26
+ X: null,
27
+ Y: null,
28
+ },
29
+ BinaryCmd: {
30
+ X: 'Stmt',
31
+ Y: 'Stmt',
32
+ },
33
+ BinaryTest: {
34
+ X: null,
35
+ Y: null,
36
+ },
37
+ Block: {
38
+ Last: 'Comment',
39
+ Stmts: 'Stmt',
40
+ },
41
+ BraceExp: {
42
+ Elems: 'Word',
43
+ },
44
+ CStyleLoop: {
45
+ Cond: null,
46
+ Init: null,
47
+ Post: null,
48
+ },
49
+ CallExpr: {
50
+ Args: 'Word',
51
+ Assigns: 'Assign',
52
+ },
53
+ CaseClause: {
54
+ Items: 'CaseItem',
55
+ Last: 'Comment',
56
+ Word: 'Word',
57
+ },
58
+ CaseItem: {
59
+ Comments: 'Comment',
60
+ Last: 'Comment',
61
+ Patterns: 'Word',
62
+ Stmts: 'Stmt',
63
+ },
64
+ CmdSubst: {
65
+ Last: 'Comment',
66
+ Stmts: 'Stmt',
67
+ },
68
+ Comment: {},
69
+ CoprocClause: {
70
+ Name: 'Word',
71
+ Stmt: 'Stmt',
72
+ },
73
+ DblQuoted: {
74
+ Parts: null,
75
+ },
76
+ DeclClause: {
77
+ Args: 'Assign',
78
+ Variant: 'Lit',
79
+ },
80
+ Expansion: {
81
+ Word: 'Word',
82
+ },
83
+ ExtGlob: {
84
+ Pattern: 'Lit',
85
+ },
86
+ File: {
87
+ Last: 'Comment',
88
+ Stmts: 'Stmt',
89
+ },
90
+ FlagsArithm: {
91
+ Flags: 'Lit',
92
+ X: null,
93
+ },
94
+ ForClause: {
95
+ Do: 'Stmt',
96
+ DoLast: 'Comment',
97
+ Loop: null,
98
+ },
99
+ FuncDecl: {
100
+ Body: 'Stmt',
101
+ Name: 'Lit',
102
+ Names: 'Lit',
103
+ },
104
+ IfClause: {
105
+ Cond: 'Stmt',
106
+ CondLast: 'Comment',
107
+ Else: 'IfClause',
108
+ Last: 'Comment',
109
+ Then: 'Stmt',
110
+ ThenLast: 'Comment',
111
+ },
112
+ LetClause: {
113
+ Exprs: null,
114
+ },
115
+ Lit: {},
116
+ ParamExp: {
117
+ Exp: 'Expansion',
118
+ Flags: 'Lit',
119
+ Index: null,
120
+ Modifiers: 'Lit',
121
+ NestedParam: null,
122
+ Param: 'Lit',
123
+ Repl: 'Replace',
124
+ Slice: 'Slice',
125
+ },
126
+ ParenArithm: {
127
+ X: null,
128
+ },
129
+ ParenTest: {
130
+ X: null,
131
+ },
132
+ ProcSubst: {
133
+ Last: 'Comment',
134
+ Stmts: 'Stmt',
135
+ },
136
+ Redirect: {
137
+ Hdoc: 'Word',
138
+ N: 'Lit',
139
+ Word: 'Word',
140
+ },
141
+ Replace: {
142
+ Orig: 'Word',
143
+ With: 'Word',
144
+ },
145
+ SglQuoted: {},
146
+ Slice: {
147
+ Length: null,
148
+ Offset: null,
149
+ },
150
+ Stmt: {
151
+ Cmd: null,
152
+ Comments: 'Comment',
153
+ Redirs: 'Redirect',
154
+ },
155
+ Subshell: {
156
+ Last: 'Comment',
157
+ Stmts: 'Stmt',
158
+ },
159
+ TestClause: {
160
+ X: null,
161
+ },
162
+ TestDecl: {
163
+ Body: 'Stmt',
164
+ Description: 'Word',
165
+ },
166
+ TimeClause: {
167
+ Stmt: 'Stmt',
168
+ },
169
+ UnaryArithm: {
170
+ X: null,
171
+ },
172
+ UnaryTest: {
173
+ X: null,
174
+ },
175
+ WhileClause: {
176
+ Cond: 'Stmt',
177
+ CondLast: 'Comment',
178
+ Do: 'Stmt',
179
+ DoLast: 'Comment',
180
+ },
181
+ Word: {
182
+ Parts: null,
183
+ },
184
+ WordIter: {
185
+ Items: 'Word',
186
+ Name: 'Lit',
187
+ },
188
+ };