parseman 0.42.0 → 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 +23 -2
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/compiler/codegen.d.ts +6 -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 +7 -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 +375 -195
- 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 +375 -195
- 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 +654 -173
- package/dist/plugin/index.cjs.map +4 -4
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +654 -173
- package/dist/plugin/index.js.map +4 -4
- package/dist/spec/index.cjs +429 -313
- package/dist/spec/index.cjs.map +4 -4
- package/dist/spec/index.js +429 -313
- package/dist/spec/index.js.map +4 -4
- package/dist/types.d.ts +8 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/plugin/index.cjs
CHANGED
|
@@ -2777,6 +2777,191 @@ function markUnusedValues(root) {
|
|
|
2777
2777
|
visit(resolveRoot(root), true);
|
|
2778
2778
|
}
|
|
2779
2779
|
|
|
2780
|
+
// src/combinators/grammar.ts
|
|
2781
|
+
function annotateResultLines(result, index) {
|
|
2782
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
2783
|
+
const errors = annotated.errors;
|
|
2784
|
+
if (errors) {
|
|
2785
|
+
;
|
|
2786
|
+
annotated.errors = errors.map((error) => ({
|
|
2787
|
+
...error,
|
|
2788
|
+
span: annotateSpan(error.span, index)
|
|
2789
|
+
}));
|
|
2790
|
+
}
|
|
2791
|
+
return annotated;
|
|
2792
|
+
}
|
|
2793
|
+
function createParseLineContext(input, pos) {
|
|
2794
|
+
const lineIndex = createLineIndex();
|
|
2795
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
2796
|
+
return { lineIndex, lineScannedTo: pos };
|
|
2797
|
+
}
|
|
2798
|
+
function parser(opts, root) {
|
|
2799
|
+
const clearTrivia = opts.trivia === null;
|
|
2800
|
+
return {
|
|
2801
|
+
_tag: "grammar",
|
|
2802
|
+
_meta: root._meta,
|
|
2803
|
+
_def: {
|
|
2804
|
+
tag: "grammar",
|
|
2805
|
+
parser: root,
|
|
2806
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2807
|
+
clearTrivia,
|
|
2808
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2809
|
+
trackLines: opts.trackLines ?? false
|
|
2810
|
+
},
|
|
2811
|
+
parse(input, pos, _ctx) {
|
|
2812
|
+
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2813
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2814
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
2815
|
+
const ctx = {
|
|
2816
|
+
..._ctx,
|
|
2817
|
+
trackLines,
|
|
2818
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2819
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2820
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
2821
|
+
...clearTrivia ? {
|
|
2822
|
+
trivia: void 0,
|
|
2823
|
+
triviaKindLabels: void 0
|
|
2824
|
+
} : opts.trivia != null ? {
|
|
2825
|
+
trivia: opts.trivia,
|
|
2826
|
+
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
2827
|
+
} : {},
|
|
2828
|
+
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
2829
|
+
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
2830
|
+
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
2831
|
+
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2832
|
+
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2833
|
+
// (capture all).
|
|
2834
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2835
|
+
};
|
|
2836
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
2837
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
2838
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
2839
|
+
}
|
|
2840
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2841
|
+
}
|
|
2842
|
+
};
|
|
2843
|
+
}
|
|
2844
|
+
function noTrivia(root) {
|
|
2845
|
+
return parser({ trivia: null }, root);
|
|
2846
|
+
}
|
|
2847
|
+
|
|
2848
|
+
// src/cst/reflection.ts
|
|
2849
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
2850
|
+
function childrenOf(def) {
|
|
2851
|
+
switch (def.tag) {
|
|
2852
|
+
case "sequence":
|
|
2853
|
+
case "choice":
|
|
2854
|
+
return def.parsers;
|
|
2855
|
+
case "dispatch":
|
|
2856
|
+
return [
|
|
2857
|
+
def.selector,
|
|
2858
|
+
...def.cases.map((c) => c.parser),
|
|
2859
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
2860
|
+
...def.otherwise ? [def.otherwise] : []
|
|
2861
|
+
];
|
|
2862
|
+
case "many":
|
|
2863
|
+
case "oneOrMore":
|
|
2864
|
+
case "optional":
|
|
2865
|
+
case "attempt":
|
|
2866
|
+
case "transform":
|
|
2867
|
+
case "trivia":
|
|
2868
|
+
case "token":
|
|
2869
|
+
case "leaf":
|
|
2870
|
+
case "label":
|
|
2871
|
+
case "field":
|
|
2872
|
+
case "not":
|
|
2873
|
+
case "peek":
|
|
2874
|
+
case "node":
|
|
2875
|
+
case "withCtx":
|
|
2876
|
+
case "recover":
|
|
2877
|
+
case "expect":
|
|
2878
|
+
return [def.parser];
|
|
2879
|
+
case "grammar":
|
|
2880
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
2881
|
+
case "sepBy":
|
|
2882
|
+
return [def.parser, def.separator];
|
|
2883
|
+
case "skip":
|
|
2884
|
+
return [def.main, def.skipped];
|
|
2885
|
+
case "scanTo":
|
|
2886
|
+
return [def.sentinel, ...def.skip];
|
|
2887
|
+
case "literal":
|
|
2888
|
+
case "regex":
|
|
2889
|
+
case "keywords":
|
|
2890
|
+
case "routed":
|
|
2891
|
+
case "guard":
|
|
2892
|
+
case "lazy":
|
|
2893
|
+
case "unknown":
|
|
2894
|
+
return [];
|
|
2895
|
+
}
|
|
2896
|
+
}
|
|
2897
|
+
function addNode(out, def) {
|
|
2898
|
+
if (def.type === void 0) return;
|
|
2899
|
+
const existing = out.get(def.type);
|
|
2900
|
+
if (existing === void 0) {
|
|
2901
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
2902
|
+
return;
|
|
2903
|
+
}
|
|
2904
|
+
if (def.tags === void 0) return;
|
|
2905
|
+
for (const tag of def.tags) {
|
|
2906
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
2907
|
+
}
|
|
2908
|
+
}
|
|
2909
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
2910
|
+
if (seen.has(parser2)) return;
|
|
2911
|
+
seen.add(parser2);
|
|
2912
|
+
const def = parser2._def;
|
|
2913
|
+
if (def.tag === "lazy") {
|
|
2914
|
+
if (followLazy) {
|
|
2915
|
+
try {
|
|
2916
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
2917
|
+
} catch {
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
return;
|
|
2921
|
+
}
|
|
2922
|
+
if (def.tag === "node") addNode(out, def);
|
|
2923
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
2924
|
+
}
|
|
2925
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
2926
|
+
const byType = /* @__PURE__ */ new Map();
|
|
2927
|
+
const followLazy = opts?.followLazy !== false;
|
|
2928
|
+
for (const [, rule] of ruleMap) {
|
|
2929
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
2930
|
+
try {
|
|
2931
|
+
const resolved = rule._def.thunk();
|
|
2932
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
2933
|
+
} catch {
|
|
2934
|
+
}
|
|
2935
|
+
continue;
|
|
2936
|
+
}
|
|
2937
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
2938
|
+
}
|
|
2939
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
2940
|
+
}
|
|
2941
|
+
function mergeGrammarReflections(reflections) {
|
|
2942
|
+
const byType = /* @__PURE__ */ new Map();
|
|
2943
|
+
for (const reflection of reflections) {
|
|
2944
|
+
for (const node2 of reflection.nodes) {
|
|
2945
|
+
const tags = byType.get(node2.type);
|
|
2946
|
+
if (tags === void 0) {
|
|
2947
|
+
byType.set(node2.type, [...node2.tags]);
|
|
2948
|
+
continue;
|
|
2949
|
+
}
|
|
2950
|
+
for (const tag of node2.tags) {
|
|
2951
|
+
if (!tags.includes(tag)) tags.push(tag);
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2955
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
2956
|
+
}
|
|
2957
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
2958
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
2959
|
+
return grammar;
|
|
2960
|
+
}
|
|
2961
|
+
function grammarReflectionSource(reflection) {
|
|
2962
|
+
return `{ nodes: ${JSON.stringify(reflection.nodes)} }`;
|
|
2963
|
+
}
|
|
2964
|
+
|
|
2780
2965
|
// src/combinators/parser.ts
|
|
2781
2966
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2782
2967
|
function tagRule(r, key) {
|
|
@@ -2852,6 +3037,21 @@ function rules(a, b) {
|
|
|
2852
3037
|
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
2853
3038
|
}
|
|
2854
3039
|
}
|
|
3040
|
+
if (options?.trackLines === true) {
|
|
3041
|
+
for (const key of Object.keys(definitions)) {
|
|
3042
|
+
const rule = cache[key];
|
|
3043
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
3044
|
+
}
|
|
3045
|
+
for (const key of Object.keys(definitions)) {
|
|
3046
|
+
const rule = cache[key];
|
|
3047
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
3048
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
3049
|
+
tagRule(wrapped, key);
|
|
3050
|
+
wrapped._meta.grammarTrackLines = true;
|
|
3051
|
+
cache[key] = wrapped;
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
}
|
|
2855
3055
|
for (const key of Object.keys(definitions)) {
|
|
2856
3056
|
markUnusedValues(cache[key]);
|
|
2857
3057
|
}
|
|
@@ -2860,6 +3060,7 @@ function rules(a, b) {
|
|
|
2860
3060
|
enumerable: false,
|
|
2861
3061
|
configurable: true
|
|
2862
3062
|
});
|
|
3063
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
2863
3064
|
return cache;
|
|
2864
3065
|
}
|
|
2865
3066
|
|
|
@@ -3180,13 +3381,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3180
3381
|
const collapse = opts?.collapse === true;
|
|
3181
3382
|
const captureTrivia = opts?.captureTrivia === true;
|
|
3182
3383
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3384
|
+
const tags = opts?.tags;
|
|
3183
3385
|
if (unwrap && collapse) {
|
|
3184
3386
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
3185
3387
|
}
|
|
3186
3388
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
3187
3389
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
3188
3390
|
}
|
|
3189
|
-
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;
|
|
3391
|
+
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;
|
|
3190
3392
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
3191
3393
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
3192
3394
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -3232,7 +3434,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3232
3434
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3233
3435
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3234
3436
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3235
|
-
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 };
|
|
3437
|
+
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 };
|
|
3236
3438
|
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 };
|
|
3237
3439
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3238
3440
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -3308,74 +3510,6 @@ function field(name, combinator) {
|
|
|
3308
3510
|
};
|
|
3309
3511
|
}
|
|
3310
3512
|
|
|
3311
|
-
// src/combinators/grammar.ts
|
|
3312
|
-
function annotateResultLines(result, index) {
|
|
3313
|
-
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
3314
|
-
const errors = annotated.errors;
|
|
3315
|
-
if (errors) {
|
|
3316
|
-
;
|
|
3317
|
-
annotated.errors = errors.map((error) => ({
|
|
3318
|
-
...error,
|
|
3319
|
-
span: annotateSpan(error.span, index)
|
|
3320
|
-
}));
|
|
3321
|
-
}
|
|
3322
|
-
return annotated;
|
|
3323
|
-
}
|
|
3324
|
-
function createParseLineContext(input, pos) {
|
|
3325
|
-
const lineIndex = createLineIndex();
|
|
3326
|
-
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
3327
|
-
return { lineIndex, lineScannedTo: pos };
|
|
3328
|
-
}
|
|
3329
|
-
function parser(opts, root) {
|
|
3330
|
-
const clearTrivia = opts.trivia === null;
|
|
3331
|
-
return {
|
|
3332
|
-
_tag: "grammar",
|
|
3333
|
-
_meta: root._meta,
|
|
3334
|
-
_def: {
|
|
3335
|
-
tag: "grammar",
|
|
3336
|
-
parser: root,
|
|
3337
|
-
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
3338
|
-
clearTrivia,
|
|
3339
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
3340
|
-
trackLines: opts.trackLines ?? false
|
|
3341
|
-
},
|
|
3342
|
-
parse(input, pos, _ctx) {
|
|
3343
|
-
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
3344
|
-
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
3345
|
-
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
3346
|
-
const ctx = {
|
|
3347
|
-
..._ctx,
|
|
3348
|
-
trackLines,
|
|
3349
|
-
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
3350
|
-
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
3351
|
-
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3352
|
-
...clearTrivia ? {
|
|
3353
|
-
trivia: void 0,
|
|
3354
|
-
triviaKindLabels: void 0
|
|
3355
|
-
} : opts.trivia != null ? {
|
|
3356
|
-
trivia: opts.trivia,
|
|
3357
|
-
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
3358
|
-
} : {},
|
|
3359
|
-
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
3360
|
-
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
3361
|
-
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
3362
|
-
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
3363
|
-
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
3364
|
-
// (capture all).
|
|
3365
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3366
|
-
};
|
|
3367
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
3368
|
-
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
3369
|
-
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
3370
|
-
}
|
|
3371
|
-
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
3372
|
-
}
|
|
3373
|
-
};
|
|
3374
|
-
}
|
|
3375
|
-
function noTrivia(root) {
|
|
3376
|
-
return parser({ trivia: null }, root);
|
|
3377
|
-
}
|
|
3378
|
-
|
|
3379
3513
|
// src/combinators/token.ts
|
|
3380
3514
|
function token(root) {
|
|
3381
3515
|
const meta = {
|
|
@@ -3472,7 +3606,7 @@ function leaf(root, fn) {
|
|
|
3472
3606
|
}
|
|
3473
3607
|
|
|
3474
3608
|
// src/version.ts
|
|
3475
|
-
var PARSEMAN_VERSION = "0.
|
|
3609
|
+
var PARSEMAN_VERSION = "0.43.0";
|
|
3476
3610
|
|
|
3477
3611
|
// src/cst/host-mode.ts
|
|
3478
3612
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -3538,7 +3672,7 @@ var SUGGESTIONS = {
|
|
|
3538
3672
|
function classifyBroadArm(arm, resolve2) {
|
|
3539
3673
|
const seen = /* @__PURE__ */ new Set();
|
|
3540
3674
|
const relabel = (inner, cause, detail) => ({ cause, detail, ...inner?.unresolvedExternal ? { unresolvedExternal: true } : {} });
|
|
3541
|
-
const
|
|
3675
|
+
const walk = (p) => {
|
|
3542
3676
|
if (seen.has(p)) return { cause: "ref-cycle", detail: "ref cycle" };
|
|
3543
3677
|
seen.add(p);
|
|
3544
3678
|
const d = p._def;
|
|
@@ -3552,7 +3686,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3552
3686
|
// peek() CARRIES its body's first-set, so it is only broad when the body is
|
|
3553
3687
|
// (or the body is nullable) — walk in for the real cause.
|
|
3554
3688
|
case "peek":
|
|
3555
|
-
return
|
|
3689
|
+
return walk(d.parser);
|
|
3556
3690
|
case "scanTo":
|
|
3557
3691
|
return { cause: "broad-recognizer", detail: "scanTo (any first char)" };
|
|
3558
3692
|
// `guard` (the `gate()` state predicate) has a genuinely-`any` first-set of
|
|
@@ -3566,7 +3700,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3566
3700
|
case "attempt":
|
|
3567
3701
|
case "withCtx":
|
|
3568
3702
|
case "recover":
|
|
3569
|
-
return
|
|
3703
|
+
return walk(d.parser);
|
|
3570
3704
|
case "lazy": {
|
|
3571
3705
|
const name = p._ruleName;
|
|
3572
3706
|
let target;
|
|
@@ -3578,13 +3712,13 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3578
3712
|
return { cause: "cross-artifact-ref", detail: `unresolved ref${name ? ` g.${name}` : ""}`, unresolvedExternal: name !== void 0 };
|
|
3579
3713
|
target = bound;
|
|
3580
3714
|
}
|
|
3581
|
-
const inner =
|
|
3715
|
+
const inner = walk(target);
|
|
3582
3716
|
if (name !== void 0) return inner ? relabel(inner, "cross-artifact-ref", `via ref g.${name} \u2192 ${inner.detail}`) : null;
|
|
3583
3717
|
return inner;
|
|
3584
3718
|
}
|
|
3585
3719
|
case "optional":
|
|
3586
3720
|
case "many": {
|
|
3587
|
-
const inner =
|
|
3721
|
+
const inner = walk(d.parser);
|
|
3588
3722
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3589
3723
|
}
|
|
3590
3724
|
case "oneOrMore":
|
|
@@ -3597,9 +3731,9 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3597
3731
|
case "node":
|
|
3598
3732
|
case "grammar":
|
|
3599
3733
|
case "expect":
|
|
3600
|
-
return
|
|
3734
|
+
return walk(d.parser);
|
|
3601
3735
|
case "skip":
|
|
3602
|
-
return
|
|
3736
|
+
return walk(d.main);
|
|
3603
3737
|
case "sequence": {
|
|
3604
3738
|
let sawNullablePrefix = false;
|
|
3605
3739
|
for (const t of d.parsers) {
|
|
@@ -3608,7 +3742,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3608
3742
|
continue;
|
|
3609
3743
|
}
|
|
3610
3744
|
if (isAny(firstSetOf(t, /* @__PURE__ */ new Set(), resolve2))) {
|
|
3611
|
-
const inner =
|
|
3745
|
+
const inner = walk(t);
|
|
3612
3746
|
if (sawNullablePrefix)
|
|
3613
3747
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3614
3748
|
return inner ?? { cause: "broad-recognizer", detail: "sequence leading term is broad" };
|
|
@@ -3623,18 +3757,18 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3623
3757
|
}
|
|
3624
3758
|
case "choice": {
|
|
3625
3759
|
for (const a of d.parsers) {
|
|
3626
|
-
const r =
|
|
3760
|
+
const r = walk(a);
|
|
3627
3761
|
if (r) return relabel(r, r.cause, `choice arm \u2192 ${r.detail}`);
|
|
3628
3762
|
}
|
|
3629
3763
|
return null;
|
|
3630
3764
|
}
|
|
3631
3765
|
case "dispatch":
|
|
3632
|
-
return
|
|
3766
|
+
return walk(d.selector);
|
|
3633
3767
|
default:
|
|
3634
3768
|
return { cause: "broad-recognizer", detail: `unmodeled construct (${d.tag})` };
|
|
3635
3769
|
}
|
|
3636
3770
|
};
|
|
3637
|
-
return
|
|
3771
|
+
return walk(arm) ?? { cause: "broad-recognizer", detail: "broad (cause not localized)" };
|
|
3638
3772
|
}
|
|
3639
3773
|
function peelToLeading(arm) {
|
|
3640
3774
|
let d = arm._def;
|
|
@@ -3836,7 +3970,7 @@ function formatGatingWarnings(report) {
|
|
|
3836
3970
|
|
|
3837
3971
|
// src/analysis/duplication.ts
|
|
3838
3972
|
var siteToString = (s) => s.path === "" ? s.rule : `${s.rule} \u203A ${s.path}`;
|
|
3839
|
-
function
|
|
3973
|
+
function childrenOf2(d) {
|
|
3840
3974
|
switch (d.tag) {
|
|
3841
3975
|
case "sequence":
|
|
3842
3976
|
case "choice":
|
|
@@ -3970,7 +4104,7 @@ function render(p, depth = 3) {
|
|
|
3970
4104
|
break;
|
|
3971
4105
|
}
|
|
3972
4106
|
if (depth <= 0) return `${d.tag}(\u2026)`;
|
|
3973
|
-
const kids =
|
|
4107
|
+
const kids = childrenOf2(d).map((k) => render(k, depth - 1));
|
|
3974
4108
|
switch (d.tag) {
|
|
3975
4109
|
case "sequence":
|
|
3976
4110
|
return `sequence(${kids.join(", ")})`;
|
|
@@ -4165,7 +4299,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4165
4299
|
if (hit !== void 0) return hit;
|
|
4166
4300
|
const d = p._def;
|
|
4167
4301
|
shapeCache.set(p, interner.hole);
|
|
4168
|
-
const kids =
|
|
4302
|
+
const kids = childrenOf2(d);
|
|
4169
4303
|
const id = interner.of(`${payloadKey(p, d)}|${kids.map(shapeOf).join(",")}`);
|
|
4170
4304
|
shapeCache.set(p, id);
|
|
4171
4305
|
return id;
|
|
@@ -4175,7 +4309,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4175
4309
|
if (hit !== void 0) return hit;
|
|
4176
4310
|
sizeCache.set(p, 1);
|
|
4177
4311
|
let n = 1;
|
|
4178
|
-
for (const k of
|
|
4312
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4179
4313
|
sizeCache.set(p, n);
|
|
4180
4314
|
return n;
|
|
4181
4315
|
};
|
|
@@ -4188,7 +4322,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4188
4322
|
visited.set(p, { p, d, site: here, shape: shapeOf(p), size: sizeOf(p), enclosingNode, enclosingReducer });
|
|
4189
4323
|
const inner = d.tag === "node" ? d.type ?? "(anonymous)" : enclosingNode;
|
|
4190
4324
|
const innerReducer = enclosingReducer || d.tag === "node" && (d.build !== void 0 || d.buildSrc !== void 0) || d.tag === "transform" || d.tag === "leaf";
|
|
4191
|
-
const kids =
|
|
4325
|
+
const kids = childrenOf2(d);
|
|
4192
4326
|
kids.forEach((k, i) => {
|
|
4193
4327
|
const seg = segment(d, i);
|
|
4194
4328
|
visit(k, here.rule, here.path === "" ? seg : `${here.path} \u203A ${seg}`, inner, innerReducer);
|
|
@@ -4248,7 +4382,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4248
4382
|
function markSubtree(p, into) {
|
|
4249
4383
|
if (into.has(p)) return;
|
|
4250
4384
|
into.add(p);
|
|
4251
|
-
for (const k of
|
|
4385
|
+
for (const k of childrenOf2(p._def)) markSubtree(k, into);
|
|
4252
4386
|
}
|
|
4253
4387
|
var stripMembers = (f) => {
|
|
4254
4388
|
const { _members, ...rest } = f;
|
|
@@ -4288,7 +4422,7 @@ function findNearDuplicates(visited, interner, shapeOf, minSize) {
|
|
|
4288
4422
|
if (hit !== void 0) return hit;
|
|
4289
4423
|
holeCache.set(p, []);
|
|
4290
4424
|
const d = p._def;
|
|
4291
|
-
const kids =
|
|
4425
|
+
const kids = childrenOf2(d);
|
|
4292
4426
|
const kidShapes = kids.map(shapeOf);
|
|
4293
4427
|
const payload = payloadKey(p, d);
|
|
4294
4428
|
const out2 = [];
|
|
@@ -4349,7 +4483,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4349
4483
|
let cur = [...members];
|
|
4350
4484
|
for (let guard2 = 0; guard2 < 64; guard2++) {
|
|
4351
4485
|
const d0 = cur[0]._def;
|
|
4352
|
-
const kidLists = cur.map((c) =>
|
|
4486
|
+
const kidLists = cur.map((c) => childrenOf2(c._def));
|
|
4353
4487
|
const arity = kidLists[0].length;
|
|
4354
4488
|
if (kidLists.some((k) => k.length !== arity) || arity === 0) break;
|
|
4355
4489
|
const diff = [];
|
|
@@ -4362,7 +4496,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4362
4496
|
path2.push(i);
|
|
4363
4497
|
defs.push(d0);
|
|
4364
4498
|
cur = kidLists.map((k) => k[i]);
|
|
4365
|
-
const nextArity =
|
|
4499
|
+
const nextArity = childrenOf2(cur[0]._def).length;
|
|
4366
4500
|
const samePayload = cur.every((c) => payloadKey(c, c._def) === payloadKey(cur[0], cur[0]._def));
|
|
4367
4501
|
if (!samePayload || nextArity === 0) break;
|
|
4368
4502
|
}
|
|
@@ -4370,7 +4504,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4370
4504
|
let slotSize = 0;
|
|
4371
4505
|
const sizeOf = (p) => {
|
|
4372
4506
|
let n = 1;
|
|
4373
|
-
for (const k of
|
|
4507
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4374
4508
|
return n;
|
|
4375
4509
|
};
|
|
4376
4510
|
for (const c of cur) slotSize = Math.max(slotSize, sizeOf(c));
|
|
@@ -4379,7 +4513,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4379
4513
|
function renderWithHole(p, path2, depth = 0) {
|
|
4380
4514
|
if (depth === path2.length) return "\u2039slot\u203A";
|
|
4381
4515
|
const d = p._def;
|
|
4382
|
-
const kids =
|
|
4516
|
+
const kids = childrenOf2(d);
|
|
4383
4517
|
const idx = path2[depth];
|
|
4384
4518
|
const parts = kids.map((k, i) => i === idx ? renderWithHole(k, path2, depth + 1) : render(k, 2));
|
|
4385
4519
|
switch (d.tag) {
|
|
@@ -4837,7 +4971,7 @@ function capturesPositionally(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4837
4971
|
seen.add(p);
|
|
4838
4972
|
const d = p._def;
|
|
4839
4973
|
if (d.tag === "field" || d.tag === "label") return true;
|
|
4840
|
-
for (const k of
|
|
4974
|
+
for (const k of childrenOf2(d)) if (capturesPositionally(k, seen)) return true;
|
|
4841
4975
|
return false;
|
|
4842
4976
|
}
|
|
4843
4977
|
function detectHandRolledSepBy(terms, shapeOf) {
|
|
@@ -4943,7 +5077,7 @@ function nestedNodeTypes(root, out, seen, isRoot) {
|
|
|
4943
5077
|
}
|
|
4944
5078
|
return;
|
|
4945
5079
|
}
|
|
4946
|
-
for (const k of
|
|
5080
|
+
for (const k of childrenOf2(d)) nestedNodeTypes(k, out, seen, false);
|
|
4947
5081
|
}
|
|
4948
5082
|
var MAX_LOST_TYPES = 8;
|
|
4949
5083
|
function findStructureLoss(visited, resolve2) {
|
|
@@ -6840,13 +6974,16 @@ function reindentStmts(stmts, targetLevels) {
|
|
|
6840
6974
|
const targetPrefix = " ".repeat(targetLevels);
|
|
6841
6975
|
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
6842
6976
|
}
|
|
6843
|
-
function failReturn(expected, posExpr) {
|
|
6977
|
+
function failReturn(ctx, expected, posExpr) {
|
|
6978
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [${expected}], span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6844
6979
|
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6845
6980
|
}
|
|
6846
|
-
function failReturnArr(expectedArr, posExpr) {
|
|
6981
|
+
function failReturnArr(ctx, expectedArr, posExpr) {
|
|
6982
|
+
if (ctx.lineTracking) return `return { ok: false, expected: ${expectedArr}, span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6847
6983
|
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6848
6984
|
}
|
|
6849
|
-
function committedReturnArr(expectedArr, posExpr) {
|
|
6985
|
+
function committedReturnArr(ctx, expectedArr, posExpr) {
|
|
6986
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [...${expectedArr}], span: ${emitSpanExpr(ctx, posExpr, posExpr)}, committed: true }`;
|
|
6850
6987
|
return `return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} }, committed: true }`;
|
|
6851
6988
|
}
|
|
6852
6989
|
function hoistExpected(ctx, constArrSource) {
|
|
@@ -6871,7 +7008,7 @@ function failBody(ctx, expected, posExpr) {
|
|
|
6871
7008
|
if (!ctx.recordFail) return probe ? `{ ${probe}${trace}break ${ctx.failLabel} }` : trace ? `{ ${trace}break ${ctx.failLabel} }` : `break ${ctx.failLabel}`;
|
|
6872
7009
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${hoistExpected(ctx, `[${expected}]`)}; ${trace}break ${ctx.failLabel} }`;
|
|
6873
7010
|
}
|
|
6874
|
-
return probe + trace + failReturn(expected, posExpr);
|
|
7011
|
+
return probe + trace + failReturn(ctx, expected, posExpr);
|
|
6875
7012
|
}
|
|
6876
7013
|
function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
6877
7014
|
const probe = probeUpdate(ctx, expectedArr, posExpr, constant);
|
|
@@ -6881,18 +7018,19 @@ function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
|
6881
7018
|
const fx = constant ? hoistExpected(ctx, expectedArr) : expectedArr;
|
|
6882
7019
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${fx}; ${trace}break ${ctx.failLabel} }`;
|
|
6883
7020
|
}
|
|
6884
|
-
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6885
|
-
return probe + trace + failReturnArr(expectedArr, posExpr);
|
|
7021
|
+
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: ${ctx.lineTracking ? emitSpanExpr(ctx, posExpr, posExpr) : `{ start: ${posExpr}, end: ${posExpr} }`} }`;
|
|
7022
|
+
return probe + trace + failReturnArr(ctx, expectedArr, posExpr);
|
|
6886
7023
|
}
|
|
6887
|
-
function resultFromRecorded(feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6888
|
-
|
|
7024
|
+
function resultFromRecorded(ctx, feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
7025
|
+
const spanExpr = ctx.lineTracking ? emitSpanExpr(ctx, feExpr, feExpr) : `{ start: ${feExpr}, end: ${feExpr} }`;
|
|
7026
|
+
return `return { ok: false, expected: [...${fxExpr}], span: ${spanExpr}, ...(_ctx._fc ? { committed: true } : {}) }`;
|
|
6889
7027
|
}
|
|
6890
7028
|
function committedFailBody(ctx, expectedArr = "_ctx._fx", posExpr = "_ctx._fe") {
|
|
6891
7029
|
if (ctx.failLabel) {
|
|
6892
7030
|
if (!ctx.recordFail) return `{ _ctx._fc = true; break ${ctx.failLabel} }`;
|
|
6893
7031
|
return `{ _ctx._fc = true; _ctx._fe = ${posExpr}; _ctx._fx = ${expectedArr}; break ${ctx.failLabel} }`;
|
|
6894
7032
|
}
|
|
6895
|
-
return committedReturnArr(expectedArr, posExpr);
|
|
7033
|
+
return committedReturnArr(ctx, expectedArr, posExpr);
|
|
6896
7034
|
}
|
|
6897
7035
|
function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
6898
7036
|
if (srcCtx !== "_ctx") {
|
|
@@ -6900,10 +7038,10 @@ function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
|
6900
7038
|
if (!ctx.recordFail) return `break ${ctx.failLabel}`;
|
|
6901
7039
|
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; break ${ctx.failLabel} }`;
|
|
6902
7040
|
}
|
|
6903
|
-
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded()} }`;
|
|
7041
|
+
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded(ctx)} }`;
|
|
6904
7042
|
}
|
|
6905
7043
|
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
6906
|
-
return resultFromRecorded();
|
|
7044
|
+
return resultFromRecorded(ctx);
|
|
6907
7045
|
}
|
|
6908
7046
|
function emitIfFail(ctx, cond, body) {
|
|
6909
7047
|
return [
|
|
@@ -8134,7 +8272,7 @@ function routedNeedsContextBridge(p, ctx, seen = /* @__PURE__ */ new Set()) {
|
|
|
8134
8272
|
const d = p._def;
|
|
8135
8273
|
if (d.tag === "dispatch") return false;
|
|
8136
8274
|
if (d.tag === "withCtx") return parserUsesRouted2(d.parser);
|
|
8137
|
-
return
|
|
8275
|
+
return childrenOf3(d).some((child) => routedNeedsContextBridge(child, ctx, seen));
|
|
8138
8276
|
}
|
|
8139
8277
|
function armReplayInScope(arm, ctx) {
|
|
8140
8278
|
let p = arm;
|
|
@@ -8336,7 +8474,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8336
8474
|
if (!ctx.recovery && !ctx.coverage && needsFirstSetGuard(def.parser)) {
|
|
8337
8475
|
const gcV = v(ctx, "_agc");
|
|
8338
8476
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8339
|
-
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(gExp, pos)} }`;
|
|
8477
|
+
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(ctx, gExp, pos)} }`;
|
|
8340
8478
|
preGuard.push(
|
|
8341
8479
|
`${ind(ctx)}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8342
8480
|
`${ind(ctx)}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8835,7 +8973,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8835
8973
|
if (!ctx.recovery && !ctx.coverage && (capturesChildren || structural) && needsFirstSetGuard(def.parser)) {
|
|
8836
8974
|
const gcV = v(ctx, "_ngc");
|
|
8837
8975
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8838
|
-
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(gExp, pos);
|
|
8976
|
+
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(ctx, gExp, pos);
|
|
8839
8977
|
preGuard.push(
|
|
8840
8978
|
`${i}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8841
8979
|
`${i}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8897,7 +9035,8 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8897
9035
|
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
8898
9036
|
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
8899
9037
|
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})`;
|
|
8900
|
-
const
|
|
9038
|
+
const hostBuildArgs = `${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV}${def.tags !== void 0 && def.tags.length > 0 ? `, ${JSON.stringify(def.tags)}` : ""}`;
|
|
9039
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${hostBuildArgs})`;
|
|
8901
9040
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8902
9041
|
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;
|
|
8903
9042
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -9351,6 +9490,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9351
9490
|
if (seen.has(p)) return false;
|
|
9352
9491
|
seen.add(p);
|
|
9353
9492
|
const d = p._def;
|
|
9493
|
+
if (p._meta.grammarTrackLines) return true;
|
|
9354
9494
|
if (d.tag === "grammar" && d.trackLines) return true;
|
|
9355
9495
|
if (d.tag === "lazy") {
|
|
9356
9496
|
try {
|
|
@@ -9359,7 +9499,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9359
9499
|
return false;
|
|
9360
9500
|
}
|
|
9361
9501
|
}
|
|
9362
|
-
return
|
|
9502
|
+
return childrenOf3(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9363
9503
|
}
|
|
9364
9504
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9365
9505
|
if (seen.has(p)) return false;
|
|
@@ -9378,7 +9518,7 @@ function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9378
9518
|
case "dispatch":
|
|
9379
9519
|
return false;
|
|
9380
9520
|
default:
|
|
9381
|
-
return
|
|
9521
|
+
return childrenOf3(d).some((child) => parserUsesRouted2(child, seen));
|
|
9382
9522
|
}
|
|
9383
9523
|
}
|
|
9384
9524
|
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -9393,9 +9533,9 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9393
9533
|
return false;
|
|
9394
9534
|
}
|
|
9395
9535
|
}
|
|
9396
|
-
return
|
|
9536
|
+
return childrenOf3(d).some((child) => hasDirectBuildDef(child, seen));
|
|
9397
9537
|
}
|
|
9398
|
-
function
|
|
9538
|
+
function childrenOf3(def) {
|
|
9399
9539
|
switch (def.tag) {
|
|
9400
9540
|
case "sequence":
|
|
9401
9541
|
case "choice":
|
|
@@ -9470,7 +9610,7 @@ function subtreeSizes(roots) {
|
|
|
9470
9610
|
const def = p._def;
|
|
9471
9611
|
let s = 1;
|
|
9472
9612
|
if (def.tag !== "lazy") {
|
|
9473
|
-
for (const child of
|
|
9613
|
+
for (const child of childrenOf3(def)) s += child._def.tag === "lazy" ? 1 : sz(child);
|
|
9474
9614
|
}
|
|
9475
9615
|
sizes.set(p, s);
|
|
9476
9616
|
return s;
|
|
@@ -9491,7 +9631,7 @@ function subtreeSizes(roots) {
|
|
|
9491
9631
|
return;
|
|
9492
9632
|
}
|
|
9493
9633
|
sz(p);
|
|
9494
|
-
for (const child of
|
|
9634
|
+
for (const child of childrenOf3(def)) visit(child);
|
|
9495
9635
|
};
|
|
9496
9636
|
for (const root of roots) visit(root);
|
|
9497
9637
|
return sizes;
|
|
@@ -9501,7 +9641,7 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9501
9641
|
const recursive = /* @__PURE__ */ new Set();
|
|
9502
9642
|
const descended = /* @__PURE__ */ new Set();
|
|
9503
9643
|
const active = /* @__PURE__ */ new Set();
|
|
9504
|
-
function
|
|
9644
|
+
function walk(p) {
|
|
9505
9645
|
const def = p._def;
|
|
9506
9646
|
if (def.tag === "lazy") {
|
|
9507
9647
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
@@ -9518,17 +9658,17 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9518
9658
|
return;
|
|
9519
9659
|
}
|
|
9520
9660
|
active.add(p);
|
|
9521
|
-
|
|
9661
|
+
walk(resolved);
|
|
9522
9662
|
active.delete(p);
|
|
9523
9663
|
return;
|
|
9524
9664
|
}
|
|
9525
9665
|
if (isHoistableTag(def.tag)) {
|
|
9526
9666
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
9527
9667
|
}
|
|
9528
|
-
for (const child of
|
|
9668
|
+
for (const child of childrenOf3(def)) walk(child);
|
|
9529
9669
|
}
|
|
9530
9670
|
const rootsArr = [...roots];
|
|
9531
|
-
for (const root of rootsArr)
|
|
9671
|
+
for (const root of rootsArr) walk(root);
|
|
9532
9672
|
return { counts, recursive, sizes: subtreeSizes(rootsArr) };
|
|
9533
9673
|
}
|
|
9534
9674
|
function ruleDependencies(ruleMap) {
|
|
@@ -9538,7 +9678,7 @@ function ruleDependencies(ruleMap) {
|
|
|
9538
9678
|
for (const [name, comb] of ruleMap) {
|
|
9539
9679
|
const found = /* @__PURE__ */ new Set();
|
|
9540
9680
|
const seen = /* @__PURE__ */ new Set();
|
|
9541
|
-
const
|
|
9681
|
+
const walk = (p, isRoot) => {
|
|
9542
9682
|
const def = p._def;
|
|
9543
9683
|
const boundary = def.tag === "lazy" ? nameOf.get(p) ?? p._ruleName : nameOf.get(p);
|
|
9544
9684
|
if (!isRoot && boundary !== void 0) {
|
|
@@ -9554,12 +9694,12 @@ function ruleDependencies(ruleMap) {
|
|
|
9554
9694
|
} catch {
|
|
9555
9695
|
return;
|
|
9556
9696
|
}
|
|
9557
|
-
|
|
9697
|
+
walk(resolved, false);
|
|
9558
9698
|
return;
|
|
9559
9699
|
}
|
|
9560
|
-
for (const child of
|
|
9700
|
+
for (const child of childrenOf3(def)) walk(child, false);
|
|
9561
9701
|
};
|
|
9562
|
-
|
|
9702
|
+
walk(comb, true);
|
|
9563
9703
|
deps.set(name, [...found]);
|
|
9564
9704
|
}
|
|
9565
9705
|
return deps;
|
|
@@ -9708,6 +9848,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9708
9848
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
9709
9849
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9710
9850
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9851
|
+
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
9711
9852
|
const ctx = {
|
|
9712
9853
|
vars: 0,
|
|
9713
9854
|
indent: 1,
|
|
@@ -9728,7 +9869,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9728
9869
|
capturing: hasNodeDef(combinator),
|
|
9729
9870
|
recovery: opts?.recovery ?? false,
|
|
9730
9871
|
hostMode: opts?.hostMode ?? grammarHostMode ?? "ast",
|
|
9731
|
-
lineTracking: opts?.trackLines === true || hasLineTrackingDef(combinator),
|
|
9872
|
+
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9732
9873
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9733
9874
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9734
9875
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9892,6 +10033,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9892
10033
|
const grammarTrivia = opts?.trivia;
|
|
9893
10034
|
const grammarScanSkip = opts?.scanSkip ?? ruleMap.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9894
10035
|
const grammarHostMode = opts?.hostMode ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10036
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
9895
10037
|
const ctx = {
|
|
9896
10038
|
vars: 0,
|
|
9897
10039
|
indent: 1,
|
|
@@ -9912,6 +10054,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9912
10054
|
capturing: ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
9913
10055
|
recovery: opts?.recovery ?? false,
|
|
9914
10056
|
hostMode: grammarHostMode ?? "ast",
|
|
10057
|
+
lineTracking: grammarTrackLines,
|
|
9915
10058
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(ruleMap.map(([, rule]) => rule), coverageWinners) } } : {},
|
|
9916
10059
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9917
10060
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9945,6 +10088,10 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9945
10088
|
const mfCovered = ctx.mapFns.length === 0 || derivedSrcs !== void 0;
|
|
9946
10089
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
9947
10090
|
if (!canInline) return null;
|
|
10091
|
+
if (ctx.lineTracking) {
|
|
10092
|
+
ctx.needsLineTrack = true;
|
|
10093
|
+
ctx.needsLineSpan = true;
|
|
10094
|
+
}
|
|
9948
10095
|
const mfDecl = derivedSrcs?.length ? ` const ${mfRef(ctx)} = [${derivedSrcs.join(", ")}]` : "";
|
|
9949
10096
|
const buildDecl = buildSources?.length ? ` const ${buildRef(ctx)} = [${buildSources.join(", ")}]` : "";
|
|
9950
10097
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
@@ -9974,15 +10121,23 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9974
10121
|
};
|
|
9975
10122
|
const entryFnText = (r, rule) => {
|
|
9976
10123
|
const ruleId = entryRuleId(rule);
|
|
10124
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10125
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10126
|
+
` else _ctx.trackLines = true`,
|
|
10127
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10128
|
+
] : [];
|
|
10129
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
9977
10130
|
const body = ruleId === void 0 ? [
|
|
10131
|
+
...linePreamble,
|
|
9978
10132
|
` let pos = _pos`,
|
|
9979
10133
|
...r.stmts,
|
|
9980
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10134
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`
|
|
9981
10135
|
] : [
|
|
10136
|
+
...linePreamble,
|
|
9982
10137
|
` const _coverageResult = (() => {`,
|
|
9983
10138
|
` let pos = _pos`,
|
|
9984
10139
|
...r.stmts,
|
|
9985
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10140
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
9986
10141
|
` })()`,
|
|
9987
10142
|
` if (!_coverageResult.ok) _ctx._grammarTrace?.write({ id: ${JSON.stringify(ruleId)}, phase: 'failure', offset: _coverageResult.span.start })`,
|
|
9988
10143
|
` return _coverageResult`
|
|
@@ -10009,6 +10164,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
10009
10164
|
// host check passes vacuously — see `withHostMode` in the plugin.
|
|
10010
10165
|
hostMode: ctx.hostMode ?? "ast",
|
|
10011
10166
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10167
|
+
reflection: collectGrammarReflection(ruleMap),
|
|
10012
10168
|
...ctx.coverage === void 0 ? {} : { coverageDefinitions: ctx.coverage.plan.definitions }
|
|
10013
10169
|
};
|
|
10014
10170
|
}
|
|
@@ -10020,6 +10176,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10020
10176
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
10021
10177
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
10022
10178
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10179
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
10023
10180
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
10024
10181
|
const d = val._def;
|
|
10025
10182
|
if (d.tag !== "lazy") return true;
|
|
@@ -10030,6 +10187,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10030
10187
|
return false;
|
|
10031
10188
|
}
|
|
10032
10189
|
});
|
|
10190
|
+
const nodeMeta = new Map(ruleMap.map(([name, rule]) => [name, collectGrammarReflection([[name, rule]], { followLazy: false })]));
|
|
10033
10191
|
const ctx = {
|
|
10034
10192
|
vars: 0,
|
|
10035
10193
|
indent: 1,
|
|
@@ -10054,6 +10212,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10054
10212
|
capturing: opts?.captureTerminals === true || ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
10055
10213
|
recovery: opts?.recovery ?? false,
|
|
10056
10214
|
hostMode: grammarHostMode ?? "ast",
|
|
10215
|
+
lineTracking: grammarTrackLines,
|
|
10057
10216
|
...opts?.coverage ? { coverage: { plan: opts.coverage } } : {},
|
|
10058
10217
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10059
10218
|
ns,
|
|
@@ -10104,7 +10263,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10104
10263
|
scanExternal(resolved);
|
|
10105
10264
|
return;
|
|
10106
10265
|
}
|
|
10107
|
-
for (const child of
|
|
10266
|
+
for (const child of childrenOf3(def)) scanExternal(child);
|
|
10108
10267
|
};
|
|
10109
10268
|
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
10110
10269
|
}
|
|
@@ -10150,6 +10309,10 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10150
10309
|
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
10151
10310
|
}
|
|
10152
10311
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
10312
|
+
if (ctx.lineTracking) {
|
|
10313
|
+
ctx.needsLineTrack = true;
|
|
10314
|
+
ctx.needsLineSpan = true;
|
|
10315
|
+
}
|
|
10153
10316
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
10154
10317
|
const buildSrcs = ctx.buildFns.length > 0 && ctx.buildSrcs.every((s) => s !== null) ? ctx.buildSrcs : null;
|
|
10155
10318
|
const ruleFns = /* @__PURE__ */ new Map();
|
|
@@ -10163,6 +10326,8 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10163
10326
|
const mfDecl = ctx.mapFns.length === 0 ? "" : mfSrcs ? `const ${mfRef(ctx)} = [${mfSrcs.join(", ")}]` : `const ${mfRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "mf")}]`;
|
|
10164
10327
|
const buildDecl = ctx.buildFns.length === 0 ? "" : buildSrcs ? `const ${buildRef(ctx)} = [${buildSrcs.join(", ")}]` : `const ${buildRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "build")}]`;
|
|
10165
10328
|
const prelude = [
|
|
10329
|
+
ctx.needsLineTrack ? LINE_TRACK_DECL : "",
|
|
10330
|
+
ctx.needsLineSpan ? LINE_SPAN_DECL : "",
|
|
10166
10331
|
...ctx.regexDecls,
|
|
10167
10332
|
...ctx.expectedDecls,
|
|
10168
10333
|
mfDecl,
|
|
@@ -10171,11 +10336,18 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10171
10336
|
].filter(Boolean);
|
|
10172
10337
|
const wrappers = /* @__PURE__ */ new Map();
|
|
10173
10338
|
for (const { key, rule, r } of perEntry) {
|
|
10339
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10340
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10341
|
+
` else _ctx.trackLines = true`,
|
|
10342
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10343
|
+
] : [];
|
|
10344
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
10174
10345
|
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
10175
10346
|
`function(input, _pos, _ctx) {`,
|
|
10347
|
+
...linePreamble,
|
|
10176
10348
|
` let pos = _pos`,
|
|
10177
10349
|
...r.stmts,
|
|
10178
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10350
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10179
10351
|
`}`
|
|
10180
10352
|
].join("\n"), ctx.triviaKindLabels));
|
|
10181
10353
|
}
|
|
@@ -10213,6 +10385,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10213
10385
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10214
10386
|
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
10215
10387
|
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs),
|
|
10388
|
+
nodeMeta,
|
|
10216
10389
|
mfFns: mfSrcs ? [] : ctx.mapFns,
|
|
10217
10390
|
buildFns: buildSrcs ? [] : ctx.buildFns
|
|
10218
10391
|
};
|
|
@@ -10233,7 +10406,7 @@ function hasExternalRuleRef(ruleMap) {
|
|
|
10233
10406
|
if (resolved === void 0) return p._ruleName !== void 0;
|
|
10234
10407
|
return visit(resolved);
|
|
10235
10408
|
}
|
|
10236
|
-
return
|
|
10409
|
+
return childrenOf3(def).some(visit);
|
|
10237
10410
|
};
|
|
10238
10411
|
return ruleMap.some(([, rule]) => visit(rule));
|
|
10239
10412
|
}
|
|
@@ -10255,7 +10428,7 @@ function hasSemanticReduction(roots, externalRefs) {
|
|
|
10255
10428
|
return true;
|
|
10256
10429
|
}
|
|
10257
10430
|
}
|
|
10258
|
-
return
|
|
10431
|
+
return childrenOf3(def).some(visit);
|
|
10259
10432
|
};
|
|
10260
10433
|
return roots.some(visit);
|
|
10261
10434
|
}
|
|
@@ -10328,7 +10501,7 @@ function withCtx(extra, combinator) {
|
|
|
10328
10501
|
}
|
|
10329
10502
|
|
|
10330
10503
|
// src/compiler/ir-serialize.ts
|
|
10331
|
-
function
|
|
10504
|
+
function childrenOf4(def) {
|
|
10332
10505
|
switch (def.tag) {
|
|
10333
10506
|
case "sequence":
|
|
10334
10507
|
case "choice":
|
|
@@ -10392,6 +10565,10 @@ function projectOpt(project) {
|
|
|
10392
10565
|
if (project === void 0) return void 0;
|
|
10393
10566
|
return `project: ${project}`;
|
|
10394
10567
|
}
|
|
10568
|
+
function tagsOpt(tags) {
|
|
10569
|
+
if (tags === void 0 || tags.length === 0) return void 0;
|
|
10570
|
+
return `tags: ${JSON.stringify(tags)}`;
|
|
10571
|
+
}
|
|
10395
10572
|
function matcherExpr(entry) {
|
|
10396
10573
|
switch (entry.kind) {
|
|
10397
10574
|
case "startsWith":
|
|
@@ -10605,7 +10782,7 @@ var Serializer = class {
|
|
|
10605
10782
|
if (target) this.assertNoRuleRef(target, seen);
|
|
10606
10783
|
return;
|
|
10607
10784
|
}
|
|
10608
|
-
for (const child of
|
|
10785
|
+
for (const child of childrenOf4(c._def)) this.assertNoRuleRef(child, seen);
|
|
10609
10786
|
}
|
|
10610
10787
|
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
10611
10788
|
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
@@ -10669,7 +10846,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10669
10846
|
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
10670
10847
|
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
10671
10848
|
active.add(c);
|
|
10672
|
-
for (const child of
|
|
10849
|
+
for (const child of childrenOf4(def)) this.analyze(child, active);
|
|
10673
10850
|
active.delete(c);
|
|
10674
10851
|
}
|
|
10675
10852
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -10786,12 +10963,14 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10786
10963
|
case "node": {
|
|
10787
10964
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
10788
10965
|
const projectEntry = projectOpt(def.project);
|
|
10966
|
+
const tagEntry = tagsOpt(def.tags);
|
|
10789
10967
|
const optEntries = [
|
|
10790
10968
|
...def.unwrap ? ["unwrap: true"] : [],
|
|
10791
10969
|
...def.collapse ? ["collapse: true"] : [],
|
|
10792
10970
|
...projectEntry === void 0 ? [] : [projectEntry],
|
|
10793
10971
|
...def.captureTrivia ? ["captureTrivia: true"] : [],
|
|
10794
|
-
...def.trailingTrivia ? ["trailingTrivia: true"] : []
|
|
10972
|
+
...def.trailingTrivia ? ["trailingTrivia: true"] : [],
|
|
10973
|
+
...tagEntry === void 0 ? [] : [tagEntry]
|
|
10795
10974
|
];
|
|
10796
10975
|
const opts = optEntries.length > 0 ? `, { ${optEntries.join(", ")} }` : "";
|
|
10797
10976
|
if (def.type === void 0) {
|
|
@@ -10829,15 +11008,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
10829
11008
|
}
|
|
10830
11009
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10831
11010
|
}
|
|
10832
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10833
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
11011
|
+
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
11012
|
+
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] };
|
|
10834
11013
|
}
|
|
10835
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
11014
|
+
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
10836
11015
|
if (typeof typeOrOptions === "string") {
|
|
10837
11016
|
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
10838
11017
|
}
|
|
10839
11018
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
10840
|
-
const
|
|
11019
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
11020
|
+
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
10841
11021
|
host._parsemanCstOutput = true;
|
|
10842
11022
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
10843
11023
|
return host;
|
|
@@ -10858,7 +11038,7 @@ function pickPieces(pieces, names) {
|
|
|
10858
11038
|
};
|
|
10859
11039
|
for (const n of names) visit(n);
|
|
10860
11040
|
const filt = (m, pc) => new Map([...m].filter(([k]) => keep.has(k) && winner.get(k) === pc));
|
|
10861
|
-
return pieces.map((pc) => ({ ...pc, keys: pc.keys.filter((k) => keep.has(k) && winner.get(k) === pc), ruleFns: filt(pc.ruleFns, pc), wrappers: filt(pc.wrappers, pc), deps: filt(pc.deps, pc) })).filter((pc) => pc.keys.length > 0);
|
|
11041
|
+
return pieces.map((pc) => ({ ...pc, keys: pc.keys.filter((k) => keep.has(k) && winner.get(k) === pc), ruleFns: filt(pc.ruleFns, pc), wrappers: filt(pc.wrappers, pc), deps: filt(pc.deps, pc), nodeMeta: filt(pc.nodeMeta, pc) })).filter((pc) => pc.keys.length > 0);
|
|
10862
11042
|
}
|
|
10863
11043
|
function fusedBody(pieces) {
|
|
10864
11044
|
for (const p of pieces) {
|
|
@@ -10896,6 +11076,7 @@ function fusedBody(pieces) {
|
|
|
10896
11076
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
10897
11077
|
];
|
|
10898
11078
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
11079
|
+
const reflection = mergeGrammarReflections([...winner].map(([k, p]) => p.nodeMeta.get(k) ?? { nodes: [] }));
|
|
10899
11080
|
const { mode, elided } = hostModeOfPieces(pieces);
|
|
10900
11081
|
const rawBody = [
|
|
10901
11082
|
...lines,
|
|
@@ -10904,6 +11085,7 @@ function fusedBody(pieces) {
|
|
|
10904
11085
|
"}",
|
|
10905
11086
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_MODE.description)}), { value: ${JSON.stringify(mode)}, enumerable: false })`,
|
|
10906
11087
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_ELIDED.description)}), { value: ${JSON.stringify(elided)}, enumerable: false })`,
|
|
11088
|
+
`Object.defineProperty(_map, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`,
|
|
10907
11089
|
// …and on each rule FUNCTION, because `run(map.Rule, …)` is handed the rule, not the
|
|
10908
11090
|
// map, and would otherwise have nothing to check against. Done once at fuse time,
|
|
10909
11091
|
// before any rule has been called, so it costs nothing per parse.
|
|
@@ -11009,7 +11191,8 @@ function materializePiece(p, trivia2, captureTerminals = false, hostMode) {
|
|
|
11009
11191
|
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, {
|
|
11010
11192
|
...trivia2 ? { trivia: trivia2 } : {},
|
|
11011
11193
|
...captureTerminals ? { captureTerminals: true } : {},
|
|
11012
|
-
...hostMode ? { hostMode } : {}
|
|
11194
|
+
...hostMode ? { hostMode } : {},
|
|
11195
|
+
...p.trackLines ? { trackLines: true } : {}
|
|
11013
11196
|
});
|
|
11014
11197
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
11015
11198
|
return pieces;
|
|
@@ -11193,19 +11376,19 @@ function directBuilderUnsupportedBindings(src) {
|
|
|
11193
11376
|
// src/plugin/evaluator.ts
|
|
11194
11377
|
function stripTsFromSource(node2, code) {
|
|
11195
11378
|
const cuts = [];
|
|
11196
|
-
const
|
|
11379
|
+
const walk = (n) => {
|
|
11197
11380
|
if (!n || typeof n !== "object") return;
|
|
11198
11381
|
const rec = n;
|
|
11199
11382
|
if (typeof rec.type === "string" && rec.type.startsWith("TS") && typeof rec.start === "number" && typeof rec.end === "number") {
|
|
11200
11383
|
const ex = rec.expression;
|
|
11201
11384
|
if ((rec.type === "TSAsExpression" || rec.type === "TSSatisfiesExpression" || rec.type === "TSNonNullExpression" || rec.type === "TSInstantiationExpression") && ex && typeof ex.end === "number") {
|
|
11202
11385
|
cuts.push([ex.end, rec.end]);
|
|
11203
|
-
|
|
11386
|
+
walk(rec.expression);
|
|
11204
11387
|
return;
|
|
11205
11388
|
}
|
|
11206
11389
|
if (rec.type === "TSTypeAssertion" && ex && typeof ex.start === "number") {
|
|
11207
11390
|
cuts.push([rec.start, ex.start]);
|
|
11208
|
-
|
|
11391
|
+
walk(rec.expression);
|
|
11209
11392
|
return;
|
|
11210
11393
|
}
|
|
11211
11394
|
cuts.push([rec.start, rec.end]);
|
|
@@ -11215,11 +11398,11 @@ function stripTsFromSource(node2, code) {
|
|
|
11215
11398
|
if (key === "type" || key === "start" || key === "end") continue;
|
|
11216
11399
|
const v2 = rec[key];
|
|
11217
11400
|
if (Array.isArray(v2)) {
|
|
11218
|
-
for (const item of v2)
|
|
11219
|
-
} else if (v2 && typeof v2 === "object")
|
|
11401
|
+
for (const item of v2) walk(item);
|
|
11402
|
+
} else if (v2 && typeof v2 === "object") walk(v2);
|
|
11220
11403
|
}
|
|
11221
11404
|
};
|
|
11222
|
-
|
|
11405
|
+
walk(node2);
|
|
11223
11406
|
const start = node2.start;
|
|
11224
11407
|
const end = node2.end;
|
|
11225
11408
|
if (cuts.length === 0) return code.slice(start, end);
|
|
@@ -11398,10 +11581,38 @@ function scopeGet(scope, name, mfs) {
|
|
|
11398
11581
|
if (isCombinator(entry)) return entry;
|
|
11399
11582
|
return null;
|
|
11400
11583
|
}
|
|
11584
|
+
function unwrapStaticExpr(expr) {
|
|
11585
|
+
let cur = expr;
|
|
11586
|
+
while (cur.type === "TSAsExpression" || cur.type === "TSSatisfiesExpression" || cur.type === "TSNonNullExpression" || cur.type === "TSTypeAssertion" || cur.type === "TSInstantiationExpression" || cur.type === "ParenthesizedExpression") {
|
|
11587
|
+
if (!cur.expression) break;
|
|
11588
|
+
cur = cur.expression;
|
|
11589
|
+
}
|
|
11590
|
+
return cur;
|
|
11591
|
+
}
|
|
11401
11592
|
function staticLiteralValue(expr) {
|
|
11402
|
-
const val = expr;
|
|
11593
|
+
const val = unwrapStaticExpr(expr);
|
|
11403
11594
|
return val.type === "Literal" || val.type === "BooleanLiteral" || val.type === "NumericLiteral" ? val.value : void 0;
|
|
11404
11595
|
}
|
|
11596
|
+
function staticStringArray(expr, scope) {
|
|
11597
|
+
const id = unwrapStaticExpr(expr);
|
|
11598
|
+
if (id.type === "Identifier" && scope !== void 0 && id.name !== void 0) {
|
|
11599
|
+
const scoped = scope.get(id.name);
|
|
11600
|
+
const value = isStaticValueEntry(scoped) ? scoped.value : scoped;
|
|
11601
|
+
return Array.isArray(value) && value.every((v2) => typeof v2 === "string") ? value : void 0;
|
|
11602
|
+
}
|
|
11603
|
+
const arr = id;
|
|
11604
|
+
if (arr.type !== "ArrayExpression" || !Array.isArray(arr.elements)) return void 0;
|
|
11605
|
+
const out = [];
|
|
11606
|
+
for (const el of arr.elements) {
|
|
11607
|
+
if (!el || el.type === "SpreadElement") return void 0;
|
|
11608
|
+
const value = staticLiteralValue(el);
|
|
11609
|
+
if (typeof value !== "string") return void 0;
|
|
11610
|
+
out.push(value);
|
|
11611
|
+
}
|
|
11612
|
+
return out;
|
|
11613
|
+
}
|
|
11614
|
+
var STATIC_NODE_OPTIONS_FAILED = /* @__PURE__ */ Symbol("parseman.staticNodeOptions.failed");
|
|
11615
|
+
var STATIC_NODE_OPTIONS_NOT_OPTIONS = /* @__PURE__ */ Symbol("parseman.staticNodeOptions.notOptions");
|
|
11405
11616
|
function staticNodeProject(expr) {
|
|
11406
11617
|
const literalValue = staticLiteralValue(expr);
|
|
11407
11618
|
if (typeof literalValue === "number" && Number.isInteger(literalValue) && literalValue >= 0) {
|
|
@@ -11410,23 +11621,60 @@ function staticNodeProject(expr) {
|
|
|
11410
11621
|
if (typeof literalValue === "number" || literalValue !== void 0) return { ok: false };
|
|
11411
11622
|
return { ok: false };
|
|
11412
11623
|
}
|
|
11413
|
-
function
|
|
11414
|
-
|
|
11624
|
+
function scopedStaticValue(expr, scope) {
|
|
11625
|
+
const unwrapped = unwrapStaticExpr(expr);
|
|
11626
|
+
if (unwrapped.type !== "Identifier" || unwrapped.name === "undefined") return { found: false };
|
|
11627
|
+
if (!scope.has(unwrapped.name)) return { found: false };
|
|
11628
|
+
const scoped = scope.get(unwrapped.name);
|
|
11629
|
+
const value = isStaticValueEntry(scoped) ? scoped.value : scoped;
|
|
11630
|
+
return { found: true, value };
|
|
11631
|
+
}
|
|
11632
|
+
function staticNodeOptionsFromValue(value) {
|
|
11633
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || isCombinator(value)) return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11634
|
+
const opts = {};
|
|
11635
|
+
const rec = value;
|
|
11636
|
+
for (const name of Object.keys(rec)) {
|
|
11637
|
+
const v2 = rec[name];
|
|
11638
|
+
if (name === "unwrap" || name === "collapse" || name === "captureTrivia" || name === "trailingTrivia") {
|
|
11639
|
+
if (v2 === true) opts[name] = true;
|
|
11640
|
+
else if (v2 !== false && v2 !== void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11641
|
+
} else if (name === "project") {
|
|
11642
|
+
if (typeof v2 !== "number" || !Number.isInteger(v2) || v2 < 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11643
|
+
opts.project = v2;
|
|
11644
|
+
} else if (name === "tags") {
|
|
11645
|
+
if (!Array.isArray(v2) || !v2.every((item) => typeof item === "string")) return STATIC_NODE_OPTIONS_FAILED;
|
|
11646
|
+
opts.tags = v2;
|
|
11647
|
+
}
|
|
11648
|
+
}
|
|
11649
|
+
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 ? opts : void 0;
|
|
11650
|
+
}
|
|
11651
|
+
function staticNodeOptions(expr, scope) {
|
|
11652
|
+
const unwrapped = unwrapStaticExpr(expr);
|
|
11653
|
+
const scoped = scopedStaticValue(unwrapped, scope);
|
|
11654
|
+
if (scoped.found) return staticNodeOptionsFromValue(scoped.value);
|
|
11655
|
+
if (unwrapped.type !== "ObjectExpression") return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11415
11656
|
const opts = {};
|
|
11416
|
-
for (const prop of
|
|
11657
|
+
for (const prop of unwrapped.properties) {
|
|
11658
|
+
if (prop.type !== "Property") return STATIC_NODE_OPTIONS_FAILED;
|
|
11417
11659
|
const p = prop;
|
|
11418
|
-
if (p.computed)
|
|
11660
|
+
if (p.computed) return STATIC_NODE_OPTIONS_FAILED;
|
|
11419
11661
|
const key = p.key;
|
|
11420
11662
|
const name = key.type === "Identifier" ? key.name : key.type === "Literal" ? String(key.value) : void 0;
|
|
11421
11663
|
if (name === "unwrap" || name === "collapse" || name === "captureTrivia" || name === "trailingTrivia") {
|
|
11422
|
-
|
|
11664
|
+
const value = staticLiteralValue(p.value);
|
|
11665
|
+
if (value === true) opts[name] = true;
|
|
11666
|
+
else if (value !== false && value !== void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11423
11667
|
} else if (name === "project") {
|
|
11424
11668
|
const project = staticNodeProject(p.value);
|
|
11425
|
-
if (project?.ok === false) return
|
|
11669
|
+
if (project?.ok === false) return STATIC_NODE_OPTIONS_FAILED;
|
|
11426
11670
|
if (project !== void 0) opts.project = project.value;
|
|
11671
|
+
} else if (name === "tags") {
|
|
11672
|
+
const tags = staticStringArray(p.value, scope);
|
|
11673
|
+
if (tags === void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11674
|
+
opts.tags = tags;
|
|
11427
11675
|
}
|
|
11428
11676
|
}
|
|
11429
|
-
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia ? opts : void 0;
|
|
11677
|
+
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 ? opts : void 0;
|
|
11430
11678
|
}
|
|
11431
11679
|
function exprToCombi(node2, scope, code, mfs) {
|
|
11432
11680
|
if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
|
|
@@ -11501,10 +11749,23 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
11501
11749
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
11502
11750
|
if (!isCombinator(inner)) return null;
|
|
11503
11751
|
const be = buildArg;
|
|
11504
|
-
const
|
|
11752
|
+
const buildExpr = be === void 0 || be.type === "SpreadElement" ? void 0 : unwrapStaticExpr(be);
|
|
11753
|
+
const buildArgOptions = be !== void 0 && be.type !== "SpreadElement" ? staticNodeOptions(buildArg, scope) : STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11754
|
+
if (buildArgOptions === STATIC_NODE_OPTIONS_FAILED) return null;
|
|
11755
|
+
const buildArgIsOptions = buildArgOptions !== STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11756
|
+
const scopedBuild = buildExpr === void 0 ? { found: false } : scopedStaticValue(buildExpr, scope);
|
|
11757
|
+
const absentBuild = buildExpr?.type === "Identifier" && buildExpr.name === "undefined" || buildExpr !== void 0 && staticLiteralValue(buildExpr) === null || scopedBuild.found && (scopedBuild.value === void 0 || scopedBuild.value === null);
|
|
11758
|
+
const hasBuild = be !== void 0 && be.type !== "SpreadElement" && !buildArgIsOptions && !absentBuild;
|
|
11505
11759
|
const buildSrc = hasBuild ? stripTsFromSource(be, code) : void 0;
|
|
11506
|
-
|
|
11507
|
-
|
|
11760
|
+
let opts;
|
|
11761
|
+
if (buildArgIsOptions) {
|
|
11762
|
+
opts = buildArgOptions;
|
|
11763
|
+
} else if (optsArg !== void 0) {
|
|
11764
|
+
if (optsArg.type === "SpreadElement") return null;
|
|
11765
|
+
const optsResult = staticNodeOptions(optsArg, scope);
|
|
11766
|
+
if (optsResult === STATIC_NODE_OPTIONS_FAILED || optsResult === STATIC_NODE_OPTIONS_NOT_OPTIONS) return null;
|
|
11767
|
+
opts = optsResult;
|
|
11768
|
+
}
|
|
11508
11769
|
try {
|
|
11509
11770
|
const combi = explicitType !== void 0 ? node(explicitType, inner, hasBuild ? () => null : void 0, opts) : node(inner, hasBuild ? () => null : void 0, opts);
|
|
11510
11771
|
if (combi._def.tag === "node" && buildSrc !== void 0) {
|
|
@@ -11727,6 +11988,10 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
11727
11988
|
}
|
|
11728
11989
|
}
|
|
11729
11990
|
function anyValue(node2, scope, code, mfs) {
|
|
11991
|
+
if (node2.type === "TSAsExpression" || node2.type === "TSSatisfiesExpression" || node2.type === "TSNonNullExpression" || node2.type === "TSTypeAssertion" || node2.type === "TSInstantiationExpression" || node2.type === "ParenthesizedExpression") {
|
|
11992
|
+
const inner = node2.expression;
|
|
11993
|
+
return inner ? anyValue(inner, scope, code, mfs) : null;
|
|
11994
|
+
}
|
|
11730
11995
|
if (node2.type === "Literal") {
|
|
11731
11996
|
if ("regex" in node2 && node2.regex !== null && node2.regex !== void 0) {
|
|
11732
11997
|
return new RegExp(node2.regex.pattern, node2.regex.flags);
|
|
@@ -11850,6 +12115,9 @@ function collectRuleKeys(retObj) {
|
|
|
11850
12115
|
}
|
|
11851
12116
|
return out;
|
|
11852
12117
|
}
|
|
12118
|
+
function evaluateStaticValue(node2, scope, code) {
|
|
12119
|
+
return anyValue(node2, scope, code, []);
|
|
12120
|
+
}
|
|
11853
12121
|
function flattenRuleEntries(retObj, scope, code) {
|
|
11854
12122
|
const out = [];
|
|
11855
12123
|
for (const prop of retObj.properties) {
|
|
@@ -12015,6 +12283,18 @@ function referencesAny(node2, names, scope) {
|
|
|
12015
12283
|
// src/plugin/index.ts
|
|
12016
12284
|
var import_node_crypto = require("node:crypto");
|
|
12017
12285
|
var PARSEMAN_MODULE = "parseman";
|
|
12286
|
+
function unwrapStaticExpression(expr) {
|
|
12287
|
+
let cur = expr;
|
|
12288
|
+
while (cur.type === "TSAsExpression" || cur.type === "TSSatisfiesExpression" || cur.type === "TSNonNullExpression" || cur.type === "TSTypeAssertion" || cur.type === "TSInstantiationExpression" || cur.type === "ParenthesizedExpression") {
|
|
12289
|
+
if (!cur.expression) break;
|
|
12290
|
+
cur = cur.expression;
|
|
12291
|
+
}
|
|
12292
|
+
return cur;
|
|
12293
|
+
}
|
|
12294
|
+
function isStaticNullishExpression(expr) {
|
|
12295
|
+
const unwrapped = unwrapStaticExpression(expr);
|
|
12296
|
+
return unwrapped.type === "Identifier" && unwrapped.name === "undefined" || unwrapped.type === "Literal" && unwrapped.value === null;
|
|
12297
|
+
}
|
|
12018
12298
|
var _compiledResolver = null;
|
|
12019
12299
|
function getCompiledResolver() {
|
|
12020
12300
|
return _compiledResolver ??= new import_oxc_resolver.ResolverFactory({
|
|
@@ -12256,6 +12536,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12256
12536
|
const macroImports = [];
|
|
12257
12537
|
const allNames = /* @__PURE__ */ new Set();
|
|
12258
12538
|
const importBindings = /* @__PURE__ */ new Map();
|
|
12539
|
+
const ordinaryImports = [];
|
|
12259
12540
|
for (const stmt of body) {
|
|
12260
12541
|
if (stmt.type !== "ImportDeclaration") continue;
|
|
12261
12542
|
const s = stmt;
|
|
@@ -12264,12 +12545,17 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12264
12545
|
return key === "type" && a.value.value === "macro";
|
|
12265
12546
|
});
|
|
12266
12547
|
if (!isMacro) {
|
|
12548
|
+
const specifiers = [];
|
|
12267
12549
|
for (const spec of s.specifiers) {
|
|
12268
12550
|
if (spec.type === "ImportSpecifier") {
|
|
12269
12551
|
const imported = spec.imported.name ?? spec.local.name;
|
|
12270
12552
|
importBindings.set(spec.local.name, { source: s.source.value, imported });
|
|
12553
|
+
specifiers.push({ type: spec.type, local: spec.local.name, start: spec.start, end: spec.end });
|
|
12554
|
+
} else {
|
|
12555
|
+
specifiers.push({ type: spec.type, local: spec.local.name, start: spec.start, end: spec.end });
|
|
12271
12556
|
}
|
|
12272
12557
|
}
|
|
12558
|
+
ordinaryImports.push({ start: s.start, end: s.end, specifiers });
|
|
12273
12559
|
continue;
|
|
12274
12560
|
}
|
|
12275
12561
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -12280,6 +12566,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12280
12566
|
for (const n of names) allNames.add(n);
|
|
12281
12567
|
}
|
|
12282
12568
|
if (macroImports.length === 0) return null;
|
|
12569
|
+
const unwrapVd = (stmt) => stmt.type === "VariableDeclaration" ? stmt : stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration" ? stmt.declaration : null;
|
|
12283
12570
|
const factoryDecls = /* @__PURE__ */ new Map();
|
|
12284
12571
|
for (const stmt of body) {
|
|
12285
12572
|
const decl = stmt.type === "ExportNamedDeclaration" ? stmt.declaration : stmt;
|
|
@@ -12297,6 +12584,101 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12297
12584
|
}
|
|
12298
12585
|
}
|
|
12299
12586
|
}
|
|
12587
|
+
const topLevelFunction = (moduleBody, name) => {
|
|
12588
|
+
for (const st of moduleBody) {
|
|
12589
|
+
const decl = st.type === "ExportNamedDeclaration" ? st.declaration : st;
|
|
12590
|
+
const idn = decl?.type === "FunctionDeclaration" ? decl.id : void 0;
|
|
12591
|
+
if (idn?.name === name) return decl ?? null;
|
|
12592
|
+
}
|
|
12593
|
+
return null;
|
|
12594
|
+
};
|
|
12595
|
+
const isParsemanMacroImport = (stmt) => {
|
|
12596
|
+
if (stmt.type !== "ImportDeclaration") return false;
|
|
12597
|
+
const s = stmt;
|
|
12598
|
+
return moduleAliases.has(s.source.value) && s.attributes.some((a) => {
|
|
12599
|
+
const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
|
|
12600
|
+
return key === "type" && a.value.value === "macro";
|
|
12601
|
+
});
|
|
12602
|
+
};
|
|
12603
|
+
const sourceScopeUntil = (moduleBody, source, until) => {
|
|
12604
|
+
const out = /* @__PURE__ */ new Map();
|
|
12605
|
+
for (const stmt of moduleBody) {
|
|
12606
|
+
if (stmt.type === "ImportDeclaration") {
|
|
12607
|
+
if (!isParsemanMacroImport(stmt)) return null;
|
|
12608
|
+
continue;
|
|
12609
|
+
}
|
|
12610
|
+
if (stmt.type === "FunctionDeclaration") continue;
|
|
12611
|
+
if (stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "FunctionDeclaration") continue;
|
|
12612
|
+
if (stmt.type === "ExportNamedDeclaration" && !stmt.declaration) {
|
|
12613
|
+
if (stmt.source) return null;
|
|
12614
|
+
continue;
|
|
12615
|
+
}
|
|
12616
|
+
const vd = unwrapVd(stmt);
|
|
12617
|
+
if (!vd || vd.kind !== "const") return null;
|
|
12618
|
+
for (const decl of vd.declarations) {
|
|
12619
|
+
const d = decl;
|
|
12620
|
+
const idn = d.id;
|
|
12621
|
+
const init = d.init;
|
|
12622
|
+
if (idn.type !== "Identifier" && idn.type !== "BindingIdentifier" || !idn.name || !init) return null;
|
|
12623
|
+
if (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression") continue;
|
|
12624
|
+
const mapFnSources = [];
|
|
12625
|
+
const combi = evaluateExpr(init, out, source, mapFnSources);
|
|
12626
|
+
if (combi) {
|
|
12627
|
+
if (stmt.start < until) out.set(idn.name, { combi, mfSrcs: mapFnSources });
|
|
12628
|
+
continue;
|
|
12629
|
+
}
|
|
12630
|
+
const wordFactory = evaluateWordFactory(init, out, source);
|
|
12631
|
+
if (wordFactory) {
|
|
12632
|
+
if (stmt.start < until) {
|
|
12633
|
+
;
|
|
12634
|
+
out.set(idn.name, wordFactory);
|
|
12635
|
+
}
|
|
12636
|
+
continue;
|
|
12637
|
+
}
|
|
12638
|
+
const whenFactory = evaluateWhenFactory(init, out, source);
|
|
12639
|
+
if (whenFactory) {
|
|
12640
|
+
if (stmt.start < until) {
|
|
12641
|
+
;
|
|
12642
|
+
out.set(idn.name, whenFactory);
|
|
12643
|
+
}
|
|
12644
|
+
continue;
|
|
12645
|
+
}
|
|
12646
|
+
const combiArray = evaluateCombinatorArray(init, out, source);
|
|
12647
|
+
if (combiArray) {
|
|
12648
|
+
if (stmt.start < until) {
|
|
12649
|
+
;
|
|
12650
|
+
out.set(idn.name, combiArray);
|
|
12651
|
+
}
|
|
12652
|
+
continue;
|
|
12653
|
+
}
|
|
12654
|
+
return null;
|
|
12655
|
+
}
|
|
12656
|
+
continue;
|
|
12657
|
+
}
|
|
12658
|
+
return out;
|
|
12659
|
+
};
|
|
12660
|
+
const usedImportedFactories = /* @__PURE__ */ new Set();
|
|
12661
|
+
const markUsedImportedFactories = (names) => {
|
|
12662
|
+
for (const name of names ?? []) usedImportedFactories.add(name);
|
|
12663
|
+
};
|
|
12664
|
+
for (const [localName, binding] of importBindings) {
|
|
12665
|
+
const file = resolvePrivateSourceModule(id, binding.source);
|
|
12666
|
+
if (!file) continue;
|
|
12667
|
+
const mod = parseModuleCached(file);
|
|
12668
|
+
if (!mod) continue;
|
|
12669
|
+
const localFor = exportLocalName(mod.body, binding.imported);
|
|
12670
|
+
const init = localFor ? topLevelInit(mod.body, localFor) ?? topLevelFunction(mod.body, localFor) : null;
|
|
12671
|
+
if (!init || init.type !== "ArrowFunctionExpression" && init.type !== "FunctionExpression" && init.type !== "FunctionDeclaration") continue;
|
|
12672
|
+
const factoryScope = sourceScopeUntil(mod.body, mod.src, init.start);
|
|
12673
|
+
if (!factoryScope) continue;
|
|
12674
|
+
factoryDecls.set(localName, {
|
|
12675
|
+
fn: init,
|
|
12676
|
+
declaredAt: -1,
|
|
12677
|
+
code: mod.src,
|
|
12678
|
+
scope: factoryScope,
|
|
12679
|
+
imported: true
|
|
12680
|
+
});
|
|
12681
|
+
}
|
|
12300
12682
|
const scope = /* @__PURE__ */ new Map();
|
|
12301
12683
|
const replacements = [];
|
|
12302
12684
|
const warnings = [];
|
|
@@ -12326,6 +12708,9 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12326
12708
|
}
|
|
12327
12709
|
const namedFactory = factoryArgRaw.type === "Identifier" ? factoryDecls.get(factoryArgRaw.name) : void 0;
|
|
12328
12710
|
const factoryArg = namedFactory !== void 0 && namedFactory.declaredAt <= init.start ? namedFactory.fn : factoryArgRaw;
|
|
12711
|
+
const factoryScope = namedFactory?.scope ?? scope;
|
|
12712
|
+
const factoryCode = namedFactory?.code ?? code;
|
|
12713
|
+
const importedFactory = namedFactory?.imported === true && factoryArg === namedFactory.fn ? factoryArgRaw.name : void 0;
|
|
12329
12714
|
const optionsArg = optionsFirst ? arg0 : arg1;
|
|
12330
12715
|
const optionValue = (name) => optionsArg?.type === "ObjectExpression" ? (optionsArg.properties ?? []).find(
|
|
12331
12716
|
(p) => p.key?.name === name
|
|
@@ -12336,7 +12721,13 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12336
12721
|
warn(init.start, `${label2}: rules({ hostMode }) must be the literal 'ast' or 'cst'`);
|
|
12337
12722
|
return null;
|
|
12338
12723
|
}
|
|
12339
|
-
const
|
|
12724
|
+
const trackLinesValue = optionValue("trackLines");
|
|
12725
|
+
const gTrackLines = trackLinesValue?.type === "Literal" ? trackLinesValue.value : void 0;
|
|
12726
|
+
if (trackLinesValue !== void 0 && typeof gTrackLines !== "boolean") {
|
|
12727
|
+
warn(init.start, `${label2}: rules({ trackLines }) must be a boolean literal`);
|
|
12728
|
+
return null;
|
|
12729
|
+
}
|
|
12730
|
+
const ruleMap = evaluateParserFactory(factoryArg, factoryScope, factoryCode, []);
|
|
12340
12731
|
if (!ruleMap) {
|
|
12341
12732
|
warn(init.start, `${label2}: rules(...) factory isn't statically evaluable`);
|
|
12342
12733
|
return null;
|
|
@@ -12361,20 +12752,37 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12361
12752
|
}
|
|
12362
12753
|
}
|
|
12363
12754
|
}
|
|
12364
|
-
|
|
12755
|
+
if (gTrackLines === true) {
|
|
12756
|
+
for (const rule of ruleMap.values()) {
|
|
12757
|
+
if (rule && !rule._meta.isTrivia) {
|
|
12758
|
+
;
|
|
12759
|
+
rule._meta.grammarTrackLines = true;
|
|
12760
|
+
}
|
|
12761
|
+
}
|
|
12762
|
+
}
|
|
12763
|
+
return {
|
|
12764
|
+
ruleMap,
|
|
12765
|
+
...gTrivia ? { trivia: gTrivia } : {},
|
|
12766
|
+
...gScanSkip ? { scanSkip: gScanSkip } : {},
|
|
12767
|
+
...gTrackLines === true ? { trackLines: true } : {},
|
|
12768
|
+
...importedFactory ? { importedFactory } : {}
|
|
12769
|
+
};
|
|
12365
12770
|
};
|
|
12366
12771
|
const compileRulesFactory = (init, label2) => {
|
|
12367
12772
|
const evaluated = evaluateRulesFactory(init, label2);
|
|
12368
12773
|
if (!evaluated) return null;
|
|
12369
|
-
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, recovery, coverage: grammarCoverage });
|
|
12774
|
+
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, ...evaluated.trackLines ? { trackLines: true } : {}, recovery, coverage: grammarCoverage });
|
|
12370
12775
|
return {
|
|
12371
12776
|
replacement: compiled?.replacement ?? null,
|
|
12372
12777
|
ruleMap: evaluated.ruleMap,
|
|
12373
12778
|
hostMode: compiled?.hostMode ?? "ast",
|
|
12374
12779
|
hostBranchElided: compiled?.hostBranchElided ?? false,
|
|
12780
|
+
reflection: compiled?.reflection ?? { nodes: [] },
|
|
12375
12781
|
...compiled?.coverageDefinitions ? { coverageDefinitions: compiled.coverageDefinitions } : {},
|
|
12376
12782
|
...evaluated.trivia ? { trivia: evaluated.trivia } : {},
|
|
12377
|
-
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}
|
|
12783
|
+
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {},
|
|
12784
|
+
...evaluated.trackLines ? { trackLines: true } : {},
|
|
12785
|
+
...evaluated.importedFactory ? { importedFactory: evaluated.importedFactory } : {}
|
|
12378
12786
|
};
|
|
12379
12787
|
};
|
|
12380
12788
|
const isRulesCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "rules";
|
|
@@ -12390,15 +12798,16 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12390
12798
|
const mapLit = (m, stripVals = false) => `new Map([${[...m].map(
|
|
12391
12799
|
([k, v2]) => `[${JSON.stringify(k)}, ${JSON.stringify(stripVals && typeof v2 === "string" ? stripIndent(v2) : v2)}]`
|
|
12392
12800
|
).join(", ")}])`;
|
|
12393
|
-
return `{ v: ${JSON.stringify(p.v)}, ns: ${JSON.stringify(p.ns)}, keys: ${JSON.stringify(p.keys)}, prelude: ${JSON.stringify(p.prelude.map(stripIndent))}, ruleFns: ${mapLit(p.ruleFns, true)}, wrappers: ${mapLit(p.wrappers, true)}, firstSets: ${mapLit(p.firstSets)}, nullable: ${p.nullable ? mapLit(p.nullable) : "new Map()"}, firstSetRecipes: ${p.firstSetRecipes ? mapLit(p.firstSetRecipes) : "new Map()"}, deps: ${mapLit(p.deps)}, hostMode: ${JSON.stringify(p.hostMode ?? "ast")}, hostBranchElided: ${p.hostBranchElided === true}, needsEmptyTl: ${p.needsEmptyTl}, needsHostReads: ${p.needsHostReads}, hasDirectBuilders: ${p.hasDirectBuilders === true}, isRecognitionOnly: ${p.isRecognitionOnly === true}, mfFns: [], buildFns: [] }`;
|
|
12801
|
+
return `{ v: ${JSON.stringify(p.v)}, ns: ${JSON.stringify(p.ns)}, keys: ${JSON.stringify(p.keys)}, prelude: ${JSON.stringify(p.prelude.map(stripIndent))}, ruleFns: ${mapLit(p.ruleFns, true)}, wrappers: ${mapLit(p.wrappers, true)}, firstSets: ${mapLit(p.firstSets)}, nullable: ${p.nullable ? mapLit(p.nullable) : "new Map()"}, firstSetRecipes: ${p.firstSetRecipes ? mapLit(p.firstSetRecipes) : "new Map()"}, deps: ${mapLit(p.deps)}, nodeMeta: ${mapLit(p.nodeMeta)}, hostMode: ${JSON.stringify(p.hostMode ?? "ast")}, hostBranchElided: ${p.hostBranchElided === true}, needsEmptyTl: ${p.needsEmptyTl}, needsHostReads: ${p.needsHostReads}, hasDirectBuilders: ${p.hasDirectBuilders === true}, isRecognitionOnly: ${p.isRecognitionOnly === true}, mfFns: [], buildFns: [] }`;
|
|
12394
12802
|
};
|
|
12395
12803
|
const isSpread = (it) => "__spreadLocal" in it;
|
|
12396
12804
|
const isIR = (it) => "ir" in it && !("ruleFns" in it);
|
|
12397
|
-
const serializeItem = (it) => isSpread(it) ? `...(${it.__spreadLocal}[Symbol.for('parseman.composedPieces')] ?? [])` : isIR(it) ? `{ ns: ${JSON.stringify(it.ns)}, ir: ${JSON.stringify(it.ir)} }` : serializePieces(it);
|
|
12805
|
+
const serializeItem = (it) => isSpread(it) ? `...(${it.__spreadLocal}[Symbol.for('parseman.composedPieces')] ?? [])` : isIR(it) ? `{ ns: ${JSON.stringify(it.ns)}, ir: ${JSON.stringify(it.ir)}${it.trackLines ? ", trackLines: true" : ""} }` : serializePieces(it);
|
|
12398
12806
|
const serializeList = (list) => `[${list.map(serializeItem).join(", ")}]`;
|
|
12399
12807
|
const withCarriedPieces = (grammarExpr, list) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.composedPieces'), { value: ${serializeList(list)}, enumerable: false })`;
|
|
12400
12808
|
const withLeafMarker = (grammarExpr) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.leafComposed'), { value: true, enumerable: false })`;
|
|
12401
12809
|
const withHostMode = (grammarExpr, mode, elided) => `/* @__PURE__ */ (m => { for (const k of Object.keys(m)) { Object.defineProperty(m[k], Symbol.for('parseman.fusedHostMode'), { value: ${JSON.stringify(mode)}, enumerable: false }); Object.defineProperty(m[k], Symbol.for('parseman.fusedHostElided'), { value: ${JSON.stringify(elided)}, enumerable: false }) } Object.defineProperty(m, Symbol.for('parseman.fusedHostMode'), { value: ${JSON.stringify(mode)}, enumerable: false }); Object.defineProperty(m, Symbol.for('parseman.fusedHostElided'), { value: ${JSON.stringify(elided)}, enumerable: false }); return m })(${grammarExpr})`;
|
|
12810
|
+
const withGrammarReflection = (grammarExpr, reflection) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`;
|
|
12402
12811
|
const withCoverageDefinitions = (grammarExpr, definitions) => !grammarCoverage ? grammarExpr : `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.grammarCoverageDefinitions'), { value: Object.freeze(${JSON.stringify(definitions)}.map(Object.freeze)), enumerable: false })`;
|
|
12403
12812
|
const emittedCoverageDefinitions = (source) => {
|
|
12404
12813
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -12525,10 +12934,11 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12525
12934
|
const localCarried = (rm, label2, composing, scanSkip) => {
|
|
12526
12935
|
const entries = [...rm];
|
|
12527
12936
|
const ns = nsFor(label2);
|
|
12937
|
+
const trackLines = entries.some(([, rule]) => rule?._meta?.grammarTrackLines === true);
|
|
12528
12938
|
const ir = serializeRuleMap(entries, scanSkip);
|
|
12529
|
-
if (ir) return { carried: [{ ns, ir }] };
|
|
12939
|
+
if (ir) return { carried: [{ ns, ir, ...trackLines ? { trackLines: true } : {} }] };
|
|
12530
12940
|
warn(0, `${label2}: rule map could not be serialized to IR; carrying FULL pieces instead. The artifact is correct but larger, and a downstream compose cannot re-lower it. Re-run with PARSEMAN_IR_DEBUG=1 to print the exact combinator that blocked serialization.`);
|
|
12531
|
-
const p = compileLinkable(entries, ns, { ...composing ? { trivia: composing } : {}, ...scanSkip ? { scanSkip } : {}, recovery });
|
|
12941
|
+
const p = compileLinkable(entries, ns, { ...composing ? { trivia: composing } : {}, ...scanSkip ? { scanSkip } : {}, ...trackLines ? { trackLines: true } : {}, recovery });
|
|
12532
12942
|
return p ? { carried: [p] } : null;
|
|
12533
12943
|
};
|
|
12534
12944
|
const argPieces = (arg, label2, composing) => {
|
|
@@ -12546,7 +12956,10 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12546
12956
|
const innerArg = argPieces(inner, `${label2}_pick`);
|
|
12547
12957
|
if (!innerArg) return null;
|
|
12548
12958
|
try {
|
|
12549
|
-
return {
|
|
12959
|
+
return {
|
|
12960
|
+
carried: pickPieces(materializeCarried(innerArg.carried, ownTrivia(inner)), names),
|
|
12961
|
+
...innerArg.importedFactories ? { importedFactories: innerArg.importedFactories } : {}
|
|
12962
|
+
};
|
|
12550
12963
|
} catch (e) {
|
|
12551
12964
|
warn(arg.start, `pick(): ${e.message}`);
|
|
12552
12965
|
return null;
|
|
@@ -12554,7 +12967,8 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12554
12967
|
}
|
|
12555
12968
|
if (isRulesCall(arg)) {
|
|
12556
12969
|
const evaluated = evaluateRulesFactory(arg, label2);
|
|
12557
|
-
|
|
12970
|
+
const carried = evaluated ? localCarried(evaluated.ruleMap, label2, composing, evaluated.scanSkip) : null;
|
|
12971
|
+
return carried ? { ...carried, ...evaluated?.importedFactory ? { importedFactories: [evaluated.importedFactory] } : {} } : null;
|
|
12558
12972
|
}
|
|
12559
12973
|
if (arg.type === "Identifier") {
|
|
12560
12974
|
const name = arg.name;
|
|
@@ -12626,6 +13040,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12626
13040
|
}
|
|
12627
13041
|
const composing = composingTrivia(elements);
|
|
12628
13042
|
const carried = [];
|
|
13043
|
+
const importedFactories = [];
|
|
12629
13044
|
for (let i = 0; i < elements.length; i++) {
|
|
12630
13045
|
const r = argPieces(elements[i], `compose${init.start}_${i}`, composing);
|
|
12631
13046
|
if (!r) {
|
|
@@ -12633,6 +13048,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12633
13048
|
return null;
|
|
12634
13049
|
}
|
|
12635
13050
|
carried.push(...r.carried);
|
|
13051
|
+
importedFactories.push(...r.importedFactories ?? []);
|
|
12636
13052
|
}
|
|
12637
13053
|
const detailed = once(() => carriedRuleMapsDetailed(carried));
|
|
12638
13054
|
runFusedGatingDiagnostic(
|
|
@@ -12642,7 +13058,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12642
13058
|
);
|
|
12643
13059
|
const pieces = materializeCarried(carried, composing, false, cHostMode);
|
|
12644
13060
|
try {
|
|
12645
|
-
return {
|
|
13061
|
+
return {
|
|
13062
|
+
replacement: emitFusedSource(pieces),
|
|
13063
|
+
carried,
|
|
13064
|
+
...composing ? { trivia: composing } : {},
|
|
13065
|
+
...importedFactories.length ? { importedFactories } : {}
|
|
13066
|
+
};
|
|
12646
13067
|
} catch (e) {
|
|
12647
13068
|
warn(init.start, `compose(): ${e.message}; falling back to runtime`);
|
|
12648
13069
|
return null;
|
|
@@ -12663,10 +13084,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12663
13084
|
const localArg = elements[elements.length - 1];
|
|
12664
13085
|
let localRules = null;
|
|
12665
13086
|
let localScanSkip;
|
|
13087
|
+
const importedFactories = [];
|
|
12666
13088
|
if (isRulesCall(localArg)) {
|
|
12667
13089
|
const evaluated = evaluateRulesFactory(localArg, `composeLeaf${init.start}`);
|
|
12668
13090
|
localRules = evaluated?.ruleMap ?? null;
|
|
12669
13091
|
localScanSkip = evaluated?.scanSkip;
|
|
13092
|
+
if (evaluated?.importedFactory) importedFactories.push(evaluated.importedFactory);
|
|
12670
13093
|
} else if (localArg.type === "Identifier") {
|
|
12671
13094
|
const name = localArg.name;
|
|
12672
13095
|
localRules = localRuleMaps.get(name) ?? null;
|
|
@@ -12685,6 +13108,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12685
13108
|
return null;
|
|
12686
13109
|
}
|
|
12687
13110
|
carried.push(...r.carried);
|
|
13111
|
+
importedFactories.push(...r.importedFactories ?? []);
|
|
12688
13112
|
}
|
|
12689
13113
|
try {
|
|
12690
13114
|
const localNs = nsFor(`composeLeaf${init.start}`);
|
|
@@ -12710,13 +13134,15 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12710
13134
|
return null;
|
|
12711
13135
|
}
|
|
12712
13136
|
const replacement = withLeafMarker(emitFusedSource(grammarCoverage ? recognitionPieces : [...recognitionPieces, plainLocalPiece]));
|
|
12713
|
-
return {
|
|
13137
|
+
return {
|
|
13138
|
+
replacement: withCoverageDefinitions(replacement, emittedCoverageDefinitions(replacement)),
|
|
13139
|
+
...importedFactories.length ? { importedFactories } : {}
|
|
13140
|
+
};
|
|
12714
13141
|
} catch (e) {
|
|
12715
13142
|
warn(init.start, `composeLeaf(): ${e.message}`);
|
|
12716
13143
|
return null;
|
|
12717
13144
|
}
|
|
12718
13145
|
};
|
|
12719
|
-
const unwrapVd = (stmt) => stmt.type === "VariableDeclaration" ? stmt : stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration" ? stmt.declaration : null;
|
|
12720
13146
|
const refNames = /* @__PURE__ */ new Set();
|
|
12721
13147
|
for (const stmt of body) {
|
|
12722
13148
|
const innerVd = unwrapVd(stmt);
|
|
@@ -12777,7 +13203,14 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12777
13203
|
const kind = vd.kind ?? "const";
|
|
12778
13204
|
if (d.id.type === "Identifier") {
|
|
12779
13205
|
const varName = d.id.name;
|
|
12780
|
-
if (!referencesAny(init, allNames, scope))
|
|
13206
|
+
if (!referencesAny(init, allNames, scope)) {
|
|
13207
|
+
const staticValue = evaluateStaticValue(init, scope, code);
|
|
13208
|
+
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
13209
|
+
;
|
|
13210
|
+
scope.set(varName, staticValue);
|
|
13211
|
+
}
|
|
13212
|
+
continue;
|
|
13213
|
+
}
|
|
12781
13214
|
if (refNames.has(varName)) {
|
|
12782
13215
|
const refEntry = scope.get(varName);
|
|
12783
13216
|
const refCombi = refEntry?.combi ?? null;
|
|
@@ -12800,6 +13233,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12800
13233
|
const ns = nsFor(varName);
|
|
12801
13234
|
const pieces = exportPrefix || compiledRules.replacement === null ? compileLinkable([...compiledRules.ruleMap], ns, {
|
|
12802
13235
|
...compiledRules.scanSkip ? { scanSkip: compiledRules.scanSkip } : {},
|
|
13236
|
+
...compiledRules.trackLines ? { trackLines: true } : {},
|
|
12803
13237
|
recovery
|
|
12804
13238
|
}) : null;
|
|
12805
13239
|
if (compiledRules.replacement === null) {
|
|
@@ -12816,12 +13250,16 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12816
13250
|
);
|
|
12817
13251
|
if (compiledRules.replacement !== null) {
|
|
12818
13252
|
replacement = withHostMode(replacement, compiledRules.hostMode, compiledRules.hostBranchElided);
|
|
13253
|
+
replacement = withGrammarReflection(replacement, compiledRules.reflection);
|
|
12819
13254
|
}
|
|
12820
13255
|
if (exportPrefix && pieces && !pieces.mfFns.length && !pieces.buildFns.length) {
|
|
12821
13256
|
const ir = serializeRuleMap([...compiledRules.ruleMap], compiledRules.scanSkip);
|
|
12822
|
-
replacement = withCarriedPieces(replacement, [ir ? { ns, ir } : pieces]);
|
|
13257
|
+
replacement = withCarriedPieces(replacement, [ir ? { ns, ir, ...compiledRules.trackLines ? { trackLines: true } : {} } : pieces]);
|
|
12823
13258
|
}
|
|
12824
13259
|
replacements.push({ start: init.start, end: init.end, replacement });
|
|
13260
|
+
if (compiledRules.replacement !== null) {
|
|
13261
|
+
markUsedImportedFactories(compiledRules.importedFactory ? [compiledRules.importedFactory] : void 0);
|
|
13262
|
+
}
|
|
12825
13263
|
continue;
|
|
12826
13264
|
}
|
|
12827
13265
|
if (isComposeCall(init)) {
|
|
@@ -12834,6 +13272,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12834
13272
|
if (fused.trivia) localComposedTrivia.set(varName, fused.trivia);
|
|
12835
13273
|
const replacement = exportPrefix ? withCarriedPieces(fused.replacement, fused.carried) : fused.replacement;
|
|
12836
13274
|
replacements.push({ start: init.start, end: init.end, replacement: withCoverageDefinitions(replacement, emittedCoverageDefinitions(replacement)) });
|
|
13275
|
+
markUsedImportedFactories(fused.importedFactories);
|
|
12837
13276
|
continue;
|
|
12838
13277
|
}
|
|
12839
13278
|
if (isComposeLeafCall(init)) {
|
|
@@ -12842,6 +13281,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12842
13281
|
throw new Error(`${id}:${lineOf(init.start)} \u2014 composeLeaf() must macro-fuse; runtime composition is forbidden`);
|
|
12843
13282
|
}
|
|
12844
13283
|
replacements.push({ start: init.start, end: init.end, replacement: fused.replacement });
|
|
13284
|
+
markUsedImportedFactories(fused.importedFactories);
|
|
12845
13285
|
continue;
|
|
12846
13286
|
}
|
|
12847
13287
|
const mapFnSources = [];
|
|
@@ -12867,6 +13307,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12867
13307
|
scope.set(varName, combiArray);
|
|
12868
13308
|
continue;
|
|
12869
13309
|
}
|
|
13310
|
+
const staticValue = evaluateStaticValue(init, scope, code);
|
|
13311
|
+
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
13312
|
+
;
|
|
13313
|
+
scope.set(varName, staticValue);
|
|
13314
|
+
continue;
|
|
13315
|
+
}
|
|
12870
13316
|
if (factoryDecls.has(varName)) continue;
|
|
12871
13317
|
warn(init.start, `"${varName}" references a parseman macro import but isn't a statically-evaluable combinator`);
|
|
12872
13318
|
continue;
|
|
@@ -12930,6 +13376,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12930
13376
|
end: stmtEnd,
|
|
12931
13377
|
replacement: lines.join("\n")
|
|
12932
13378
|
});
|
|
13379
|
+
markUsedImportedFactories(compiledRules.importedFactory ? [compiledRules.importedFactory] : void 0);
|
|
12933
13380
|
}
|
|
12934
13381
|
}
|
|
12935
13382
|
}
|
|
@@ -12938,6 +13385,40 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12938
13385
|
imp.fullyResolved = !anyUnresolved && !keepMacroImport;
|
|
12939
13386
|
}
|
|
12940
13387
|
const ms = new import_magic_string.default(code);
|
|
13388
|
+
const replacementRanges = runtimeComposeFallback ? [] : replacements.map(({ start, end }) => ({ start, end }));
|
|
13389
|
+
const isInsideReplacement = (start, end) => replacementRanges.some((r) => start >= r.start && end <= r.end);
|
|
13390
|
+
const importedBindingStillReferenced = (local) => {
|
|
13391
|
+
const walk = (node2, parent, parentKey) => {
|
|
13392
|
+
if (!node2 || typeof node2 !== "object") return false;
|
|
13393
|
+
const rec = node2;
|
|
13394
|
+
if (rec.type === "ImportDeclaration") return false;
|
|
13395
|
+
if (typeof rec.start === "number" && typeof rec.end === "number" && isInsideReplacement(rec.start, rec.end)) return false;
|
|
13396
|
+
if ((rec.type === "Identifier" || rec.type === "BindingIdentifier") && rec.name === local) {
|
|
13397
|
+
if (parentKey === "key" && (parent?.type === "ObjectProperty" || parent?.type === "Property" || parent?.type === "PropertyDefinition") && parent.computed !== true) return false;
|
|
13398
|
+
if (parentKey === "property" && parent?.type === "StaticMemberExpression") return false;
|
|
13399
|
+
if (parentKey === "property" && parent?.type === "MemberExpression" && parent.computed !== true) return false;
|
|
13400
|
+
return true;
|
|
13401
|
+
}
|
|
13402
|
+
for (const key of Object.keys(rec)) {
|
|
13403
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
13404
|
+
const value = rec[key];
|
|
13405
|
+
if (Array.isArray(value)) {
|
|
13406
|
+
if (value.some((child) => walk(child, rec, key))) return true;
|
|
13407
|
+
} else if (walk(value, rec, key)) {
|
|
13408
|
+
return true;
|
|
13409
|
+
}
|
|
13410
|
+
}
|
|
13411
|
+
return false;
|
|
13412
|
+
};
|
|
13413
|
+
return body.some((stmt) => walk(stmt));
|
|
13414
|
+
};
|
|
13415
|
+
for (const imp of ordinaryImports) {
|
|
13416
|
+
if (!runtimeComposeFallback && imp.specifiers.length > 0 && imp.specifiers.every(
|
|
13417
|
+
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !importedBindingStillReferenced(spec.local)
|
|
13418
|
+
)) {
|
|
13419
|
+
ms.remove(imp.start, imp.end);
|
|
13420
|
+
}
|
|
13421
|
+
}
|
|
12941
13422
|
if (!anyUnresolved) {
|
|
12942
13423
|
for (const { start, end } of defineRemovals) ms.remove(start, end);
|
|
12943
13424
|
}
|