parseman 0.45.0 → 0.47.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 +8 -3
- package/dist/analysis/choice-cost-gate.d.ts +158 -0
- package/dist/analysis/choice-cost-gate.d.ts.map +1 -0
- package/dist/analysis/choice-cost-render.d.ts +96 -0
- package/dist/analysis/choice-cost-render.d.ts.map +1 -0
- package/dist/analysis/choice-cost.d.ts +383 -0
- package/dist/analysis/choice-cost.d.ts.map +1 -0
- package/dist/analysis/commitment.d.ts +131 -0
- package/dist/analysis/commitment.d.ts.map +1 -0
- package/dist/analysis/corpus.d.ts +73 -0
- package/dist/analysis/corpus.d.ts.map +1 -0
- package/dist/analysis/diagnose-render.d.ts +65 -0
- package/dist/analysis/diagnose-render.d.ts.map +1 -0
- package/dist/analysis/diagnose.d.ts +15 -0
- package/dist/analysis/diagnose.d.ts.map +1 -1
- package/dist/analysis/diagnostics.cjs +13736 -0
- package/dist/analysis/diagnostics.cjs.map +6 -0
- package/dist/analysis/diagnostics.d.ts +27 -0
- package/dist/analysis/diagnostics.d.ts.map +1 -0
- package/dist/analysis/diagnostics.js +13713 -0
- package/dist/analysis/diagnostics.js.map +6 -0
- package/dist/analysis/duplication.d.ts.map +1 -1
- package/dist/analysis/fix-render.d.ts +43 -0
- package/dist/analysis/fix-render.d.ts.map +1 -0
- package/dist/analysis/fix.d.ts +172 -0
- package/dist/analysis/fix.d.ts.map +1 -0
- package/dist/analysis/format-number.d.ts +23 -0
- package/dist/analysis/format-number.d.ts.map +1 -0
- package/dist/analysis/gating.d.ts +47 -2
- package/dist/analysis/gating.d.ts.map +1 -1
- package/dist/analysis/rebuild.d.ts +61 -0
- package/dist/analysis/rebuild.d.ts.map +1 -0
- package/dist/analysis/terminal.d.ts +145 -0
- package/dist/analysis/terminal.d.ts.map +1 -0
- package/dist/cli/index.cjs +14837 -0
- package/dist/cli/index.cjs.map +6 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +14814 -0
- package/dist/cli/index.js.map +6 -0
- package/dist/combinators/adjacency.d.ts +100 -0
- package/dist/combinators/adjacency.d.ts.map +1 -0
- package/dist/combinators/choice.d.ts.map +1 -1
- package/dist/combinators/completions.d.ts.map +1 -1
- package/dist/combinators/dispatch.d.ts +8 -1
- package/dist/combinators/dispatch.d.ts.map +1 -1
- package/dist/combinators/expect.d.ts.map +1 -1
- package/dist/combinators/first-set.d.ts.map +1 -1
- package/dist/combinators/gate.d.ts.map +1 -1
- package/dist/combinators/grammar.d.ts +22 -0
- package/dist/combinators/grammar.d.ts.map +1 -1
- package/dist/combinators/literal.d.ts +8 -0
- package/dist/combinators/literal.d.ts.map +1 -1
- package/dist/combinators/map.d.ts +0 -1
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/node.d.ts +13 -3
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +1 -1
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/ref.d.ts.map +1 -1
- package/dist/combinators/regex.d.ts +1 -16
- package/dist/combinators/regex.d.ts.map +1 -1
- package/dist/combinators/repeat.d.ts +30 -2
- package/dist/combinators/repeat.d.ts.map +1 -1
- package/dist/combinators/scanTo.d.ts +71 -1
- package/dist/combinators/scanTo.d.ts.map +1 -1
- package/dist/combinators/sequence.d.ts.map +1 -1
- package/dist/combinators/token.d.ts.map +1 -1
- package/dist/combinators/trivia-boundary.d.ts +26 -0
- package/dist/combinators/trivia-boundary.d.ts.map +1 -0
- package/dist/combinators/trivia-skip.d.ts +40 -1
- package/dist/combinators/trivia-skip.d.ts.map +1 -1
- package/dist/combinators/withCtx.d.ts.map +1 -1
- package/dist/compiler/build-arity.d.ts.map +1 -1
- package/dist/compiler/compile-linkable-table.d.ts +104 -0
- package/dist/compiler/compile-linkable-table.d.ts.map +1 -0
- package/dist/compiler/degradation.d.ts +0 -2
- package/dist/compiler/degradation.d.ts.map +1 -1
- package/dist/compiler/fields.d.ts +13 -0
- package/dist/compiler/fields.d.ts.map +1 -1
- package/dist/compiler/grammar-coverage-ids.d.ts +5 -5
- package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +79 -47
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/compiler/token-alphabet.d.ts +81 -0
- package/dist/compiler/token-alphabet.d.ts.map +1 -0
- package/dist/compiler/token-dispatch.d.ts +95 -0
- package/dist/compiler/token-dispatch.d.ts.map +1 -0
- package/dist/compiler/token-scanner.d.ts +53 -0
- package/dist/compiler/token-scanner.d.ts.map +1 -0
- package/dist/compiler/value-usage.d.ts.map +1 -1
- package/dist/coverage.d.ts +1 -1
- package/dist/coverage.d.ts.map +1 -1
- package/dist/cst/capture-buffer.d.ts +35 -0
- package/dist/cst/capture-buffer.d.ts.map +1 -1
- package/dist/cst/reflection-attach.d.ts +8 -0
- package/dist/cst/reflection-attach.d.ts.map +1 -0
- package/dist/cst/reflection-symbols.d.ts +10 -0
- package/dist/cst/reflection-symbols.d.ts.map +1 -0
- package/dist/cst/reflection.d.ts +2 -4
- package/dist/cst/reflection.d.ts.map +1 -1
- package/dist/cst/root-trivia-scope.d.ts +26 -0
- package/dist/cst/root-trivia-scope.d.ts.map +1 -0
- package/dist/cst/trivia-charscan.d.ts +18 -0
- package/dist/cst/trivia-charscan.d.ts.map +1 -0
- package/dist/cst/trivia-kinds.d.ts +19 -0
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/functional/doc.d.ts.map +1 -1
- package/dist/functional/run-tabled.d.ts +12 -0
- package/dist/functional/run-tabled.d.ts.map +1 -0
- package/dist/functional/run.d.ts +25 -42
- package/dist/functional/run.d.ts.map +1 -1
- package/dist/grammar-metadata.d.ts +3 -0
- package/dist/grammar-metadata.d.ts.map +1 -0
- package/dist/index.cjs +10499 -7478
- package/dist/index.cjs.map +3 -4
- package/dist/index.d.ts +24 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10499 -7478
- package/dist/index.js.map +3 -4
- package/dist/language-service/index.cjs +311 -121
- package/dist/language-service/index.cjs.map +3 -4
- package/dist/language-service/index.js +311 -121
- package/dist/language-service/index.js.map +3 -4
- package/dist/oracle/index.cjs.map +0 -1
- package/dist/oracle/index.js.map +0 -1
- package/dist/parse-context.d.ts +49 -0
- package/dist/parse-context.d.ts.map +1 -0
- package/dist/plugin/evaluator.d.ts +41 -2
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/free-identifiers.d.ts +23 -0
- package/dist/plugin/free-identifiers.d.ts.map +1 -0
- package/dist/plugin/index.cjs +11381 -9442
- package/dist/plugin/index.cjs.map +3 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +11381 -9442
- package/dist/plugin/index.js.map +3 -4
- package/dist/plugin/reducer-resolver.d.ts +17 -1
- package/dist/plugin/reducer-resolver.d.ts.map +1 -1
- package/dist/regex/classes.d.ts +28 -0
- package/dist/regex/classes.d.ts.map +1 -1
- package/dist/regex/first-set.d.ts +14 -0
- package/dist/regex/first-set.d.ts.map +1 -1
- package/dist/run/index.cjs +136 -51
- package/dist/run/index.cjs.map +2 -3
- package/dist/run/index.js +136 -51
- package/dist/run/index.js.map +2 -3
- package/dist/spec/index.cjs +2898 -1622
- package/dist/spec/index.cjs.map +3 -4
- package/dist/spec/index.js +2898 -1622
- package/dist/spec/index.js.map +3 -4
- package/dist/spec/model.d.ts +8 -0
- package/dist/spec/model.d.ts.map +1 -1
- package/dist/table/assemble.d.ts +307 -0
- package/dist/table/assemble.d.ts.map +1 -0
- package/dist/table/cell.d.ts +42 -0
- package/dist/table/cell.d.ts.map +1 -0
- package/dist/table/child-slots.d.ts +30 -0
- package/dist/table/child-slots.d.ts.map +1 -0
- package/dist/table/compile-rule-map.d.ts +136 -0
- package/dist/table/compile-rule-map.d.ts.map +1 -0
- package/dist/table/compile.d.ts +56 -0
- package/dist/table/compile.d.ts.map +1 -0
- package/dist/table/duplication-hook.d.ts +32 -0
- package/dist/table/duplication-hook.d.ts.map +1 -0
- package/dist/table/emit-assembly.d.ts +139 -0
- package/dist/table/emit-assembly.d.ts.map +1 -0
- package/dist/table/emit.d.ts +113 -0
- package/dist/table/emit.d.ts.map +1 -0
- package/dist/table/encode-baseline.d.ts +16 -0
- package/dist/table/encode-baseline.d.ts.map +1 -0
- package/dist/table/encode.d.ts +71 -0
- package/dist/table/encode.d.ts.map +1 -0
- package/dist/table/exec-baseline.d.ts +9 -0
- package/dist/table/exec-baseline.d.ts.map +1 -0
- package/dist/table/exec.d.ts +72 -0
- package/dist/table/exec.d.ts.map +1 -0
- package/dist/table/fold.d.ts +25 -0
- package/dist/table/fold.d.ts.map +1 -0
- package/dist/table/index.cjs +11375 -0
- package/dist/table/index.cjs.map +6 -0
- package/dist/table/index.d.ts +100 -0
- package/dist/table/index.d.ts.map +1 -0
- package/dist/table/index.js +11352 -0
- package/dist/table/index.js.map +6 -0
- package/dist/table/inspect.d.ts +17 -0
- package/dist/table/inspect.d.ts.map +1 -0
- package/dist/table/ops.d.ts +446 -0
- package/dist/table/ops.d.ts.map +1 -0
- package/dist/table/program.d.ts +493 -0
- package/dist/table/program.d.ts.map +1 -0
- package/dist/table/run-support.d.ts +38 -0
- package/dist/table/run-support.d.ts.map +1 -0
- package/dist/{compiler/scannable-run.d.ts → table/scan-shapes.d.ts} +14 -13
- package/dist/table/scan-shapes.d.ts.map +1 -0
- package/dist/table/site-labels.d.ts +58 -0
- package/dist/table/site-labels.d.ts.map +1 -0
- package/dist/table/stamp.d.ts +70 -0
- package/dist/table/stamp.d.ts.map +1 -0
- package/dist/types.d.ts +80 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +41 -3
- package/src/analysis/choice-cost-gate.ts +359 -0
- package/src/analysis/choice-cost-render.ts +293 -0
- package/src/analysis/choice-cost.ts +1008 -0
- package/src/analysis/commitment.ts +557 -0
- package/src/analysis/corpus.ts +130 -0
- package/src/analysis/diagnose-render.ts +625 -0
- package/src/analysis/diagnose.ts +317 -0
- package/src/analysis/diagnostics.ts +33 -0
- package/src/analysis/duplication.ts +1955 -0
- package/src/analysis/fix-render.ts +217 -0
- package/src/analysis/fix.ts +669 -0
- package/src/analysis/format-number.ts +31 -0
- package/src/analysis/gating.ts +792 -0
- package/src/analysis/grammar.ts +72 -0
- package/src/analysis/rebuild.ts +287 -0
- package/src/analysis/terminal.ts +336 -0
- package/src/cli/index.ts +413 -0
- package/src/combinators/adjacency.ts +171 -0
- package/src/combinators/attempt.ts +41 -0
- package/src/combinators/case-fold.ts +90 -0
- package/src/combinators/choice.ts +466 -0
- package/src/combinators/completions.ts +64 -0
- package/src/combinators/dispatch.ts +358 -0
- package/src/combinators/expect.ts +159 -0
- package/src/combinators/first-set.ts +322 -0
- package/src/combinators/gate.ts +50 -0
- package/src/combinators/grammar.ts +272 -0
- package/src/combinators/keywords.ts +145 -0
- package/src/combinators/literal.ts +102 -0
- package/src/combinators/map.ts +106 -0
- package/src/combinators/node.ts +345 -0
- package/src/combinators/not.ts +55 -0
- package/src/combinators/parser.ts +266 -0
- package/src/combinators/peek.ts +63 -0
- package/src/combinators/probe.ts +25 -0
- package/src/combinators/ref.ts +109 -0
- package/src/combinators/regex.ts +170 -0
- package/src/combinators/repeat.ts +561 -0
- package/src/combinators/scanTo.ts +393 -0
- package/src/combinators/sequence.ts +221 -0
- package/src/combinators/token.ts +120 -0
- package/src/combinators/trivia-boundary.ts +48 -0
- package/src/combinators/trivia-skip.ts +821 -0
- package/src/combinators/withCtx.ts +45 -0
- package/src/compiler/build-arity.ts +330 -0
- package/src/compiler/compile-linkable-table.ts +209 -0
- package/src/compiler/degradation.ts +266 -0
- package/src/compiler/fields.ts +191 -0
- package/src/compiler/grammar-coverage-ids.ts +129 -0
- package/src/compiler/ir-serialize.ts +615 -0
- package/src/compiler/linker.ts +954 -0
- package/src/compiler/token-alphabet.ts +209 -0
- package/src/compiler/token-dispatch.ts +353 -0
- package/src/compiler/token-scanner.ts +318 -0
- package/src/compiler/value-usage.ts +147 -0
- package/src/coverage.ts +383 -0
- package/src/cst/capture-buffer.ts +297 -0
- package/src/cst/host-mode.ts +69 -0
- package/src/cst/reflection-attach.ts +11 -0
- package/src/cst/reflection-symbols.ts +9 -0
- package/src/cst/reflection.ts +149 -0
- package/src/cst/relative-spans.ts +207 -0
- package/src/cst/root-trivia-scope.ts +30 -0
- package/src/cst/trivia-charscan.ts +312 -0
- package/src/cst/trivia-entries.ts +285 -0
- package/src/cst/trivia-index.ts +131 -0
- package/src/cst/trivia-kinds.ts +358 -0
- package/src/cst/types.ts +76 -0
- package/src/cst/walk.ts +101 -0
- package/src/functional/doc.ts +959 -0
- package/src/functional/run-tabled.ts +153 -0
- package/src/functional/run.ts +558 -0
- package/src/grammar-metadata.ts +2 -0
- package/src/index.ts +189 -0
- package/src/language-service/index.ts +221 -0
- package/src/line-index.ts +131 -0
- package/src/oracle/digest.ts +620 -0
- package/src/oracle/index.ts +55 -0
- package/src/parse-context.ts +91 -0
- package/src/plugin/direct-builder-static.ts +102 -0
- package/src/plugin/evaluator.ts +1505 -0
- package/src/plugin/free-identifiers.ts +338 -0
- package/src/plugin/index.ts +2281 -0
- package/src/plugin/reducer-resolver.ts +606 -0
- package/src/recovery/scan.ts +155 -0
- package/src/regex/classes.ts +183 -0
- package/src/regex/first-set.ts +316 -0
- package/src/run/index.ts +31 -0
- package/src/spec/ebnf.ts +128 -0
- package/src/spec/index.ts +54 -0
- package/src/spec/model.ts +636 -0
- package/src/spec/railroad-lib.ts +559 -0
- package/src/spec/railroad.ts +256 -0
- package/src/table/assemble.ts +2994 -0
- package/src/table/cell.ts +42 -0
- package/src/table/child-slots.ts +113 -0
- package/src/table/compile-rule-map.ts +336 -0
- package/src/table/compile.ts +244 -0
- package/src/table/duplication-hook.ts +89 -0
- package/src/table/emit-assembly.ts +1766 -0
- package/src/table/emit.ts +418 -0
- package/src/table/encode-baseline.ts +340 -0
- package/src/table/encode.ts +1569 -0
- package/src/table/exec-baseline.ts +537 -0
- package/src/table/exec.ts +1672 -0
- package/src/table/fold.ts +38 -0
- package/src/table/index.ts +108 -0
- package/src/table/inspect.ts +52 -0
- package/src/table/ops.ts +459 -0
- package/src/table/program.ts +855 -0
- package/src/table/run-support.ts +66 -0
- package/src/table/scan-shapes.ts +1578 -0
- package/src/table/site-labels.ts +228 -0
- package/src/table/stamp.ts +229 -0
- package/src/types.ts +563 -0
- package/src/version.ts +16 -0
- package/dist/compiler/codegen.d.ts +0 -334
- package/dist/compiler/codegen.d.ts.map +0 -1
- package/dist/compiler/inline-build.d.ts +0 -11
- package/dist/compiler/inline-build.d.ts.map +0 -1
- package/dist/compiler/inline-callback.d.ts +0 -21
- package/dist/compiler/inline-callback.d.ts.map +0 -1
- package/dist/compiler/line-index.d.ts +0 -2
- package/dist/compiler/line-index.d.ts.map +0 -1
- package/dist/compiler/scannable-run.d.ts.map +0 -1
- package/dist/compiler/scannable-terminal.d.ts +0 -23
- package/dist/compiler/scannable-terminal.d.ts.map +0 -1
- package/dist/compiler/trivia-fast-path.d.ts +0 -38
- package/dist/compiler/trivia-fast-path.d.ts.map +0 -1
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { ParseContext } from './types.ts'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* THE canonical `ParseContext` literal — the only place in the runtime where one
|
|
5
|
+
* is constructed from scratch.
|
|
6
|
+
*
|
|
7
|
+
* `ctx` is threaded through every combinator call, so it is the single most
|
|
8
|
+
* megamorphism-sensitive object in the system: every `ctx.<field>` load in
|
|
9
|
+
* `choice`/`sequence`/`regex`/`node`/… is an inline cache keyed on its hidden
|
|
10
|
+
* class. Historically the entry points built `ctx` with CONDITIONAL SPREADS
|
|
11
|
+
* (`...(cond ? { x } : {})`), which is a shape hazard, not a cost-free idiom:
|
|
12
|
+
*
|
|
13
|
+
* - `run()` had SIX of them (root trivia, grammar trivia, scan-skip, capture
|
|
14
|
+
* mask, tolerant, instrumentation) — up to 2^6 distinct hidden classes for
|
|
15
|
+
* `ctx` across configurations, all landing on the same ICs.
|
|
16
|
+
* - Fields that appear only inside a spread are ABSENT from the map on the
|
|
17
|
+
* paths that don't take the branch. That is why `ctx._triviaLog = undefined`
|
|
18
|
+
* is not free there: it is a property ADD (a map transition), not a store.
|
|
19
|
+
* And it is why `delete ctx._triviaLog` is expensive on the paths where the
|
|
20
|
+
* field IS present: a transition to dictionary mode.
|
|
21
|
+
*
|
|
22
|
+
* Declaring every field unconditionally — `undefined` when unset — collapses
|
|
23
|
+
* that to ONE realised map. Clearing a field is then a plain in-object store to
|
|
24
|
+
* an existing slot on every path, so `delete` is never needed and neither
|
|
25
|
+
* operation can transition the map.
|
|
26
|
+
*
|
|
27
|
+
* This is safe because absence and `undefined` are already interchangeable
|
|
28
|
+
* throughout the runtime: every reader tests `!== undefined` or truthiness, and
|
|
29
|
+
* none uses `in`, `hasOwnProperty`, or `Object.keys` on a `ParseContext`.
|
|
30
|
+
* `recovery/scan.ts` already restores these exact fields by assigning the saved
|
|
31
|
+
* value, which is `undefined` when the field was absent.
|
|
32
|
+
*
|
|
33
|
+
* Callers assign what they need AFTER construction; because every slot already
|
|
34
|
+
* exists those are in-object stores, and the shape is preserved. Do NOT
|
|
35
|
+
* reintroduce a conditional spread, and do NOT add a field here without also
|
|
36
|
+
* declaring it on `ParseContext`.
|
|
37
|
+
*
|
|
38
|
+
* Key ORDER matters as much as the key set — two literals with the same keys in
|
|
39
|
+
* a different order are two different maps — which is why there is one literal
|
|
40
|
+
* and not one per call site. It follows the declaration order of `ParseContext`.
|
|
41
|
+
*/
|
|
42
|
+
export function createParseContext(): ParseContext {
|
|
43
|
+
return {
|
|
44
|
+
trivia: undefined,
|
|
45
|
+
scanSkip: undefined,
|
|
46
|
+
triviaKindLabels: undefined,
|
|
47
|
+
captureTrivia: undefined,
|
|
48
|
+
_triviaCaptureMask: undefined,
|
|
49
|
+
trackLines: false,
|
|
50
|
+
state: undefined,
|
|
51
|
+
build: undefined,
|
|
52
|
+
_errors: undefined,
|
|
53
|
+
_tolerant: undefined,
|
|
54
|
+
_sync: undefined,
|
|
55
|
+
_rec: undefined,
|
|
56
|
+
_fe: undefined,
|
|
57
|
+
_fx: undefined,
|
|
58
|
+
_fc: undefined,
|
|
59
|
+
_probe: undefined,
|
|
60
|
+
_cstChildren: undefined,
|
|
61
|
+
_cstLeaves: undefined,
|
|
62
|
+
_cstRawChildren: undefined,
|
|
63
|
+
_triviaLog: undefined,
|
|
64
|
+
_rootTriviaLog: undefined,
|
|
65
|
+
_rootTriviaKindIndex: undefined,
|
|
66
|
+
_rootTriviaStrictScopes: undefined,
|
|
67
|
+
_rootTriviaCapture: undefined,
|
|
68
|
+
_cstTriviaLog: undefined,
|
|
69
|
+
_fields: undefined,
|
|
70
|
+
_cstBuf: undefined,
|
|
71
|
+
_routed: undefined,
|
|
72
|
+
_lineStarts: undefined,
|
|
73
|
+
_lineIndex: undefined,
|
|
74
|
+
_lineScannedTo: undefined,
|
|
75
|
+
_grammarCoverage: undefined,
|
|
76
|
+
_grammarTrace: undefined,
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* A `ctx` for a THROWAWAY sub-parse that must not inherit or pollute any sink —
|
|
82
|
+
* the trailing-trivia probe in `run()`/`doc()`, the trivia-kind classifier, and
|
|
83
|
+
* the no-capture trivia parses in `trivia-skip`. Identical shape to
|
|
84
|
+
* `createParseContext()`; only `trackLines`/`state` are seeded.
|
|
85
|
+
*/
|
|
86
|
+
export function createDetachedParseContext(trackLines: boolean, state: unknown): ParseContext {
|
|
87
|
+
const ctx = createParseContext()
|
|
88
|
+
ctx.trackLines = trackLines
|
|
89
|
+
ctx.state = state
|
|
90
|
+
return ctx
|
|
91
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-time validation for a direct node builder that may cross a compiled
|
|
3
|
+
* artifact boundary. This module deliberately belongs to the macro plugin: the
|
|
4
|
+
* public parser/compiler runtime must not import Oxc or its platform bindings.
|
|
5
|
+
*/
|
|
6
|
+
import { parseSync } from 'oxc-parser'
|
|
7
|
+
|
|
8
|
+
const STATIC_BUILDER_GLOBALS = new Set([
|
|
9
|
+
'Array', 'Boolean', 'Date', 'JSON', 'Math', 'NaN', 'Number', 'Object', 'String',
|
|
10
|
+
'Infinity', 'parseFloat', 'parseInt', 'undefined',
|
|
11
|
+
])
|
|
12
|
+
|
|
13
|
+
type Ast = { type: string; [key: string]: unknown }
|
|
14
|
+
|
|
15
|
+
function astArray(value: unknown): Ast[] {
|
|
16
|
+
return Array.isArray(value) ? value as Ast[] : []
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function astChild(value: unknown): Ast | null {
|
|
20
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value)
|
|
21
|
+
? value as Ast
|
|
22
|
+
: null
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function unwrapCallbackExpression(node: Ast | undefined): Ast | undefined {
|
|
26
|
+
let current = node
|
|
27
|
+
while (current?.type === 'ParenthesizedExpression') current = astChild(current.expression) ?? undefined
|
|
28
|
+
return current
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Return lexical reads that cannot cross an artifact boundary. This is an Oxc
|
|
33
|
+
* AST binding check, never a source-text heuristic: property names and plain
|
|
34
|
+
* object keys are not lexical reads. The result becomes inert metadata on the
|
|
35
|
+
* macro-produced node and is enforced later by the runtime IR re-lowerer.
|
|
36
|
+
*/
|
|
37
|
+
export function directBuilderUnsupportedBindings(src: string): string[] {
|
|
38
|
+
let init: Ast | undefined
|
|
39
|
+
try {
|
|
40
|
+
const parsed = parseSync('parseman-direct-builder.ts', `const _direct = (${src})`)
|
|
41
|
+
if (parsed.errors.length > 0) return ['invalid callback source']
|
|
42
|
+
const program = parsed.program as unknown as Ast
|
|
43
|
+
const statement = (program.body as Ast[] | undefined)?.[0]
|
|
44
|
+
const declaration = (statement?.declarations as Ast[] | undefined)?.[0]
|
|
45
|
+
init = unwrapCallbackExpression(declaration?.init as Ast | undefined)
|
|
46
|
+
} catch {
|
|
47
|
+
return ['invalid callback source']
|
|
48
|
+
}
|
|
49
|
+
if (init?.type !== 'ArrowFunctionExpression' || !Array.isArray(init.params)) return ['unsupported callback shape']
|
|
50
|
+
const allowed = new Set(STATIC_BUILDER_GLOBALS)
|
|
51
|
+
for (const param of init.params as Ast[]) {
|
|
52
|
+
if (param.type !== 'Identifier' || typeof param.name !== 'string') return ['unsupported parameter pattern']
|
|
53
|
+
allowed.add(param.name)
|
|
54
|
+
}
|
|
55
|
+
const unsupported = new Set<string>()
|
|
56
|
+
const reportUnsupportedNode = (ast: Ast): void => { unsupported.add(`unsupported ${ast.type}`) }
|
|
57
|
+
const read = (ast: Ast, allowedNames: ReadonlySet<string>): void => {
|
|
58
|
+
if (typeof ast.name === 'string' && allowedNames.has(ast.name)) return
|
|
59
|
+
unsupported.add(typeof ast.name === 'string' ? ast.name : 'identifier')
|
|
60
|
+
}
|
|
61
|
+
const expression = (node: unknown, allowedNames: ReadonlySet<string>): void => {
|
|
62
|
+
const ast = astChild(node)
|
|
63
|
+
if (!ast) return
|
|
64
|
+
switch (ast.type) {
|
|
65
|
+
case 'Literal': return
|
|
66
|
+
case 'Identifier': read(ast, allowedNames); return
|
|
67
|
+
case 'ParenthesizedExpression': case 'ChainExpression': case 'TSAsExpression':
|
|
68
|
+
case 'TSTypeAssertion': case 'TSNonNullExpression': expression(ast.expression, allowedNames); return
|
|
69
|
+
case 'ArrayExpression': for (const element of astArray(ast.elements)) expression(element, allowedNames); return
|
|
70
|
+
case 'ObjectExpression':
|
|
71
|
+
for (const property of astArray(ast.properties)) {
|
|
72
|
+
if (property.type === 'SpreadElement') { expression(property.argument, allowedNames); continue }
|
|
73
|
+
if (property.type !== 'Property' || property.method === true || property.kind !== 'init') { reportUnsupportedNode(property); continue }
|
|
74
|
+
if (property.computed === true) expression(property.key, allowedNames)
|
|
75
|
+
expression(property.value, allowedNames)
|
|
76
|
+
}
|
|
77
|
+
return
|
|
78
|
+
case 'MemberExpression': expression(ast.object, allowedNames); if (ast.computed === true) expression(ast.property, allowedNames); return
|
|
79
|
+
case 'CallExpression': case 'NewExpression': expression(ast.callee, allowedNames); for (const argument of astArray(ast.arguments)) expression(argument, allowedNames); return
|
|
80
|
+
case 'UnaryExpression': case 'UpdateExpression': expression(ast.argument, allowedNames); return
|
|
81
|
+
case 'BinaryExpression': case 'LogicalExpression': case 'AssignmentExpression': expression(ast.left, allowedNames); expression(ast.right, allowedNames); return
|
|
82
|
+
case 'ConditionalExpression': expression(ast.test, allowedNames); expression(ast.consequent, allowedNames); expression(ast.alternate, allowedNames); return
|
|
83
|
+
case 'SequenceExpression': for (const value of astArray(ast.expressions)) expression(value, allowedNames); return
|
|
84
|
+
case 'TemplateLiteral': for (const value of astArray(ast.expressions)) expression(value, allowedNames); return
|
|
85
|
+
case 'SpreadElement': expression(ast.argument, allowedNames); return
|
|
86
|
+
case 'ArrowFunctionExpression': {
|
|
87
|
+
const nested = new Set(allowedNames)
|
|
88
|
+
for (const param of astArray(ast.params)) {
|
|
89
|
+
if (param.type !== 'Identifier' || typeof param.name !== 'string') { reportUnsupportedNode(param); continue }
|
|
90
|
+
nested.add(param.name)
|
|
91
|
+
}
|
|
92
|
+
if (astChild(ast.body)?.type === 'BlockStatement') { reportUnsupportedNode(astChild(ast.body)!); return }
|
|
93
|
+
expression(ast.body, nested)
|
|
94
|
+
return
|
|
95
|
+
}
|
|
96
|
+
default: reportUnsupportedNode(ast); return
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (astChild(init.body)?.type === 'BlockStatement') unsupported.add('unsupported BlockStatement')
|
|
100
|
+
else expression(init.body, allowed)
|
|
101
|
+
return [...unsupported]
|
|
102
|
+
}
|