parseman 0.42.1 → 0.43.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/combinators/node.d.ts +21 -7
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +17 -2
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +4 -0
- package/dist/compiler/codegen.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +6 -1
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts +24 -0
- package/dist/cst/reflection.d.ts.map +1 -0
- package/dist/cst/types.d.ts +2 -0
- package/dist/cst/types.d.ts.map +1 -1
- package/dist/cst/walk.d.ts +27 -62
- package/dist/cst/walk.d.ts.map +1 -1
- package/dist/index.cjs +227 -84
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +227 -84
- package/dist/index.js.map +4 -4
- package/dist/language-service/index.cjs +25 -33
- package/dist/language-service/index.cjs.map +4 -4
- package/dist/language-service/index.d.ts +1 -1
- package/dist/language-service/index.d.ts.map +1 -1
- package/dist/language-service/index.js +25 -33
- package/dist/language-service/index.js.map +4 -4
- package/dist/plugin/evaluator.d.ts +1 -0
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.cjs +323 -78
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +323 -78
- package/dist/plugin/index.js.map +4 -4
- package/dist/spec/index.cjs +107 -6
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +107 -6
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -121,7 +121,6 @@ __export(index_exports, {
|
|
|
121
121
|
trivia: () => trivia,
|
|
122
122
|
triviaEntries: () => triviaEntries,
|
|
123
123
|
triviaKindMask: () => triviaKindMask,
|
|
124
|
-
walk: () => walk,
|
|
125
124
|
when: () => when,
|
|
126
125
|
withCtx: () => withCtx,
|
|
127
126
|
word: () => word
|
|
@@ -2993,6 +2992,126 @@ function parse(combinator, input, opts = {}) {
|
|
|
2993
2992
|
return lineIndex ? annotateResultLines(withErrors, normalizeLineIndex(lineIndex)) : withErrors;
|
|
2994
2993
|
}
|
|
2995
2994
|
|
|
2995
|
+
// src/cst/reflection.ts
|
|
2996
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
2997
|
+
function childrenOf(def) {
|
|
2998
|
+
switch (def.tag) {
|
|
2999
|
+
case "sequence":
|
|
3000
|
+
case "choice":
|
|
3001
|
+
return def.parsers;
|
|
3002
|
+
case "dispatch":
|
|
3003
|
+
return [
|
|
3004
|
+
def.selector,
|
|
3005
|
+
...def.cases.map((c) => c.parser),
|
|
3006
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
3007
|
+
...def.otherwise ? [def.otherwise] : []
|
|
3008
|
+
];
|
|
3009
|
+
case "many":
|
|
3010
|
+
case "oneOrMore":
|
|
3011
|
+
case "optional":
|
|
3012
|
+
case "attempt":
|
|
3013
|
+
case "transform":
|
|
3014
|
+
case "trivia":
|
|
3015
|
+
case "token":
|
|
3016
|
+
case "leaf":
|
|
3017
|
+
case "label":
|
|
3018
|
+
case "field":
|
|
3019
|
+
case "not":
|
|
3020
|
+
case "peek":
|
|
3021
|
+
case "node":
|
|
3022
|
+
case "withCtx":
|
|
3023
|
+
case "recover":
|
|
3024
|
+
case "expect":
|
|
3025
|
+
return [def.parser];
|
|
3026
|
+
case "grammar":
|
|
3027
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
3028
|
+
case "sepBy":
|
|
3029
|
+
return [def.parser, def.separator];
|
|
3030
|
+
case "skip":
|
|
3031
|
+
return [def.main, def.skipped];
|
|
3032
|
+
case "scanTo":
|
|
3033
|
+
return [def.sentinel, ...def.skip];
|
|
3034
|
+
case "literal":
|
|
3035
|
+
case "regex":
|
|
3036
|
+
case "keywords":
|
|
3037
|
+
case "routed":
|
|
3038
|
+
case "guard":
|
|
3039
|
+
case "lazy":
|
|
3040
|
+
case "unknown":
|
|
3041
|
+
return [];
|
|
3042
|
+
}
|
|
3043
|
+
}
|
|
3044
|
+
function addNode(out, def) {
|
|
3045
|
+
if (def.type === void 0) return;
|
|
3046
|
+
const existing = out.get(def.type);
|
|
3047
|
+
if (existing === void 0) {
|
|
3048
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
3049
|
+
return;
|
|
3050
|
+
}
|
|
3051
|
+
if (def.tags === void 0) return;
|
|
3052
|
+
for (const tag of def.tags) {
|
|
3053
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
3057
|
+
if (seen.has(parser2)) return;
|
|
3058
|
+
seen.add(parser2);
|
|
3059
|
+
const def = parser2._def;
|
|
3060
|
+
if (def.tag === "lazy") {
|
|
3061
|
+
if (followLazy) {
|
|
3062
|
+
try {
|
|
3063
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
3064
|
+
} catch {
|
|
3065
|
+
}
|
|
3066
|
+
}
|
|
3067
|
+
return;
|
|
3068
|
+
}
|
|
3069
|
+
if (def.tag === "node") addNode(out, def);
|
|
3070
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
3071
|
+
}
|
|
3072
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
3073
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3074
|
+
const followLazy = opts?.followLazy !== false;
|
|
3075
|
+
for (const [, rule] of ruleMap) {
|
|
3076
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
3077
|
+
try {
|
|
3078
|
+
const resolved = rule._def.thunk();
|
|
3079
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
3080
|
+
} catch {
|
|
3081
|
+
}
|
|
3082
|
+
continue;
|
|
3083
|
+
}
|
|
3084
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
3085
|
+
}
|
|
3086
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3087
|
+
}
|
|
3088
|
+
function mergeGrammarReflections(reflections) {
|
|
3089
|
+
const byType = /* @__PURE__ */ new Map();
|
|
3090
|
+
for (const reflection of reflections) {
|
|
3091
|
+
for (const node2 of reflection.nodes) {
|
|
3092
|
+
const tags = byType.get(node2.type);
|
|
3093
|
+
if (tags === void 0) {
|
|
3094
|
+
byType.set(node2.type, [...node2.tags]);
|
|
3095
|
+
continue;
|
|
3096
|
+
}
|
|
3097
|
+
for (const tag of node2.tags) {
|
|
3098
|
+
if (!tags.includes(tag)) tags.push(tag);
|
|
3099
|
+
}
|
|
3100
|
+
}
|
|
3101
|
+
}
|
|
3102
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
3103
|
+
}
|
|
3104
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
3105
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
3106
|
+
return grammar;
|
|
3107
|
+
}
|
|
3108
|
+
function grammarReflectionOf(grammar) {
|
|
3109
|
+
return grammar[GRAMMAR_REFLECTION];
|
|
3110
|
+
}
|
|
3111
|
+
function grammarReflectionSource(reflection) {
|
|
3112
|
+
return `{ nodes: ${JSON.stringify(reflection.nodes)} }`;
|
|
3113
|
+
}
|
|
3114
|
+
|
|
2996
3115
|
// src/combinators/parser.ts
|
|
2997
3116
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2998
3117
|
function tagRule(r, key) {
|
|
@@ -3091,6 +3210,7 @@ function rules(a, b) {
|
|
|
3091
3210
|
enumerable: false,
|
|
3092
3211
|
configurable: true
|
|
3093
3212
|
});
|
|
3213
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
3094
3214
|
return cache;
|
|
3095
3215
|
}
|
|
3096
3216
|
|
|
@@ -3411,13 +3531,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3411
3531
|
const collapse = opts?.collapse === true;
|
|
3412
3532
|
const captureTrivia = opts?.captureTrivia === true;
|
|
3413
3533
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3534
|
+
const tags = opts?.tags;
|
|
3414
3535
|
if (unwrap && collapse) {
|
|
3415
3536
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
3416
3537
|
}
|
|
3417
3538
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
3418
3539
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
3419
3540
|
}
|
|
3420
|
-
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {} } : baseDef;
|
|
3541
|
+
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
3421
3542
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
3422
3543
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
3423
3544
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -3463,7 +3584,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3463
3584
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3464
3585
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3465
3586
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3466
|
-
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3587
|
+
const built = unwrap && children2.length === 1 ? unwrapChild(children2[0]) : collapse && children2.length === 1 ? children2[0] : !build && project === void 0 && ctx.build?._parsemanCstCollapse && children2.length === 1 && rawChildren.length === 1 && ctx.build._parsemanCstCollapse(nodeType, children2[0], children2, rawChildren) ? children2[0] : project !== void 0 ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : projectChild(children2, project, nodeType) : build ? cstOutput && ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, hostState, tags) : build(children2, fields, span, rawChildren, triviaLog, st) : ctx.build ? ctx.build(nodeType, children2, fields, span, rawChildren, triviaLog, st, tags) : { _tag: "node", type: nodeType, span: ctx.trackLines ? { ...span } : { start: r.span.start, end: r.span.end }, state: st ?? null, children: children2 };
|
|
3467
3588
|
const rawEntry = isCstChild(built) ? built : { _tag: "leaf", value: typeof built === "string" ? built : typeof built === "object" && built !== null ? input.slice(r.span.start, r.span.end) : "", span };
|
|
3468
3589
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3469
3590
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -3635,7 +3756,7 @@ function leaf(root, fn) {
|
|
|
3635
3756
|
}
|
|
3636
3757
|
|
|
3637
3758
|
// src/version.ts
|
|
3638
|
-
var PARSEMAN_VERSION = "0.
|
|
3759
|
+
var PARSEMAN_VERSION = "0.43.0";
|
|
3639
3760
|
|
|
3640
3761
|
// src/cst/host-mode.ts
|
|
3641
3762
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -3701,7 +3822,7 @@ var SUGGESTIONS = {
|
|
|
3701
3822
|
function classifyBroadArm(arm, resolve) {
|
|
3702
3823
|
const seen = /* @__PURE__ */ new Set();
|
|
3703
3824
|
const relabel = (inner, cause, detail) => ({ cause, detail, ...inner?.unresolvedExternal ? { unresolvedExternal: true } : {} });
|
|
3704
|
-
const
|
|
3825
|
+
const walk = (p) => {
|
|
3705
3826
|
if (seen.has(p)) return { cause: "ref-cycle", detail: "ref cycle" };
|
|
3706
3827
|
seen.add(p);
|
|
3707
3828
|
const d = p._def;
|
|
@@ -3715,7 +3836,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3715
3836
|
// peek() CARRIES its body's first-set, so it is only broad when the body is
|
|
3716
3837
|
// (or the body is nullable) — walk in for the real cause.
|
|
3717
3838
|
case "peek":
|
|
3718
|
-
return
|
|
3839
|
+
return walk(d.parser);
|
|
3719
3840
|
case "scanTo":
|
|
3720
3841
|
return { cause: "broad-recognizer", detail: "scanTo (any first char)" };
|
|
3721
3842
|
// `guard` (the `gate()` state predicate) has a genuinely-`any` first-set of
|
|
@@ -3729,7 +3850,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3729
3850
|
case "attempt":
|
|
3730
3851
|
case "withCtx":
|
|
3731
3852
|
case "recover":
|
|
3732
|
-
return
|
|
3853
|
+
return walk(d.parser);
|
|
3733
3854
|
case "lazy": {
|
|
3734
3855
|
const name = p._ruleName;
|
|
3735
3856
|
let target;
|
|
@@ -3741,13 +3862,13 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3741
3862
|
return { cause: "cross-artifact-ref", detail: `unresolved ref${name ? ` g.${name}` : ""}`, unresolvedExternal: name !== void 0 };
|
|
3742
3863
|
target = bound;
|
|
3743
3864
|
}
|
|
3744
|
-
const inner =
|
|
3865
|
+
const inner = walk(target);
|
|
3745
3866
|
if (name !== void 0) return inner ? relabel(inner, "cross-artifact-ref", `via ref g.${name} \u2192 ${inner.detail}`) : null;
|
|
3746
3867
|
return inner;
|
|
3747
3868
|
}
|
|
3748
3869
|
case "optional":
|
|
3749
3870
|
case "many": {
|
|
3750
|
-
const inner =
|
|
3871
|
+
const inner = walk(d.parser);
|
|
3751
3872
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3752
3873
|
}
|
|
3753
3874
|
case "oneOrMore":
|
|
@@ -3760,9 +3881,9 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3760
3881
|
case "node":
|
|
3761
3882
|
case "grammar":
|
|
3762
3883
|
case "expect":
|
|
3763
|
-
return
|
|
3884
|
+
return walk(d.parser);
|
|
3764
3885
|
case "skip":
|
|
3765
|
-
return
|
|
3886
|
+
return walk(d.main);
|
|
3766
3887
|
case "sequence": {
|
|
3767
3888
|
let sawNullablePrefix = false;
|
|
3768
3889
|
for (const t of d.parsers) {
|
|
@@ -3771,7 +3892,7 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3771
3892
|
continue;
|
|
3772
3893
|
}
|
|
3773
3894
|
if (isAny(firstSetOf(t, /* @__PURE__ */ new Set(), resolve))) {
|
|
3774
|
-
const inner =
|
|
3895
|
+
const inner = walk(t);
|
|
3775
3896
|
if (sawNullablePrefix)
|
|
3776
3897
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3777
3898
|
return inner ?? { cause: "broad-recognizer", detail: "sequence leading term is broad" };
|
|
@@ -3786,18 +3907,18 @@ function classifyBroadArm(arm, resolve) {
|
|
|
3786
3907
|
}
|
|
3787
3908
|
case "choice": {
|
|
3788
3909
|
for (const a of d.parsers) {
|
|
3789
|
-
const r =
|
|
3910
|
+
const r = walk(a);
|
|
3790
3911
|
if (r) return relabel(r, r.cause, `choice arm \u2192 ${r.detail}`);
|
|
3791
3912
|
}
|
|
3792
3913
|
return null;
|
|
3793
3914
|
}
|
|
3794
3915
|
case "dispatch":
|
|
3795
|
-
return
|
|
3916
|
+
return walk(d.selector);
|
|
3796
3917
|
default:
|
|
3797
3918
|
return { cause: "broad-recognizer", detail: `unmodeled construct (${d.tag})` };
|
|
3798
3919
|
}
|
|
3799
3920
|
};
|
|
3800
|
-
return
|
|
3921
|
+
return walk(arm) ?? { cause: "broad-recognizer", detail: "broad (cause not localized)" };
|
|
3801
3922
|
}
|
|
3802
3923
|
function peelToLeading(arm) {
|
|
3803
3924
|
let d = arm._def;
|
|
@@ -3999,7 +4120,7 @@ function formatGatingWarnings(report) {
|
|
|
3999
4120
|
|
|
4000
4121
|
// src/analysis/duplication.ts
|
|
4001
4122
|
var siteToString = (s) => s.path === "" ? s.rule : `${s.rule} \u203A ${s.path}`;
|
|
4002
|
-
function
|
|
4123
|
+
function childrenOf2(d) {
|
|
4003
4124
|
switch (d.tag) {
|
|
4004
4125
|
case "sequence":
|
|
4005
4126
|
case "choice":
|
|
@@ -4133,7 +4254,7 @@ function render(p, depth = 3) {
|
|
|
4133
4254
|
break;
|
|
4134
4255
|
}
|
|
4135
4256
|
if (depth <= 0) return `${d.tag}(\u2026)`;
|
|
4136
|
-
const kids =
|
|
4257
|
+
const kids = childrenOf2(d).map((k) => render(k, depth - 1));
|
|
4137
4258
|
switch (d.tag) {
|
|
4138
4259
|
case "sequence":
|
|
4139
4260
|
return `sequence(${kids.join(", ")})`;
|
|
@@ -4328,7 +4449,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4328
4449
|
if (hit !== void 0) return hit;
|
|
4329
4450
|
const d = p._def;
|
|
4330
4451
|
shapeCache.set(p, interner.hole);
|
|
4331
|
-
const kids =
|
|
4452
|
+
const kids = childrenOf2(d);
|
|
4332
4453
|
const id = interner.of(`${payloadKey(p, d)}|${kids.map(shapeOf).join(",")}`);
|
|
4333
4454
|
shapeCache.set(p, id);
|
|
4334
4455
|
return id;
|
|
@@ -4338,7 +4459,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4338
4459
|
if (hit !== void 0) return hit;
|
|
4339
4460
|
sizeCache.set(p, 1);
|
|
4340
4461
|
let n = 1;
|
|
4341
|
-
for (const k of
|
|
4462
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4342
4463
|
sizeCache.set(p, n);
|
|
4343
4464
|
return n;
|
|
4344
4465
|
};
|
|
@@ -4351,7 +4472,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4351
4472
|
visited.set(p, { p, d, site: here, shape: shapeOf(p), size: sizeOf(p), enclosingNode, enclosingReducer });
|
|
4352
4473
|
const inner = d.tag === "node" ? d.type ?? "(anonymous)" : enclosingNode;
|
|
4353
4474
|
const innerReducer = enclosingReducer || d.tag === "node" && (d.build !== void 0 || d.buildSrc !== void 0) || d.tag === "transform" || d.tag === "leaf";
|
|
4354
|
-
const kids =
|
|
4475
|
+
const kids = childrenOf2(d);
|
|
4355
4476
|
kids.forEach((k, i) => {
|
|
4356
4477
|
const seg = segment(d, i);
|
|
4357
4478
|
visit(k, here.rule, here.path === "" ? seg : `${here.path} \u203A ${seg}`, inner, innerReducer);
|
|
@@ -4411,7 +4532,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4411
4532
|
function markSubtree(p, into) {
|
|
4412
4533
|
if (into.has(p)) return;
|
|
4413
4534
|
into.add(p);
|
|
4414
|
-
for (const k of
|
|
4535
|
+
for (const k of childrenOf2(p._def)) markSubtree(k, into);
|
|
4415
4536
|
}
|
|
4416
4537
|
var stripMembers = (f) => {
|
|
4417
4538
|
const { _members, ...rest } = f;
|
|
@@ -4451,7 +4572,7 @@ function findNearDuplicates(visited, interner, shapeOf, minSize) {
|
|
|
4451
4572
|
if (hit !== void 0) return hit;
|
|
4452
4573
|
holeCache.set(p, []);
|
|
4453
4574
|
const d = p._def;
|
|
4454
|
-
const kids =
|
|
4575
|
+
const kids = childrenOf2(d);
|
|
4455
4576
|
const kidShapes = kids.map(shapeOf);
|
|
4456
4577
|
const payload = payloadKey(p, d);
|
|
4457
4578
|
const out2 = [];
|
|
@@ -4512,7 +4633,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4512
4633
|
let cur = [...members];
|
|
4513
4634
|
for (let guard2 = 0; guard2 < 64; guard2++) {
|
|
4514
4635
|
const d0 = cur[0]._def;
|
|
4515
|
-
const kidLists = cur.map((c) =>
|
|
4636
|
+
const kidLists = cur.map((c) => childrenOf2(c._def));
|
|
4516
4637
|
const arity = kidLists[0].length;
|
|
4517
4638
|
if (kidLists.some((k) => k.length !== arity) || arity === 0) break;
|
|
4518
4639
|
const diff = [];
|
|
@@ -4525,7 +4646,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4525
4646
|
path.push(i);
|
|
4526
4647
|
defs.push(d0);
|
|
4527
4648
|
cur = kidLists.map((k) => k[i]);
|
|
4528
|
-
const nextArity =
|
|
4649
|
+
const nextArity = childrenOf2(cur[0]._def).length;
|
|
4529
4650
|
const samePayload = cur.every((c) => payloadKey(c, c._def) === payloadKey(cur[0], cur[0]._def));
|
|
4530
4651
|
if (!samePayload || nextArity === 0) break;
|
|
4531
4652
|
}
|
|
@@ -4533,7 +4654,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4533
4654
|
let slotSize = 0;
|
|
4534
4655
|
const sizeOf = (p) => {
|
|
4535
4656
|
let n = 1;
|
|
4536
|
-
for (const k of
|
|
4657
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4537
4658
|
return n;
|
|
4538
4659
|
};
|
|
4539
4660
|
for (const c of cur) slotSize = Math.max(slotSize, sizeOf(c));
|
|
@@ -4542,7 +4663,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4542
4663
|
function renderWithHole(p, path, depth = 0) {
|
|
4543
4664
|
if (depth === path.length) return "\u2039slot\u203A";
|
|
4544
4665
|
const d = p._def;
|
|
4545
|
-
const kids =
|
|
4666
|
+
const kids = childrenOf2(d);
|
|
4546
4667
|
const idx = path[depth];
|
|
4547
4668
|
const parts = kids.map((k, i) => i === idx ? renderWithHole(k, path, depth + 1) : render(k, 2));
|
|
4548
4669
|
switch (d.tag) {
|
|
@@ -5000,7 +5121,7 @@ function capturesPositionally(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
5000
5121
|
seen.add(p);
|
|
5001
5122
|
const d = p._def;
|
|
5002
5123
|
if (d.tag === "field" || d.tag === "label") return true;
|
|
5003
|
-
for (const k of
|
|
5124
|
+
for (const k of childrenOf2(d)) if (capturesPositionally(k, seen)) return true;
|
|
5004
5125
|
return false;
|
|
5005
5126
|
}
|
|
5006
5127
|
function detectHandRolledSepBy(terms, shapeOf) {
|
|
@@ -5106,7 +5227,7 @@ function nestedNodeTypes(root, out, seen, isRoot) {
|
|
|
5106
5227
|
}
|
|
5107
5228
|
return;
|
|
5108
5229
|
}
|
|
5109
|
-
for (const k of
|
|
5230
|
+
for (const k of childrenOf2(d)) nestedNodeTypes(k, out, seen, false);
|
|
5110
5231
|
}
|
|
5111
5232
|
var MAX_LOST_TYPES = 8;
|
|
5112
5233
|
function findStructureLoss(visited, resolve) {
|
|
@@ -8293,7 +8414,7 @@ function routedNeedsContextBridge(p, ctx, seen = /* @__PURE__ */ new Set()) {
|
|
|
8293
8414
|
const d = p._def;
|
|
8294
8415
|
if (d.tag === "dispatch") return false;
|
|
8295
8416
|
if (d.tag === "withCtx") return parserUsesRouted2(d.parser);
|
|
8296
|
-
return
|
|
8417
|
+
return childrenOf3(d).some((child) => routedNeedsContextBridge(child, ctx, seen));
|
|
8297
8418
|
}
|
|
8298
8419
|
function armReplayInScope(arm, ctx) {
|
|
8299
8420
|
let p = arm;
|
|
@@ -9056,7 +9177,8 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
9056
9177
|
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
9057
9178
|
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
9058
9179
|
const buildExpr = structural ? `{ _tag: 'node', type: ${JSON.stringify(def.type)}, span: ${nodeSpanV}, state: ${stV} ?? null, children: ${chV} }` : mkType ? emitInlineMkNodeExpr(mkType, chV, rawV, nodeSpanV, tlV) : def.project !== void 0 ? emitNodeProjectExpr(def.type, def.project, chV) : `${buildRef(ctx)}[${buildIdx}](${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV})`;
|
|
9059
|
-
const
|
|
9180
|
+
const hostBuildArgs = `${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV}${def.tags !== void 0 && def.tags.length > 0 ? `, ${JSON.stringify(def.tags)}` : ""}`;
|
|
9181
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${hostBuildArgs})`;
|
|
9060
9182
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
9061
9183
|
const hostCollapseExpr = structural ? `_ctx.build !== undefined && _ctx.build._parsemanCstCollapse !== undefined && ${chV}.length === 1 && ${rawV}.length === 1 && _ctx.build._parsemanCstCollapse(${JSON.stringify(def.type)}, ${chV}[0], ${chV}, ${rawV}) ? ${chV}[0] : (${ndExpr})` : ndExpr;
|
|
9062
9184
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -9519,7 +9641,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9519
9641
|
return false;
|
|
9520
9642
|
}
|
|
9521
9643
|
}
|
|
9522
|
-
return
|
|
9644
|
+
return childrenOf3(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9523
9645
|
}
|
|
9524
9646
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9525
9647
|
if (seen.has(p)) return false;
|
|
@@ -9538,7 +9660,7 @@ function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9538
9660
|
case "dispatch":
|
|
9539
9661
|
return false;
|
|
9540
9662
|
default:
|
|
9541
|
-
return
|
|
9663
|
+
return childrenOf3(d).some((child) => parserUsesRouted2(child, seen));
|
|
9542
9664
|
}
|
|
9543
9665
|
}
|
|
9544
9666
|
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -9553,9 +9675,9 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9553
9675
|
return false;
|
|
9554
9676
|
}
|
|
9555
9677
|
}
|
|
9556
|
-
return
|
|
9678
|
+
return childrenOf3(d).some((child) => hasDirectBuildDef(child, seen));
|
|
9557
9679
|
}
|
|
9558
|
-
function
|
|
9680
|
+
function childrenOf3(def) {
|
|
9559
9681
|
switch (def.tag) {
|
|
9560
9682
|
case "sequence":
|
|
9561
9683
|
case "choice":
|
|
@@ -9630,7 +9752,7 @@ function subtreeSizes(roots) {
|
|
|
9630
9752
|
const def = p._def;
|
|
9631
9753
|
let s = 1;
|
|
9632
9754
|
if (def.tag !== "lazy") {
|
|
9633
|
-
for (const child of
|
|
9755
|
+
for (const child of childrenOf3(def)) s += child._def.tag === "lazy" ? 1 : sz(child);
|
|
9634
9756
|
}
|
|
9635
9757
|
sizes.set(p, s);
|
|
9636
9758
|
return s;
|
|
@@ -9651,7 +9773,7 @@ function subtreeSizes(roots) {
|
|
|
9651
9773
|
return;
|
|
9652
9774
|
}
|
|
9653
9775
|
sz(p);
|
|
9654
|
-
for (const child of
|
|
9776
|
+
for (const child of childrenOf3(def)) visit(child);
|
|
9655
9777
|
};
|
|
9656
9778
|
for (const root of roots) visit(root);
|
|
9657
9779
|
return sizes;
|
|
@@ -9661,7 +9783,7 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9661
9783
|
const recursive = /* @__PURE__ */ new Set();
|
|
9662
9784
|
const descended = /* @__PURE__ */ new Set();
|
|
9663
9785
|
const active = /* @__PURE__ */ new Set();
|
|
9664
|
-
function
|
|
9786
|
+
function walk(p) {
|
|
9665
9787
|
const def = p._def;
|
|
9666
9788
|
if (def.tag === "lazy") {
|
|
9667
9789
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
@@ -9678,17 +9800,17 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9678
9800
|
return;
|
|
9679
9801
|
}
|
|
9680
9802
|
active.add(p);
|
|
9681
|
-
|
|
9803
|
+
walk(resolved);
|
|
9682
9804
|
active.delete(p);
|
|
9683
9805
|
return;
|
|
9684
9806
|
}
|
|
9685
9807
|
if (isHoistableTag(def.tag)) {
|
|
9686
9808
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
9687
9809
|
}
|
|
9688
|
-
for (const child of
|
|
9810
|
+
for (const child of childrenOf3(def)) walk(child);
|
|
9689
9811
|
}
|
|
9690
9812
|
const rootsArr = [...roots];
|
|
9691
|
-
for (const root of rootsArr)
|
|
9813
|
+
for (const root of rootsArr) walk(root);
|
|
9692
9814
|
return { counts, recursive, sizes: subtreeSizes(rootsArr) };
|
|
9693
9815
|
}
|
|
9694
9816
|
function ruleDependencies(ruleMap) {
|
|
@@ -9698,7 +9820,7 @@ function ruleDependencies(ruleMap) {
|
|
|
9698
9820
|
for (const [name, comb] of ruleMap) {
|
|
9699
9821
|
const found = /* @__PURE__ */ new Set();
|
|
9700
9822
|
const seen = /* @__PURE__ */ new Set();
|
|
9701
|
-
const
|
|
9823
|
+
const walk = (p, isRoot) => {
|
|
9702
9824
|
const def = p._def;
|
|
9703
9825
|
const boundary = def.tag === "lazy" ? nameOf.get(p) ?? p._ruleName : nameOf.get(p);
|
|
9704
9826
|
if (!isRoot && boundary !== void 0) {
|
|
@@ -9714,12 +9836,12 @@ function ruleDependencies(ruleMap) {
|
|
|
9714
9836
|
} catch {
|
|
9715
9837
|
return;
|
|
9716
9838
|
}
|
|
9717
|
-
|
|
9839
|
+
walk(resolved, false);
|
|
9718
9840
|
return;
|
|
9719
9841
|
}
|
|
9720
|
-
for (const child of
|
|
9842
|
+
for (const child of childrenOf3(def)) walk(child, false);
|
|
9721
9843
|
};
|
|
9722
|
-
|
|
9844
|
+
walk(comb, true);
|
|
9723
9845
|
deps.set(name, [...found]);
|
|
9724
9846
|
}
|
|
9725
9847
|
return deps;
|
|
@@ -10064,6 +10186,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10064
10186
|
return false;
|
|
10065
10187
|
}
|
|
10066
10188
|
});
|
|
10189
|
+
const nodeMeta = new Map(ruleMap.map(([name, rule]) => [name, collectGrammarReflection([[name, rule]], { followLazy: false })]));
|
|
10067
10190
|
const ctx = {
|
|
10068
10191
|
vars: 0,
|
|
10069
10192
|
indent: 1,
|
|
@@ -10139,7 +10262,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10139
10262
|
scanExternal(resolved);
|
|
10140
10263
|
return;
|
|
10141
10264
|
}
|
|
10142
|
-
for (const child of
|
|
10265
|
+
for (const child of childrenOf3(def)) scanExternal(child);
|
|
10143
10266
|
};
|
|
10144
10267
|
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
10145
10268
|
}
|
|
@@ -10261,6 +10384,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10261
10384
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10262
10385
|
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
10263
10386
|
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs),
|
|
10387
|
+
nodeMeta,
|
|
10264
10388
|
mfFns: mfSrcs ? [] : ctx.mapFns,
|
|
10265
10389
|
buildFns: buildSrcs ? [] : ctx.buildFns
|
|
10266
10390
|
};
|
|
@@ -10281,7 +10405,7 @@ function hasExternalRuleRef(ruleMap) {
|
|
|
10281
10405
|
if (resolved === void 0) return p._ruleName !== void 0;
|
|
10282
10406
|
return visit(resolved);
|
|
10283
10407
|
}
|
|
10284
|
-
return
|
|
10408
|
+
return childrenOf3(def).some(visit);
|
|
10285
10409
|
};
|
|
10286
10410
|
return ruleMap.some(([, rule]) => visit(rule));
|
|
10287
10411
|
}
|
|
@@ -10303,7 +10427,7 @@ function hasSemanticReduction(roots, externalRefs) {
|
|
|
10303
10427
|
return true;
|
|
10304
10428
|
}
|
|
10305
10429
|
}
|
|
10306
|
-
return
|
|
10430
|
+
return childrenOf3(def).some(visit);
|
|
10307
10431
|
};
|
|
10308
10432
|
return roots.some(visit);
|
|
10309
10433
|
}
|
|
@@ -10376,7 +10500,7 @@ function withCtx(extra, combinator) {
|
|
|
10376
10500
|
}
|
|
10377
10501
|
|
|
10378
10502
|
// src/compiler/ir-serialize.ts
|
|
10379
|
-
function
|
|
10503
|
+
function childrenOf4(def) {
|
|
10380
10504
|
switch (def.tag) {
|
|
10381
10505
|
case "sequence":
|
|
10382
10506
|
case "choice":
|
|
@@ -10440,6 +10564,10 @@ function projectOpt(project) {
|
|
|
10440
10564
|
if (project === void 0) return void 0;
|
|
10441
10565
|
return `project: ${project}`;
|
|
10442
10566
|
}
|
|
10567
|
+
function tagsOpt(tags) {
|
|
10568
|
+
if (tags === void 0 || tags.length === 0) return void 0;
|
|
10569
|
+
return `tags: ${JSON.stringify(tags)}`;
|
|
10570
|
+
}
|
|
10443
10571
|
function matcherExpr(entry) {
|
|
10444
10572
|
switch (entry.kind) {
|
|
10445
10573
|
case "startsWith":
|
|
@@ -10653,7 +10781,7 @@ var Serializer = class {
|
|
|
10653
10781
|
if (target) this.assertNoRuleRef(target, seen);
|
|
10654
10782
|
return;
|
|
10655
10783
|
}
|
|
10656
|
-
for (const child of
|
|
10784
|
+
for (const child of childrenOf4(c._def)) this.assertNoRuleRef(child, seen);
|
|
10657
10785
|
}
|
|
10658
10786
|
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
10659
10787
|
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
@@ -10717,7 +10845,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10717
10845
|
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
10718
10846
|
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
10719
10847
|
active.add(c);
|
|
10720
|
-
for (const child of
|
|
10848
|
+
for (const child of childrenOf4(def)) this.analyze(child, active);
|
|
10721
10849
|
active.delete(c);
|
|
10722
10850
|
}
|
|
10723
10851
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -10834,12 +10962,14 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10834
10962
|
case "node": {
|
|
10835
10963
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
10836
10964
|
const projectEntry = projectOpt(def.project);
|
|
10965
|
+
const tagEntry = tagsOpt(def.tags);
|
|
10837
10966
|
const optEntries = [
|
|
10838
10967
|
...def.unwrap ? ["unwrap: true"] : [],
|
|
10839
10968
|
...def.collapse ? ["collapse: true"] : [],
|
|
10840
10969
|
...projectEntry === void 0 ? [] : [projectEntry],
|
|
10841
10970
|
...def.captureTrivia ? ["captureTrivia: true"] : [],
|
|
10842
|
-
...def.trailingTrivia ? ["trailingTrivia: true"] : []
|
|
10971
|
+
...def.trailingTrivia ? ["trailingTrivia: true"] : [],
|
|
10972
|
+
...tagEntry === void 0 ? [] : [tagEntry]
|
|
10843
10973
|
];
|
|
10844
10974
|
const opts = optEntries.length > 0 ? `, { ${optEntries.join(", ")} }` : "";
|
|
10845
10975
|
if (def.type === void 0) {
|
|
@@ -10887,15 +11017,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
10887
11017
|
}
|
|
10888
11018
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10889
11019
|
}
|
|
10890
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10891
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
11020
|
+
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
11021
|
+
return tags !== void 0 && tags.length > 0 ? { _tag: "node", type, tags, span: { ...span }, state: state ?? null, children: [...children2] } : { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10892
11022
|
}
|
|
10893
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
11023
|
+
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
10894
11024
|
if (typeof typeOrOptions === "string") {
|
|
10895
11025
|
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
10896
11026
|
}
|
|
10897
11027
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
10898
|
-
const
|
|
11028
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
11029
|
+
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
10899
11030
|
host._parsemanCstOutput = true;
|
|
10900
11031
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
10901
11032
|
return host;
|
|
@@ -10937,6 +11068,7 @@ function fusedBody(pieces) {
|
|
|
10937
11068
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
10938
11069
|
];
|
|
10939
11070
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
11071
|
+
const reflection = mergeGrammarReflections([...winner].map(([k, p]) => p.nodeMeta.get(k) ?? { nodes: [] }));
|
|
10940
11072
|
const { mode, elided } = hostModeOfPieces(pieces);
|
|
10941
11073
|
const rawBody = [
|
|
10942
11074
|
...lines,
|
|
@@ -10945,6 +11077,7 @@ function fusedBody(pieces) {
|
|
|
10945
11077
|
"}",
|
|
10946
11078
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_MODE.description)}), { value: ${JSON.stringify(mode)}, enumerable: false })`,
|
|
10947
11079
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_ELIDED.description)}), { value: ${JSON.stringify(elided)}, enumerable: false })`,
|
|
11080
|
+
`Object.defineProperty(_map, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`,
|
|
10948
11081
|
// …and on each rule FUNCTION, because `run(map.Rule, …)` is handed the rule, not the
|
|
10949
11082
|
// map, and would otherwise have nothing to check against. Done once at fuse time,
|
|
10950
11083
|
// before any rule has been called, so it costs nothing per parse.
|
|
@@ -12373,38 +12506,48 @@ function buildTriviaIndex(root, input = "", opts) {
|
|
|
12373
12506
|
}
|
|
12374
12507
|
|
|
12375
12508
|
// src/cst/walk.ts
|
|
12376
|
-
function
|
|
12377
|
-
|
|
12378
|
-
|
|
12379
|
-
|
|
12380
|
-
|
|
12381
|
-
|
|
12382
|
-
|
|
12383
|
-
|
|
12384
|
-
|
|
12385
|
-
|
|
12386
|
-
|
|
12387
|
-
|
|
12388
|
-
const
|
|
12389
|
-
|
|
12390
|
-
|
|
12391
|
-
|
|
12392
|
-
|
|
12393
|
-
|
|
12394
|
-
|
|
12395
|
-
|
|
12396
|
-
|
|
12397
|
-
|
|
12398
|
-
|
|
12399
|
-
|
|
12400
|
-
|
|
12401
|
-
|
|
12509
|
+
function isCombinator(value) {
|
|
12510
|
+
return !!value && typeof value === "object" && "_def" in value && "_meta" in value && typeof value.parse === "function";
|
|
12511
|
+
}
|
|
12512
|
+
function reflectionFor(grammar) {
|
|
12513
|
+
const stamped = grammarReflectionOf(grammar);
|
|
12514
|
+
if (stamped) return stamped;
|
|
12515
|
+
const entries = Object.entries(grammar).filter((entry) => isCombinator(entry[1]));
|
|
12516
|
+
return collectGrammarReflection(entries);
|
|
12517
|
+
}
|
|
12518
|
+
function createVisitor(grammar, spec) {
|
|
12519
|
+
const reflection = reflectionFor(grammar);
|
|
12520
|
+
const typeHandlers = spec.type;
|
|
12521
|
+
const tagSpec = spec.tag;
|
|
12522
|
+
const tagHandlersByType = /* @__PURE__ */ new Map();
|
|
12523
|
+
if (tagSpec !== void 0) {
|
|
12524
|
+
for (const node2 of reflection.nodes) {
|
|
12525
|
+
const handlers = [];
|
|
12526
|
+
for (const tag of node2.tags) {
|
|
12527
|
+
const handler = tagSpec[tag];
|
|
12528
|
+
if (handler) handlers.push(handler);
|
|
12529
|
+
}
|
|
12530
|
+
if (handlers.length > 0) tagHandlersByType.set(node2.type, handlers);
|
|
12531
|
+
}
|
|
12532
|
+
}
|
|
12533
|
+
return (root, ctx = void 0) => {
|
|
12534
|
+
const go = (node2, parent) => {
|
|
12535
|
+
const descend = spec.enter ? spec.enter(node2, parent, ctx) : void 0;
|
|
12536
|
+
if (node2._tag === "node" && node2.type !== void 0) {
|
|
12537
|
+
typeHandlers?.[node2.type]?.(node2, parent, ctx);
|
|
12538
|
+
const tagHandlers = tagHandlersByType.get(node2.type);
|
|
12539
|
+
if (tagHandlers !== void 0) {
|
|
12540
|
+
for (const handler of tagHandlers) handler(node2, parent, ctx);
|
|
12402
12541
|
}
|
|
12403
12542
|
}
|
|
12404
|
-
|
|
12405
|
-
|
|
12543
|
+
const children2 = node2.children;
|
|
12544
|
+
if (descend !== false && Array.isArray(children2)) {
|
|
12545
|
+
for (const child of children2) go(child, node2);
|
|
12546
|
+
}
|
|
12547
|
+
spec.leave?.(node2, parent, ctx);
|
|
12548
|
+
};
|
|
12549
|
+
go(root, null);
|
|
12406
12550
|
};
|
|
12407
|
-
return (node2) => api.visit(node2);
|
|
12408
12551
|
}
|
|
12409
12552
|
|
|
12410
12553
|
// src/cst/offset-model.ts
|