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.js
CHANGED
|
@@ -2742,6 +2742,191 @@ function markUnusedValues(root) {
|
|
|
2742
2742
|
visit(resolveRoot(root), true);
|
|
2743
2743
|
}
|
|
2744
2744
|
|
|
2745
|
+
// src/combinators/grammar.ts
|
|
2746
|
+
function annotateResultLines(result, index) {
|
|
2747
|
+
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
2748
|
+
const errors = annotated.errors;
|
|
2749
|
+
if (errors) {
|
|
2750
|
+
;
|
|
2751
|
+
annotated.errors = errors.map((error) => ({
|
|
2752
|
+
...error,
|
|
2753
|
+
span: annotateSpan(error.span, index)
|
|
2754
|
+
}));
|
|
2755
|
+
}
|
|
2756
|
+
return annotated;
|
|
2757
|
+
}
|
|
2758
|
+
function createParseLineContext(input, pos) {
|
|
2759
|
+
const lineIndex = createLineIndex();
|
|
2760
|
+
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
2761
|
+
return { lineIndex, lineScannedTo: pos };
|
|
2762
|
+
}
|
|
2763
|
+
function parser(opts, root) {
|
|
2764
|
+
const clearTrivia = opts.trivia === null;
|
|
2765
|
+
return {
|
|
2766
|
+
_tag: "grammar",
|
|
2767
|
+
_meta: root._meta,
|
|
2768
|
+
_def: {
|
|
2769
|
+
tag: "grammar",
|
|
2770
|
+
parser: root,
|
|
2771
|
+
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
2772
|
+
clearTrivia,
|
|
2773
|
+
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
2774
|
+
trackLines: opts.trackLines ?? false
|
|
2775
|
+
},
|
|
2776
|
+
parse(input, pos, _ctx) {
|
|
2777
|
+
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
2778
|
+
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
2779
|
+
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
2780
|
+
const ctx = {
|
|
2781
|
+
..._ctx,
|
|
2782
|
+
trackLines,
|
|
2783
|
+
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
2784
|
+
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
2785
|
+
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
2786
|
+
...clearTrivia ? {
|
|
2787
|
+
trivia: void 0,
|
|
2788
|
+
triviaKindLabels: void 0
|
|
2789
|
+
} : opts.trivia != null ? {
|
|
2790
|
+
trivia: opts.trivia,
|
|
2791
|
+
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
2792
|
+
} : {},
|
|
2793
|
+
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
2794
|
+
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
2795
|
+
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
2796
|
+
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
2797
|
+
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
2798
|
+
// (capture all).
|
|
2799
|
+
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
2800
|
+
};
|
|
2801
|
+
const result = root.parse(input, pos ?? 0, ctx);
|
|
2802
|
+
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
2803
|
+
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
2804
|
+
}
|
|
2805
|
+
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
2806
|
+
}
|
|
2807
|
+
};
|
|
2808
|
+
}
|
|
2809
|
+
function noTrivia(root) {
|
|
2810
|
+
return parser({ trivia: null }, root);
|
|
2811
|
+
}
|
|
2812
|
+
|
|
2813
|
+
// src/cst/reflection.ts
|
|
2814
|
+
var GRAMMAR_REFLECTION = /* @__PURE__ */ Symbol.for("parseman.grammarReflection");
|
|
2815
|
+
function childrenOf(def) {
|
|
2816
|
+
switch (def.tag) {
|
|
2817
|
+
case "sequence":
|
|
2818
|
+
case "choice":
|
|
2819
|
+
return def.parsers;
|
|
2820
|
+
case "dispatch":
|
|
2821
|
+
return [
|
|
2822
|
+
def.selector,
|
|
2823
|
+
...def.cases.map((c) => c.parser),
|
|
2824
|
+
...def.matchers ? def.matchers.map((c) => c.parser) : [],
|
|
2825
|
+
...def.otherwise ? [def.otherwise] : []
|
|
2826
|
+
];
|
|
2827
|
+
case "many":
|
|
2828
|
+
case "oneOrMore":
|
|
2829
|
+
case "optional":
|
|
2830
|
+
case "attempt":
|
|
2831
|
+
case "transform":
|
|
2832
|
+
case "trivia":
|
|
2833
|
+
case "token":
|
|
2834
|
+
case "leaf":
|
|
2835
|
+
case "label":
|
|
2836
|
+
case "field":
|
|
2837
|
+
case "not":
|
|
2838
|
+
case "peek":
|
|
2839
|
+
case "node":
|
|
2840
|
+
case "withCtx":
|
|
2841
|
+
case "recover":
|
|
2842
|
+
case "expect":
|
|
2843
|
+
return [def.parser];
|
|
2844
|
+
case "grammar":
|
|
2845
|
+
return def.triviaParser ? [def.parser, def.triviaParser] : [def.parser];
|
|
2846
|
+
case "sepBy":
|
|
2847
|
+
return [def.parser, def.separator];
|
|
2848
|
+
case "skip":
|
|
2849
|
+
return [def.main, def.skipped];
|
|
2850
|
+
case "scanTo":
|
|
2851
|
+
return [def.sentinel, ...def.skip];
|
|
2852
|
+
case "literal":
|
|
2853
|
+
case "regex":
|
|
2854
|
+
case "keywords":
|
|
2855
|
+
case "routed":
|
|
2856
|
+
case "guard":
|
|
2857
|
+
case "lazy":
|
|
2858
|
+
case "unknown":
|
|
2859
|
+
return [];
|
|
2860
|
+
}
|
|
2861
|
+
}
|
|
2862
|
+
function addNode(out, def) {
|
|
2863
|
+
if (def.type === void 0) return;
|
|
2864
|
+
const existing = out.get(def.type);
|
|
2865
|
+
if (existing === void 0) {
|
|
2866
|
+
out.set(def.type, def.tags === void 0 ? [] : [...def.tags]);
|
|
2867
|
+
return;
|
|
2868
|
+
}
|
|
2869
|
+
if (def.tags === void 0) return;
|
|
2870
|
+
for (const tag of def.tags) {
|
|
2871
|
+
if (!existing.includes(tag)) existing.push(tag);
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
2875
|
+
if (seen.has(parser2)) return;
|
|
2876
|
+
seen.add(parser2);
|
|
2877
|
+
const def = parser2._def;
|
|
2878
|
+
if (def.tag === "lazy") {
|
|
2879
|
+
if (followLazy) {
|
|
2880
|
+
try {
|
|
2881
|
+
collectFromCombinator(def.thunk(), out, seen, followLazy);
|
|
2882
|
+
} catch {
|
|
2883
|
+
}
|
|
2884
|
+
}
|
|
2885
|
+
return;
|
|
2886
|
+
}
|
|
2887
|
+
if (def.tag === "node") addNode(out, def);
|
|
2888
|
+
for (const child of childrenOf(def)) collectFromCombinator(child, out, seen, followLazy);
|
|
2889
|
+
}
|
|
2890
|
+
function collectGrammarReflection(ruleMap, opts) {
|
|
2891
|
+
const byType = /* @__PURE__ */ new Map();
|
|
2892
|
+
const followLazy = opts?.followLazy !== false;
|
|
2893
|
+
for (const [, rule] of ruleMap) {
|
|
2894
|
+
if (!followLazy && rule._def.tag === "lazy") {
|
|
2895
|
+
try {
|
|
2896
|
+
const resolved = rule._def.thunk();
|
|
2897
|
+
if (resolved._def.tag !== "lazy") collectFromCombinator(resolved, byType, /* @__PURE__ */ new Set(), false);
|
|
2898
|
+
} catch {
|
|
2899
|
+
}
|
|
2900
|
+
continue;
|
|
2901
|
+
}
|
|
2902
|
+
collectFromCombinator(rule, byType, /* @__PURE__ */ new Set(), followLazy);
|
|
2903
|
+
}
|
|
2904
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
2905
|
+
}
|
|
2906
|
+
function mergeGrammarReflections(reflections) {
|
|
2907
|
+
const byType = /* @__PURE__ */ new Map();
|
|
2908
|
+
for (const reflection of reflections) {
|
|
2909
|
+
for (const node2 of reflection.nodes) {
|
|
2910
|
+
const tags = byType.get(node2.type);
|
|
2911
|
+
if (tags === void 0) {
|
|
2912
|
+
byType.set(node2.type, [...node2.tags]);
|
|
2913
|
+
continue;
|
|
2914
|
+
}
|
|
2915
|
+
for (const tag of node2.tags) {
|
|
2916
|
+
if (!tags.includes(tag)) tags.push(tag);
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
2921
|
+
}
|
|
2922
|
+
function attachGrammarReflection(grammar, reflection) {
|
|
2923
|
+
Object.defineProperty(grammar, GRAMMAR_REFLECTION, { value: reflection, enumerable: false, configurable: true });
|
|
2924
|
+
return grammar;
|
|
2925
|
+
}
|
|
2926
|
+
function grammarReflectionSource(reflection) {
|
|
2927
|
+
return `{ nodes: ${JSON.stringify(reflection.nodes)} }`;
|
|
2928
|
+
}
|
|
2929
|
+
|
|
2745
2930
|
// src/combinators/parser.ts
|
|
2746
2931
|
var RULE_ORDER = "__parsemanRuleOrder";
|
|
2747
2932
|
function tagRule(r, key) {
|
|
@@ -2817,6 +3002,21 @@ function rules(a, b) {
|
|
|
2817
3002
|
if (rule && !rule._meta.isTrivia) rule._meta.grammarHostMode = "cst";
|
|
2818
3003
|
}
|
|
2819
3004
|
}
|
|
3005
|
+
if (options?.trackLines === true) {
|
|
3006
|
+
for (const key of Object.keys(definitions)) {
|
|
3007
|
+
const rule = cache[key];
|
|
3008
|
+
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
3009
|
+
}
|
|
3010
|
+
for (const key of Object.keys(definitions)) {
|
|
3011
|
+
const rule = cache[key];
|
|
3012
|
+
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
3013
|
+
const wrapped = parser({ trackLines: true }, rule);
|
|
3014
|
+
tagRule(wrapped, key);
|
|
3015
|
+
wrapped._meta.grammarTrackLines = true;
|
|
3016
|
+
cache[key] = wrapped;
|
|
3017
|
+
}
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
2820
3020
|
for (const key of Object.keys(definitions)) {
|
|
2821
3021
|
markUnusedValues(cache[key]);
|
|
2822
3022
|
}
|
|
@@ -2825,6 +3025,7 @@ function rules(a, b) {
|
|
|
2825
3025
|
enumerable: false,
|
|
2826
3026
|
configurable: true
|
|
2827
3027
|
});
|
|
3028
|
+
attachGrammarReflection(cache, collectGrammarReflection(Object.keys(definitions).map((key) => [key, cache[key]])));
|
|
2828
3029
|
return cache;
|
|
2829
3030
|
}
|
|
2830
3031
|
|
|
@@ -3145,13 +3346,14 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3145
3346
|
const collapse = opts?.collapse === true;
|
|
3146
3347
|
const captureTrivia = opts?.captureTrivia === true;
|
|
3147
3348
|
const trailingTrivia = opts?.trailingTrivia === true;
|
|
3349
|
+
const tags = opts?.tags;
|
|
3148
3350
|
if (unwrap && collapse) {
|
|
3149
3351
|
throw new Error("node() options cannot set both unwrap and collapse");
|
|
3150
3352
|
}
|
|
3151
3353
|
if (project !== void 0 && (unwrap || collapse)) {
|
|
3152
3354
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
3153
3355
|
}
|
|
3154
|
-
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;
|
|
3356
|
+
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;
|
|
3155
3357
|
const capturesTrivia = captureTrivia || trailingTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
3156
3358
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
3157
3359
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
@@ -3197,7 +3399,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
3197
3399
|
const cstOutput = cstOutputHost(ctx.build);
|
|
3198
3400
|
const span = ctx.trackLines ? annotateSpanFromLineContext(r.span, ctx) : r.span;
|
|
3199
3401
|
const hostState = clonesState ? st : ctx.state !== void 0 ? Object.assign({}, ctx.state) : void 0;
|
|
3200
|
-
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 };
|
|
3402
|
+
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 };
|
|
3201
3403
|
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 };
|
|
3202
3404
|
if (saved.buf !== void 0 || saved.ch !== void 0) {
|
|
3203
3405
|
pushCstChild(ctx, built, rawEntry);
|
|
@@ -3273,74 +3475,6 @@ function field(name, combinator) {
|
|
|
3273
3475
|
};
|
|
3274
3476
|
}
|
|
3275
3477
|
|
|
3276
|
-
// src/combinators/grammar.ts
|
|
3277
|
-
function annotateResultLines(result, index) {
|
|
3278
|
-
const annotated = { ...result, span: annotateSpan(result.span, index) };
|
|
3279
|
-
const errors = annotated.errors;
|
|
3280
|
-
if (errors) {
|
|
3281
|
-
;
|
|
3282
|
-
annotated.errors = errors.map((error) => ({
|
|
3283
|
-
...error,
|
|
3284
|
-
span: annotateSpan(error.span, index)
|
|
3285
|
-
}));
|
|
3286
|
-
}
|
|
3287
|
-
return annotated;
|
|
3288
|
-
}
|
|
3289
|
-
function createParseLineContext(input, pos) {
|
|
3290
|
-
const lineIndex = createLineIndex();
|
|
3291
|
-
if (pos > 0) recordLineRange(lineIndex, input, 0, pos);
|
|
3292
|
-
return { lineIndex, lineScannedTo: pos };
|
|
3293
|
-
}
|
|
3294
|
-
function parser(opts, root) {
|
|
3295
|
-
const clearTrivia = opts.trivia === null;
|
|
3296
|
-
return {
|
|
3297
|
-
_tag: "grammar",
|
|
3298
|
-
_meta: root._meta,
|
|
3299
|
-
_def: {
|
|
3300
|
-
tag: "grammar",
|
|
3301
|
-
parser: root,
|
|
3302
|
-
triviaParser: clearTrivia ? void 0 : opts.trivia ?? void 0,
|
|
3303
|
-
clearTrivia,
|
|
3304
|
-
...opts.captureTrivia ? { captureTrivia: true } : {},
|
|
3305
|
-
trackLines: opts.trackLines ?? false
|
|
3306
|
-
},
|
|
3307
|
-
parse(input, pos, _ctx) {
|
|
3308
|
-
const trackLines = opts.trackLines ?? _ctx?.trackLines ?? false;
|
|
3309
|
-
const lineContext = trackLines && _ctx?._lineIndex === void 0 && _ctx?._lineStarts === void 0 ? createParseLineContext(input, pos ?? 0) : void 0;
|
|
3310
|
-
const lineIndex = trackLines ? _ctx?._lineIndex ?? (_ctx?._lineStarts ? { lineStarts: _ctx._lineStarts } : lineContext.lineIndex) : void 0;
|
|
3311
|
-
const ctx = {
|
|
3312
|
-
..._ctx,
|
|
3313
|
-
trackLines,
|
|
3314
|
-
...lineIndex ? { _lineIndex: lineIndex } : {},
|
|
3315
|
-
...lineContext ? { _lineScannedTo: lineContext.lineScannedTo } : {},
|
|
3316
|
-
// trivia: null clears (contiguous terms); a Combinator sets; undefined inherits.
|
|
3317
|
-
...clearTrivia ? {
|
|
3318
|
-
trivia: void 0,
|
|
3319
|
-
triviaKindLabels: void 0
|
|
3320
|
-
} : opts.trivia != null ? {
|
|
3321
|
-
trivia: opts.trivia,
|
|
3322
|
-
...opts.trivia._meta.triviaKindLabels ? { triviaKindLabels: opts.trivia._meta.triviaKindLabels } : {}
|
|
3323
|
-
} : {},
|
|
3324
|
-
...opts.captureTrivia || _ctx?.captureTrivia ? { captureTrivia: true } : {},
|
|
3325
|
-
// Kind-filter for per-node capture. Resolve against this scope's trivia
|
|
3326
|
-
// labels — this parser's own trivia if it declares one, else the INHERITED
|
|
3327
|
-
// labels (`_ctx.triviaKindLabels`), so captureTriviaKinds still applies when
|
|
3328
|
-
// trivia is inherited rather than re-declared here. No labels → undefined
|
|
3329
|
-
// (capture all).
|
|
3330
|
-
...opts.captureTriviaKinds && !clearTrivia ? { _triviaCaptureMask: triviaKindMask(opts.trivia?._meta.triviaKindLabels ?? _ctx?.triviaKindLabels, opts.captureTriviaKinds) } : {}
|
|
3331
|
-
};
|
|
3332
|
-
const result = root.parse(input, pos ?? 0, ctx);
|
|
3333
|
-
if (trackLines && _ctx && ctx._lineScannedTo !== void 0) {
|
|
3334
|
-
_ctx._lineScannedTo = Math.max(_ctx._lineScannedTo ?? 0, ctx._lineScannedTo);
|
|
3335
|
-
}
|
|
3336
|
-
return lineIndex ? annotateResultLines(result, normalizeLineIndex(lineIndex)) : result;
|
|
3337
|
-
}
|
|
3338
|
-
};
|
|
3339
|
-
}
|
|
3340
|
-
function noTrivia(root) {
|
|
3341
|
-
return parser({ trivia: null }, root);
|
|
3342
|
-
}
|
|
3343
|
-
|
|
3344
3478
|
// src/combinators/token.ts
|
|
3345
3479
|
function token(root) {
|
|
3346
3480
|
const meta = {
|
|
@@ -3437,7 +3571,7 @@ function leaf(root, fn) {
|
|
|
3437
3571
|
}
|
|
3438
3572
|
|
|
3439
3573
|
// src/version.ts
|
|
3440
|
-
var PARSEMAN_VERSION = "0.
|
|
3574
|
+
var PARSEMAN_VERSION = "0.43.0";
|
|
3441
3575
|
|
|
3442
3576
|
// src/cst/host-mode.ts
|
|
3443
3577
|
var FUSED_HOST_MODE = /* @__PURE__ */ Symbol.for("parseman.fusedHostMode");
|
|
@@ -3503,7 +3637,7 @@ var SUGGESTIONS = {
|
|
|
3503
3637
|
function classifyBroadArm(arm, resolve2) {
|
|
3504
3638
|
const seen = /* @__PURE__ */ new Set();
|
|
3505
3639
|
const relabel = (inner, cause, detail) => ({ cause, detail, ...inner?.unresolvedExternal ? { unresolvedExternal: true } : {} });
|
|
3506
|
-
const
|
|
3640
|
+
const walk = (p) => {
|
|
3507
3641
|
if (seen.has(p)) return { cause: "ref-cycle", detail: "ref cycle" };
|
|
3508
3642
|
seen.add(p);
|
|
3509
3643
|
const d = p._def;
|
|
@@ -3517,7 +3651,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3517
3651
|
// peek() CARRIES its body's first-set, so it is only broad when the body is
|
|
3518
3652
|
// (or the body is nullable) — walk in for the real cause.
|
|
3519
3653
|
case "peek":
|
|
3520
|
-
return
|
|
3654
|
+
return walk(d.parser);
|
|
3521
3655
|
case "scanTo":
|
|
3522
3656
|
return { cause: "broad-recognizer", detail: "scanTo (any first char)" };
|
|
3523
3657
|
// `guard` (the `gate()` state predicate) has a genuinely-`any` first-set of
|
|
@@ -3531,7 +3665,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3531
3665
|
case "attempt":
|
|
3532
3666
|
case "withCtx":
|
|
3533
3667
|
case "recover":
|
|
3534
|
-
return
|
|
3668
|
+
return walk(d.parser);
|
|
3535
3669
|
case "lazy": {
|
|
3536
3670
|
const name = p._ruleName;
|
|
3537
3671
|
let target;
|
|
@@ -3543,13 +3677,13 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3543
3677
|
return { cause: "cross-artifact-ref", detail: `unresolved ref${name ? ` g.${name}` : ""}`, unresolvedExternal: name !== void 0 };
|
|
3544
3678
|
target = bound;
|
|
3545
3679
|
}
|
|
3546
|
-
const inner =
|
|
3680
|
+
const inner = walk(target);
|
|
3547
3681
|
if (name !== void 0) return inner ? relabel(inner, "cross-artifact-ref", `via ref g.${name} \u2192 ${inner.detail}`) : null;
|
|
3548
3682
|
return inner;
|
|
3549
3683
|
}
|
|
3550
3684
|
case "optional":
|
|
3551
3685
|
case "many": {
|
|
3552
|
-
const inner =
|
|
3686
|
+
const inner = walk(d.parser);
|
|
3553
3687
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3554
3688
|
}
|
|
3555
3689
|
case "oneOrMore":
|
|
@@ -3562,9 +3696,9 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3562
3696
|
case "node":
|
|
3563
3697
|
case "grammar":
|
|
3564
3698
|
case "expect":
|
|
3565
|
-
return
|
|
3699
|
+
return walk(d.parser);
|
|
3566
3700
|
case "skip":
|
|
3567
|
-
return
|
|
3701
|
+
return walk(d.main);
|
|
3568
3702
|
case "sequence": {
|
|
3569
3703
|
let sawNullablePrefix = false;
|
|
3570
3704
|
for (const t of d.parsers) {
|
|
@@ -3573,7 +3707,7 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3573
3707
|
continue;
|
|
3574
3708
|
}
|
|
3575
3709
|
if (isAny(firstSetOf(t, /* @__PURE__ */ new Set(), resolve2))) {
|
|
3576
|
-
const inner =
|
|
3710
|
+
const inner = walk(t);
|
|
3577
3711
|
if (sawNullablePrefix)
|
|
3578
3712
|
return relabel(inner, "nullable-prefix", inner ? `nullable prefix \u2192 ${inner.detail}` : "nullable prefix to broad term");
|
|
3579
3713
|
return inner ?? { cause: "broad-recognizer", detail: "sequence leading term is broad" };
|
|
@@ -3588,18 +3722,18 @@ function classifyBroadArm(arm, resolve2) {
|
|
|
3588
3722
|
}
|
|
3589
3723
|
case "choice": {
|
|
3590
3724
|
for (const a of d.parsers) {
|
|
3591
|
-
const r =
|
|
3725
|
+
const r = walk(a);
|
|
3592
3726
|
if (r) return relabel(r, r.cause, `choice arm \u2192 ${r.detail}`);
|
|
3593
3727
|
}
|
|
3594
3728
|
return null;
|
|
3595
3729
|
}
|
|
3596
3730
|
case "dispatch":
|
|
3597
|
-
return
|
|
3731
|
+
return walk(d.selector);
|
|
3598
3732
|
default:
|
|
3599
3733
|
return { cause: "broad-recognizer", detail: `unmodeled construct (${d.tag})` };
|
|
3600
3734
|
}
|
|
3601
3735
|
};
|
|
3602
|
-
return
|
|
3736
|
+
return walk(arm) ?? { cause: "broad-recognizer", detail: "broad (cause not localized)" };
|
|
3603
3737
|
}
|
|
3604
3738
|
function peelToLeading(arm) {
|
|
3605
3739
|
let d = arm._def;
|
|
@@ -3801,7 +3935,7 @@ function formatGatingWarnings(report) {
|
|
|
3801
3935
|
|
|
3802
3936
|
// src/analysis/duplication.ts
|
|
3803
3937
|
var siteToString = (s) => s.path === "" ? s.rule : `${s.rule} \u203A ${s.path}`;
|
|
3804
|
-
function
|
|
3938
|
+
function childrenOf2(d) {
|
|
3805
3939
|
switch (d.tag) {
|
|
3806
3940
|
case "sequence":
|
|
3807
3941
|
case "choice":
|
|
@@ -3935,7 +4069,7 @@ function render(p, depth = 3) {
|
|
|
3935
4069
|
break;
|
|
3936
4070
|
}
|
|
3937
4071
|
if (depth <= 0) return `${d.tag}(\u2026)`;
|
|
3938
|
-
const kids =
|
|
4072
|
+
const kids = childrenOf2(d).map((k) => render(k, depth - 1));
|
|
3939
4073
|
switch (d.tag) {
|
|
3940
4074
|
case "sequence":
|
|
3941
4075
|
return `sequence(${kids.join(", ")})`;
|
|
@@ -4130,7 +4264,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4130
4264
|
if (hit !== void 0) return hit;
|
|
4131
4265
|
const d = p._def;
|
|
4132
4266
|
shapeCache.set(p, interner.hole);
|
|
4133
|
-
const kids =
|
|
4267
|
+
const kids = childrenOf2(d);
|
|
4134
4268
|
const id = interner.of(`${payloadKey(p, d)}|${kids.map(shapeOf).join(",")}`);
|
|
4135
4269
|
shapeCache.set(p, id);
|
|
4136
4270
|
return id;
|
|
@@ -4140,7 +4274,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4140
4274
|
if (hit !== void 0) return hit;
|
|
4141
4275
|
sizeCache.set(p, 1);
|
|
4142
4276
|
let n = 1;
|
|
4143
|
-
for (const k of
|
|
4277
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4144
4278
|
sizeCache.set(p, n);
|
|
4145
4279
|
return n;
|
|
4146
4280
|
};
|
|
@@ -4153,7 +4287,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4153
4287
|
visited.set(p, { p, d, site: here, shape: shapeOf(p), size: sizeOf(p), enclosingNode, enclosingReducer });
|
|
4154
4288
|
const inner = d.tag === "node" ? d.type ?? "(anonymous)" : enclosingNode;
|
|
4155
4289
|
const innerReducer = enclosingReducer || d.tag === "node" && (d.build !== void 0 || d.buildSrc !== void 0) || d.tag === "transform" || d.tag === "leaf";
|
|
4156
|
-
const kids =
|
|
4290
|
+
const kids = childrenOf2(d);
|
|
4157
4291
|
kids.forEach((k, i) => {
|
|
4158
4292
|
const seg = segment(d, i);
|
|
4159
4293
|
visit(k, here.rule, here.path === "" ? seg : `${here.path} \u203A ${seg}`, inner, innerReducer);
|
|
@@ -4213,7 +4347,7 @@ function analyzeDuplicationRules(ruleMap, opts) {
|
|
|
4213
4347
|
function markSubtree(p, into) {
|
|
4214
4348
|
if (into.has(p)) return;
|
|
4215
4349
|
into.add(p);
|
|
4216
|
-
for (const k of
|
|
4350
|
+
for (const k of childrenOf2(p._def)) markSubtree(k, into);
|
|
4217
4351
|
}
|
|
4218
4352
|
var stripMembers = (f) => {
|
|
4219
4353
|
const { _members, ...rest } = f;
|
|
@@ -4253,7 +4387,7 @@ function findNearDuplicates(visited, interner, shapeOf, minSize) {
|
|
|
4253
4387
|
if (hit !== void 0) return hit;
|
|
4254
4388
|
holeCache.set(p, []);
|
|
4255
4389
|
const d = p._def;
|
|
4256
|
-
const kids =
|
|
4390
|
+
const kids = childrenOf2(d);
|
|
4257
4391
|
const kidShapes = kids.map(shapeOf);
|
|
4258
4392
|
const payload = payloadKey(p, d);
|
|
4259
4393
|
const out2 = [];
|
|
@@ -4314,7 +4448,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4314
4448
|
let cur = [...members];
|
|
4315
4449
|
for (let guard2 = 0; guard2 < 64; guard2++) {
|
|
4316
4450
|
const d0 = cur[0]._def;
|
|
4317
|
-
const kidLists = cur.map((c) =>
|
|
4451
|
+
const kidLists = cur.map((c) => childrenOf2(c._def));
|
|
4318
4452
|
const arity = kidLists[0].length;
|
|
4319
4453
|
if (kidLists.some((k) => k.length !== arity) || arity === 0) break;
|
|
4320
4454
|
const diff = [];
|
|
@@ -4327,7 +4461,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4327
4461
|
path2.push(i);
|
|
4328
4462
|
defs.push(d0);
|
|
4329
4463
|
cur = kidLists.map((k) => k[i]);
|
|
4330
|
-
const nextArity =
|
|
4464
|
+
const nextArity = childrenOf2(cur[0]._def).length;
|
|
4331
4465
|
const samePayload = cur.every((c) => payloadKey(c, c._def) === payloadKey(cur[0], cur[0]._def));
|
|
4332
4466
|
if (!samePayload || nextArity === 0) break;
|
|
4333
4467
|
}
|
|
@@ -4335,7 +4469,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4335
4469
|
let slotSize = 0;
|
|
4336
4470
|
const sizeOf = (p) => {
|
|
4337
4471
|
let n = 1;
|
|
4338
|
-
for (const k of
|
|
4472
|
+
for (const k of childrenOf2(p._def)) n += sizeOf(k);
|
|
4339
4473
|
return n;
|
|
4340
4474
|
};
|
|
4341
4475
|
for (const c of cur) slotSize = Math.max(slotSize, sizeOf(c));
|
|
@@ -4344,7 +4478,7 @@ function findDivergentSlot(members, shapeOf) {
|
|
|
4344
4478
|
function renderWithHole(p, path2, depth = 0) {
|
|
4345
4479
|
if (depth === path2.length) return "\u2039slot\u203A";
|
|
4346
4480
|
const d = p._def;
|
|
4347
|
-
const kids =
|
|
4481
|
+
const kids = childrenOf2(d);
|
|
4348
4482
|
const idx = path2[depth];
|
|
4349
4483
|
const parts = kids.map((k, i) => i === idx ? renderWithHole(k, path2, depth + 1) : render(k, 2));
|
|
4350
4484
|
switch (d.tag) {
|
|
@@ -4802,7 +4936,7 @@ function capturesPositionally(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
4802
4936
|
seen.add(p);
|
|
4803
4937
|
const d = p._def;
|
|
4804
4938
|
if (d.tag === "field" || d.tag === "label") return true;
|
|
4805
|
-
for (const k of
|
|
4939
|
+
for (const k of childrenOf2(d)) if (capturesPositionally(k, seen)) return true;
|
|
4806
4940
|
return false;
|
|
4807
4941
|
}
|
|
4808
4942
|
function detectHandRolledSepBy(terms, shapeOf) {
|
|
@@ -4908,7 +5042,7 @@ function nestedNodeTypes(root, out, seen, isRoot) {
|
|
|
4908
5042
|
}
|
|
4909
5043
|
return;
|
|
4910
5044
|
}
|
|
4911
|
-
for (const k of
|
|
5045
|
+
for (const k of childrenOf2(d)) nestedNodeTypes(k, out, seen, false);
|
|
4912
5046
|
}
|
|
4913
5047
|
var MAX_LOST_TYPES = 8;
|
|
4914
5048
|
function findStructureLoss(visited, resolve2) {
|
|
@@ -6805,13 +6939,16 @@ function reindentStmts(stmts, targetLevels) {
|
|
|
6805
6939
|
const targetPrefix = " ".repeat(targetLevels);
|
|
6806
6940
|
return stmts.map((s) => s.trim().length === 0 ? "" : targetPrefix + s.slice(minLeading));
|
|
6807
6941
|
}
|
|
6808
|
-
function failReturn(expected, posExpr) {
|
|
6942
|
+
function failReturn(ctx, expected, posExpr) {
|
|
6943
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [${expected}], span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6809
6944
|
return `return { ok: false, expected: [${expected}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6810
6945
|
}
|
|
6811
|
-
function failReturnArr(expectedArr, posExpr) {
|
|
6946
|
+
function failReturnArr(ctx, expectedArr, posExpr) {
|
|
6947
|
+
if (ctx.lineTracking) return `return { ok: false, expected: ${expectedArr}, span: ${emitSpanExpr(ctx, posExpr, posExpr)} }`;
|
|
6812
6948
|
return `return { ok: false, expected: ${expectedArr}, span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6813
6949
|
}
|
|
6814
|
-
function committedReturnArr(expectedArr, posExpr) {
|
|
6950
|
+
function committedReturnArr(ctx, expectedArr, posExpr) {
|
|
6951
|
+
if (ctx.lineTracking) return `return { ok: false, expected: [...${expectedArr}], span: ${emitSpanExpr(ctx, posExpr, posExpr)}, committed: true }`;
|
|
6815
6952
|
return `return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} }, committed: true }`;
|
|
6816
6953
|
}
|
|
6817
6954
|
function hoistExpected(ctx, constArrSource) {
|
|
@@ -6836,7 +6973,7 @@ function failBody(ctx, expected, posExpr) {
|
|
|
6836
6973
|
if (!ctx.recordFail) return probe ? `{ ${probe}${trace}break ${ctx.failLabel} }` : trace ? `{ ${trace}break ${ctx.failLabel} }` : `break ${ctx.failLabel}`;
|
|
6837
6974
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${hoistExpected(ctx, `[${expected}]`)}; ${trace}break ${ctx.failLabel} }`;
|
|
6838
6975
|
}
|
|
6839
|
-
return probe + trace + failReturn(expected, posExpr);
|
|
6976
|
+
return probe + trace + failReturn(ctx, expected, posExpr);
|
|
6840
6977
|
}
|
|
6841
6978
|
function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
6842
6979
|
const probe = probeUpdate(ctx, expectedArr, posExpr, constant);
|
|
@@ -6846,18 +6983,19 @@ function failArrBody(ctx, expectedArr, posExpr, constant = true) {
|
|
|
6846
6983
|
const fx = constant ? hoistExpected(ctx, expectedArr) : expectedArr;
|
|
6847
6984
|
return `{ ${probe}_ctx._fe = ${posExpr}; _ctx._fx = ${fx}; ${trace}break ${ctx.failLabel} }`;
|
|
6848
6985
|
}
|
|
6849
|
-
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: { start: ${posExpr}, end: ${posExpr} } }`;
|
|
6850
|
-
return probe + trace + failReturnArr(expectedArr, posExpr);
|
|
6986
|
+
if (!constant) return `${probe}${trace}return { ok: false, expected: [...${expectedArr}], span: ${ctx.lineTracking ? emitSpanExpr(ctx, posExpr, posExpr) : `{ start: ${posExpr}, end: ${posExpr} }`} }`;
|
|
6987
|
+
return probe + trace + failReturnArr(ctx, expectedArr, posExpr);
|
|
6851
6988
|
}
|
|
6852
|
-
function resultFromRecorded(feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6853
|
-
|
|
6989
|
+
function resultFromRecorded(ctx, feExpr = "_ctx._fe", fxExpr = "_ctx._fx") {
|
|
6990
|
+
const spanExpr = ctx.lineTracking ? emitSpanExpr(ctx, feExpr, feExpr) : `{ start: ${feExpr}, end: ${feExpr} }`;
|
|
6991
|
+
return `return { ok: false, expected: [...${fxExpr}], span: ${spanExpr}, ...(_ctx._fc ? { committed: true } : {}) }`;
|
|
6854
6992
|
}
|
|
6855
6993
|
function committedFailBody(ctx, expectedArr = "_ctx._fx", posExpr = "_ctx._fe") {
|
|
6856
6994
|
if (ctx.failLabel) {
|
|
6857
6995
|
if (!ctx.recordFail) return `{ _ctx._fc = true; break ${ctx.failLabel} }`;
|
|
6858
6996
|
return `{ _ctx._fc = true; _ctx._fe = ${posExpr}; _ctx._fx = ${expectedArr}; break ${ctx.failLabel} }`;
|
|
6859
6997
|
}
|
|
6860
|
-
return committedReturnArr(expectedArr, posExpr);
|
|
6998
|
+
return committedReturnArr(ctx, expectedArr, posExpr);
|
|
6861
6999
|
}
|
|
6862
7000
|
function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
6863
7001
|
if (srcCtx !== "_ctx") {
|
|
@@ -6865,10 +7003,10 @@ function propagateFailBody(ctx, srcCtx = "_ctx") {
|
|
|
6865
7003
|
if (!ctx.recordFail) return `break ${ctx.failLabel}`;
|
|
6866
7004
|
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; break ${ctx.failLabel} }`;
|
|
6867
7005
|
}
|
|
6868
|
-
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded()} }`;
|
|
7006
|
+
return `{ _ctx._fe = ${srcCtx}._fe; _ctx._fx = ${srcCtx}._fx; _ctx._fc = ${srcCtx}._fc; ${resultFromRecorded(ctx)} }`;
|
|
6869
7007
|
}
|
|
6870
7008
|
if (ctx.failLabel) return `break ${ctx.failLabel}`;
|
|
6871
|
-
return resultFromRecorded();
|
|
7009
|
+
return resultFromRecorded(ctx);
|
|
6872
7010
|
}
|
|
6873
7011
|
function emitIfFail(ctx, cond, body) {
|
|
6874
7012
|
return [
|
|
@@ -8099,7 +8237,7 @@ function routedNeedsContextBridge(p, ctx, seen = /* @__PURE__ */ new Set()) {
|
|
|
8099
8237
|
const d = p._def;
|
|
8100
8238
|
if (d.tag === "dispatch") return false;
|
|
8101
8239
|
if (d.tag === "withCtx") return parserUsesRouted2(d.parser);
|
|
8102
|
-
return
|
|
8240
|
+
return childrenOf3(d).some((child) => routedNeedsContextBridge(child, ctx, seen));
|
|
8103
8241
|
}
|
|
8104
8242
|
function armReplayInScope(arm, ctx) {
|
|
8105
8243
|
let p = arm;
|
|
@@ -8301,7 +8439,7 @@ function emitAttempt(p, def, ctx, pos) {
|
|
|
8301
8439
|
if (!ctx.recovery && !ctx.coverage && needsFirstSetGuard(def.parser)) {
|
|
8302
8440
|
const gcV = v(ctx, "_agc");
|
|
8303
8441
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8304
|
-
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(gExp, pos)} }`;
|
|
8442
|
+
const gFail = ctx.failLabel ? `{ _ctx._fe = ${pos};${ctx.recordFail ? ` _ctx._fx = ${gExp};` : ""} break ${ctx.failLabel} }` : `{ _ctx._fe = ${pos}; ${failReturnArr(ctx, gExp, pos)} }`;
|
|
8305
8443
|
preGuard.push(
|
|
8306
8444
|
`${ind(ctx)}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8307
8445
|
`${ind(ctx)}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8800,7 +8938,7 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8800
8938
|
if (!ctx.recovery && !ctx.coverage && (capturesChildren || structural) && needsFirstSetGuard(def.parser)) {
|
|
8801
8939
|
const gcV = v(ctx, "_ngc");
|
|
8802
8940
|
const gExp = armStaticExpected(ctx, def.parser);
|
|
8803
|
-
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(gExp, pos);
|
|
8941
|
+
const gFail = ctx.failLabel ? ctx.recordFail ? `{ _ctx._fe = ${pos}; _ctx._fx = ${gExp}; break ${ctx.failLabel} }` : `break ${ctx.failLabel}` : failReturnArr(ctx, gExp, pos);
|
|
8804
8942
|
preGuard.push(
|
|
8805
8943
|
`${i}const ${gcV} = ${pos} < input.length ? (input.codePointAt(${pos}) ?? -1) : -1`,
|
|
8806
8944
|
`${i}if (!(${firstSetCond(gcV, def.parser._meta.firstSet)})) ${gFail}`
|
|
@@ -8862,7 +9000,8 @@ ${i}const ${chV} = ${chAlloc}, ${rawV} = ${profileRecognizer} ? undefined : [],
|
|
|
8862
9000
|
const nodeSpanV = ctx.lineTracking ? v(ctx, "_nspan") : nodeSpanExpr;
|
|
8863
9001
|
if (ctx.lineTracking) stmts.push(`${i}const ${nodeSpanV} = ${nodeSpanExpr}`);
|
|
8864
9002
|
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})`;
|
|
8865
|
-
const
|
|
9003
|
+
const hostBuildArgs = `${JSON.stringify(def.type)}, ${chV}, ${fObj}, ${nodeSpanV}, ${rawV}, ${tlV}, ${stV}${def.tags !== void 0 && def.tags.length > 0 ? `, ${JSON.stringify(def.tags)}` : ""}`;
|
|
9004
|
+
const hostBuildExpr = `_ctx._pmProfile?.phase === 'host' && _ctx._pmProfile.hostCalls++, _ctx.build(${hostBuildArgs})`;
|
|
8866
9005
|
const ndExpr = structural ? `_ctx.build !== undefined ? (${hostBuildExpr}) : (${buildExpr})` : cstOut ? hostBuildExpr : buildExpr;
|
|
8867
9006
|
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;
|
|
8868
9007
|
const unwrapExpr = `${chV}.length === 1 ? (${chV}[0] !== null && typeof ${chV}[0] === 'object' && ${chV}[0]._tag === 'leaf' ? ${chV}[0].value : ${chV}[0]) : (${ndExpr})`;
|
|
@@ -9316,6 +9455,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9316
9455
|
if (seen.has(p)) return false;
|
|
9317
9456
|
seen.add(p);
|
|
9318
9457
|
const d = p._def;
|
|
9458
|
+
if (p._meta.grammarTrackLines) return true;
|
|
9319
9459
|
if (d.tag === "grammar" && d.trackLines) return true;
|
|
9320
9460
|
if (d.tag === "lazy") {
|
|
9321
9461
|
try {
|
|
@@ -9324,7 +9464,7 @@ function hasLineTrackingDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9324
9464
|
return false;
|
|
9325
9465
|
}
|
|
9326
9466
|
}
|
|
9327
|
-
return
|
|
9467
|
+
return childrenOf3(d).some((child) => hasLineTrackingDef(child, seen));
|
|
9328
9468
|
}
|
|
9329
9469
|
function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
9330
9470
|
if (seen.has(p)) return false;
|
|
@@ -9343,7 +9483,7 @@ function parserUsesRouted2(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9343
9483
|
case "dispatch":
|
|
9344
9484
|
return false;
|
|
9345
9485
|
default:
|
|
9346
|
-
return
|
|
9486
|
+
return childrenOf3(d).some((child) => parserUsesRouted2(child, seen));
|
|
9347
9487
|
}
|
|
9348
9488
|
}
|
|
9349
9489
|
function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -9358,9 +9498,9 @@ function hasDirectBuildDef(p, seen = /* @__PURE__ */ new Set()) {
|
|
|
9358
9498
|
return false;
|
|
9359
9499
|
}
|
|
9360
9500
|
}
|
|
9361
|
-
return
|
|
9501
|
+
return childrenOf3(d).some((child) => hasDirectBuildDef(child, seen));
|
|
9362
9502
|
}
|
|
9363
|
-
function
|
|
9503
|
+
function childrenOf3(def) {
|
|
9364
9504
|
switch (def.tag) {
|
|
9365
9505
|
case "sequence":
|
|
9366
9506
|
case "choice":
|
|
@@ -9435,7 +9575,7 @@ function subtreeSizes(roots) {
|
|
|
9435
9575
|
const def = p._def;
|
|
9436
9576
|
let s = 1;
|
|
9437
9577
|
if (def.tag !== "lazy") {
|
|
9438
|
-
for (const child of
|
|
9578
|
+
for (const child of childrenOf3(def)) s += child._def.tag === "lazy" ? 1 : sz(child);
|
|
9439
9579
|
}
|
|
9440
9580
|
sizes.set(p, s);
|
|
9441
9581
|
return s;
|
|
@@ -9456,7 +9596,7 @@ function subtreeSizes(roots) {
|
|
|
9456
9596
|
return;
|
|
9457
9597
|
}
|
|
9458
9598
|
sz(p);
|
|
9459
|
-
for (const child of
|
|
9599
|
+
for (const child of childrenOf3(def)) visit(child);
|
|
9460
9600
|
};
|
|
9461
9601
|
for (const root of roots) visit(root);
|
|
9462
9602
|
return sizes;
|
|
@@ -9466,7 +9606,7 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9466
9606
|
const recursive = /* @__PURE__ */ new Set();
|
|
9467
9607
|
const descended = /* @__PURE__ */ new Set();
|
|
9468
9608
|
const active = /* @__PURE__ */ new Set();
|
|
9469
|
-
function
|
|
9609
|
+
function walk(p) {
|
|
9470
9610
|
const def = p._def;
|
|
9471
9611
|
if (def.tag === "lazy") {
|
|
9472
9612
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
@@ -9483,17 +9623,17 @@ function analyzeLazyUsageMulti(roots) {
|
|
|
9483
9623
|
return;
|
|
9484
9624
|
}
|
|
9485
9625
|
active.add(p);
|
|
9486
|
-
|
|
9626
|
+
walk(resolved);
|
|
9487
9627
|
active.delete(p);
|
|
9488
9628
|
return;
|
|
9489
9629
|
}
|
|
9490
9630
|
if (isHoistableTag(def.tag)) {
|
|
9491
9631
|
counts.set(p, (counts.get(p) ?? 0) + 1);
|
|
9492
9632
|
}
|
|
9493
|
-
for (const child of
|
|
9633
|
+
for (const child of childrenOf3(def)) walk(child);
|
|
9494
9634
|
}
|
|
9495
9635
|
const rootsArr = [...roots];
|
|
9496
|
-
for (const root of rootsArr)
|
|
9636
|
+
for (const root of rootsArr) walk(root);
|
|
9497
9637
|
return { counts, recursive, sizes: subtreeSizes(rootsArr) };
|
|
9498
9638
|
}
|
|
9499
9639
|
function ruleDependencies(ruleMap) {
|
|
@@ -9503,7 +9643,7 @@ function ruleDependencies(ruleMap) {
|
|
|
9503
9643
|
for (const [name, comb] of ruleMap) {
|
|
9504
9644
|
const found = /* @__PURE__ */ new Set();
|
|
9505
9645
|
const seen = /* @__PURE__ */ new Set();
|
|
9506
|
-
const
|
|
9646
|
+
const walk = (p, isRoot) => {
|
|
9507
9647
|
const def = p._def;
|
|
9508
9648
|
const boundary = def.tag === "lazy" ? nameOf.get(p) ?? p._ruleName : nameOf.get(p);
|
|
9509
9649
|
if (!isRoot && boundary !== void 0) {
|
|
@@ -9519,12 +9659,12 @@ function ruleDependencies(ruleMap) {
|
|
|
9519
9659
|
} catch {
|
|
9520
9660
|
return;
|
|
9521
9661
|
}
|
|
9522
|
-
|
|
9662
|
+
walk(resolved, false);
|
|
9523
9663
|
return;
|
|
9524
9664
|
}
|
|
9525
|
-
for (const child of
|
|
9665
|
+
for (const child of childrenOf3(def)) walk(child, false);
|
|
9526
9666
|
};
|
|
9527
|
-
|
|
9667
|
+
walk(comb, true);
|
|
9528
9668
|
deps.set(name, [...found]);
|
|
9529
9669
|
}
|
|
9530
9670
|
return deps;
|
|
@@ -9673,6 +9813,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9673
9813
|
const grammarTrivia = combinator._meta.grammarTrivia;
|
|
9674
9814
|
const grammarScanSkip = combinator._meta.grammarScanSkip;
|
|
9675
9815
|
const grammarHostMode = combinator._meta.grammarHostMode;
|
|
9816
|
+
const grammarTrackLines = combinator._meta.grammarTrackLines;
|
|
9676
9817
|
const ctx = {
|
|
9677
9818
|
vars: 0,
|
|
9678
9819
|
indent: 1,
|
|
@@ -9693,7 +9834,7 @@ function compile(combinator, mapFnSources, opts) {
|
|
|
9693
9834
|
capturing: hasNodeDef(combinator),
|
|
9694
9835
|
recovery: opts?.recovery ?? false,
|
|
9695
9836
|
hostMode: opts?.hostMode ?? grammarHostMode ?? "ast",
|
|
9696
|
-
lineTracking: opts?.trackLines === true || hasLineTrackingDef(combinator),
|
|
9837
|
+
lineTracking: opts?.trackLines === true || grammarTrackLines === true || hasLineTrackingDef(combinator),
|
|
9697
9838
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(combinator), entry: combinator } } : {},
|
|
9698
9839
|
lazyUsage: analyzeLazyUsage(combinator),
|
|
9699
9840
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9857,6 +9998,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9857
9998
|
const grammarTrivia = opts?.trivia;
|
|
9858
9999
|
const grammarScanSkip = opts?.scanSkip ?? ruleMap.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9859
10000
|
const grammarHostMode = opts?.hostMode ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10001
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
9860
10002
|
const ctx = {
|
|
9861
10003
|
vars: 0,
|
|
9862
10004
|
indent: 1,
|
|
@@ -9877,6 +10019,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9877
10019
|
capturing: ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
9878
10020
|
recovery: opts?.recovery ?? false,
|
|
9879
10021
|
hostMode: grammarHostMode ?? "ast",
|
|
10022
|
+
lineTracking: grammarTrackLines,
|
|
9880
10023
|
...opts?.coverage ? { coverage: { plan: buildGrammarPlan(ruleMap.map(([, rule]) => rule), coverageWinners) } } : {},
|
|
9881
10024
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
9882
10025
|
...grammarTrivia ? { activeTrivia: grammarTrivia, triviaKindLabels: grammarTrivia._meta.triviaKindLabels } : {},
|
|
@@ -9910,6 +10053,10 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9910
10053
|
const mfCovered = ctx.mapFns.length === 0 || derivedSrcs !== void 0;
|
|
9911
10054
|
const canInline = ctx.runtimeParsers.length === 0 && mfCovered && buildCovered;
|
|
9912
10055
|
if (!canInline) return null;
|
|
10056
|
+
if (ctx.lineTracking) {
|
|
10057
|
+
ctx.needsLineTrack = true;
|
|
10058
|
+
ctx.needsLineSpan = true;
|
|
10059
|
+
}
|
|
9913
10060
|
const mfDecl = derivedSrcs?.length ? ` const ${mfRef(ctx)} = [${derivedSrcs.join(", ")}]` : "";
|
|
9914
10061
|
const buildDecl = buildSources?.length ? ` const ${buildRef(ctx)} = [${buildSources.join(", ")}]` : "";
|
|
9915
10062
|
const namedPrelude = ctx.namedFnDecls.length > 0 ? namedFnPrelude() : [];
|
|
@@ -9939,15 +10086,23 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9939
10086
|
};
|
|
9940
10087
|
const entryFnText = (r, rule) => {
|
|
9941
10088
|
const ruleId = entryRuleId(rule);
|
|
10089
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10090
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10091
|
+
` else _ctx.trackLines = true`,
|
|
10092
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10093
|
+
] : [];
|
|
10094
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
9942
10095
|
const body = ruleId === void 0 ? [
|
|
10096
|
+
...linePreamble,
|
|
9943
10097
|
` let pos = _pos`,
|
|
9944
10098
|
...r.stmts,
|
|
9945
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10099
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`
|
|
9946
10100
|
] : [
|
|
10101
|
+
...linePreamble,
|
|
9947
10102
|
` const _coverageResult = (() => {`,
|
|
9948
10103
|
` let pos = _pos`,
|
|
9949
10104
|
...r.stmts,
|
|
9950
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10105
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
9951
10106
|
` })()`,
|
|
9952
10107
|
` if (!_coverageResult.ok) _ctx._grammarTrace?.write({ id: ${JSON.stringify(ruleId)}, phase: 'failure', offset: _coverageResult.span.start })`,
|
|
9953
10108
|
` return _coverageResult`
|
|
@@ -9974,6 +10129,7 @@ function compileRuleMap(ruleMap, opts) {
|
|
|
9974
10129
|
// host check passes vacuously — see `withHostMode` in the plugin.
|
|
9975
10130
|
hostMode: ctx.hostMode ?? "ast",
|
|
9976
10131
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10132
|
+
reflection: collectGrammarReflection(ruleMap),
|
|
9977
10133
|
...ctx.coverage === void 0 ? {} : { coverageDefinitions: ctx.coverage.plan.definitions }
|
|
9978
10134
|
};
|
|
9979
10135
|
}
|
|
@@ -9985,6 +10141,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9985
10141
|
const grammarTrivia = opts?.trivia ?? ruleMapArg.map(([, r]) => r._meta.grammarTrivia).find(Boolean);
|
|
9986
10142
|
const grammarScanSkip = opts?.scanSkip ?? ruleMapArg.map(([, r]) => r._meta.grammarScanSkip).find(Boolean);
|
|
9987
10143
|
const grammarHostMode = opts?.hostMode ?? ruleMapArg.map(([, r]) => r._meta.grammarHostMode).find(Boolean);
|
|
10144
|
+
const grammarTrackLines = opts?.trackLines === true || ruleMapArg.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
9988
10145
|
const ruleMap = ruleMapArg.filter(([, val]) => {
|
|
9989
10146
|
const d = val._def;
|
|
9990
10147
|
if (d.tag !== "lazy") return true;
|
|
@@ -9995,6 +10152,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
9995
10152
|
return false;
|
|
9996
10153
|
}
|
|
9997
10154
|
});
|
|
10155
|
+
const nodeMeta = new Map(ruleMap.map(([name, rule]) => [name, collectGrammarReflection([[name, rule]], { followLazy: false })]));
|
|
9998
10156
|
const ctx = {
|
|
9999
10157
|
vars: 0,
|
|
10000
10158
|
indent: 1,
|
|
@@ -10019,6 +10177,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10019
10177
|
capturing: opts?.captureTerminals === true || ruleMap.some(([, rule]) => hasNodeDef(rule)),
|
|
10020
10178
|
recovery: opts?.recovery ?? false,
|
|
10021
10179
|
hostMode: grammarHostMode ?? "ast",
|
|
10180
|
+
lineTracking: grammarTrackLines,
|
|
10022
10181
|
...opts?.coverage ? { coverage: { plan: opts.coverage } } : {},
|
|
10023
10182
|
lazyUsage: analyzeLazyUsageMulti(ruleMap.map(([, rule]) => rule)),
|
|
10024
10183
|
ns,
|
|
@@ -10069,7 +10228,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10069
10228
|
scanExternal(resolved);
|
|
10070
10229
|
return;
|
|
10071
10230
|
}
|
|
10072
|
-
for (const child of
|
|
10231
|
+
for (const child of childrenOf3(def)) scanExternal(child);
|
|
10073
10232
|
};
|
|
10074
10233
|
for (const [, rule] of ruleMap) scanExternal(rule);
|
|
10075
10234
|
}
|
|
@@ -10115,6 +10274,10 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10115
10274
|
perEntry.push({ key, rule, r: emitNamedFnCall(ctx, fn, "_pos") });
|
|
10116
10275
|
}
|
|
10117
10276
|
if (ctx.runtimeParsers.length !== 0) return null;
|
|
10277
|
+
if (ctx.lineTracking) {
|
|
10278
|
+
ctx.needsLineTrack = true;
|
|
10279
|
+
ctx.needsLineSpan = true;
|
|
10280
|
+
}
|
|
10118
10281
|
const mfSrcs = ctx.mapFns.length > 0 && ctx.mapFnSrcs.every((s) => s !== null) ? ctx.mapFnSrcs : null;
|
|
10119
10282
|
const buildSrcs = ctx.buildFns.length > 0 && ctx.buildSrcs.every((s) => s !== null) ? ctx.buildSrcs : null;
|
|
10120
10283
|
const ruleFns = /* @__PURE__ */ new Map();
|
|
@@ -10128,6 +10291,8 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10128
10291
|
const mfDecl = ctx.mapFns.length === 0 ? "" : mfSrcs ? `const ${mfRef(ctx)} = [${mfSrcs.join(", ")}]` : `const ${mfRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "mf")}]`;
|
|
10129
10292
|
const buildDecl = ctx.buildFns.length === 0 ? "" : buildSrcs ? `const ${buildRef(ctx)} = [${buildSrcs.join(", ")}]` : `const ${buildRef(ctx)} = _env[${JSON.stringify(nsp(ctx) + "build")}]`;
|
|
10130
10293
|
const prelude = [
|
|
10294
|
+
ctx.needsLineTrack ? LINE_TRACK_DECL : "",
|
|
10295
|
+
ctx.needsLineSpan ? LINE_SPAN_DECL : "",
|
|
10131
10296
|
...ctx.regexDecls,
|
|
10132
10297
|
...ctx.expectedDecls,
|
|
10133
10298
|
mfDecl,
|
|
@@ -10136,11 +10301,18 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10136
10301
|
].filter(Boolean);
|
|
10137
10302
|
const wrappers = /* @__PURE__ */ new Map();
|
|
10138
10303
|
for (const { key, rule, r } of perEntry) {
|
|
10304
|
+
const linePreamble = ctx.lineTracking ? [
|
|
10305
|
+
` if (_ctx._lineStarts === undefined) _ctx = { ..._ctx, trackLines: true, _lineStarts: [0], _lineScannedTo: 0 }`,
|
|
10306
|
+
` else _ctx.trackLines = true`,
|
|
10307
|
+
` if (_pos > (_ctx._lineScannedTo ?? 0)) _trackLines(_ctx, input, 0, _pos)`
|
|
10308
|
+
] : [];
|
|
10309
|
+
const resultSpan = ctx.lineTracking ? `_spanLines(_ctx, _pos, ${r.endVar})` : `{ start: _pos, end: ${r.endVar} }`;
|
|
10139
10310
|
wrappers.set(key, publicRuleWrapperSource(rule, [
|
|
10140
10311
|
`function(input, _pos, _ctx) {`,
|
|
10312
|
+
...linePreamble,
|
|
10141
10313
|
` let pos = _pos`,
|
|
10142
10314
|
...r.stmts,
|
|
10143
|
-
` return { ok: true, value: ${r.valueVar}, span:
|
|
10315
|
+
` return { ok: true, value: ${r.valueVar}, span: ${resultSpan} }`,
|
|
10144
10316
|
`}`
|
|
10145
10317
|
].join("\n"), ctx.triviaKindLabels));
|
|
10146
10318
|
}
|
|
@@ -10178,6 +10350,7 @@ function compileLinkable(ruleMapArg, ns, opts) {
|
|
|
10178
10350
|
hostBranchElided: !!ctx.hostBranchElided,
|
|
10179
10351
|
hasDirectBuilders: ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
10180
10352
|
isRecognitionOnly: !hasSemanticReduction(ruleMap.map(([, rule]) => rule), externalRefs),
|
|
10353
|
+
nodeMeta,
|
|
10181
10354
|
mfFns: mfSrcs ? [] : ctx.mapFns,
|
|
10182
10355
|
buildFns: buildSrcs ? [] : ctx.buildFns
|
|
10183
10356
|
};
|
|
@@ -10198,7 +10371,7 @@ function hasExternalRuleRef(ruleMap) {
|
|
|
10198
10371
|
if (resolved === void 0) return p._ruleName !== void 0;
|
|
10199
10372
|
return visit(resolved);
|
|
10200
10373
|
}
|
|
10201
|
-
return
|
|
10374
|
+
return childrenOf3(def).some(visit);
|
|
10202
10375
|
};
|
|
10203
10376
|
return ruleMap.some(([, rule]) => visit(rule));
|
|
10204
10377
|
}
|
|
@@ -10220,7 +10393,7 @@ function hasSemanticReduction(roots, externalRefs) {
|
|
|
10220
10393
|
return true;
|
|
10221
10394
|
}
|
|
10222
10395
|
}
|
|
10223
|
-
return
|
|
10396
|
+
return childrenOf3(def).some(visit);
|
|
10224
10397
|
};
|
|
10225
10398
|
return roots.some(visit);
|
|
10226
10399
|
}
|
|
@@ -10293,7 +10466,7 @@ function withCtx(extra, combinator) {
|
|
|
10293
10466
|
}
|
|
10294
10467
|
|
|
10295
10468
|
// src/compiler/ir-serialize.ts
|
|
10296
|
-
function
|
|
10469
|
+
function childrenOf4(def) {
|
|
10297
10470
|
switch (def.tag) {
|
|
10298
10471
|
case "sequence":
|
|
10299
10472
|
case "choice":
|
|
@@ -10357,6 +10530,10 @@ function projectOpt(project) {
|
|
|
10357
10530
|
if (project === void 0) return void 0;
|
|
10358
10531
|
return `project: ${project}`;
|
|
10359
10532
|
}
|
|
10533
|
+
function tagsOpt(tags) {
|
|
10534
|
+
if (tags === void 0 || tags.length === 0) return void 0;
|
|
10535
|
+
return `tags: ${JSON.stringify(tags)}`;
|
|
10536
|
+
}
|
|
10360
10537
|
function matcherExpr(entry) {
|
|
10361
10538
|
switch (entry.kind) {
|
|
10362
10539
|
case "startsWith":
|
|
@@ -10570,7 +10747,7 @@ var Serializer = class {
|
|
|
10570
10747
|
if (target) this.assertNoRuleRef(target, seen);
|
|
10571
10748
|
return;
|
|
10572
10749
|
}
|
|
10573
|
-
for (const child of
|
|
10750
|
+
for (const child of childrenOf4(c._def)) this.assertNoRuleRef(child, seen);
|
|
10574
10751
|
}
|
|
10575
10752
|
/** A `rules()` map wraps each rule value in a named `lazy` proxy; the real body is
|
|
10576
10753
|
* its target (compileLinkable unwraps the same way). A ref INSIDE a body stays a
|
|
@@ -10634,7 +10811,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10634
10811
|
this.counts.set(c, (this.counts.get(c) ?? 0) + 1);
|
|
10635
10812
|
if ((this.counts.get(c) ?? 0) > 1) return;
|
|
10636
10813
|
active.add(c);
|
|
10637
|
-
for (const child of
|
|
10814
|
+
for (const child of childrenOf4(def)) this.analyze(child, active);
|
|
10638
10815
|
active.delete(c);
|
|
10639
10816
|
}
|
|
10640
10817
|
/** Reference `c`: a const var if it has one (emitting its decl first), else inline.
|
|
@@ -10751,12 +10928,14 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
10751
10928
|
case "node": {
|
|
10752
10929
|
if (def.build !== void 0 && def.buildSrc === void 0) throw new Unserializable("node build without buildSrc");
|
|
10753
10930
|
const projectEntry = projectOpt(def.project);
|
|
10931
|
+
const tagEntry = tagsOpt(def.tags);
|
|
10754
10932
|
const optEntries = [
|
|
10755
10933
|
...def.unwrap ? ["unwrap: true"] : [],
|
|
10756
10934
|
...def.collapse ? ["collapse: true"] : [],
|
|
10757
10935
|
...projectEntry === void 0 ? [] : [projectEntry],
|
|
10758
10936
|
...def.captureTrivia ? ["captureTrivia: true"] : [],
|
|
10759
|
-
...def.trailingTrivia ? ["trailingTrivia: true"] : []
|
|
10937
|
+
...def.trailingTrivia ? ["trailingTrivia: true"] : [],
|
|
10938
|
+
...tagEntry === void 0 ? [] : [tagEntry]
|
|
10760
10939
|
];
|
|
10761
10940
|
const opts = optEntries.length > 0 ? `, { ${optEntries.join(", ")} }` : "";
|
|
10762
10941
|
if (def.type === void 0) {
|
|
@@ -10794,15 +10973,16 @@ function normalizeCstCollapse(collapse) {
|
|
|
10794
10973
|
}
|
|
10795
10974
|
return typeof collapse === "function" ? collapse : void 0;
|
|
10796
10975
|
}
|
|
10797
|
-
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state) {
|
|
10798
|
-
return { _tag: "node", type, span: { ...span }, state: state ?? null, children: [...children2] };
|
|
10976
|
+
function buildCstNode(type, children2, _fields, span, _rawChildren, _triviaLog, state, tags) {
|
|
10977
|
+
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] };
|
|
10799
10978
|
}
|
|
10800
|
-
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state) {
|
|
10979
|
+
function cstBuildHost(typeOrOptions, children2, _fields, span, rawChildren, triviaLog, state, _tags) {
|
|
10801
10980
|
if (typeof typeOrOptions === "string") {
|
|
10802
10981
|
return buildCstNode(typeOrOptions, children2 ?? [], _fields, span ?? { start: 0, end: 0 }, rawChildren, triviaLog, state);
|
|
10803
10982
|
}
|
|
10804
10983
|
const collapse = normalizeCstCollapse(typeOrOptions?.collapse);
|
|
10805
|
-
const
|
|
10984
|
+
const materializeTags = typeOrOptions?.tags === true;
|
|
10985
|
+
const host = (type, children3, fields, span2, rawChildren2, triviaLog2, state2, tags) => buildCstNode(type, children3 ?? [], fields, span2, rawChildren2, triviaLog2, state2, materializeTags ? tags : void 0);
|
|
10806
10986
|
host._parsemanCstOutput = true;
|
|
10807
10987
|
if (collapse) host._parsemanCstCollapse = collapse;
|
|
10808
10988
|
return host;
|
|
@@ -10823,7 +11003,7 @@ function pickPieces(pieces, names) {
|
|
|
10823
11003
|
};
|
|
10824
11004
|
for (const n of names) visit(n);
|
|
10825
11005
|
const filt = (m, pc) => new Map([...m].filter(([k]) => keep.has(k) && winner.get(k) === pc));
|
|
10826
|
-
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);
|
|
11006
|
+
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);
|
|
10827
11007
|
}
|
|
10828
11008
|
function fusedBody(pieces) {
|
|
10829
11009
|
for (const p of pieces) {
|
|
@@ -10861,6 +11041,7 @@ function fusedBody(pieces) {
|
|
|
10861
11041
|
...[...winner].map(([k, p]) => p.ruleFns.get(k))
|
|
10862
11042
|
];
|
|
10863
11043
|
const wrapperEntries = [...winner].map(([k, p]) => `${JSON.stringify(k)}: ${p.wrappers.get(k)}`);
|
|
11044
|
+
const reflection = mergeGrammarReflections([...winner].map(([k, p]) => p.nodeMeta.get(k) ?? { nodes: [] }));
|
|
10864
11045
|
const { mode, elided } = hostModeOfPieces(pieces);
|
|
10865
11046
|
const rawBody = [
|
|
10866
11047
|
...lines,
|
|
@@ -10869,6 +11050,7 @@ function fusedBody(pieces) {
|
|
|
10869
11050
|
"}",
|
|
10870
11051
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_MODE.description)}), { value: ${JSON.stringify(mode)}, enumerable: false })`,
|
|
10871
11052
|
`Object.defineProperty(_map, Symbol.for(${JSON.stringify(FUSED_HOST_ELIDED.description)}), { value: ${JSON.stringify(elided)}, enumerable: false })`,
|
|
11053
|
+
`Object.defineProperty(_map, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`,
|
|
10872
11054
|
// …and on each rule FUNCTION, because `run(map.Rule, …)` is handed the rule, not the
|
|
10873
11055
|
// map, and would otherwise have nothing to check against. Done once at fuse time,
|
|
10874
11056
|
// before any rule has been called, so it costs nothing per parse.
|
|
@@ -10974,7 +11156,8 @@ function materializePiece(p, trivia2, captureTerminals = false, hostMode) {
|
|
|
10974
11156
|
const pieces = compileLinkable(evalRuleMapIR(p.ir), p.ns, {
|
|
10975
11157
|
...trivia2 ? { trivia: trivia2 } : {},
|
|
10976
11158
|
...captureTerminals ? { captureTerminals: true } : {},
|
|
10977
|
-
...hostMode ? { hostMode } : {}
|
|
11159
|
+
...hostMode ? { hostMode } : {},
|
|
11160
|
+
...p.trackLines ? { trackLines: true } : {}
|
|
10978
11161
|
});
|
|
10979
11162
|
if (!pieces) throw new Error(`compose: carried IR for ns "${p.ns}" could not be re-lowered`);
|
|
10980
11163
|
return pieces;
|
|
@@ -11158,19 +11341,19 @@ function directBuilderUnsupportedBindings(src) {
|
|
|
11158
11341
|
// src/plugin/evaluator.ts
|
|
11159
11342
|
function stripTsFromSource(node2, code) {
|
|
11160
11343
|
const cuts = [];
|
|
11161
|
-
const
|
|
11344
|
+
const walk = (n) => {
|
|
11162
11345
|
if (!n || typeof n !== "object") return;
|
|
11163
11346
|
const rec = n;
|
|
11164
11347
|
if (typeof rec.type === "string" && rec.type.startsWith("TS") && typeof rec.start === "number" && typeof rec.end === "number") {
|
|
11165
11348
|
const ex = rec.expression;
|
|
11166
11349
|
if ((rec.type === "TSAsExpression" || rec.type === "TSSatisfiesExpression" || rec.type === "TSNonNullExpression" || rec.type === "TSInstantiationExpression") && ex && typeof ex.end === "number") {
|
|
11167
11350
|
cuts.push([ex.end, rec.end]);
|
|
11168
|
-
|
|
11351
|
+
walk(rec.expression);
|
|
11169
11352
|
return;
|
|
11170
11353
|
}
|
|
11171
11354
|
if (rec.type === "TSTypeAssertion" && ex && typeof ex.start === "number") {
|
|
11172
11355
|
cuts.push([rec.start, ex.start]);
|
|
11173
|
-
|
|
11356
|
+
walk(rec.expression);
|
|
11174
11357
|
return;
|
|
11175
11358
|
}
|
|
11176
11359
|
cuts.push([rec.start, rec.end]);
|
|
@@ -11180,11 +11363,11 @@ function stripTsFromSource(node2, code) {
|
|
|
11180
11363
|
if (key === "type" || key === "start" || key === "end") continue;
|
|
11181
11364
|
const v2 = rec[key];
|
|
11182
11365
|
if (Array.isArray(v2)) {
|
|
11183
|
-
for (const item of v2)
|
|
11184
|
-
} else if (v2 && typeof v2 === "object")
|
|
11366
|
+
for (const item of v2) walk(item);
|
|
11367
|
+
} else if (v2 && typeof v2 === "object") walk(v2);
|
|
11185
11368
|
}
|
|
11186
11369
|
};
|
|
11187
|
-
|
|
11370
|
+
walk(node2);
|
|
11188
11371
|
const start = node2.start;
|
|
11189
11372
|
const end = node2.end;
|
|
11190
11373
|
if (cuts.length === 0) return code.slice(start, end);
|
|
@@ -11363,10 +11546,38 @@ function scopeGet(scope, name, mfs) {
|
|
|
11363
11546
|
if (isCombinator(entry)) return entry;
|
|
11364
11547
|
return null;
|
|
11365
11548
|
}
|
|
11549
|
+
function unwrapStaticExpr(expr) {
|
|
11550
|
+
let cur = expr;
|
|
11551
|
+
while (cur.type === "TSAsExpression" || cur.type === "TSSatisfiesExpression" || cur.type === "TSNonNullExpression" || cur.type === "TSTypeAssertion" || cur.type === "TSInstantiationExpression" || cur.type === "ParenthesizedExpression") {
|
|
11552
|
+
if (!cur.expression) break;
|
|
11553
|
+
cur = cur.expression;
|
|
11554
|
+
}
|
|
11555
|
+
return cur;
|
|
11556
|
+
}
|
|
11366
11557
|
function staticLiteralValue(expr) {
|
|
11367
|
-
const val = expr;
|
|
11558
|
+
const val = unwrapStaticExpr(expr);
|
|
11368
11559
|
return val.type === "Literal" || val.type === "BooleanLiteral" || val.type === "NumericLiteral" ? val.value : void 0;
|
|
11369
11560
|
}
|
|
11561
|
+
function staticStringArray(expr, scope) {
|
|
11562
|
+
const id = unwrapStaticExpr(expr);
|
|
11563
|
+
if (id.type === "Identifier" && scope !== void 0 && id.name !== void 0) {
|
|
11564
|
+
const scoped = scope.get(id.name);
|
|
11565
|
+
const value = isStaticValueEntry(scoped) ? scoped.value : scoped;
|
|
11566
|
+
return Array.isArray(value) && value.every((v2) => typeof v2 === "string") ? value : void 0;
|
|
11567
|
+
}
|
|
11568
|
+
const arr = id;
|
|
11569
|
+
if (arr.type !== "ArrayExpression" || !Array.isArray(arr.elements)) return void 0;
|
|
11570
|
+
const out = [];
|
|
11571
|
+
for (const el of arr.elements) {
|
|
11572
|
+
if (!el || el.type === "SpreadElement") return void 0;
|
|
11573
|
+
const value = staticLiteralValue(el);
|
|
11574
|
+
if (typeof value !== "string") return void 0;
|
|
11575
|
+
out.push(value);
|
|
11576
|
+
}
|
|
11577
|
+
return out;
|
|
11578
|
+
}
|
|
11579
|
+
var STATIC_NODE_OPTIONS_FAILED = /* @__PURE__ */ Symbol("parseman.staticNodeOptions.failed");
|
|
11580
|
+
var STATIC_NODE_OPTIONS_NOT_OPTIONS = /* @__PURE__ */ Symbol("parseman.staticNodeOptions.notOptions");
|
|
11370
11581
|
function staticNodeProject(expr) {
|
|
11371
11582
|
const literalValue = staticLiteralValue(expr);
|
|
11372
11583
|
if (typeof literalValue === "number" && Number.isInteger(literalValue) && literalValue >= 0) {
|
|
@@ -11375,23 +11586,60 @@ function staticNodeProject(expr) {
|
|
|
11375
11586
|
if (typeof literalValue === "number" || literalValue !== void 0) return { ok: false };
|
|
11376
11587
|
return { ok: false };
|
|
11377
11588
|
}
|
|
11378
|
-
function
|
|
11379
|
-
|
|
11589
|
+
function scopedStaticValue(expr, scope) {
|
|
11590
|
+
const unwrapped = unwrapStaticExpr(expr);
|
|
11591
|
+
if (unwrapped.type !== "Identifier" || unwrapped.name === "undefined") return { found: false };
|
|
11592
|
+
if (!scope.has(unwrapped.name)) return { found: false };
|
|
11593
|
+
const scoped = scope.get(unwrapped.name);
|
|
11594
|
+
const value = isStaticValueEntry(scoped) ? scoped.value : scoped;
|
|
11595
|
+
return { found: true, value };
|
|
11596
|
+
}
|
|
11597
|
+
function staticNodeOptionsFromValue(value) {
|
|
11598
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || isCombinator(value)) return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11599
|
+
const opts = {};
|
|
11600
|
+
const rec = value;
|
|
11601
|
+
for (const name of Object.keys(rec)) {
|
|
11602
|
+
const v2 = rec[name];
|
|
11603
|
+
if (name === "unwrap" || name === "collapse" || name === "captureTrivia" || name === "trailingTrivia") {
|
|
11604
|
+
if (v2 === true) opts[name] = true;
|
|
11605
|
+
else if (v2 !== false && v2 !== void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11606
|
+
} else if (name === "project") {
|
|
11607
|
+
if (typeof v2 !== "number" || !Number.isInteger(v2) || v2 < 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11608
|
+
opts.project = v2;
|
|
11609
|
+
} else if (name === "tags") {
|
|
11610
|
+
if (!Array.isArray(v2) || !v2.every((item) => typeof item === "string")) return STATIC_NODE_OPTIONS_FAILED;
|
|
11611
|
+
opts.tags = v2;
|
|
11612
|
+
}
|
|
11613
|
+
}
|
|
11614
|
+
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 ? opts : void 0;
|
|
11615
|
+
}
|
|
11616
|
+
function staticNodeOptions(expr, scope) {
|
|
11617
|
+
const unwrapped = unwrapStaticExpr(expr);
|
|
11618
|
+
const scoped = scopedStaticValue(unwrapped, scope);
|
|
11619
|
+
if (scoped.found) return staticNodeOptionsFromValue(scoped.value);
|
|
11620
|
+
if (unwrapped.type !== "ObjectExpression") return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11380
11621
|
const opts = {};
|
|
11381
|
-
for (const prop of
|
|
11622
|
+
for (const prop of unwrapped.properties) {
|
|
11623
|
+
if (prop.type !== "Property") return STATIC_NODE_OPTIONS_FAILED;
|
|
11382
11624
|
const p = prop;
|
|
11383
|
-
if (p.computed)
|
|
11625
|
+
if (p.computed) return STATIC_NODE_OPTIONS_FAILED;
|
|
11384
11626
|
const key = p.key;
|
|
11385
11627
|
const name = key.type === "Identifier" ? key.name : key.type === "Literal" ? String(key.value) : void 0;
|
|
11386
11628
|
if (name === "unwrap" || name === "collapse" || name === "captureTrivia" || name === "trailingTrivia") {
|
|
11387
|
-
|
|
11629
|
+
const value = staticLiteralValue(p.value);
|
|
11630
|
+
if (value === true) opts[name] = true;
|
|
11631
|
+
else if (value !== false && value !== void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11388
11632
|
} else if (name === "project") {
|
|
11389
11633
|
const project = staticNodeProject(p.value);
|
|
11390
|
-
if (project?.ok === false) return
|
|
11634
|
+
if (project?.ok === false) return STATIC_NODE_OPTIONS_FAILED;
|
|
11391
11635
|
if (project !== void 0) opts.project = project.value;
|
|
11636
|
+
} else if (name === "tags") {
|
|
11637
|
+
const tags = staticStringArray(p.value, scope);
|
|
11638
|
+
if (tags === void 0) return STATIC_NODE_OPTIONS_FAILED;
|
|
11639
|
+
opts.tags = tags;
|
|
11392
11640
|
}
|
|
11393
11641
|
}
|
|
11394
|
-
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia ? opts : void 0;
|
|
11642
|
+
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 ? opts : void 0;
|
|
11395
11643
|
}
|
|
11396
11644
|
function exprToCombi(node2, scope, code, mfs) {
|
|
11397
11645
|
if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
|
|
@@ -11466,10 +11714,23 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
11466
11714
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
11467
11715
|
if (!isCombinator(inner)) return null;
|
|
11468
11716
|
const be = buildArg;
|
|
11469
|
-
const
|
|
11717
|
+
const buildExpr = be === void 0 || be.type === "SpreadElement" ? void 0 : unwrapStaticExpr(be);
|
|
11718
|
+
const buildArgOptions = be !== void 0 && be.type !== "SpreadElement" ? staticNodeOptions(buildArg, scope) : STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11719
|
+
if (buildArgOptions === STATIC_NODE_OPTIONS_FAILED) return null;
|
|
11720
|
+
const buildArgIsOptions = buildArgOptions !== STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
11721
|
+
const scopedBuild = buildExpr === void 0 ? { found: false } : scopedStaticValue(buildExpr, scope);
|
|
11722
|
+
const absentBuild = buildExpr?.type === "Identifier" && buildExpr.name === "undefined" || buildExpr !== void 0 && staticLiteralValue(buildExpr) === null || scopedBuild.found && (scopedBuild.value === void 0 || scopedBuild.value === null);
|
|
11723
|
+
const hasBuild = be !== void 0 && be.type !== "SpreadElement" && !buildArgIsOptions && !absentBuild;
|
|
11470
11724
|
const buildSrc = hasBuild ? stripTsFromSource(be, code) : void 0;
|
|
11471
|
-
|
|
11472
|
-
|
|
11725
|
+
let opts;
|
|
11726
|
+
if (buildArgIsOptions) {
|
|
11727
|
+
opts = buildArgOptions;
|
|
11728
|
+
} else if (optsArg !== void 0) {
|
|
11729
|
+
if (optsArg.type === "SpreadElement") return null;
|
|
11730
|
+
const optsResult = staticNodeOptions(optsArg, scope);
|
|
11731
|
+
if (optsResult === STATIC_NODE_OPTIONS_FAILED || optsResult === STATIC_NODE_OPTIONS_NOT_OPTIONS) return null;
|
|
11732
|
+
opts = optsResult;
|
|
11733
|
+
}
|
|
11473
11734
|
try {
|
|
11474
11735
|
const combi = explicitType !== void 0 ? node(explicitType, inner, hasBuild ? () => null : void 0, opts) : node(inner, hasBuild ? () => null : void 0, opts);
|
|
11475
11736
|
if (combi._def.tag === "node" && buildSrc !== void 0) {
|
|
@@ -11692,6 +11953,10 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
11692
11953
|
}
|
|
11693
11954
|
}
|
|
11694
11955
|
function anyValue(node2, scope, code, mfs) {
|
|
11956
|
+
if (node2.type === "TSAsExpression" || node2.type === "TSSatisfiesExpression" || node2.type === "TSNonNullExpression" || node2.type === "TSTypeAssertion" || node2.type === "TSInstantiationExpression" || node2.type === "ParenthesizedExpression") {
|
|
11957
|
+
const inner = node2.expression;
|
|
11958
|
+
return inner ? anyValue(inner, scope, code, mfs) : null;
|
|
11959
|
+
}
|
|
11695
11960
|
if (node2.type === "Literal") {
|
|
11696
11961
|
if ("regex" in node2 && node2.regex !== null && node2.regex !== void 0) {
|
|
11697
11962
|
return new RegExp(node2.regex.pattern, node2.regex.flags);
|
|
@@ -11815,6 +12080,9 @@ function collectRuleKeys(retObj) {
|
|
|
11815
12080
|
}
|
|
11816
12081
|
return out;
|
|
11817
12082
|
}
|
|
12083
|
+
function evaluateStaticValue(node2, scope, code) {
|
|
12084
|
+
return anyValue(node2, scope, code, []);
|
|
12085
|
+
}
|
|
11818
12086
|
function flattenRuleEntries(retObj, scope, code) {
|
|
11819
12087
|
const out = [];
|
|
11820
12088
|
for (const prop of retObj.properties) {
|
|
@@ -11980,6 +12248,18 @@ function referencesAny(node2, names, scope) {
|
|
|
11980
12248
|
// src/plugin/index.ts
|
|
11981
12249
|
import { createHash } from "node:crypto";
|
|
11982
12250
|
var PARSEMAN_MODULE = "parseman";
|
|
12251
|
+
function unwrapStaticExpression(expr) {
|
|
12252
|
+
let cur = expr;
|
|
12253
|
+
while (cur.type === "TSAsExpression" || cur.type === "TSSatisfiesExpression" || cur.type === "TSNonNullExpression" || cur.type === "TSTypeAssertion" || cur.type === "TSInstantiationExpression" || cur.type === "ParenthesizedExpression") {
|
|
12254
|
+
if (!cur.expression) break;
|
|
12255
|
+
cur = cur.expression;
|
|
12256
|
+
}
|
|
12257
|
+
return cur;
|
|
12258
|
+
}
|
|
12259
|
+
function isStaticNullishExpression(expr) {
|
|
12260
|
+
const unwrapped = unwrapStaticExpression(expr);
|
|
12261
|
+
return unwrapped.type === "Identifier" && unwrapped.name === "undefined" || unwrapped.type === "Literal" && unwrapped.value === null;
|
|
12262
|
+
}
|
|
11983
12263
|
var _compiledResolver = null;
|
|
11984
12264
|
function getCompiledResolver() {
|
|
11985
12265
|
return _compiledResolver ??= new ResolverFactory({
|
|
@@ -12221,6 +12501,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12221
12501
|
const macroImports = [];
|
|
12222
12502
|
const allNames = /* @__PURE__ */ new Set();
|
|
12223
12503
|
const importBindings = /* @__PURE__ */ new Map();
|
|
12504
|
+
const ordinaryImports = [];
|
|
12224
12505
|
for (const stmt of body) {
|
|
12225
12506
|
if (stmt.type !== "ImportDeclaration") continue;
|
|
12226
12507
|
const s = stmt;
|
|
@@ -12229,12 +12510,17 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12229
12510
|
return key === "type" && a.value.value === "macro";
|
|
12230
12511
|
});
|
|
12231
12512
|
if (!isMacro) {
|
|
12513
|
+
const specifiers = [];
|
|
12232
12514
|
for (const spec of s.specifiers) {
|
|
12233
12515
|
if (spec.type === "ImportSpecifier") {
|
|
12234
12516
|
const imported = spec.imported.name ?? spec.local.name;
|
|
12235
12517
|
importBindings.set(spec.local.name, { source: s.source.value, imported });
|
|
12518
|
+
specifiers.push({ type: spec.type, local: spec.local.name, start: spec.start, end: spec.end });
|
|
12519
|
+
} else {
|
|
12520
|
+
specifiers.push({ type: spec.type, local: spec.local.name, start: spec.start, end: spec.end });
|
|
12236
12521
|
}
|
|
12237
12522
|
}
|
|
12523
|
+
ordinaryImports.push({ start: s.start, end: s.end, specifiers });
|
|
12238
12524
|
continue;
|
|
12239
12525
|
}
|
|
12240
12526
|
const names = /* @__PURE__ */ new Set();
|
|
@@ -12245,6 +12531,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12245
12531
|
for (const n of names) allNames.add(n);
|
|
12246
12532
|
}
|
|
12247
12533
|
if (macroImports.length === 0) return null;
|
|
12534
|
+
const unwrapVd = (stmt) => stmt.type === "VariableDeclaration" ? stmt : stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration" ? stmt.declaration : null;
|
|
12248
12535
|
const factoryDecls = /* @__PURE__ */ new Map();
|
|
12249
12536
|
for (const stmt of body) {
|
|
12250
12537
|
const decl = stmt.type === "ExportNamedDeclaration" ? stmt.declaration : stmt;
|
|
@@ -12262,6 +12549,101 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12262
12549
|
}
|
|
12263
12550
|
}
|
|
12264
12551
|
}
|
|
12552
|
+
const topLevelFunction = (moduleBody, name) => {
|
|
12553
|
+
for (const st of moduleBody) {
|
|
12554
|
+
const decl = st.type === "ExportNamedDeclaration" ? st.declaration : st;
|
|
12555
|
+
const idn = decl?.type === "FunctionDeclaration" ? decl.id : void 0;
|
|
12556
|
+
if (idn?.name === name) return decl ?? null;
|
|
12557
|
+
}
|
|
12558
|
+
return null;
|
|
12559
|
+
};
|
|
12560
|
+
const isParsemanMacroImport = (stmt) => {
|
|
12561
|
+
if (stmt.type !== "ImportDeclaration") return false;
|
|
12562
|
+
const s = stmt;
|
|
12563
|
+
return moduleAliases.has(s.source.value) && s.attributes.some((a) => {
|
|
12564
|
+
const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
|
|
12565
|
+
return key === "type" && a.value.value === "macro";
|
|
12566
|
+
});
|
|
12567
|
+
};
|
|
12568
|
+
const sourceScopeUntil = (moduleBody, source, until) => {
|
|
12569
|
+
const out = /* @__PURE__ */ new Map();
|
|
12570
|
+
for (const stmt of moduleBody) {
|
|
12571
|
+
if (stmt.type === "ImportDeclaration") {
|
|
12572
|
+
if (!isParsemanMacroImport(stmt)) return null;
|
|
12573
|
+
continue;
|
|
12574
|
+
}
|
|
12575
|
+
if (stmt.type === "FunctionDeclaration") continue;
|
|
12576
|
+
if (stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "FunctionDeclaration") continue;
|
|
12577
|
+
if (stmt.type === "ExportNamedDeclaration" && !stmt.declaration) {
|
|
12578
|
+
if (stmt.source) return null;
|
|
12579
|
+
continue;
|
|
12580
|
+
}
|
|
12581
|
+
const vd = unwrapVd(stmt);
|
|
12582
|
+
if (!vd || vd.kind !== "const") return null;
|
|
12583
|
+
for (const decl of vd.declarations) {
|
|
12584
|
+
const d = decl;
|
|
12585
|
+
const idn = d.id;
|
|
12586
|
+
const init = d.init;
|
|
12587
|
+
if (idn.type !== "Identifier" && idn.type !== "BindingIdentifier" || !idn.name || !init) return null;
|
|
12588
|
+
if (init.type === "ArrowFunctionExpression" || init.type === "FunctionExpression") continue;
|
|
12589
|
+
const mapFnSources = [];
|
|
12590
|
+
const combi = evaluateExpr(init, out, source, mapFnSources);
|
|
12591
|
+
if (combi) {
|
|
12592
|
+
if (stmt.start < until) out.set(idn.name, { combi, mfSrcs: mapFnSources });
|
|
12593
|
+
continue;
|
|
12594
|
+
}
|
|
12595
|
+
const wordFactory = evaluateWordFactory(init, out, source);
|
|
12596
|
+
if (wordFactory) {
|
|
12597
|
+
if (stmt.start < until) {
|
|
12598
|
+
;
|
|
12599
|
+
out.set(idn.name, wordFactory);
|
|
12600
|
+
}
|
|
12601
|
+
continue;
|
|
12602
|
+
}
|
|
12603
|
+
const whenFactory = evaluateWhenFactory(init, out, source);
|
|
12604
|
+
if (whenFactory) {
|
|
12605
|
+
if (stmt.start < until) {
|
|
12606
|
+
;
|
|
12607
|
+
out.set(idn.name, whenFactory);
|
|
12608
|
+
}
|
|
12609
|
+
continue;
|
|
12610
|
+
}
|
|
12611
|
+
const combiArray = evaluateCombinatorArray(init, out, source);
|
|
12612
|
+
if (combiArray) {
|
|
12613
|
+
if (stmt.start < until) {
|
|
12614
|
+
;
|
|
12615
|
+
out.set(idn.name, combiArray);
|
|
12616
|
+
}
|
|
12617
|
+
continue;
|
|
12618
|
+
}
|
|
12619
|
+
return null;
|
|
12620
|
+
}
|
|
12621
|
+
continue;
|
|
12622
|
+
}
|
|
12623
|
+
return out;
|
|
12624
|
+
};
|
|
12625
|
+
const usedImportedFactories = /* @__PURE__ */ new Set();
|
|
12626
|
+
const markUsedImportedFactories = (names) => {
|
|
12627
|
+
for (const name of names ?? []) usedImportedFactories.add(name);
|
|
12628
|
+
};
|
|
12629
|
+
for (const [localName, binding] of importBindings) {
|
|
12630
|
+
const file = resolvePrivateSourceModule(id, binding.source);
|
|
12631
|
+
if (!file) continue;
|
|
12632
|
+
const mod = parseModuleCached(file);
|
|
12633
|
+
if (!mod) continue;
|
|
12634
|
+
const localFor = exportLocalName(mod.body, binding.imported);
|
|
12635
|
+
const init = localFor ? topLevelInit(mod.body, localFor) ?? topLevelFunction(mod.body, localFor) : null;
|
|
12636
|
+
if (!init || init.type !== "ArrowFunctionExpression" && init.type !== "FunctionExpression" && init.type !== "FunctionDeclaration") continue;
|
|
12637
|
+
const factoryScope = sourceScopeUntil(mod.body, mod.src, init.start);
|
|
12638
|
+
if (!factoryScope) continue;
|
|
12639
|
+
factoryDecls.set(localName, {
|
|
12640
|
+
fn: init,
|
|
12641
|
+
declaredAt: -1,
|
|
12642
|
+
code: mod.src,
|
|
12643
|
+
scope: factoryScope,
|
|
12644
|
+
imported: true
|
|
12645
|
+
});
|
|
12646
|
+
}
|
|
12265
12647
|
const scope = /* @__PURE__ */ new Map();
|
|
12266
12648
|
const replacements = [];
|
|
12267
12649
|
const warnings = [];
|
|
@@ -12291,6 +12673,9 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12291
12673
|
}
|
|
12292
12674
|
const namedFactory = factoryArgRaw.type === "Identifier" ? factoryDecls.get(factoryArgRaw.name) : void 0;
|
|
12293
12675
|
const factoryArg = namedFactory !== void 0 && namedFactory.declaredAt <= init.start ? namedFactory.fn : factoryArgRaw;
|
|
12676
|
+
const factoryScope = namedFactory?.scope ?? scope;
|
|
12677
|
+
const factoryCode = namedFactory?.code ?? code;
|
|
12678
|
+
const importedFactory = namedFactory?.imported === true && factoryArg === namedFactory.fn ? factoryArgRaw.name : void 0;
|
|
12294
12679
|
const optionsArg = optionsFirst ? arg0 : arg1;
|
|
12295
12680
|
const optionValue = (name) => optionsArg?.type === "ObjectExpression" ? (optionsArg.properties ?? []).find(
|
|
12296
12681
|
(p) => p.key?.name === name
|
|
@@ -12301,7 +12686,13 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12301
12686
|
warn(init.start, `${label2}: rules({ hostMode }) must be the literal 'ast' or 'cst'`);
|
|
12302
12687
|
return null;
|
|
12303
12688
|
}
|
|
12304
|
-
const
|
|
12689
|
+
const trackLinesValue = optionValue("trackLines");
|
|
12690
|
+
const gTrackLines = trackLinesValue?.type === "Literal" ? trackLinesValue.value : void 0;
|
|
12691
|
+
if (trackLinesValue !== void 0 && typeof gTrackLines !== "boolean") {
|
|
12692
|
+
warn(init.start, `${label2}: rules({ trackLines }) must be a boolean literal`);
|
|
12693
|
+
return null;
|
|
12694
|
+
}
|
|
12695
|
+
const ruleMap = evaluateParserFactory(factoryArg, factoryScope, factoryCode, []);
|
|
12305
12696
|
if (!ruleMap) {
|
|
12306
12697
|
warn(init.start, `${label2}: rules(...) factory isn't statically evaluable`);
|
|
12307
12698
|
return null;
|
|
@@ -12326,20 +12717,37 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12326
12717
|
}
|
|
12327
12718
|
}
|
|
12328
12719
|
}
|
|
12329
|
-
|
|
12720
|
+
if (gTrackLines === true) {
|
|
12721
|
+
for (const rule of ruleMap.values()) {
|
|
12722
|
+
if (rule && !rule._meta.isTrivia) {
|
|
12723
|
+
;
|
|
12724
|
+
rule._meta.grammarTrackLines = true;
|
|
12725
|
+
}
|
|
12726
|
+
}
|
|
12727
|
+
}
|
|
12728
|
+
return {
|
|
12729
|
+
ruleMap,
|
|
12730
|
+
...gTrivia ? { trivia: gTrivia } : {},
|
|
12731
|
+
...gScanSkip ? { scanSkip: gScanSkip } : {},
|
|
12732
|
+
...gTrackLines === true ? { trackLines: true } : {},
|
|
12733
|
+
...importedFactory ? { importedFactory } : {}
|
|
12734
|
+
};
|
|
12330
12735
|
};
|
|
12331
12736
|
const compileRulesFactory = (init, label2) => {
|
|
12332
12737
|
const evaluated = evaluateRulesFactory(init, label2);
|
|
12333
12738
|
if (!evaluated) return null;
|
|
12334
|
-
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, recovery, coverage: grammarCoverage });
|
|
12739
|
+
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, ...evaluated.trackLines ? { trackLines: true } : {}, recovery, coverage: grammarCoverage });
|
|
12335
12740
|
return {
|
|
12336
12741
|
replacement: compiled?.replacement ?? null,
|
|
12337
12742
|
ruleMap: evaluated.ruleMap,
|
|
12338
12743
|
hostMode: compiled?.hostMode ?? "ast",
|
|
12339
12744
|
hostBranchElided: compiled?.hostBranchElided ?? false,
|
|
12745
|
+
reflection: compiled?.reflection ?? { nodes: [] },
|
|
12340
12746
|
...compiled?.coverageDefinitions ? { coverageDefinitions: compiled.coverageDefinitions } : {},
|
|
12341
12747
|
...evaluated.trivia ? { trivia: evaluated.trivia } : {},
|
|
12342
|
-
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}
|
|
12748
|
+
...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {},
|
|
12749
|
+
...evaluated.trackLines ? { trackLines: true } : {},
|
|
12750
|
+
...evaluated.importedFactory ? { importedFactory: evaluated.importedFactory } : {}
|
|
12343
12751
|
};
|
|
12344
12752
|
};
|
|
12345
12753
|
const isRulesCall = (init) => init.type === "CallExpression" && init.callee.type === "Identifier" && init.callee.name === "rules";
|
|
@@ -12355,15 +12763,16 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12355
12763
|
const mapLit = (m, stripVals = false) => `new Map([${[...m].map(
|
|
12356
12764
|
([k, v2]) => `[${JSON.stringify(k)}, ${JSON.stringify(stripVals && typeof v2 === "string" ? stripIndent(v2) : v2)}]`
|
|
12357
12765
|
).join(", ")}])`;
|
|
12358
|
-
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: [] }`;
|
|
12766
|
+
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: [] }`;
|
|
12359
12767
|
};
|
|
12360
12768
|
const isSpread = (it) => "__spreadLocal" in it;
|
|
12361
12769
|
const isIR = (it) => "ir" in it && !("ruleFns" in it);
|
|
12362
|
-
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);
|
|
12770
|
+
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);
|
|
12363
12771
|
const serializeList = (list) => `[${list.map(serializeItem).join(", ")}]`;
|
|
12364
12772
|
const withCarriedPieces = (grammarExpr, list) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.composedPieces'), { value: ${serializeList(list)}, enumerable: false })`;
|
|
12365
12773
|
const withLeafMarker = (grammarExpr) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.leafComposed'), { value: true, enumerable: false })`;
|
|
12366
12774
|
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})`;
|
|
12775
|
+
const withGrammarReflection = (grammarExpr, reflection) => `/* @__PURE__ */ Object.defineProperty(${grammarExpr}, Symbol.for('parseman.grammarReflection'), { value: ${grammarReflectionSource(reflection)}, enumerable: false })`;
|
|
12367
12776
|
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 })`;
|
|
12368
12777
|
const emittedCoverageDefinitions = (source) => {
|
|
12369
12778
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -12490,10 +12899,11 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12490
12899
|
const localCarried = (rm, label2, composing, scanSkip) => {
|
|
12491
12900
|
const entries = [...rm];
|
|
12492
12901
|
const ns = nsFor(label2);
|
|
12902
|
+
const trackLines = entries.some(([, rule]) => rule?._meta?.grammarTrackLines === true);
|
|
12493
12903
|
const ir = serializeRuleMap(entries, scanSkip);
|
|
12494
|
-
if (ir) return { carried: [{ ns, ir }] };
|
|
12904
|
+
if (ir) return { carried: [{ ns, ir, ...trackLines ? { trackLines: true } : {} }] };
|
|
12495
12905
|
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.`);
|
|
12496
|
-
const p = compileLinkable(entries, ns, { ...composing ? { trivia: composing } : {}, ...scanSkip ? { scanSkip } : {}, recovery });
|
|
12906
|
+
const p = compileLinkable(entries, ns, { ...composing ? { trivia: composing } : {}, ...scanSkip ? { scanSkip } : {}, ...trackLines ? { trackLines: true } : {}, recovery });
|
|
12497
12907
|
return p ? { carried: [p] } : null;
|
|
12498
12908
|
};
|
|
12499
12909
|
const argPieces = (arg, label2, composing) => {
|
|
@@ -12511,7 +12921,10 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12511
12921
|
const innerArg = argPieces(inner, `${label2}_pick`);
|
|
12512
12922
|
if (!innerArg) return null;
|
|
12513
12923
|
try {
|
|
12514
|
-
return {
|
|
12924
|
+
return {
|
|
12925
|
+
carried: pickPieces(materializeCarried(innerArg.carried, ownTrivia(inner)), names),
|
|
12926
|
+
...innerArg.importedFactories ? { importedFactories: innerArg.importedFactories } : {}
|
|
12927
|
+
};
|
|
12515
12928
|
} catch (e) {
|
|
12516
12929
|
warn(arg.start, `pick(): ${e.message}`);
|
|
12517
12930
|
return null;
|
|
@@ -12519,7 +12932,8 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12519
12932
|
}
|
|
12520
12933
|
if (isRulesCall(arg)) {
|
|
12521
12934
|
const evaluated = evaluateRulesFactory(arg, label2);
|
|
12522
|
-
|
|
12935
|
+
const carried = evaluated ? localCarried(evaluated.ruleMap, label2, composing, evaluated.scanSkip) : null;
|
|
12936
|
+
return carried ? { ...carried, ...evaluated?.importedFactory ? { importedFactories: [evaluated.importedFactory] } : {} } : null;
|
|
12523
12937
|
}
|
|
12524
12938
|
if (arg.type === "Identifier") {
|
|
12525
12939
|
const name = arg.name;
|
|
@@ -12591,6 +13005,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12591
13005
|
}
|
|
12592
13006
|
const composing = composingTrivia(elements);
|
|
12593
13007
|
const carried = [];
|
|
13008
|
+
const importedFactories = [];
|
|
12594
13009
|
for (let i = 0; i < elements.length; i++) {
|
|
12595
13010
|
const r = argPieces(elements[i], `compose${init.start}_${i}`, composing);
|
|
12596
13011
|
if (!r) {
|
|
@@ -12598,6 +13013,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12598
13013
|
return null;
|
|
12599
13014
|
}
|
|
12600
13015
|
carried.push(...r.carried);
|
|
13016
|
+
importedFactories.push(...r.importedFactories ?? []);
|
|
12601
13017
|
}
|
|
12602
13018
|
const detailed = once(() => carriedRuleMapsDetailed(carried));
|
|
12603
13019
|
runFusedGatingDiagnostic(
|
|
@@ -12607,7 +13023,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12607
13023
|
);
|
|
12608
13024
|
const pieces = materializeCarried(carried, composing, false, cHostMode);
|
|
12609
13025
|
try {
|
|
12610
|
-
return {
|
|
13026
|
+
return {
|
|
13027
|
+
replacement: emitFusedSource(pieces),
|
|
13028
|
+
carried,
|
|
13029
|
+
...composing ? { trivia: composing } : {},
|
|
13030
|
+
...importedFactories.length ? { importedFactories } : {}
|
|
13031
|
+
};
|
|
12611
13032
|
} catch (e) {
|
|
12612
13033
|
warn(init.start, `compose(): ${e.message}; falling back to runtime`);
|
|
12613
13034
|
return null;
|
|
@@ -12628,10 +13049,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12628
13049
|
const localArg = elements[elements.length - 1];
|
|
12629
13050
|
let localRules = null;
|
|
12630
13051
|
let localScanSkip;
|
|
13052
|
+
const importedFactories = [];
|
|
12631
13053
|
if (isRulesCall(localArg)) {
|
|
12632
13054
|
const evaluated = evaluateRulesFactory(localArg, `composeLeaf${init.start}`);
|
|
12633
13055
|
localRules = evaluated?.ruleMap ?? null;
|
|
12634
13056
|
localScanSkip = evaluated?.scanSkip;
|
|
13057
|
+
if (evaluated?.importedFactory) importedFactories.push(evaluated.importedFactory);
|
|
12635
13058
|
} else if (localArg.type === "Identifier") {
|
|
12636
13059
|
const name = localArg.name;
|
|
12637
13060
|
localRules = localRuleMaps.get(name) ?? null;
|
|
@@ -12650,6 +13073,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12650
13073
|
return null;
|
|
12651
13074
|
}
|
|
12652
13075
|
carried.push(...r.carried);
|
|
13076
|
+
importedFactories.push(...r.importedFactories ?? []);
|
|
12653
13077
|
}
|
|
12654
13078
|
try {
|
|
12655
13079
|
const localNs = nsFor(`composeLeaf${init.start}`);
|
|
@@ -12675,13 +13099,15 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12675
13099
|
return null;
|
|
12676
13100
|
}
|
|
12677
13101
|
const replacement = withLeafMarker(emitFusedSource(grammarCoverage ? recognitionPieces : [...recognitionPieces, plainLocalPiece]));
|
|
12678
|
-
return {
|
|
13102
|
+
return {
|
|
13103
|
+
replacement: withCoverageDefinitions(replacement, emittedCoverageDefinitions(replacement)),
|
|
13104
|
+
...importedFactories.length ? { importedFactories } : {}
|
|
13105
|
+
};
|
|
12679
13106
|
} catch (e) {
|
|
12680
13107
|
warn(init.start, `composeLeaf(): ${e.message}`);
|
|
12681
13108
|
return null;
|
|
12682
13109
|
}
|
|
12683
13110
|
};
|
|
12684
|
-
const unwrapVd = (stmt) => stmt.type === "VariableDeclaration" ? stmt : stmt.type === "ExportNamedDeclaration" && stmt.declaration?.type === "VariableDeclaration" ? stmt.declaration : null;
|
|
12685
13111
|
const refNames = /* @__PURE__ */ new Set();
|
|
12686
13112
|
for (const stmt of body) {
|
|
12687
13113
|
const innerVd = unwrapVd(stmt);
|
|
@@ -12742,7 +13168,14 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12742
13168
|
const kind = vd.kind ?? "const";
|
|
12743
13169
|
if (d.id.type === "Identifier") {
|
|
12744
13170
|
const varName = d.id.name;
|
|
12745
|
-
if (!referencesAny(init, allNames, scope))
|
|
13171
|
+
if (!referencesAny(init, allNames, scope)) {
|
|
13172
|
+
const staticValue = evaluateStaticValue(init, scope, code);
|
|
13173
|
+
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
13174
|
+
;
|
|
13175
|
+
scope.set(varName, staticValue);
|
|
13176
|
+
}
|
|
13177
|
+
continue;
|
|
13178
|
+
}
|
|
12746
13179
|
if (refNames.has(varName)) {
|
|
12747
13180
|
const refEntry = scope.get(varName);
|
|
12748
13181
|
const refCombi = refEntry?.combi ?? null;
|
|
@@ -12765,6 +13198,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12765
13198
|
const ns = nsFor(varName);
|
|
12766
13199
|
const pieces = exportPrefix || compiledRules.replacement === null ? compileLinkable([...compiledRules.ruleMap], ns, {
|
|
12767
13200
|
...compiledRules.scanSkip ? { scanSkip: compiledRules.scanSkip } : {},
|
|
13201
|
+
...compiledRules.trackLines ? { trackLines: true } : {},
|
|
12768
13202
|
recovery
|
|
12769
13203
|
}) : null;
|
|
12770
13204
|
if (compiledRules.replacement === null) {
|
|
@@ -12781,12 +13215,16 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12781
13215
|
);
|
|
12782
13216
|
if (compiledRules.replacement !== null) {
|
|
12783
13217
|
replacement = withHostMode(replacement, compiledRules.hostMode, compiledRules.hostBranchElided);
|
|
13218
|
+
replacement = withGrammarReflection(replacement, compiledRules.reflection);
|
|
12784
13219
|
}
|
|
12785
13220
|
if (exportPrefix && pieces && !pieces.mfFns.length && !pieces.buildFns.length) {
|
|
12786
13221
|
const ir = serializeRuleMap([...compiledRules.ruleMap], compiledRules.scanSkip);
|
|
12787
|
-
replacement = withCarriedPieces(replacement, [ir ? { ns, ir } : pieces]);
|
|
13222
|
+
replacement = withCarriedPieces(replacement, [ir ? { ns, ir, ...compiledRules.trackLines ? { trackLines: true } : {} } : pieces]);
|
|
12788
13223
|
}
|
|
12789
13224
|
replacements.push({ start: init.start, end: init.end, replacement });
|
|
13225
|
+
if (compiledRules.replacement !== null) {
|
|
13226
|
+
markUsedImportedFactories(compiledRules.importedFactory ? [compiledRules.importedFactory] : void 0);
|
|
13227
|
+
}
|
|
12790
13228
|
continue;
|
|
12791
13229
|
}
|
|
12792
13230
|
if (isComposeCall(init)) {
|
|
@@ -12799,6 +13237,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12799
13237
|
if (fused.trivia) localComposedTrivia.set(varName, fused.trivia);
|
|
12800
13238
|
const replacement = exportPrefix ? withCarriedPieces(fused.replacement, fused.carried) : fused.replacement;
|
|
12801
13239
|
replacements.push({ start: init.start, end: init.end, replacement: withCoverageDefinitions(replacement, emittedCoverageDefinitions(replacement)) });
|
|
13240
|
+
markUsedImportedFactories(fused.importedFactories);
|
|
12802
13241
|
continue;
|
|
12803
13242
|
}
|
|
12804
13243
|
if (isComposeLeafCall(init)) {
|
|
@@ -12807,6 +13246,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12807
13246
|
throw new Error(`${id}:${lineOf(init.start)} \u2014 composeLeaf() must macro-fuse; runtime composition is forbidden`);
|
|
12808
13247
|
}
|
|
12809
13248
|
replacements.push({ start: init.start, end: init.end, replacement: fused.replacement });
|
|
13249
|
+
markUsedImportedFactories(fused.importedFactories);
|
|
12810
13250
|
continue;
|
|
12811
13251
|
}
|
|
12812
13252
|
const mapFnSources = [];
|
|
@@ -12832,6 +13272,12 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12832
13272
|
scope.set(varName, combiArray);
|
|
12833
13273
|
continue;
|
|
12834
13274
|
}
|
|
13275
|
+
const staticValue = evaluateStaticValue(init, scope, code);
|
|
13276
|
+
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
13277
|
+
;
|
|
13278
|
+
scope.set(varName, staticValue);
|
|
13279
|
+
continue;
|
|
13280
|
+
}
|
|
12835
13281
|
if (factoryDecls.has(varName)) continue;
|
|
12836
13282
|
warn(init.start, `"${varName}" references a parseman macro import but isn't a statically-evaluable combinator`);
|
|
12837
13283
|
continue;
|
|
@@ -12895,6 +13341,7 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12895
13341
|
end: stmtEnd,
|
|
12896
13342
|
replacement: lines.join("\n")
|
|
12897
13343
|
});
|
|
13344
|
+
markUsedImportedFactories(compiledRules.importedFactory ? [compiledRules.importedFactory] : void 0);
|
|
12898
13345
|
}
|
|
12899
13346
|
}
|
|
12900
13347
|
}
|
|
@@ -12903,6 +13350,40 @@ function transformMacro(code, id, moduleAliases = /* @__PURE__ */ new Set([PARSE
|
|
|
12903
13350
|
imp.fullyResolved = !anyUnresolved && !keepMacroImport;
|
|
12904
13351
|
}
|
|
12905
13352
|
const ms = new MagicString(code);
|
|
13353
|
+
const replacementRanges = runtimeComposeFallback ? [] : replacements.map(({ start, end }) => ({ start, end }));
|
|
13354
|
+
const isInsideReplacement = (start, end) => replacementRanges.some((r) => start >= r.start && end <= r.end);
|
|
13355
|
+
const importedBindingStillReferenced = (local) => {
|
|
13356
|
+
const walk = (node2, parent, parentKey) => {
|
|
13357
|
+
if (!node2 || typeof node2 !== "object") return false;
|
|
13358
|
+
const rec = node2;
|
|
13359
|
+
if (rec.type === "ImportDeclaration") return false;
|
|
13360
|
+
if (typeof rec.start === "number" && typeof rec.end === "number" && isInsideReplacement(rec.start, rec.end)) return false;
|
|
13361
|
+
if ((rec.type === "Identifier" || rec.type === "BindingIdentifier") && rec.name === local) {
|
|
13362
|
+
if (parentKey === "key" && (parent?.type === "ObjectProperty" || parent?.type === "Property" || parent?.type === "PropertyDefinition") && parent.computed !== true) return false;
|
|
13363
|
+
if (parentKey === "property" && parent?.type === "StaticMemberExpression") return false;
|
|
13364
|
+
if (parentKey === "property" && parent?.type === "MemberExpression" && parent.computed !== true) return false;
|
|
13365
|
+
return true;
|
|
13366
|
+
}
|
|
13367
|
+
for (const key of Object.keys(rec)) {
|
|
13368
|
+
if (key === "type" || key === "start" || key === "end") continue;
|
|
13369
|
+
const value = rec[key];
|
|
13370
|
+
if (Array.isArray(value)) {
|
|
13371
|
+
if (value.some((child) => walk(child, rec, key))) return true;
|
|
13372
|
+
} else if (walk(value, rec, key)) {
|
|
13373
|
+
return true;
|
|
13374
|
+
}
|
|
13375
|
+
}
|
|
13376
|
+
return false;
|
|
13377
|
+
};
|
|
13378
|
+
return body.some((stmt) => walk(stmt));
|
|
13379
|
+
};
|
|
13380
|
+
for (const imp of ordinaryImports) {
|
|
13381
|
+
if (!runtimeComposeFallback && imp.specifiers.length > 0 && imp.specifiers.every(
|
|
13382
|
+
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !importedBindingStillReferenced(spec.local)
|
|
13383
|
+
)) {
|
|
13384
|
+
ms.remove(imp.start, imp.end);
|
|
13385
|
+
}
|
|
13386
|
+
}
|
|
12906
13387
|
if (!anyUnresolved) {
|
|
12907
13388
|
for (const { start, end } of defineRemovals) ms.remove(start, end);
|
|
12908
13389
|
}
|