parseman 0.51.2 → 0.53.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/analysis/commitment.d.ts.map +1 -1
- package/dist/analysis/diagnostics.js +411 -28
- package/dist/analysis/diagnostics.js.map +3 -3
- package/dist/cli/index.js +6162 -6372
- package/dist/cli/index.js.map +3 -3
- package/dist/combinators/attempt.d.ts +11 -1
- package/dist/combinators/attempt.d.ts.map +1 -1
- package/dist/combinators/map.d.ts.map +1 -1
- package/dist/combinators/node.d.ts +6 -2
- package/dist/combinators/node.d.ts.map +1 -1
- package/dist/combinators/parser.d.ts +34 -0
- package/dist/combinators/parser.d.ts.map +1 -1
- package/dist/combinators/ref.d.ts +0 -13
- package/dist/combinators/ref.d.ts.map +1 -1
- package/dist/compiler/borrowed-rules.d.ts +30 -0
- package/dist/compiler/borrowed-rules.d.ts.map +1 -0
- package/dist/compiler/compile-linkable-table.d.ts +1 -1
- package/dist/compiler/grammar-coverage-ids.d.ts.map +1 -1
- package/dist/compiler/ir-serialize.d.ts +10 -4
- package/dist/compiler/ir-serialize.d.ts.map +1 -1
- package/dist/compiler/linker.d.ts +48 -91
- package/dist/compiler/linker.d.ts.map +1 -1
- package/dist/compiler/token-capability.js +4 -0
- package/dist/compiler/token-capability.js.map +1 -1
- package/dist/coverage.d.ts +1 -1
- package/dist/coverage.d.ts.map +1 -1
- package/dist/cst/reflection.d.ts.map +1 -1
- package/dist/cst/trivia-kinds.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +470 -725
- package/dist/index.js.map +3 -3
- package/dist/language-service/index.js.map +1 -1
- package/dist/plugin/evaluator.d.ts +38 -2
- package/dist/plugin/evaluator.d.ts.map +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1127 -544
- package/dist/plugin/index.js.map +3 -3
- package/dist/plugin/ir-eval.d.ts +21 -0
- package/dist/plugin/ir-eval.d.ts.map +1 -0
- package/dist/plugin/reducer-resolver.d.ts +6 -0
- package/dist/plugin/reducer-resolver.d.ts.map +1 -1
- package/dist/spec/index.js +555 -6086
- package/dist/spec/index.js.map +3 -3
- package/dist/spec/railroad-lib.d.ts +7 -2
- package/dist/spec/railroad-lib.d.ts.map +1 -1
- package/dist/spec/railroad.d.ts.map +1 -1
- package/dist/table/assemble.d.ts.map +1 -1
- package/dist/table/compile-rule-map.d.ts +11 -4
- package/dist/table/compile-rule-map.d.ts.map +1 -1
- package/dist/table/compile.d.ts +16 -0
- package/dist/table/compile.d.ts.map +1 -1
- package/dist/table/emit-assembly.d.ts.map +1 -1
- package/dist/table/encode-baseline.d.ts.map +1 -1
- package/dist/table/exec.d.ts.map +1 -1
- package/dist/table/index.js +272 -102
- package/dist/table/index.js.map +2 -2
- package/dist/table/ops.d.ts +7 -5
- package/dist/table/ops.d.ts.map +1 -1
- package/dist/table/site-labels.d.ts.map +1 -1
- 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/src/analysis/commitment.ts +3 -1
- package/src/analysis/rebuild.ts +1 -1
- package/src/combinators/attempt.ts +26 -3
- package/src/combinators/first-set.ts +5 -1
- package/src/combinators/map.ts +5 -1
- package/src/combinators/node.ts +12 -3
- package/src/combinators/parser.ts +133 -67
- package/src/combinators/ref.ts +10 -1
- package/src/compiler/borrowed-rules.ts +88 -0
- package/src/compiler/compile-linkable-table.ts +1 -1
- package/src/compiler/grammar-coverage-ids.ts +35 -6
- package/src/compiler/ir-serialize.ts +13 -119
- package/src/compiler/linker.ts +190 -666
- package/src/coverage.ts +7 -5
- package/src/cst/reflection.ts +6 -1
- package/src/cst/trivia-kinds.ts +6 -0
- package/src/index.ts +1 -0
- package/src/plugin/evaluator.ts +114 -14
- package/src/plugin/index.ts +588 -110
- package/src/plugin/ir-eval.ts +165 -0
- package/src/plugin/reducer-resolver.ts +20 -3
- package/src/spec/railroad-lib.ts +18 -8
- package/src/spec/railroad.ts +3 -4
- package/src/table/assemble.ts +22 -8
- package/src/table/compile-rule-map.ts +18 -8
- package/src/table/compile.ts +61 -0
- package/src/table/emit-assembly.ts +8 -3
- package/src/table/encode-baseline.ts +5 -1
- package/src/table/encode.ts +13 -13
- package/src/table/exec.ts +6 -2
- package/src/table/ops.ts +7 -5
- package/src/table/site-labels.ts +3 -1
- package/src/types.ts +8 -1
- package/src/version.ts +1 -1
package/dist/plugin/index.js
CHANGED
|
@@ -265,6 +265,10 @@ function firstSetBody(p, seen, resolve3, activeTrivia) {
|
|
|
265
265
|
case "node":
|
|
266
266
|
case "sepBy":
|
|
267
267
|
case "expect":
|
|
268
|
+
// A transaction accepts exactly what its inner accepts. Its own `_meta` is
|
|
269
|
+
// the inner's construction-time set, which reads `any` when the inner opens
|
|
270
|
+
// with a rule reference — resolve through it like any other wrapper.
|
|
271
|
+
case "attempt":
|
|
268
272
|
return fs3(d.parser);
|
|
269
273
|
case "grammar":
|
|
270
274
|
return firstSetOf(
|
|
@@ -363,6 +367,7 @@ function withRuleTrivia(trivia2, ctx, run) {
|
|
|
363
367
|
ctx.triviaKindLabels = savedLabels;
|
|
364
368
|
}
|
|
365
369
|
}
|
|
370
|
+
var UNDEFINED_REF = new Error("ref<T>() used before .define() was called");
|
|
366
371
|
function ref() {
|
|
367
372
|
let resolved = null;
|
|
368
373
|
let resolvedScalar = null;
|
|
@@ -378,7 +383,7 @@ function ref() {
|
|
|
378
383
|
_def: {
|
|
379
384
|
tag: "lazy",
|
|
380
385
|
thunk: () => {
|
|
381
|
-
if (!resolved) throw
|
|
386
|
+
if (!resolved) throw UNDEFINED_REF;
|
|
382
387
|
return resolved;
|
|
383
388
|
}
|
|
384
389
|
},
|
|
@@ -1404,6 +1409,10 @@ function peelLabel(p) {
|
|
|
1404
1409
|
return null;
|
|
1405
1410
|
}
|
|
1406
1411
|
function analyzeLabeledTrivia(trivia2) {
|
|
1412
|
+
if (trivia2._def.tag === "trivia") {
|
|
1413
|
+
const own = trivia2._meta.labeledTriviaSpec;
|
|
1414
|
+
if (own !== void 0) return own;
|
|
1415
|
+
}
|
|
1407
1416
|
if (trivia2 === labeledTrivia0) return labeledSpec0;
|
|
1408
1417
|
if (trivia2 === labeledTrivia1) return labeledSpec1;
|
|
1409
1418
|
if (trivia2 === labeledTrivia2) return labeledSpec2;
|
|
@@ -1802,6 +1811,7 @@ function collectFromCombinator(parser2, out, seen, followLazy = true) {
|
|
|
1802
1811
|
function collectGrammarReflection(ruleMap, opts) {
|
|
1803
1812
|
const byType = /* @__PURE__ */ new Map();
|
|
1804
1813
|
const followLazy = opts?.followLazy !== false;
|
|
1814
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1805
1815
|
for (const [, rule] of ruleMap) {
|
|
1806
1816
|
if (!followLazy && rule._def.tag === "lazy") {
|
|
1807
1817
|
try {
|
|
@@ -1811,7 +1821,7 @@ function collectGrammarReflection(ruleMap, opts) {
|
|
|
1811
1821
|
}
|
|
1812
1822
|
continue;
|
|
1813
1823
|
}
|
|
1814
|
-
collectFromCombinator(rule, byType,
|
|
1824
|
+
collectFromCombinator(rule, byType, seen, followLazy);
|
|
1815
1825
|
}
|
|
1816
1826
|
return { nodes: [...byType].map(([type, tags]) => ({ type, tags })) };
|
|
1817
1827
|
}
|
|
@@ -1842,9 +1852,26 @@ function isNamedRuleRefForAnotherRule(r, key) {
|
|
|
1842
1852
|
const name = r._def.tag === "lazy" ? ruleNameOf(r) : void 0;
|
|
1843
1853
|
return name !== void 0 && name !== key;
|
|
1844
1854
|
}
|
|
1855
|
+
var claimedRules = /* @__PURE__ */ new WeakSet();
|
|
1856
|
+
function ownRule(p, copies) {
|
|
1857
|
+
if (!claimedRules.has(p) || p._meta.isTrivia) return p;
|
|
1858
|
+
let own = copies.get(p);
|
|
1859
|
+
if (own === void 0) {
|
|
1860
|
+
const { grammarTrivia: _t, grammarScanSkip: _s, grammarHostMode: _h, grammarTrackLines: _l, ...meta } = p._meta;
|
|
1861
|
+
copies.set(p, own = { ...p, _meta: meta });
|
|
1862
|
+
}
|
|
1863
|
+
return own;
|
|
1864
|
+
}
|
|
1845
1865
|
function rules(a, b) {
|
|
1846
1866
|
const factory = typeof a === "function" ? a : b;
|
|
1847
1867
|
const options = typeof a === "function" ? b : a;
|
|
1868
|
+
const recipe = { factory, options };
|
|
1869
|
+
const map = linkRules([recipe]);
|
|
1870
|
+
Object.defineProperty(map, RULES_RECIPE, { value: [recipe], enumerable: false });
|
|
1871
|
+
return map;
|
|
1872
|
+
}
|
|
1873
|
+
var RULES_RECIPE = /* @__PURE__ */ Symbol.for("parseman.rulesRecipe");
|
|
1874
|
+
function linkRules(recipes, link) {
|
|
1848
1875
|
const cache = {};
|
|
1849
1876
|
const proxy = new Proxy(cache, {
|
|
1850
1877
|
get(target, key) {
|
|
@@ -1858,10 +1885,18 @@ function rules(a, b) {
|
|
|
1858
1885
|
return record[key];
|
|
1859
1886
|
}
|
|
1860
1887
|
});
|
|
1861
|
-
const
|
|
1862
|
-
for (const
|
|
1888
|
+
const winners = /* @__PURE__ */ new Map();
|
|
1889
|
+
for (const recipe of recipes) {
|
|
1890
|
+
const definitions = recipe.factory(proxy);
|
|
1891
|
+
for (const key of Object.keys(definitions)) {
|
|
1892
|
+
winners.set(key, { parser: definitions[key], options: recipe.options });
|
|
1893
|
+
}
|
|
1894
|
+
}
|
|
1895
|
+
const keys = [...winners.keys()];
|
|
1896
|
+
const copies = /* @__PURE__ */ new Map();
|
|
1897
|
+
for (const [key, { parser: defined }] of winners) {
|
|
1863
1898
|
const placeholder = cache[key];
|
|
1864
|
-
const parser2 =
|
|
1899
|
+
const parser2 = ownRule(defined, copies);
|
|
1865
1900
|
if (placeholder === parser2) {
|
|
1866
1901
|
throw new Error(`rules(): rule "${key}" cannot be a direct alias to itself`);
|
|
1867
1902
|
}
|
|
@@ -1870,7 +1905,8 @@ function rules(a, b) {
|
|
|
1870
1905
|
placeholder.define(parser2);
|
|
1871
1906
|
placeholder._meta.firstSet = parser2._meta.firstSet;
|
|
1872
1907
|
placeholder._meta.canMatchNewline = parser2._meta.canMatchNewline;
|
|
1873
|
-
} else if (isNamedRuleRefForAnotherRule(parser2, key)) {
|
|
1908
|
+
} else if (isNamedRuleRefForAnotherRule(parser2, key) || link !== void 0) {
|
|
1909
|
+
if (!isNamedRuleRefForAnotherRule(parser2, key)) tagRule(parser2, key);
|
|
1874
1910
|
const alias = ref();
|
|
1875
1911
|
tagRule(alias, key);
|
|
1876
1912
|
alias.define(parser2);
|
|
@@ -1882,48 +1918,34 @@ function rules(a, b) {
|
|
|
1882
1918
|
cache[key] = parser2;
|
|
1883
1919
|
}
|
|
1884
1920
|
}
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
if (
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
}
|
|
1903
|
-
if (options?.trackLines === true) {
|
|
1904
|
-
for (const key of Object.keys(definitions)) {
|
|
1905
|
-
const rule = cache[key];
|
|
1906
|
-
if (rule && !rule._meta.isTrivia) rule._meta.grammarTrackLines = true;
|
|
1907
|
-
}
|
|
1908
|
-
for (const key of Object.keys(definitions)) {
|
|
1909
|
-
const rule = cache[key];
|
|
1910
|
-
if (rule && !rule._meta.isTrivia && rule._def.tag !== "grammar") {
|
|
1911
|
-
const wrapped = parser({ trackLines: true }, rule);
|
|
1912
|
-
tagRule(wrapped, key);
|
|
1913
|
-
wrapped._meta.grammarTrackLines = true;
|
|
1914
|
-
cache[key] = wrapped;
|
|
1921
|
+
for (const key of keys) {
|
|
1922
|
+
const options = winners.get(key).options;
|
|
1923
|
+
let rule = cache[key];
|
|
1924
|
+
if (!rule._meta.isTrivia) {
|
|
1925
|
+
const meta = rule._meta;
|
|
1926
|
+
const trivia2 = link !== void 0 ? link.trivia : options?.trivia;
|
|
1927
|
+
if (trivia2 != null) meta.grammarTrivia = trivia2;
|
|
1928
|
+
if (options?.scanSkip != null) meta.grammarScanSkip = options.scanSkip;
|
|
1929
|
+
if ((link?.hostMode ?? options?.hostMode) === "cst") meta.grammarHostMode = "cst";
|
|
1930
|
+
if (options?.trackLines === true) {
|
|
1931
|
+
meta.grammarTrackLines = true;
|
|
1932
|
+
if (rule._def.tag !== "grammar") {
|
|
1933
|
+
rule = parser({ trackLines: true }, rule);
|
|
1934
|
+
tagRule(rule, key);
|
|
1935
|
+
rule._meta.grammarTrackLines = true;
|
|
1936
|
+
cache[key] = rule;
|
|
1937
|
+
}
|
|
1915
1938
|
}
|
|
1916
1939
|
}
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
markUnusedValues(cache[key]);
|
|
1940
|
+
markUnusedValues(rule);
|
|
1941
|
+
claimedRules.add(winners.get(key).parser).add(rule);
|
|
1920
1942
|
}
|
|
1921
1943
|
Object.defineProperty(cache, RULE_ORDER, {
|
|
1922
|
-
value:
|
|
1944
|
+
value: keys,
|
|
1923
1945
|
enumerable: false,
|
|
1924
1946
|
configurable: true
|
|
1925
1947
|
});
|
|
1926
|
-
attachGrammarReflection(cache, collectGrammarReflection(
|
|
1948
|
+
attachGrammarReflection(cache, collectGrammarReflection(keys.map((key) => [key, cache[key]])));
|
|
1927
1949
|
return cache;
|
|
1928
1950
|
}
|
|
1929
1951
|
|
|
@@ -4061,13 +4083,24 @@ function dispatch(selector, ...arms) {
|
|
|
4061
4083
|
}
|
|
4062
4084
|
|
|
4063
4085
|
// src/combinators/attempt.ts
|
|
4064
|
-
function
|
|
4086
|
+
function containOption(options) {
|
|
4087
|
+
if (options === void 0) return false;
|
|
4088
|
+
for (const key of Object.keys(options)) {
|
|
4089
|
+
if (key !== "contain") throw new TypeError(`attempt(): unknown option ${JSON.stringify(key)}`);
|
|
4090
|
+
}
|
|
4091
|
+
if (options.contain !== void 0 && typeof options.contain !== "boolean") {
|
|
4092
|
+
throw new TypeError("attempt(): `contain` must be a boolean");
|
|
4093
|
+
}
|
|
4094
|
+
return options.contain === true;
|
|
4095
|
+
}
|
|
4096
|
+
function attempt(parser2, options) {
|
|
4097
|
+
const contain = containOption(options);
|
|
4065
4098
|
const guardable = parser2._meta.firstSet.kind !== "any" && !matchesEmpty(parser2);
|
|
4066
4099
|
let failExpected;
|
|
4067
4100
|
return {
|
|
4068
4101
|
_tag: "attempt",
|
|
4069
4102
|
_meta: parser2._meta,
|
|
4070
|
-
_def: { tag: "attempt", parser: parser2 },
|
|
4103
|
+
_def: contain ? { tag: "attempt", parser: parser2, contain: true } : { tag: "attempt", parser: parser2 },
|
|
4071
4104
|
parse(input, pos, ctx) {
|
|
4072
4105
|
if (guardable && ctx._probe === void 0 && !ctx._tolerant && !startsFirstSet(parser2, input, pos)) {
|
|
4073
4106
|
if (failExpected === void 0) {
|
|
@@ -4084,7 +4117,7 @@ function attempt(parser2) {
|
|
|
4084
4117
|
rollbackCstCapture(ctx, mark);
|
|
4085
4118
|
if (log !== void 0 && ctx._triviaLog && ctx._triviaLog.length !== log) ctx._triviaLog.length = log;
|
|
4086
4119
|
if (rootLog !== void 0 && ctx._rootTriviaLog && ctx._rootTriviaLog.length !== rootLog) ctx._rootTriviaLog.length = rootLog;
|
|
4087
|
-
if (result.committed) return result;
|
|
4120
|
+
if (result.committed && !contain) return result;
|
|
4088
4121
|
return { ok: false, expected: result.expected, span: { start: pos, end: pos } };
|
|
4089
4122
|
}
|
|
4090
4123
|
};
|
|
@@ -4939,7 +4972,7 @@ function node(typeOrCombinator, combinatorOrBuild, buildOrOpts, maybeOpts) {
|
|
|
4939
4972
|
throw new Error("node() options cannot combine project with unwrap or collapse");
|
|
4940
4973
|
}
|
|
4941
4974
|
const def = unwrap || collapse || project !== void 0 || captureTrivia || trailingTrivia || buildArity !== void 0 || tags !== void 0 && tags.length > 0 ? { ...baseDef, ...unwrap ? { unwrap: true } : {}, ...collapse ? { collapse: true } : {}, ...project !== void 0 ? { project } : {}, ...captureTrivia ? { captureTrivia: true } : {}, ...trailingTrivia ? { trailingTrivia: true } : {}, ...buildArity !== void 0 ? { buildArity } : {}, ...tags !== void 0 && tags.length > 0 ? { tags } : {} } : baseDef;
|
|
4942
|
-
const capturesTrivia = captureTrivia ||
|
|
4975
|
+
const capturesTrivia = captureTrivia || (build ? buildReadsTrivia(def) : project === void 0);
|
|
4943
4976
|
const clonesState = build ? buildReadsState(def) : project === void 0;
|
|
4944
4977
|
const hasOwnFields = parserHasOwnFields(combinator);
|
|
4945
4978
|
const capturesFields = hasOwnFields && (build ? buildReadsFields(def) : project === void 0);
|
|
@@ -5053,13 +5086,17 @@ function transform(combinator, fn) {
|
|
|
5053
5086
|
};
|
|
5054
5087
|
}
|
|
5055
5088
|
function trivia(combinator) {
|
|
5056
|
-
const
|
|
5089
|
+
const labeled = analyzeLabeledTrivia(combinator);
|
|
5090
|
+
const kindLabels = labeled?.labels;
|
|
5057
5091
|
return {
|
|
5058
5092
|
_tag: combinator._tag,
|
|
5059
5093
|
_meta: {
|
|
5060
5094
|
...combinator._meta,
|
|
5061
5095
|
isTrivia: true,
|
|
5062
5096
|
triviaScanner: fastTriviaScanner(combinator),
|
|
5097
|
+
// Every labeled scan of this trivia reads its spec; the module's four-slot
|
|
5098
|
+
// memo alone thrashes on a grammar with more than four trivia tables.
|
|
5099
|
+
labeledTriviaSpec: labeled,
|
|
5063
5100
|
...kindLabels ? { triviaKindLabels: kindLabels } : {}
|
|
5064
5101
|
},
|
|
5065
5102
|
_def: { tag: "trivia", parser: combinator },
|
|
@@ -5592,10 +5629,12 @@ function mayCommitFailure(p, seen = /* @__PURE__ */ new Set(), resolve3) {
|
|
|
5592
5629
|
case "choice":
|
|
5593
5630
|
case "sequence":
|
|
5594
5631
|
return d.parsers.some((x) => mayCommitFailure(x, seen, resolve3));
|
|
5632
|
+
// A contained transaction reports every failure uncommitted.
|
|
5633
|
+
case "attempt":
|
|
5634
|
+
return d.contain !== true && mayCommitFailure(d.parser, seen, resolve3);
|
|
5595
5635
|
case "many":
|
|
5596
5636
|
case "oneOrMore":
|
|
5597
5637
|
case "optional":
|
|
5598
|
-
case "attempt":
|
|
5599
5638
|
case "transform":
|
|
5600
5639
|
case "label":
|
|
5601
5640
|
case "field":
|
|
@@ -7704,7 +7743,7 @@ var Encoder = class {
|
|
|
7704
7743
|
const derivedState = d.build !== void 0 ? buildReadsState(d) : noBuildCaptures;
|
|
7705
7744
|
const derivedFields = d.build !== void 0 ? buildReadsFields(d) : noBuildCaptures;
|
|
7706
7745
|
const wantsFields = parserHasOwnFields(d.parser) && (cstOut || derivedFields);
|
|
7707
|
-
const flags = (cstOut || d.captureTrivia === true ||
|
|
7746
|
+
const flags = (cstOut || d.captureTrivia === true || derivedTrivia ? 4 : 0) | (!cstOut && omitsRaw ? 2 : 0) | (cstOut || derivedState ? 8 : 0) | (wantsFields ? 16 : 0) | (d.collapse === true ? 32 : 0) | (d.unwrap === true ? 64 : 0) | (d.trailingTrivia === true ? 128 : 0) | (d.captureTrivia === true ? 1 : 0);
|
|
7708
7747
|
const body = this.emit(
|
|
7709
7748
|
this.track ? OP_NODE_TRACK : OP_NODE,
|
|
7710
7749
|
d.build === void 0 ? -1 : this.fn(d.build, d.buildSrc ?? null),
|
|
@@ -7830,7 +7869,7 @@ var Encoder = class {
|
|
|
7830
7869
|
// A TRANSACTION IS A ROW. See `OP_ATTEMPT` for why the transparent
|
|
7831
7870
|
// lowering was correct only for a choice arm.
|
|
7832
7871
|
case "attempt": {
|
|
7833
|
-
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip);
|
|
7872
|
+
const inner = this.emit(OP_ATTEMPT, this.node(d.parser).ip, d.contain === true ? 1 : 0);
|
|
7834
7873
|
if (!this.failureNeedsRollback(d.parser, void 0)) this.failureRollbackCleanSites.add(inner);
|
|
7835
7874
|
const fs3 = d.parser._def.tag === "lazy" ? firstSetOf(d.parser, /* @__PURE__ */ new Set(), this.refResolver(), this.activeTrivia) : d.parser._meta.firstSet;
|
|
7836
7875
|
if (fs3.kind === "any" || matchesEmpty(d.parser)) return inner;
|
|
@@ -9223,7 +9262,7 @@ function transfer(code, ip, at, hostCst) {
|
|
|
9223
9262
|
}
|
|
9224
9263
|
if (op === OP_NODE || op === OP_NODE_TRACK) {
|
|
9225
9264
|
const flags = code[ip + 3];
|
|
9226
|
-
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && (flags === 2 || flags === 18 || flags === 34);
|
|
9265
|
+
const directChildren = !hostCst && op === OP_NODE && code[ip + 1] >= 0 && code[ip + 4] < 0 && ((flags & ~128) === 2 || flags === 18 || flags === 34);
|
|
9227
9266
|
if (directChildren) {
|
|
9228
9267
|
return { tri: at.tri, buf: false, raw: RAW_UNKNOWN, cap: CAP_OFF };
|
|
9229
9268
|
}
|
|
@@ -10427,7 +10466,7 @@ ${clean ? "" : emitMark(p, L.buf, L.raw, sinks)}
|
|
|
10427
10466
|
const v=${child}(input,pos,ctx)
|
|
10428
10467
|
if(v!==FAIL)return v
|
|
10429
10468
|
${clean ? "" : emitRollback(p, L.buf, L.raw, sinks)}
|
|
10430
|
-
if(ctx._fc===true)return FAIL
|
|
10469
|
+
${code[ip + 2] === 1 ? "ctx._fc=false" : "if(ctx._fc===true)return FAIL"}
|
|
10431
10470
|
ctx._fe=pos
|
|
10432
10471
|
return FAIL
|
|
10433
10472
|
}`;
|
|
@@ -11016,7 +11055,8 @@ return nd
|
|
|
11016
11055
|
const unwrap = (flags & 64) !== 0;
|
|
11017
11056
|
const trailingTrivia = (flags & 128) !== 0;
|
|
11018
11057
|
const build = buildIdx >= 0 ? fnRef(buildIdx) : void 0;
|
|
11019
|
-
|
|
11058
|
+
const leanFlags = flags & ~128;
|
|
11059
|
+
if (!hostCst && !tracked && build !== void 0 && proj < 0 && (leanFlags === 2 || (flags === 18 || flags === 34))) {
|
|
11020
11060
|
const fields = flags === 18;
|
|
11021
11061
|
const collapseChildren = flags === 34;
|
|
11022
11062
|
const publish = L.buf && L.raw === RAW_OMIT ? "_pushNodeNoRawBuf(ctx,nd)" : L.buf && L.raw === RAW_CAPTURE ? `if(sBuf!==undefined){
|
|
@@ -11061,7 +11101,8 @@ ctx._cstTriviaLog=undefined
|
|
|
11061
11101
|
ctx.captureTrivia=false
|
|
11062
11102
|
ctx._fields=${fields ? "[]" : "undefined"}
|
|
11063
11103
|
const v=${child}(input,pos,ctx)
|
|
11064
|
-
|
|
11104
|
+
${trailingTrivia && L.tri !== TRI_NONE ? `if(v!==FAIL${L.tri === TRI_UNKNOWN ? "&&ctx.trivia!==undefined" : ""})EC.e=consumeTrivia(input,EC.e,ctx)
|
|
11105
|
+
` : ""}const captured=_capturedFlatChildren(flat)
|
|
11065
11106
|
${fields ? "const fieldMap=buildFieldMap(ctx._fields)\n" : ""}ctx._fields=sFields
|
|
11066
11107
|
ctx._cstBuf=sBuf
|
|
11067
11108
|
ctx._cstChildren=sCh
|
|
@@ -11681,7 +11722,7 @@ function assemble(t, prog, cfg) {
|
|
|
11681
11722
|
const lf = { _tag: "leaf", value, span: { start: s, end: e } };
|
|
11682
11723
|
pushCstLeaf(ctx, lf);
|
|
11683
11724
|
}
|
|
11684
|
-
function plainBuildNode(child, build) {
|
|
11725
|
+
function plainBuildNode(child, build, trailing) {
|
|
11685
11726
|
return (input, pos, ctx) => {
|
|
11686
11727
|
const sCh = ctx._cstChildren;
|
|
11687
11728
|
const sLv = ctx._cstLeaves;
|
|
@@ -11699,6 +11740,7 @@ function assemble(t, prog, cfg) {
|
|
|
11699
11740
|
ctx.captureTrivia = false;
|
|
11700
11741
|
ctx._fields = void 0;
|
|
11701
11742
|
const value = child(input, pos, ctx);
|
|
11743
|
+
if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
|
|
11702
11744
|
const kids = buf.ch ?? (buf.single !== void 0 ? [buf.single] : EMPTY_CH);
|
|
11703
11745
|
const rawKids = buf.raw ?? (buf.rawSingle !== void 0 ? [buf.rawSingle] : EMPTY_CH);
|
|
11704
11746
|
ctx._fields = savedFields;
|
|
@@ -11726,7 +11768,7 @@ function assemble(t, prog, cfg) {
|
|
|
11726
11768
|
while (first < children3.length && children3[first] === void 0) first++;
|
|
11727
11769
|
return first === children3.length ? EMPTY_CH : children3.slice(first);
|
|
11728
11770
|
}
|
|
11729
|
-
function childrenOnlyBuildNode(child, build) {
|
|
11771
|
+
function childrenOnlyBuildNode(child, build, trailing) {
|
|
11730
11772
|
return (input, pos, ctx) => {
|
|
11731
11773
|
const sCh = ctx._cstChildren;
|
|
11732
11774
|
const sLv = ctx._cstLeaves;
|
|
@@ -11744,6 +11786,7 @@ function assemble(t, prog, cfg) {
|
|
|
11744
11786
|
ctx.captureTrivia = false;
|
|
11745
11787
|
ctx._fields = void 0;
|
|
11746
11788
|
const value = child(input, pos, ctx);
|
|
11789
|
+
if (trailing && value !== FAIL && ctx.trivia !== void 0) EC.e = consumeTrivia(input, EC.e, ctx);
|
|
11747
11790
|
const captured = capturedFlatChildren(kids);
|
|
11748
11791
|
ctx._fields = savedFields;
|
|
11749
11792
|
ctx._cstBuf = sBuf;
|
|
@@ -12768,6 +12811,7 @@ function assemble(t, prog, cfg) {
|
|
|
12768
12811
|
/* ── transaction ─────────────────────────────────────────────────────── */
|
|
12769
12812
|
case OP_ATTEMPT: {
|
|
12770
12813
|
const child = link(code[ip + 1]);
|
|
12814
|
+
const contain = code[ip + 2] === 1;
|
|
12771
12815
|
return (input, pos, ctx) => {
|
|
12772
12816
|
const need = markCst(ctx);
|
|
12773
12817
|
const mRaw = MRAW;
|
|
@@ -12780,7 +12824,10 @@ function assemble(t, prog, cfg) {
|
|
|
12780
12824
|
const v = child(input, pos, ctx);
|
|
12781
12825
|
if (v !== FAIL) return v;
|
|
12782
12826
|
if (need) rollbackTriviaAt(ctx, mRaw, mTl, mLv, mFl, mEr, mLog, mRoot);
|
|
12783
|
-
if (committed3(ctx))
|
|
12827
|
+
if (committed3(ctx)) {
|
|
12828
|
+
if (!contain) return FAIL;
|
|
12829
|
+
ctx._fc = false;
|
|
12830
|
+
}
|
|
12784
12831
|
ctx._fe = pos;
|
|
12785
12832
|
return FAIL;
|
|
12786
12833
|
};
|
|
@@ -14231,11 +14278,11 @@ function assemble(t, prog, cfg) {
|
|
|
14231
14278
|
const trailingTrivia = (flags & 128) !== 0;
|
|
14232
14279
|
const build = buildIdx >= 0 ? fns[buildIdx] : void 0;
|
|
14233
14280
|
if (!hostCst && !tracked) {
|
|
14234
|
-
if (build !== void 0 && proj < 0 && flags === 0) {
|
|
14235
|
-
return plainBuildNode(child, build);
|
|
14281
|
+
if (build !== void 0 && proj < 0 && (flags & ~128) === 0) {
|
|
14282
|
+
return plainBuildNode(child, build, trailingTrivia);
|
|
14236
14283
|
}
|
|
14237
|
-
if (build !== void 0 && proj < 0 && flags === 2) {
|
|
14238
|
-
return childrenOnlyBuildNode(child, build);
|
|
14284
|
+
if (build !== void 0 && proj < 0 && (flags & ~128) === 2) {
|
|
14285
|
+
return childrenOnlyBuildNode(child, build, trailingTrivia);
|
|
14239
14286
|
}
|
|
14240
14287
|
if (build !== void 0 && proj < 0 && flags === 18) {
|
|
14241
14288
|
return childrenOnlyFieldsBuildNode(child, build);
|
|
@@ -14987,7 +15034,8 @@ function children(def, winners) {
|
|
|
14987
15034
|
return [];
|
|
14988
15035
|
}
|
|
14989
15036
|
const name = resolved._ruleName;
|
|
14990
|
-
|
|
15037
|
+
const winner = name ? winners?.[name] : void 0;
|
|
15038
|
+
return winner !== void 0 && winner._def !== def ? [winner] : [resolved];
|
|
14991
15039
|
}
|
|
14992
15040
|
default:
|
|
14993
15041
|
return [];
|
|
@@ -15012,16 +15060,39 @@ function buildGrammarPlan(entry, winners) {
|
|
|
15012
15060
|
}
|
|
15013
15061
|
}
|
|
15014
15062
|
}
|
|
15063
|
+
const selfWinnerBody = (parser2) => {
|
|
15064
|
+
if (parser2._def.tag !== "lazy" || winners === void 0) return void 0;
|
|
15065
|
+
const name = winnerNames.get(parser2);
|
|
15066
|
+
if (name === void 0 || winners[name] !== parser2) return void 0;
|
|
15067
|
+
try {
|
|
15068
|
+
return parser2._def.thunk();
|
|
15069
|
+
} catch {
|
|
15070
|
+
return void 0;
|
|
15071
|
+
}
|
|
15072
|
+
};
|
|
15073
|
+
const slotsPerBody = /* @__PURE__ */ new Map();
|
|
15074
|
+
if (winners) {
|
|
15075
|
+
for (const winner of Object.values(winners)) {
|
|
15076
|
+
const body = selfWinnerBody(winner);
|
|
15077
|
+
if (body !== void 0) slotsPerBody.set(body, (slotsPerBody.get(body) ?? 0) + 1);
|
|
15078
|
+
}
|
|
15079
|
+
}
|
|
15080
|
+
const sharedBody = (parser2) => (slotsPerBody.get(parser2) ?? 0) > 1;
|
|
15081
|
+
const ownRule2 = (parser2, rule) => {
|
|
15082
|
+
const id = `rule:${rule}`;
|
|
15083
|
+
definitions.set(id, { id, kind: "rule" });
|
|
15084
|
+
rules2.set(parser2, id);
|
|
15085
|
+
};
|
|
15015
15086
|
const seen = /* @__PURE__ */ new Set();
|
|
15016
15087
|
const visit = (parser2, path3) => {
|
|
15017
15088
|
if (seen.has(parser2)) return;
|
|
15018
15089
|
seen.add(parser2);
|
|
15019
15090
|
const rule = winnerNames.get(parser2) ?? parser2._ruleName;
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
-
|
|
15023
|
-
rules2.set(parser2, id);
|
|
15091
|
+
const body = selfWinnerBody(parser2);
|
|
15092
|
+
if (rule && body === void 0 && !sharedBody(parser2) && (winnerNames.has(parser2) || parser2._def.tag !== "lazy")) {
|
|
15093
|
+
ownRule2(parser2, rule);
|
|
15024
15094
|
}
|
|
15095
|
+
if (rule && body !== void 0 && sharedBody(body)) ownRule2(parser2, rule);
|
|
15025
15096
|
if (parser2._def.tag === "choice") {
|
|
15026
15097
|
const ids = parser2._def.parsers.map((_, index) => `choice:${path3}/arm:${index}`);
|
|
15027
15098
|
choices.set(parser2, ids);
|
|
@@ -15042,7 +15113,13 @@ function buildGrammarPlan(entry, winners) {
|
|
|
15042
15113
|
};
|
|
15043
15114
|
const roots = Array.isArray(entry) ? entry : [entry];
|
|
15044
15115
|
for (const root of roots) {
|
|
15045
|
-
|
|
15116
|
+
const name = winnerNames.get(root) ?? root._ruleName ?? "entry";
|
|
15117
|
+
const body = selfWinnerBody(root);
|
|
15118
|
+
if (body !== void 0 && sharedBody(body) && !seen.has(root)) {
|
|
15119
|
+
seen.add(root);
|
|
15120
|
+
ownRule2(root, name);
|
|
15121
|
+
}
|
|
15122
|
+
visit(body ?? root, name);
|
|
15046
15123
|
}
|
|
15047
15124
|
return { definitions: [...definitions.values()].sort((a, b) => a.id.localeCompare(b.id)), choices, dispatches, attempts, labels, rules: rules2 };
|
|
15048
15125
|
}
|
|
@@ -16348,6 +16425,183 @@ function runDuplicationDiagnosticRules(ruleMap, opt) {
|
|
|
16348
16425
|
return reportDuplication(opt, (o) => analyzeDuplicationRules(ruleMap, o));
|
|
16349
16426
|
}
|
|
16350
16427
|
|
|
16428
|
+
// src/table/compile-rule-map.ts
|
|
16429
|
+
var DEFAULT_PRECOMPILE_MIN_WORDS = 1024;
|
|
16430
|
+
function resolveHostMode(ruleMap, explicit) {
|
|
16431
|
+
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
16432
|
+
}
|
|
16433
|
+
function resolveTrackLines(ruleMap, explicit) {
|
|
16434
|
+
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
16435
|
+
}
|
|
16436
|
+
function withAmbient(ruleMap, opts) {
|
|
16437
|
+
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
16438
|
+
const wrappers = /* @__PURE__ */ new Map();
|
|
16439
|
+
return ruleMap.map(([name, rule]) => {
|
|
16440
|
+
if (rule._meta.isTrivia) return [name, rule];
|
|
16441
|
+
const addTrivia = opts.trivia !== void 0 && rule._meta.grammarTrivia === void 0;
|
|
16442
|
+
const addScanSkip = opts.scanSkip !== void 0 && rule._meta.grammarScanSkip === void 0;
|
|
16443
|
+
if (!addTrivia && !addScanSkip) return [name, rule];
|
|
16444
|
+
let wrapped = wrappers.get(rule);
|
|
16445
|
+
if (wrapped === void 0) {
|
|
16446
|
+
wrapped = {
|
|
16447
|
+
...rule,
|
|
16448
|
+
_meta: {
|
|
16449
|
+
...rule._meta,
|
|
16450
|
+
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
16451
|
+
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
16452
|
+
}
|
|
16453
|
+
};
|
|
16454
|
+
wrappers.set(rule, wrapped);
|
|
16455
|
+
}
|
|
16456
|
+
return [name, wrapped];
|
|
16457
|
+
});
|
|
16458
|
+
}
|
|
16459
|
+
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
16460
|
+
const encoded = encodeForRun(ruleMap, opts);
|
|
16461
|
+
if (encoded === null) return null;
|
|
16462
|
+
const { prog, hostMode, plan } = encoded;
|
|
16463
|
+
const artifact = closureArtifact(prog);
|
|
16464
|
+
const reflection = collectGrammarReflection(ruleMap);
|
|
16465
|
+
return {
|
|
16466
|
+
keys: ruleMap.map(([key]) => key),
|
|
16467
|
+
hostMode,
|
|
16468
|
+
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
16469
|
+
reflection,
|
|
16470
|
+
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16471
|
+
// Reflection rides on the map's metadata prototype from birth. Only `compile()`
|
|
16472
|
+
// asks to specialise; every other caller runs the closure artifact.
|
|
16473
|
+
rules: tableRules(opts.specialise === true ? prog : artifact, { [GRAMMAR_REFLECTION]: reflection }),
|
|
16474
|
+
prog: artifact
|
|
16475
|
+
};
|
|
16476
|
+
}
|
|
16477
|
+
function encodeForRun(ruleMap, opts) {
|
|
16478
|
+
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
16479
|
+
const encodeMap = withAmbient(ruleMap, opts);
|
|
16480
|
+
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
16481
|
+
encodeMap.map(([, rule]) => rule),
|
|
16482
|
+
Object.fromEntries(encodeMap.filter(([, rule]) => rule._def.tag !== "lazy"))
|
|
16483
|
+
) : void 0;
|
|
16484
|
+
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
16485
|
+
const settings = {
|
|
16486
|
+
hostMode,
|
|
16487
|
+
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
16488
|
+
...opts.recovery === true ? { recovery: true } : {},
|
|
16489
|
+
...plan === void 0 ? {} : { coverage: plan }
|
|
16490
|
+
};
|
|
16491
|
+
try {
|
|
16492
|
+
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
16493
|
+
return { prog, fnSrcs, hostMode, plan };
|
|
16494
|
+
} catch (e) {
|
|
16495
|
+
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
16496
|
+
return null;
|
|
16497
|
+
}
|
|
16498
|
+
}
|
|
16499
|
+
function compileRuleMap(ruleMap, opts = {}) {
|
|
16500
|
+
const encoded = encodeForRun(ruleMap, opts);
|
|
16501
|
+
if (encoded === null) return null;
|
|
16502
|
+
const { prog, fnSrcs, hostMode, plan } = encoded;
|
|
16503
|
+
const artifact = closureArtifact(prog);
|
|
16504
|
+
if (artifact.runtimeOnly !== void 0 && artifact.runtimeOnly.length > 0) {
|
|
16505
|
+
opts.refusals?.push(...artifact.runtimeOnly);
|
|
16506
|
+
return null;
|
|
16507
|
+
}
|
|
16508
|
+
const supplied = opts.fnSources;
|
|
16509
|
+
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? null);
|
|
16510
|
+
if (sources.some((s) => s === null)) {
|
|
16511
|
+
const missing = sources.flatMap((s, i) => s === null ? [i] : []);
|
|
16512
|
+
opts.refusals?.push(
|
|
16513
|
+
`author reducer source missing for prog.fns[${missing.join(", ")}] \u2014 printing would emit \`() => {}\` and the parse would return no value`
|
|
16514
|
+
);
|
|
16515
|
+
return null;
|
|
16516
|
+
}
|
|
16517
|
+
if (supplied !== void 0 && supplied.length > fnSrcs.length) {
|
|
16518
|
+
throw new Error(
|
|
16519
|
+
`compileRuleMap: got ${supplied.length} fnSources for a pool of ${fnSrcs.length}. The list is positional, in prog.fns order, so a longer one means it belongs to a different encode \u2014 and the entries would be silently misassigned.`
|
|
16520
|
+
);
|
|
16521
|
+
}
|
|
16522
|
+
const replacementWithMetadata = (metadataSource, options = {}) => emitTableExpression(artifact, {
|
|
16523
|
+
entry: null,
|
|
16524
|
+
runtimeRef: opts.runtimeRef ?? "tableRules",
|
|
16525
|
+
fnSources: sources,
|
|
16526
|
+
...options.precompileDefault === true && hostMode === "ast" && prog.lines !== 1 && prog.code.length >= DEFAULT_PRECOMPILE_MIN_WORDS ? { assemblies: defaultAssemblyCfgs(artifact).slice(0, 1) } : {},
|
|
16527
|
+
...metadataSource === void 0 ? {} : { metadataSource }
|
|
16528
|
+
});
|
|
16529
|
+
const replacement = replacementWithMetadata();
|
|
16530
|
+
return {
|
|
16531
|
+
keys: ruleMap.map(([key]) => key),
|
|
16532
|
+
replacement,
|
|
16533
|
+
replacementWithMetadata,
|
|
16534
|
+
hostMode,
|
|
16535
|
+
// WHAT THE FLAG MEANS is "a DIRECT BUILDER's positioned-CST branch was
|
|
16536
|
+
// dropped", which is what the driver's `'ast' artifact + CST host` check keys
|
|
16537
|
+
// off. `mode === 'ast'` alone over-reports it: an all-STRUCTURAL grammar has no
|
|
16538
|
+
// direct builder, so there was no branch to drop and it stays usable with either
|
|
16539
|
+
// host — the long-standing `node(parser)` contract. Same predicate codegen uses
|
|
16540
|
+
// for its own `hasDirectBuilders` (both read `analysis/commitment.ts`), so the two
|
|
16541
|
+
// lowerings stamp the same artifact rather than disagreeing about it.
|
|
16542
|
+
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
16543
|
+
reflection: collectGrammarReflection(ruleMap),
|
|
16544
|
+
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
16545
|
+
rules: tableRules(artifact),
|
|
16546
|
+
prog: artifact
|
|
16547
|
+
};
|
|
16548
|
+
}
|
|
16549
|
+
|
|
16550
|
+
// src/compiler/borrowed-rules.ts
|
|
16551
|
+
var nameOf = (c) => c._ruleName;
|
|
16552
|
+
function deref(c) {
|
|
16553
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16554
|
+
let current = c;
|
|
16555
|
+
while (current._def.tag === "lazy" && !seen.has(current)) {
|
|
16556
|
+
seen.add(current);
|
|
16557
|
+
try {
|
|
16558
|
+
current = current._def.thunk();
|
|
16559
|
+
} catch {
|
|
16560
|
+
return void 0;
|
|
16561
|
+
}
|
|
16562
|
+
}
|
|
16563
|
+
return current;
|
|
16564
|
+
}
|
|
16565
|
+
function borrowedRuleReference(map) {
|
|
16566
|
+
const seen = /* @__PURE__ */ new Set();
|
|
16567
|
+
for (const [rule, self] of Object.entries(map)) {
|
|
16568
|
+
let found;
|
|
16569
|
+
const visit = (c) => {
|
|
16570
|
+
if (found !== void 0) return;
|
|
16571
|
+
if (c._def.tag === "lazy") {
|
|
16572
|
+
if (!winnerWrapsReference(self, c)) {
|
|
16573
|
+
const name = nameOf(c);
|
|
16574
|
+
const winner = name !== void 0 && Object.hasOwn(map, name) ? map[name] : void 0;
|
|
16575
|
+
if (winner !== void 0) {
|
|
16576
|
+
if (winnerWrapsReference(winner, c) || deref(c) === deref(winner)) return;
|
|
16577
|
+
found = name;
|
|
16578
|
+
return;
|
|
16579
|
+
}
|
|
16580
|
+
}
|
|
16581
|
+
if (seen.has(c)) return;
|
|
16582
|
+
seen.add(c);
|
|
16583
|
+
let body;
|
|
16584
|
+
try {
|
|
16585
|
+
body = c._def.thunk();
|
|
16586
|
+
} catch {
|
|
16587
|
+
return;
|
|
16588
|
+
}
|
|
16589
|
+
visit(body);
|
|
16590
|
+
return;
|
|
16591
|
+
}
|
|
16592
|
+
if (seen.has(c)) return;
|
|
16593
|
+
seen.add(c);
|
|
16594
|
+
for (const child of childrenOf2(c._def)) visit(child);
|
|
16595
|
+
};
|
|
16596
|
+
visit(self);
|
|
16597
|
+
if (found !== void 0) return { rule, reference: found };
|
|
16598
|
+
}
|
|
16599
|
+
return void 0;
|
|
16600
|
+
}
|
|
16601
|
+
function borrowedRuleMessage(api, hit) {
|
|
16602
|
+
return `${api}: rule "${hit.rule}" is a rule object borrowed from another grammar, and its graph references "${hit.reference}", which this grammar also defines. The interpreter would keep the other grammar's "${hit.reference}" while a compiled table binds this grammar's, so the two would accept different input. Compose the grammar that defines "${hit.rule}" instead of borrowing its rule object, so its references resolve to this grammar's rules.`;
|
|
16603
|
+
}
|
|
16604
|
+
|
|
16351
16605
|
// src/table/compile.ts
|
|
16352
16606
|
var ENTRY = "Entry";
|
|
16353
16607
|
function ownSource(fn) {
|
|
@@ -16357,7 +16611,47 @@ function ownSource(fn) {
|
|
|
16357
16611
|
const name = fn.name;
|
|
16358
16612
|
return typeof name === "string" && name.length > 0 && globalThis[name] === fn ? name : null;
|
|
16359
16613
|
}
|
|
16360
|
-
function compile(
|
|
16614
|
+
function compile(target, second, third) {
|
|
16615
|
+
if (!isCombinator(target)) return compileMap(target, second);
|
|
16616
|
+
return compileRoot(target, second, third);
|
|
16617
|
+
}
|
|
16618
|
+
function isCombinator(x) {
|
|
16619
|
+
return typeof x === "object" && x !== null && typeof x.parse === "function" && "_def" in x;
|
|
16620
|
+
}
|
|
16621
|
+
function compileMap(grammar, opts = {}) {
|
|
16622
|
+
const entries = [];
|
|
16623
|
+
for (const [key, value] of Object.entries(grammar)) {
|
|
16624
|
+
if (!isCombinator(value)) throw new TypeError(`compile: grammar entry "${key}" is not a parser`);
|
|
16625
|
+
if (value._def.tag === "lazy") {
|
|
16626
|
+
try {
|
|
16627
|
+
value._def.thunk();
|
|
16628
|
+
} catch {
|
|
16629
|
+
continue;
|
|
16630
|
+
}
|
|
16631
|
+
}
|
|
16632
|
+
entries.push([key, value]);
|
|
16633
|
+
}
|
|
16634
|
+
const borrowed = borrowedRuleReference(Object.fromEntries(entries));
|
|
16635
|
+
if (borrowed !== void 0) throw new Error(borrowedRuleMessage("compile", borrowed));
|
|
16636
|
+
const drain = beginCompileDegradationDrain();
|
|
16637
|
+
let done = false;
|
|
16638
|
+
try {
|
|
16639
|
+
const refusals = [];
|
|
16640
|
+
const compiled = compileRuleMapRunnable(entries, {
|
|
16641
|
+
...opts.hostMode ? { hostMode: opts.hostMode } : {},
|
|
16642
|
+
refusals,
|
|
16643
|
+
specialise: true
|
|
16644
|
+
});
|
|
16645
|
+
if (compiled === null) {
|
|
16646
|
+
throw new Error(`compile: this grammar could not be encoded to a table${refusals.length ? ` \u2014 ${refusals.join("; ")}` : ""}`);
|
|
16647
|
+
}
|
|
16648
|
+
done = true;
|
|
16649
|
+
return compiled.rules;
|
|
16650
|
+
} finally {
|
|
16651
|
+
drain(done);
|
|
16652
|
+
}
|
|
16653
|
+
}
|
|
16654
|
+
function compileRoot(combinator, mapFnSources, opts = {}) {
|
|
16361
16655
|
runDuplicationDiagnostic(combinator, opts.duplication);
|
|
16362
16656
|
const drain = beginCompileDegradationDrain();
|
|
16363
16657
|
let compiled = false;
|
|
@@ -16427,29 +16721,6 @@ function compileImpl(combinator, mapFnSources, opts = {}) {
|
|
|
16427
16721
|
};
|
|
16428
16722
|
}
|
|
16429
16723
|
|
|
16430
|
-
// src/combinators/withCtx.ts
|
|
16431
|
-
function withCtx(extra, combinator) {
|
|
16432
|
-
const meta = {
|
|
16433
|
-
firstSet: combinator._meta.firstSet,
|
|
16434
|
-
canMatchNewline: combinator._meta.canMatchNewline,
|
|
16435
|
-
isTrivia: false
|
|
16436
|
-
};
|
|
16437
|
-
return {
|
|
16438
|
-
_tag: "withCtx",
|
|
16439
|
-
_meta: meta,
|
|
16440
|
-
_def: { tag: "withCtx", extra, parser: combinator },
|
|
16441
|
-
parse(input, pos, ctx) {
|
|
16442
|
-
const saved = ctx.state;
|
|
16443
|
-
ctx.state = extra;
|
|
16444
|
-
try {
|
|
16445
|
-
return combinator.parse(input, pos, ctx);
|
|
16446
|
-
} finally {
|
|
16447
|
-
ctx.state = saved;
|
|
16448
|
-
}
|
|
16449
|
-
}
|
|
16450
|
-
};
|
|
16451
|
-
}
|
|
16452
|
-
|
|
16453
16724
|
// src/compiler/ir-serialize.ts
|
|
16454
16725
|
function childrenOf3(def) {
|
|
16455
16726
|
switch (def.tag) {
|
|
@@ -16546,195 +16817,28 @@ function serializeRuleMap(ruleMap, scanSkip) {
|
|
|
16546
16817
|
throw e;
|
|
16547
16818
|
}
|
|
16548
16819
|
}
|
|
16549
|
-
function
|
|
16550
|
-
|
|
16551
|
-
|
|
16552
|
-
|
|
16553
|
-
|
|
16554
|
-
|
|
16555
|
-
|
|
16556
|
-
|
|
16557
|
-
|
|
16558
|
-
|
|
16559
|
-
|
|
16560
|
-
|
|
16561
|
-
|
|
16562
|
-
|
|
16563
|
-
|
|
16564
|
-
|
|
16565
|
-
|
|
16566
|
-
|
|
16567
|
-
|
|
16568
|
-
|
|
16569
|
-
|
|
16570
|
-
|
|
16571
|
-
};
|
|
16572
|
-
}
|
|
16573
|
-
const l = source ? sourceLeaf(child, fn2) : leaf(child, fn2);
|
|
16574
|
-
l._def.fnSrc = src;
|
|
16575
|
-
return l;
|
|
16576
|
-
};
|
|
16577
|
-
const _nd = (type, child, src, opts, staticError, sigSrc, buildImports, rawUnused) => {
|
|
16578
|
-
if (staticError !== void 0 && staticError.length > 0) {
|
|
16579
|
-
throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
|
|
16580
|
-
}
|
|
16581
|
-
const n = node(type, child, (() => {
|
|
16582
|
-
throw new Error("IR node build requires static re-lowering");
|
|
16583
|
-
}), opts);
|
|
16584
|
-
n._def.buildSrc = src;
|
|
16585
|
-
if (staticError !== void 0) n._def.buildStaticError = staticError;
|
|
16586
|
-
if (sigSrc !== void 0) n._def.buildSigSrc = sigSrc;
|
|
16587
|
-
if (rawUnused === true) n._def.buildRawUnused = true;
|
|
16588
|
-
if (buildImports !== void 0) n._def.buildImports = buildImports;
|
|
16589
|
-
return n;
|
|
16590
|
-
};
|
|
16591
|
-
const _gch = (items) => {
|
|
16592
|
-
const gateSrcs = [];
|
|
16593
|
-
const arms = items.map((it) => {
|
|
16594
|
-
if (Array.isArray(it)) {
|
|
16595
|
-
const [src, comb] = it;
|
|
16596
|
-
gateSrcs.push(src);
|
|
16597
|
-
let gate2;
|
|
16598
|
-
try {
|
|
16599
|
-
gate2 = (0, eval)(`(${src})`);
|
|
16600
|
-
} catch {
|
|
16601
|
-
gate2 = () => {
|
|
16602
|
-
throw new Error("IR gate fn not materialized");
|
|
16603
|
-
};
|
|
16604
|
-
}
|
|
16605
|
-
return { gate: gate2, combinator: comb };
|
|
16606
|
-
}
|
|
16607
|
-
gateSrcs.push(null);
|
|
16608
|
-
return it;
|
|
16609
|
-
});
|
|
16610
|
-
const c = choice(...arms);
|
|
16611
|
-
const gates = c._def.gates;
|
|
16612
|
-
if (gates && gates.length !== gateSrcs.length) {
|
|
16613
|
-
throw new Error(`_gch: gateSrcs length ${gateSrcs.length} != choice gates length ${gates.length}`);
|
|
16614
|
-
}
|
|
16615
|
-
;
|
|
16616
|
-
c._def.gateSrcs = gateSrcs;
|
|
16617
|
-
return c;
|
|
16618
|
-
};
|
|
16619
|
-
const _wc = (src, inner) => {
|
|
16620
|
-
let extra;
|
|
16621
|
-
try {
|
|
16622
|
-
extra = (0, eval)(`(${src})`);
|
|
16623
|
-
} catch {
|
|
16624
|
-
extra = void 0;
|
|
16625
|
-
}
|
|
16626
|
-
const w = withCtx(extra, inner);
|
|
16627
|
-
w._def.extraSrc = src;
|
|
16628
|
-
return w;
|
|
16629
|
-
};
|
|
16630
|
-
const fn = new Function(
|
|
16631
|
-
"rules",
|
|
16632
|
-
"ref",
|
|
16633
|
-
"regex",
|
|
16634
|
-
"literal",
|
|
16635
|
-
"keywords",
|
|
16636
|
-
"sequence",
|
|
16637
|
-
"choice",
|
|
16638
|
-
"dispatch",
|
|
16639
|
-
"when",
|
|
16640
|
-
"startsWith",
|
|
16641
|
-
"endsWith",
|
|
16642
|
-
"matches",
|
|
16643
|
-
"otherwise",
|
|
16644
|
-
"routed",
|
|
16645
|
-
"attempt",
|
|
16646
|
-
"many",
|
|
16647
|
-
"oneOrMore",
|
|
16648
|
-
"optional",
|
|
16649
|
-
"sepBy",
|
|
16650
|
-
"keepSeparator",
|
|
16651
|
-
"not",
|
|
16652
|
-
"peek",
|
|
16653
|
-
"node",
|
|
16654
|
-
"parser",
|
|
16655
|
-
"scanTo",
|
|
16656
|
-
"balanced",
|
|
16657
|
-
"token",
|
|
16658
|
-
"leaf",
|
|
16659
|
-
"transform",
|
|
16660
|
-
"trivia",
|
|
16661
|
-
"classifiedTrivia",
|
|
16662
|
-
"label",
|
|
16663
|
-
"field",
|
|
16664
|
-
"expect",
|
|
16665
|
-
"adjacent",
|
|
16666
|
-
"notAdjacent",
|
|
16667
|
-
"_tf",
|
|
16668
|
-
"_lf",
|
|
16669
|
-
"_nd",
|
|
16670
|
-
"_gch",
|
|
16671
|
-
"_wc",
|
|
16672
|
-
`return (${ir})`
|
|
16673
|
-
);
|
|
16674
|
-
const map = fn(
|
|
16675
|
-
rules,
|
|
16676
|
-
ref,
|
|
16677
|
-
regex,
|
|
16678
|
-
literal,
|
|
16679
|
-
keywords,
|
|
16680
|
-
sequence,
|
|
16681
|
-
choice,
|
|
16682
|
-
dispatch,
|
|
16683
|
-
when,
|
|
16684
|
-
startsWith,
|
|
16685
|
-
endsWith,
|
|
16686
|
-
matches,
|
|
16687
|
-
otherwise,
|
|
16688
|
-
routed,
|
|
16689
|
-
attempt,
|
|
16690
|
-
many,
|
|
16691
|
-
oneOrMore,
|
|
16692
|
-
optional,
|
|
16693
|
-
sepBy,
|
|
16694
|
-
keepSeparator,
|
|
16695
|
-
not,
|
|
16696
|
-
peek,
|
|
16697
|
-
node,
|
|
16698
|
-
parser,
|
|
16699
|
-
scanTo,
|
|
16700
|
-
balanced,
|
|
16701
|
-
token,
|
|
16702
|
-
leaf,
|
|
16703
|
-
transform,
|
|
16704
|
-
trivia,
|
|
16705
|
-
classifiedTrivia,
|
|
16706
|
-
label,
|
|
16707
|
-
field,
|
|
16708
|
-
expect,
|
|
16709
|
-
adjacent,
|
|
16710
|
-
notAdjacent,
|
|
16711
|
-
_tf,
|
|
16712
|
-
_lf,
|
|
16713
|
-
_nd,
|
|
16714
|
-
_gch,
|
|
16715
|
-
_wc
|
|
16716
|
-
);
|
|
16717
|
-
return Object.entries(map);
|
|
16718
|
-
}
|
|
16719
|
-
var Serializer = class {
|
|
16720
|
-
counts = /* @__PURE__ */ new Map();
|
|
16721
|
-
selfRef = /* @__PURE__ */ new Set();
|
|
16722
|
-
// combinators reached by an unnamed lazy pointing back into their own subtree
|
|
16723
|
-
cycleInterior = /* @__PURE__ */ new Set();
|
|
16724
|
-
// combinators lying ON a self-reference cycle (strictly below its target)
|
|
16725
|
-
constName = /* @__PURE__ */ new Map();
|
|
16726
|
-
emitted = /* @__PURE__ */ new Set();
|
|
16727
|
-
decls = [];
|
|
16728
|
-
ruleValues = /* @__PURE__ */ new Set();
|
|
16729
|
-
localRuleNames = /* @__PURE__ */ new Map();
|
|
16730
|
-
ruleMap;
|
|
16731
|
-
scanSkip;
|
|
16732
|
-
constructor(ruleMap, scanSkip = []) {
|
|
16733
|
-
this.ruleMap = ruleMap;
|
|
16734
|
-
this.scanSkip = scanSkip;
|
|
16735
|
-
for (const [name, c] of ruleMap) {
|
|
16736
|
-
this.localRuleNames.set(c, name);
|
|
16737
|
-
this.ruleValues.add(this.body(c));
|
|
16820
|
+
function serializeCombinator(c) {
|
|
16821
|
+
return serializeRuleMap([], [c]);
|
|
16822
|
+
}
|
|
16823
|
+
var Serializer = class {
|
|
16824
|
+
counts = /* @__PURE__ */ new Map();
|
|
16825
|
+
selfRef = /* @__PURE__ */ new Set();
|
|
16826
|
+
// combinators reached by an unnamed lazy pointing back into their own subtree
|
|
16827
|
+
cycleInterior = /* @__PURE__ */ new Set();
|
|
16828
|
+
// combinators lying ON a self-reference cycle (strictly below its target)
|
|
16829
|
+
constName = /* @__PURE__ */ new Map();
|
|
16830
|
+
emitted = /* @__PURE__ */ new Set();
|
|
16831
|
+
decls = [];
|
|
16832
|
+
ruleValues = /* @__PURE__ */ new Set();
|
|
16833
|
+
localRuleNames = /* @__PURE__ */ new Map();
|
|
16834
|
+
ruleMap;
|
|
16835
|
+
scanSkip;
|
|
16836
|
+
constructor(ruleMap, scanSkip = []) {
|
|
16837
|
+
this.ruleMap = ruleMap;
|
|
16838
|
+
this.scanSkip = scanSkip;
|
|
16839
|
+
for (const [name, c] of ruleMap) {
|
|
16840
|
+
this.localRuleNames.set(c, name);
|
|
16841
|
+
this.ruleValues.add(this.body(c));
|
|
16738
16842
|
}
|
|
16739
16843
|
}
|
|
16740
16844
|
/** A grammar-level `scanSkip` unit is an opaque TERMINAL (a string, a balanced
|
|
@@ -16954,7 +17058,7 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
16954
17058
|
case "optional":
|
|
16955
17059
|
return `optional(${kid(def.parser)})`;
|
|
16956
17060
|
case "attempt":
|
|
16957
|
-
return `attempt(${kid(def.parser)})`;
|
|
17061
|
+
return `attempt(${kid(def.parser)}${def.contain === true ? ", { contain: true }" : ""})`;
|
|
16958
17062
|
// `keepSeparators` is an opt-in expressed at the SEPARATOR, not in the options
|
|
16959
17063
|
// bag, so it must round-trip as `keepSeparator(sep)` — serializing it as an
|
|
16960
17064
|
// option would reconstruct a grammar whose call site no longer states its own
|
|
@@ -17042,127 +17146,8 @@ ${outerDecls.map((d) => " " + d).join("\n")}
|
|
|
17042
17146
|
}
|
|
17043
17147
|
};
|
|
17044
17148
|
|
|
17045
|
-
// src/table/compile-rule-map.ts
|
|
17046
|
-
var DEFAULT_PRECOMPILE_MIN_WORDS = 1024;
|
|
17047
|
-
function resolveHostMode(ruleMap, explicit) {
|
|
17048
|
-
return explicit ?? ruleMap.map(([, r]) => r._meta.grammarHostMode).find(Boolean) ?? "ast";
|
|
17049
|
-
}
|
|
17050
|
-
function resolveTrackLines(ruleMap, explicit) {
|
|
17051
|
-
return explicit === true || ruleMap.some(([, r]) => r._meta.grammarTrackLines === true);
|
|
17052
|
-
}
|
|
17053
|
-
function withAmbient(ruleMap, opts) {
|
|
17054
|
-
if (opts.trivia === void 0 && opts.scanSkip === void 0) return ruleMap;
|
|
17055
|
-
const wrappers = /* @__PURE__ */ new Map();
|
|
17056
|
-
return ruleMap.map(([name, rule]) => {
|
|
17057
|
-
if (rule._meta.isTrivia) return [name, rule];
|
|
17058
|
-
const addTrivia = opts.trivia !== void 0 && rule._meta.grammarTrivia === void 0;
|
|
17059
|
-
const addScanSkip = opts.scanSkip !== void 0 && rule._meta.grammarScanSkip === void 0;
|
|
17060
|
-
if (!addTrivia && !addScanSkip) return [name, rule];
|
|
17061
|
-
let wrapped = wrappers.get(rule);
|
|
17062
|
-
if (wrapped === void 0) {
|
|
17063
|
-
wrapped = {
|
|
17064
|
-
...rule,
|
|
17065
|
-
_meta: {
|
|
17066
|
-
...rule._meta,
|
|
17067
|
-
...addTrivia ? { grammarTrivia: opts.trivia } : {},
|
|
17068
|
-
...addScanSkip ? { grammarScanSkip: opts.scanSkip } : {}
|
|
17069
|
-
}
|
|
17070
|
-
};
|
|
17071
|
-
wrappers.set(rule, wrapped);
|
|
17072
|
-
}
|
|
17073
|
-
return [name, wrapped];
|
|
17074
|
-
});
|
|
17075
|
-
}
|
|
17076
|
-
function compileRuleMapRunnable(ruleMap, opts = {}) {
|
|
17077
|
-
const encoded = encodeForRun(ruleMap, opts);
|
|
17078
|
-
if (encoded === null) return null;
|
|
17079
|
-
const { prog, hostMode, plan } = encoded;
|
|
17080
|
-
const artifact = closureArtifact(prog);
|
|
17081
|
-
return {
|
|
17082
|
-
keys: ruleMap.map(([key]) => key),
|
|
17083
|
-
hostMode,
|
|
17084
|
-
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
17085
|
-
reflection: collectGrammarReflection(ruleMap),
|
|
17086
|
-
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
17087
|
-
rules: tableRules(prog),
|
|
17088
|
-
prog: artifact
|
|
17089
|
-
};
|
|
17090
|
-
}
|
|
17091
|
-
function encodeForRun(ruleMap, opts) {
|
|
17092
|
-
runDuplicationDiagnosticRules(ruleMap, opts.duplication);
|
|
17093
|
-
const encodeMap = withAmbient(ruleMap, opts);
|
|
17094
|
-
const plan = opts.coverage === true ? buildGrammarPlan(
|
|
17095
|
-
encodeMap.map(([, rule]) => rule),
|
|
17096
|
-
Object.fromEntries(encodeMap.filter(([, rule]) => rule._def.tag !== "lazy"))
|
|
17097
|
-
) : void 0;
|
|
17098
|
-
const hostMode = resolveHostMode(ruleMap, opts.hostMode);
|
|
17099
|
-
const settings = {
|
|
17100
|
-
hostMode,
|
|
17101
|
-
...resolveTrackLines(ruleMap, opts.trackLines) ? { trackLines: true } : {},
|
|
17102
|
-
...opts.recovery === true ? { recovery: true } : {},
|
|
17103
|
-
...plan === void 0 ? {} : { coverage: plan }
|
|
17104
|
-
};
|
|
17105
|
-
try {
|
|
17106
|
-
const { prog, fnSrcs } = encodeTableProgram(Object.fromEntries(encodeMap), settings);
|
|
17107
|
-
return { prog, fnSrcs, hostMode, plan };
|
|
17108
|
-
} catch (e) {
|
|
17109
|
-
opts.refusals?.push(e instanceof Error ? e.message : String(e));
|
|
17110
|
-
return null;
|
|
17111
|
-
}
|
|
17112
|
-
}
|
|
17113
|
-
function compileRuleMap(ruleMap, opts = {}) {
|
|
17114
|
-
const encoded = encodeForRun(ruleMap, opts);
|
|
17115
|
-
if (encoded === null) return null;
|
|
17116
|
-
const { prog, fnSrcs, hostMode, plan } = encoded;
|
|
17117
|
-
const artifact = closureArtifact(prog);
|
|
17118
|
-
if (artifact.runtimeOnly !== void 0 && artifact.runtimeOnly.length > 0) {
|
|
17119
|
-
opts.refusals?.push(...artifact.runtimeOnly);
|
|
17120
|
-
return null;
|
|
17121
|
-
}
|
|
17122
|
-
const supplied = opts.fnSources;
|
|
17123
|
-
const sources = fnSrcs.map((s, i) => s ?? supplied?.[i] ?? null);
|
|
17124
|
-
if (sources.some((s) => s === null)) {
|
|
17125
|
-
const missing = sources.flatMap((s, i) => s === null ? [i] : []);
|
|
17126
|
-
opts.refusals?.push(
|
|
17127
|
-
`author reducer source missing for prog.fns[${missing.join(", ")}] \u2014 printing would emit \`() => {}\` and the parse would return no value`
|
|
17128
|
-
);
|
|
17129
|
-
return null;
|
|
17130
|
-
}
|
|
17131
|
-
if (supplied !== void 0 && supplied.length > fnSrcs.length) {
|
|
17132
|
-
throw new Error(
|
|
17133
|
-
`compileRuleMap: got ${supplied.length} fnSources for a pool of ${fnSrcs.length}. The list is positional, in prog.fns order, so a longer one means it belongs to a different encode \u2014 and the entries would be silently misassigned.`
|
|
17134
|
-
);
|
|
17135
|
-
}
|
|
17136
|
-
const replacementWithMetadata = (metadataSource, options = {}) => emitTableExpression(artifact, {
|
|
17137
|
-
entry: null,
|
|
17138
|
-
runtimeRef: opts.runtimeRef ?? "tableRules",
|
|
17139
|
-
fnSources: sources,
|
|
17140
|
-
...options.precompileDefault === true && hostMode === "ast" && prog.lines !== 1 && prog.code.length >= DEFAULT_PRECOMPILE_MIN_WORDS ? { assemblies: defaultAssemblyCfgs(artifact).slice(0, 1) } : {},
|
|
17141
|
-
...metadataSource === void 0 ? {} : { metadataSource }
|
|
17142
|
-
});
|
|
17143
|
-
const replacement = replacementWithMetadata();
|
|
17144
|
-
return {
|
|
17145
|
-
keys: ruleMap.map(([key]) => key),
|
|
17146
|
-
replacement,
|
|
17147
|
-
replacementWithMetadata,
|
|
17148
|
-
hostMode,
|
|
17149
|
-
// WHAT THE FLAG MEANS is "a DIRECT BUILDER's positioned-CST branch was
|
|
17150
|
-
// dropped", which is what the driver's `'ast' artifact + CST host` check keys
|
|
17151
|
-
// off. `mode === 'ast'` alone over-reports it: an all-STRUCTURAL grammar has no
|
|
17152
|
-
// direct builder, so there was no branch to drop and it stays usable with either
|
|
17153
|
-
// host — the long-standing `node(parser)` contract. Same predicate codegen uses
|
|
17154
|
-
// for its own `hasDirectBuilders` (both read `analysis/commitment.ts`), so the two
|
|
17155
|
-
// lowerings stamp the same artifact rather than disagreeing about it.
|
|
17156
|
-
hostBranchElided: hostMode === "ast" && ruleMap.some(([, rule]) => hasDirectBuildDef(rule)),
|
|
17157
|
-
reflection: collectGrammarReflection(ruleMap),
|
|
17158
|
-
...plan === void 0 ? {} : { coverageDefinitions: plan.definitions },
|
|
17159
|
-
rules: tableRules(prog),
|
|
17160
|
-
prog: artifact
|
|
17161
|
-
};
|
|
17162
|
-
}
|
|
17163
|
-
|
|
17164
17149
|
// src/version.ts
|
|
17165
|
-
var PARSEMAN_VERSION = "0.
|
|
17150
|
+
var PARSEMAN_VERSION = "0.53.0";
|
|
17166
17151
|
|
|
17167
17152
|
// src/compiler/compile-linkable-table.ts
|
|
17168
17153
|
function isLocal(rule) {
|
|
@@ -17274,6 +17259,29 @@ function gate(predicate) {
|
|
|
17274
17259
|
};
|
|
17275
17260
|
}
|
|
17276
17261
|
|
|
17262
|
+
// src/combinators/withCtx.ts
|
|
17263
|
+
function withCtx(extra, combinator) {
|
|
17264
|
+
const meta = {
|
|
17265
|
+
firstSet: combinator._meta.firstSet,
|
|
17266
|
+
canMatchNewline: combinator._meta.canMatchNewline,
|
|
17267
|
+
isTrivia: false
|
|
17268
|
+
};
|
|
17269
|
+
return {
|
|
17270
|
+
_tag: "withCtx",
|
|
17271
|
+
_meta: meta,
|
|
17272
|
+
_def: { tag: "withCtx", extra, parser: combinator },
|
|
17273
|
+
parse(input, pos, ctx) {
|
|
17274
|
+
const saved = ctx.state;
|
|
17275
|
+
ctx.state = extra;
|
|
17276
|
+
try {
|
|
17277
|
+
return combinator.parse(input, pos, ctx);
|
|
17278
|
+
} finally {
|
|
17279
|
+
ctx.state = saved;
|
|
17280
|
+
}
|
|
17281
|
+
}
|
|
17282
|
+
};
|
|
17283
|
+
}
|
|
17284
|
+
|
|
17277
17285
|
// src/plugin/direct-builder-static.ts
|
|
17278
17286
|
import { parseSync } from "oxc-parser";
|
|
17279
17287
|
var STATIC_BUILDER_GLOBALS = /* @__PURE__ */ new Set([
|
|
@@ -17559,6 +17567,41 @@ var _builderImports = null;
|
|
|
17559
17567
|
function setBuilderImportResolver(r) {
|
|
17560
17568
|
_builderImports = r;
|
|
17561
17569
|
}
|
|
17570
|
+
var ModuleScope = class _ModuleScope extends Map {
|
|
17571
|
+
tried = /* @__PURE__ */ new Map();
|
|
17572
|
+
resolveFree;
|
|
17573
|
+
unresolved;
|
|
17574
|
+
constructor(resolveFree, unresolved) {
|
|
17575
|
+
super();
|
|
17576
|
+
this.resolveFree = resolveFree;
|
|
17577
|
+
this.unresolved = unresolved;
|
|
17578
|
+
}
|
|
17579
|
+
has(name) {
|
|
17580
|
+
return super.has(name) || this.resolve(name);
|
|
17581
|
+
}
|
|
17582
|
+
get(name) {
|
|
17583
|
+
if (super.has(name) || this.resolve(name)) return super.get(name);
|
|
17584
|
+
const why = this.tried.get(name);
|
|
17585
|
+
if (why !== void 0) this.unresolved.add(`\`${name}\` ${why}`);
|
|
17586
|
+
return void 0;
|
|
17587
|
+
}
|
|
17588
|
+
/** A child scope (a factory body) that keeps resolving this module's free names. */
|
|
17589
|
+
fork() {
|
|
17590
|
+
const child = new _ModuleScope(this.resolveFree, this.unresolved);
|
|
17591
|
+
for (const [k, v] of super.entries()) child.set(k, v);
|
|
17592
|
+
return child;
|
|
17593
|
+
}
|
|
17594
|
+
resolve(name) {
|
|
17595
|
+
if (this.tried.has(name)) return false;
|
|
17596
|
+
const r = this.resolveFree(name);
|
|
17597
|
+
if (r !== null && "value" in r) {
|
|
17598
|
+
super.set(name, r.value);
|
|
17599
|
+
return true;
|
|
17600
|
+
}
|
|
17601
|
+
if (r !== null) this.tried.set(name, r.unresolved);
|
|
17602
|
+
return false;
|
|
17603
|
+
}
|
|
17604
|
+
};
|
|
17562
17605
|
function isWordFactory(v) {
|
|
17563
17606
|
return !!v && typeof v === "object" && v.tag === "wordFactory";
|
|
17564
17607
|
}
|
|
@@ -17611,7 +17654,7 @@ var SUPPORTED = {
|
|
|
17611
17654
|
word: (...a) => word(a[0], a[1], a[2]),
|
|
17612
17655
|
sequence: (...a) => sequence(...a),
|
|
17613
17656
|
choice: (...a) => choice(...a),
|
|
17614
|
-
attempt: (...a) => attempt(a[0]),
|
|
17657
|
+
attempt: (...a) => attempt(a[0], a[1]),
|
|
17615
17658
|
optional: (...a) => optional(a[0]),
|
|
17616
17659
|
trivia: (...a) => trivia(a[0]),
|
|
17617
17660
|
classifiedTrivia: (...a) => classifiedTrivia(
|
|
@@ -17682,7 +17725,7 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
17682
17725
|
if (!keyArg || !parserArg || extraArg !== void 0 || keyArg.type === "SpreadElement" || parserArg.type === "SpreadElement") return null;
|
|
17683
17726
|
const key = anyValue(keyArg, scope, code, mfs);
|
|
17684
17727
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
17685
|
-
if (!
|
|
17728
|
+
if (!isCombinator2(parserValue)) return null;
|
|
17686
17729
|
const opts = { caseInsensitive: factory.caseInsensitive };
|
|
17687
17730
|
if (typeof key === "string") return when(key, parserValue, opts);
|
|
17688
17731
|
if (Array.isArray(key) && key.every((item) => typeof item === "string")) return when(key, parserValue, opts);
|
|
@@ -17693,7 +17736,7 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
17693
17736
|
const [parserArg] = node2.arguments;
|
|
17694
17737
|
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
17695
17738
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
17696
|
-
if (!
|
|
17739
|
+
if (!isCombinator2(parserValue)) return null;
|
|
17697
17740
|
return otherwise(parserValue);
|
|
17698
17741
|
}
|
|
17699
17742
|
if (callee.name === "when") {
|
|
@@ -17703,24 +17746,24 @@ function dispatchArmValue(node2, scope, code, mfs) {
|
|
|
17703
17746
|
const parserValue = anyValue(parserArg, scope, code, mfs);
|
|
17704
17747
|
const opts = dispatchWhenOptions(optsArg === void 0 ? void 0 : anyValue(optsArg, scope, code, mfs));
|
|
17705
17748
|
if (opts === null) return null;
|
|
17706
|
-
if (!
|
|
17749
|
+
if (!isCombinator2(parserValue)) return null;
|
|
17707
17750
|
if (typeof key === "string") return when(key, parserValue, opts);
|
|
17708
17751
|
if (Array.isArray(key) && key.every((item) => typeof item === "string")) return when(key, parserValue, opts);
|
|
17709
17752
|
if (isDispatchMatcher(key)) return when(key, parserValue, opts);
|
|
17710
17753
|
}
|
|
17711
17754
|
return null;
|
|
17712
17755
|
}
|
|
17713
|
-
function
|
|
17756
|
+
function isCombinator2(v) {
|
|
17714
17757
|
return !!v && typeof v === "object" && "_def" in v;
|
|
17715
17758
|
}
|
|
17716
17759
|
function isDispatchArm(v) {
|
|
17717
17760
|
if (!v || typeof v !== "object") return false;
|
|
17718
17761
|
const rec = v;
|
|
17719
|
-
if (rec.kind === "otherwise") return
|
|
17762
|
+
if (rec.kind === "otherwise") return isCombinator2(rec.parser);
|
|
17720
17763
|
if (rec.kind === "whenMatcher") {
|
|
17721
|
-
return isDispatchMatcher(rec.matcher) && typeof rec.caseInsensitive === "boolean" &&
|
|
17764
|
+
return isDispatchMatcher(rec.matcher) && typeof rec.caseInsensitive === "boolean" && isCombinator2(rec.parser);
|
|
17722
17765
|
}
|
|
17723
|
-
return rec.kind === "when" && Array.isArray(rec.keys) && rec.keys.every((key) => typeof key === "string") && typeof rec.caseInsensitive === "boolean" &&
|
|
17766
|
+
return rec.kind === "when" && Array.isArray(rec.keys) && rec.keys.every((key) => typeof key === "string") && typeof rec.caseInsensitive === "boolean" && isCombinator2(rec.parser);
|
|
17724
17767
|
}
|
|
17725
17768
|
function isDispatchMatcher(v) {
|
|
17726
17769
|
if (!v || typeof v !== "object") return false;
|
|
@@ -17735,7 +17778,7 @@ function scopeGet(scope, name, mfs) {
|
|
|
17735
17778
|
if (mfs && entry.mfSrcs.length > 0) mfs.push(...entry.mfSrcs);
|
|
17736
17779
|
return entry.combi;
|
|
17737
17780
|
}
|
|
17738
|
-
if (
|
|
17781
|
+
if (isCombinator2(entry)) return entry;
|
|
17739
17782
|
return null;
|
|
17740
17783
|
}
|
|
17741
17784
|
function unwrapStaticExpr(expr) {
|
|
@@ -17787,7 +17830,7 @@ function scopedStaticValue(expr, scope) {
|
|
|
17787
17830
|
return { found: true, value };
|
|
17788
17831
|
}
|
|
17789
17832
|
function staticNodeOptionsFromValue(value) {
|
|
17790
|
-
if (value === null || typeof value !== "object" || Array.isArray(value) ||
|
|
17833
|
+
if (value === null || typeof value !== "object" || Array.isArray(value) || isCombinator2(value)) return STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
17791
17834
|
const opts = {};
|
|
17792
17835
|
const rec = value;
|
|
17793
17836
|
for (const name of Object.keys(rec)) {
|
|
@@ -17839,6 +17882,13 @@ function staticNodeOptions(expr, scope) {
|
|
|
17839
17882
|
}
|
|
17840
17883
|
return opts.unwrap || opts.collapse || opts.project !== void 0 || opts.captureTrivia || opts.trailingTrivia || opts.tags !== void 0 || opts.buildArity !== void 0 ? opts : void 0;
|
|
17841
17884
|
}
|
|
17885
|
+
var UNKNOWN_OPTIONS = /* @__PURE__ */ Symbol("parseman.unknownOptions");
|
|
17886
|
+
function scanOptions(optsArg, scope, code) {
|
|
17887
|
+
if (optsArg === void 0) return void 0;
|
|
17888
|
+
if (optsArg.type === "SpreadElement") return UNKNOWN_OPTIONS;
|
|
17889
|
+
const opts = anyValue(optsArg, scope, code, []);
|
|
17890
|
+
return isHole(optsArg, opts, scope) ? UNKNOWN_OPTIONS : opts;
|
|
17891
|
+
}
|
|
17842
17892
|
function exprToCombi(node2, scope, code, mfs) {
|
|
17843
17893
|
if (node2.type === "Identifier") return scopeGet(scope, node2.name, mfs);
|
|
17844
17894
|
if (node2.type !== "CallExpression") return null;
|
|
@@ -17874,7 +17924,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17874
17924
|
const [parserArg, fnArg] = node2.arguments;
|
|
17875
17925
|
if (!parserArg || !fnArg || parserArg.type === "SpreadElement" || fnArg.type === "SpreadElement") return null;
|
|
17876
17926
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
17877
|
-
if (!
|
|
17927
|
+
if (!isCombinator2(inner)) return null;
|
|
17878
17928
|
const fnSrc = stripTsFromSource(fnArg, code);
|
|
17879
17929
|
mfs.push(fnSrc);
|
|
17880
17930
|
try {
|
|
@@ -17889,7 +17939,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17889
17939
|
const [parserArg, fnArg] = node2.arguments;
|
|
17890
17940
|
if (!parserArg || !fnArg || parserArg.type === "SpreadElement" || fnArg.type === "SpreadElement") return null;
|
|
17891
17941
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
17892
|
-
if (!
|
|
17942
|
+
if (!isCombinator2(inner)) return null;
|
|
17893
17943
|
const fnSrc = stripTsFromSource(fnArg, code);
|
|
17894
17944
|
mfs.push(fnSrc);
|
|
17895
17945
|
try {
|
|
@@ -17910,7 +17960,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17910
17960
|
const optsArg = explicitType !== void 0 ? fourthArg : thirdArg;
|
|
17911
17961
|
if (!parserArg || parserArg.type === "SpreadElement") return null;
|
|
17912
17962
|
const inner = anyValue(parserArg, scope, code, mfs);
|
|
17913
|
-
if (!
|
|
17963
|
+
if (!isCombinator2(inner)) return null;
|
|
17914
17964
|
const be = buildArg;
|
|
17915
17965
|
const buildExpr = be === void 0 || be.type === "SpreadElement" ? void 0 : unwrapStaticExpr(be);
|
|
17916
17966
|
const buildArgOptions = be !== void 0 && be.type !== "SpreadElement" ? staticNodeOptions(buildArg, scope) : STATIC_NODE_OPTIONS_NOT_OPTIONS;
|
|
@@ -17984,7 +18034,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17984
18034
|
const opts = anyValue(optsArg, scope, code, []);
|
|
17985
18035
|
if (!opts || typeof opts !== "object") return null;
|
|
17986
18036
|
const root = anyValue(rootArg, scope, code, mfs);
|
|
17987
|
-
if (!
|
|
18037
|
+
if (!isCombinator2(root)) return null;
|
|
17988
18038
|
try {
|
|
17989
18039
|
return parser(opts, root);
|
|
17990
18040
|
} catch {
|
|
@@ -17996,10 +18046,10 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
17996
18046
|
if (!itemArg || !sepArg || itemArg.type === "SpreadElement" || sepArg.type === "SpreadElement") return null;
|
|
17997
18047
|
const itemMfs = [];
|
|
17998
18048
|
const itemCombi = anyValue(itemArg, scope, code, itemMfs);
|
|
17999
|
-
if (!
|
|
18049
|
+
if (!isCombinator2(itemCombi)) return null;
|
|
18000
18050
|
const sepMfs = [];
|
|
18001
18051
|
const sepCombi = anyValue(sepArg, scope, code, sepMfs);
|
|
18002
|
-
if (!
|
|
18052
|
+
if (!isCombinator2(sepCombi)) return null;
|
|
18003
18053
|
let opts;
|
|
18004
18054
|
if (optsArg) {
|
|
18005
18055
|
if (optsArg.type === "SpreadElement") return null;
|
|
@@ -18019,7 +18069,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18019
18069
|
if (!itemArg || itemArg.type === "SpreadElement") return null;
|
|
18020
18070
|
const itemMfs = [];
|
|
18021
18071
|
const itemCombi = anyValue(itemArg, scope, code, itemMfs);
|
|
18022
|
-
if (!
|
|
18072
|
+
if (!isCombinator2(itemCombi)) return null;
|
|
18023
18073
|
let opts;
|
|
18024
18074
|
if (optsArg) {
|
|
18025
18075
|
if (optsArg.type === "SpreadElement") return null;
|
|
@@ -18041,7 +18091,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18041
18091
|
const [innerArg] = node2.arguments;
|
|
18042
18092
|
if (!innerArg || innerArg.type === "SpreadElement") return null;
|
|
18043
18093
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18044
|
-
if (!
|
|
18094
|
+
if (!isCombinator2(inner)) return null;
|
|
18045
18095
|
try {
|
|
18046
18096
|
return not(inner);
|
|
18047
18097
|
} catch {
|
|
@@ -18052,7 +18102,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18052
18102
|
const [innerArg] = node2.arguments;
|
|
18053
18103
|
if (!innerArg || innerArg.type === "SpreadElement") return null;
|
|
18054
18104
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18055
|
-
if (!
|
|
18105
|
+
if (!isCombinator2(inner)) return null;
|
|
18056
18106
|
try {
|
|
18057
18107
|
return peek(inner);
|
|
18058
18108
|
} catch {
|
|
@@ -18065,7 +18115,8 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18065
18115
|
const open = anyValue(openArg, scope, code, []);
|
|
18066
18116
|
const close = anyValue(closeArg, scope, code, []);
|
|
18067
18117
|
if (typeof open !== "string" || typeof close !== "string") return null;
|
|
18068
|
-
const opts =
|
|
18118
|
+
const opts = scanOptions(optsArg, scope, code);
|
|
18119
|
+
if (opts === UNKNOWN_OPTIONS) return null;
|
|
18069
18120
|
try {
|
|
18070
18121
|
return balanced(open, close, opts);
|
|
18071
18122
|
} catch {
|
|
@@ -18076,8 +18127,9 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18076
18127
|
const [sentinelArg, optsArg] = node2.arguments;
|
|
18077
18128
|
if (!sentinelArg || sentinelArg.type === "SpreadElement") return null;
|
|
18078
18129
|
const sentinel = anyValue(sentinelArg, scope, code, []);
|
|
18079
|
-
if (!
|
|
18080
|
-
const opts =
|
|
18130
|
+
if (!isCombinator2(sentinel)) return null;
|
|
18131
|
+
const opts = scanOptions(optsArg, scope, code);
|
|
18132
|
+
if (opts === UNKNOWN_OPTIONS) return null;
|
|
18081
18133
|
try {
|
|
18082
18134
|
return scanTo(sentinel, opts);
|
|
18083
18135
|
} catch {
|
|
@@ -18106,7 +18158,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18106
18158
|
const extraSrc = stripTsFromSource(extraArg, code);
|
|
18107
18159
|
mfs.push(extraSrc);
|
|
18108
18160
|
const inner = anyValue(innerArg, scope, code, mfs);
|
|
18109
|
-
if (!
|
|
18161
|
+
if (!isCombinator2(inner)) return null;
|
|
18110
18162
|
try {
|
|
18111
18163
|
const evaluated = anyValue(extraArg, scope, code, []);
|
|
18112
18164
|
const usable = typeof evaluated === "object" && evaluated !== null && !Array.isArray(evaluated) && Object.getPrototypeOf(evaluated) === Object.prototype;
|
|
@@ -18122,7 +18174,7 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18122
18174
|
const [selectorArg, ...armArgs] = node2.arguments;
|
|
18123
18175
|
if (!selectorArg || selectorArg.type === "SpreadElement") return null;
|
|
18124
18176
|
const selector = anyValue(selectorArg, scope, code, mfs);
|
|
18125
|
-
if (!
|
|
18177
|
+
if (!isCombinator2(selector)) return null;
|
|
18126
18178
|
const arms = [];
|
|
18127
18179
|
for (const arg of armArgs) {
|
|
18128
18180
|
if (arg.type === "SpreadElement") return null;
|
|
@@ -18149,12 +18201,12 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18149
18201
|
const gateSrc = stripTsFromSource(parts.gate, code);
|
|
18150
18202
|
mfs.push(gateSrc);
|
|
18151
18203
|
const combi = anyValue(parts.combinator, scope, code, mfs);
|
|
18152
|
-
if (!
|
|
18204
|
+
if (!isCombinator2(combi)) return null;
|
|
18153
18205
|
arms.push({ gate: () => true, combinator: combi });
|
|
18154
18206
|
gateSrcs.push(gateSrc);
|
|
18155
18207
|
} else {
|
|
18156
18208
|
const combi = anyValue(argNode, scope, code, mfs);
|
|
18157
|
-
if (!
|
|
18209
|
+
if (!isCombinator2(combi)) return null;
|
|
18158
18210
|
arms.push(combi);
|
|
18159
18211
|
gateSrcs.push(null);
|
|
18160
18212
|
}
|
|
@@ -18184,6 +18236,12 @@ function exprToCombi(node2, scope, code, mfs) {
|
|
|
18184
18236
|
return null;
|
|
18185
18237
|
}
|
|
18186
18238
|
}
|
|
18239
|
+
function isHole(node2, value, scope) {
|
|
18240
|
+
if (value !== null) return false;
|
|
18241
|
+
const n = unwrapStaticExpr(node2);
|
|
18242
|
+
if (n.type === "Identifier") return !scope.has(n.name);
|
|
18243
|
+
return !(n.type === "Literal" && n.value === null) && n.type !== "ArrowFunctionExpression" && n.type !== "FunctionExpression";
|
|
18244
|
+
}
|
|
18187
18245
|
function anyValue(node2, scope, code, mfs) {
|
|
18188
18246
|
if (node2.type === "TSAsExpression" || node2.type === "TSSatisfiesExpression" || node2.type === "TSNonNullExpression" || node2.type === "TSTypeAssertion" || node2.type === "TSInstantiationExpression" || node2.type === "ParenthesizedExpression") {
|
|
18189
18247
|
const inner = node2.expression;
|
|
@@ -18204,7 +18262,9 @@ function anyValue(node2, scope, code, mfs) {
|
|
|
18204
18262
|
continue;
|
|
18205
18263
|
}
|
|
18206
18264
|
if (el.type === "SpreadElement") return null;
|
|
18207
|
-
|
|
18265
|
+
const v = anyValue(el, scope, code, mfs);
|
|
18266
|
+
if (isHole(el, v, scope)) return null;
|
|
18267
|
+
out.push(v);
|
|
18208
18268
|
}
|
|
18209
18269
|
return out;
|
|
18210
18270
|
}
|
|
@@ -18213,7 +18273,10 @@ function anyValue(node2, scope, code, mfs) {
|
|
|
18213
18273
|
for (const prop of node2.properties) {
|
|
18214
18274
|
const key = propName(prop);
|
|
18215
18275
|
if (key === null) return null;
|
|
18216
|
-
|
|
18276
|
+
const valueNode = prop.value;
|
|
18277
|
+
const v = anyValue(valueNode, scope, code, mfs);
|
|
18278
|
+
if (isHole(valueNode, v, scope)) return null;
|
|
18279
|
+
obj[key] = v;
|
|
18217
18280
|
}
|
|
18218
18281
|
return obj;
|
|
18219
18282
|
}
|
|
@@ -18289,10 +18352,9 @@ function evaluateExpr(node2, scope, code, mapFnSources) {
|
|
|
18289
18352
|
return exprToCombi(node2, scope, code, mapFnSources);
|
|
18290
18353
|
}
|
|
18291
18354
|
function evaluateCombinatorArray(node2, scope, code) {
|
|
18292
|
-
if (node2.type !== "ArrayExpression") return null;
|
|
18293
18355
|
const val = anyValue(node2, scope, code, []);
|
|
18294
18356
|
if (!Array.isArray(val) || val.length === 0) return null;
|
|
18295
|
-
if (!val.every(
|
|
18357
|
+
if (!val.every(isCombinator2)) return null;
|
|
18296
18358
|
return val;
|
|
18297
18359
|
}
|
|
18298
18360
|
function collectRuleKeys(retObj) {
|
|
@@ -18370,7 +18432,7 @@ function evalBodyStatements(statements, scope, code, out) {
|
|
|
18370
18432
|
return false;
|
|
18371
18433
|
}
|
|
18372
18434
|
const thisDeclMfSrcs = bodyMfs.slice(before);
|
|
18373
|
-
if (
|
|
18435
|
+
if (isCombinator2(val)) scope.set(name, { combi: val, mfSrcs: thisDeclMfSrcs });
|
|
18374
18436
|
else if (isDispatchArm(val)) scope.set(name, { value: val, mfSrcs: thisDeclMfSrcs });
|
|
18375
18437
|
else scope.set(name, val);
|
|
18376
18438
|
}
|
|
@@ -18415,7 +18477,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18415
18477
|
let built;
|
|
18416
18478
|
try {
|
|
18417
18479
|
built = rules(options ?? {}, (g) => {
|
|
18418
|
-
const localScope = new Map(scope);
|
|
18480
|
+
const localScope = scope instanceof ModuleScope ? scope.fork() : new Map(scope);
|
|
18419
18481
|
localScope.set(proxyName, g);
|
|
18420
18482
|
if (!evalBodyStatements(statements, localScope, code, out)) throw ABORT;
|
|
18421
18483
|
const entries = flattenRuleEntries(retObj, localScope, code);
|
|
@@ -18425,7 +18487,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18425
18487
|
const definitions = {};
|
|
18426
18488
|
for (const [key, e] of finalByKey) {
|
|
18427
18489
|
const val = anyValue(e.value, e.scope, e.code, mapFnSources);
|
|
18428
|
-
if (!
|
|
18490
|
+
if (!isCombinator2(val)) throw ABORT;
|
|
18429
18491
|
definitions[key] = val;
|
|
18430
18492
|
}
|
|
18431
18493
|
return definitions;
|
|
@@ -18440,7 +18502,7 @@ function evaluateParserFactory(factoryNode, scope, code, mapFnSources, out, opti
|
|
|
18440
18502
|
return map;
|
|
18441
18503
|
}
|
|
18442
18504
|
function isDefinableRef2(v) {
|
|
18443
|
-
return
|
|
18505
|
+
return isCombinator2(v) && typeof v.define === "function" && v._def.tag === "lazy";
|
|
18444
18506
|
}
|
|
18445
18507
|
function evaluateRefDeclaration(init, name, scope) {
|
|
18446
18508
|
if (init.type !== "CallExpression") return null;
|
|
@@ -18460,12 +18522,12 @@ function applyDefineStatement(callExpr, scope, code) {
|
|
|
18460
18522
|
if (mem.property.type !== "Identifier" || mem.property.name !== "define") return false;
|
|
18461
18523
|
if (mem.object.type !== "Identifier" || !mem.object.name) return false;
|
|
18462
18524
|
const target = scope.get(mem.object.name);
|
|
18463
|
-
const refCombi = isScopeEntry(target) ? target.combi :
|
|
18525
|
+
const refCombi = isScopeEntry(target) ? target.combi : isCombinator2(target) ? target : null;
|
|
18464
18526
|
if (!refCombi || !isDefinableRef2(refCombi)) return false;
|
|
18465
18527
|
const args = callExpr.arguments;
|
|
18466
18528
|
if (args.length !== 1 || args[0].type === "SpreadElement") return false;
|
|
18467
18529
|
const inner = anyValue(args[0], scope, code, []);
|
|
18468
|
-
if (!
|
|
18530
|
+
if (!isCombinator2(inner)) return false;
|
|
18469
18531
|
try {
|
|
18470
18532
|
refCombi.define(inner);
|
|
18471
18533
|
} catch {
|
|
@@ -18475,7 +18537,7 @@ function applyDefineStatement(callExpr, scope, code) {
|
|
|
18475
18537
|
}
|
|
18476
18538
|
function referencesAny(node2, names, scope) {
|
|
18477
18539
|
if (node2.type === "Identifier") {
|
|
18478
|
-
return names.has(node2.name) ||
|
|
18540
|
+
return names.has(node2.name) || Map.prototype.has.call(scope, node2.name);
|
|
18479
18541
|
}
|
|
18480
18542
|
for (const key of Object.keys(node2)) {
|
|
18481
18543
|
const child = node2[key];
|
|
@@ -18536,7 +18598,9 @@ function patternNames(pat, out) {
|
|
|
18536
18598
|
}
|
|
18537
18599
|
}
|
|
18538
18600
|
function declare(scope, name, b) {
|
|
18539
|
-
|
|
18601
|
+
const prev = scope.bindings.get(name);
|
|
18602
|
+
if (prev) prev.reassigned = true;
|
|
18603
|
+
else scope.bindings.set(name, b);
|
|
18540
18604
|
}
|
|
18541
18605
|
function functionScope(scope) {
|
|
18542
18606
|
let s = scope;
|
|
@@ -18636,7 +18700,8 @@ function markReassignments(body, root) {
|
|
|
18636
18700
|
}
|
|
18637
18701
|
const node2 = n;
|
|
18638
18702
|
if (typeof node2.type !== "string") return;
|
|
18639
|
-
|
|
18703
|
+
const loopWrite = (node2.type === "ForOfStatement" || node2.type === "ForInStatement") && node2.left?.type !== "VariableDeclaration";
|
|
18704
|
+
if (node2.type === "AssignmentExpression" || node2.type === "UpdateExpression" || loopWrite) {
|
|
18640
18705
|
const target = node2.type === "UpdateExpression" ? node2.argument : node2.left;
|
|
18641
18706
|
const names = [];
|
|
18642
18707
|
if (target) patternNames(target, names);
|
|
@@ -18652,6 +18717,11 @@ function markReassignments(body, root) {
|
|
|
18652
18717
|
};
|
|
18653
18718
|
for (const stmt of body) walk(stmt);
|
|
18654
18719
|
}
|
|
18720
|
+
function topLevelIsStable(body, moduleEnd) {
|
|
18721
|
+
const root = buildScopeTree(body, moduleEnd);
|
|
18722
|
+
markReassignments(body, root);
|
|
18723
|
+
return (name) => root.bindings.get(name)?.reassigned !== true;
|
|
18724
|
+
}
|
|
18655
18725
|
function functionArity(fn) {
|
|
18656
18726
|
const params = fn.params ?? [];
|
|
18657
18727
|
let count = 0;
|
|
@@ -19104,7 +19174,7 @@ function ast(value) {
|
|
|
19104
19174
|
function nodes(value) {
|
|
19105
19175
|
return Array.isArray(value) ? value.filter((v) => ast(v) !== void 0) : [];
|
|
19106
19176
|
}
|
|
19107
|
-
function
|
|
19177
|
+
function nameOf2(node2) {
|
|
19108
19178
|
return node2?.type === "Identifier" && typeof node2.name === "string" ? node2.name : void 0;
|
|
19109
19179
|
}
|
|
19110
19180
|
function range(node2) {
|
|
@@ -19137,7 +19207,7 @@ function isDirectCallUse(call, parent, statement) {
|
|
|
19137
19207
|
return declarations.length === 1 && declarations[0] === parent && parent.init === call;
|
|
19138
19208
|
}
|
|
19139
19209
|
if (parent.type === "AssignmentExpression") {
|
|
19140
|
-
return statement.type === "ExpressionStatement" && statement.expression === parent &&
|
|
19210
|
+
return statement.type === "ExpressionStatement" && statement.expression === parent && nameOf2(ast(parent.left)) !== void 0 && parent.right === call && parent.operator === "=";
|
|
19141
19211
|
}
|
|
19142
19212
|
if (parent.type === "ReturnStatement") return statement === parent && parent.argument === call;
|
|
19143
19213
|
return false;
|
|
@@ -19155,7 +19225,7 @@ function hasInlineScopeHazard(fn) {
|
|
|
19155
19225
|
if (node2.type === "Identifier" && node2.name === "arguments") hazard = true;
|
|
19156
19226
|
else if (node2.type === "ThisExpression") hazard = true;
|
|
19157
19227
|
else if (node2.type === "VariableDeclaration" && node2.kind === "var") hazard = true;
|
|
19158
|
-
else if (node2.type === "MetaProperty" &&
|
|
19228
|
+
else if (node2.type === "MetaProperty" && nameOf2(ast(node2.meta)) === "new" && nameOf2(ast(node2.property)) === "target") hazard = true;
|
|
19159
19229
|
else for (const child of children2(node2)) walk(child);
|
|
19160
19230
|
};
|
|
19161
19231
|
walk(fn.body);
|
|
@@ -19163,7 +19233,7 @@ function hasInlineScopeHazard(fn) {
|
|
|
19163
19233
|
}
|
|
19164
19234
|
function hasInlineSignature(fn) {
|
|
19165
19235
|
const params = nodes(fn.node.params);
|
|
19166
|
-
return params.length === 3 &&
|
|
19236
|
+
return params.length === 3 && nameOf2(params[0]) === "input" && nameOf2(params[1]) === "pos" && nameOf2(params[2]) === "ctx";
|
|
19167
19237
|
}
|
|
19168
19238
|
function render2(source, start, end, edits) {
|
|
19169
19239
|
const ordered = [...edits].sort((a, b) => a.start - b.start || a.end - b.end);
|
|
@@ -19256,7 +19326,7 @@ function supercompileRuleMapReplacement(prog, replacement) {
|
|
|
19256
19326
|
const call = ast(declarator?.init);
|
|
19257
19327
|
const table = nodes(call?.arguments)[0];
|
|
19258
19328
|
if (declaration?.type !== "VariableDeclaration" || declarator?.type !== "VariableDeclarator" || call?.type !== "CallExpression" || table?.type !== "ObjectExpression") return replacement;
|
|
19259
|
-
const property = (object, key) => nodes(object.properties).find((prop) => prop.type === "Property" &&
|
|
19329
|
+
const property = (object, key) => nodes(object.properties).find((prop) => prop.type === "Property" && nameOf2(ast(prop.key)) === key);
|
|
19260
19330
|
const assembliesProp = property(table, "a");
|
|
19261
19331
|
const assemblies = nodes(ast(assembliesProp?.value)?.elements);
|
|
19262
19332
|
if (assembliesProp === void 0 || assemblies.length !== 1 || assemblies[0]?.type !== "ObjectExpression") return replacement;
|
|
@@ -19289,7 +19359,7 @@ function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
|
19289
19359
|
const fns = /* @__PURE__ */ new Map();
|
|
19290
19360
|
for (const statement of nodes(wrapperBody.body)) {
|
|
19291
19361
|
if (statement.type !== "FunctionDeclaration") continue;
|
|
19292
|
-
const name =
|
|
19362
|
+
const name = nameOf2(ast(statement.id));
|
|
19293
19363
|
const hit = name === void 0 ? void 0 : PIECE.exec(name);
|
|
19294
19364
|
const body = ast(statement.body);
|
|
19295
19365
|
if (hit !== void 0 && hit !== null && body?.type === "BlockStatement") {
|
|
@@ -19302,7 +19372,7 @@ function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
|
19302
19372
|
const allCalls = [];
|
|
19303
19373
|
const walk = (node2, current, parent, statement, statementParent) => {
|
|
19304
19374
|
if (isFunction(node2) && node2 !== current?.node) {
|
|
19305
|
-
const own = node2.type === "FunctionDeclaration" ?
|
|
19375
|
+
const own = node2.type === "FunctionDeclaration" ? nameOf2(ast(node2.id)) : void 0;
|
|
19306
19376
|
const hit = own === void 0 ? void 0 : PIECE.exec(own);
|
|
19307
19377
|
if (hit !== void 0 && hit !== null) {
|
|
19308
19378
|
const fn = fns.get(Number(hit[1]));
|
|
@@ -19326,12 +19396,12 @@ function supercompileEmittedAssembly(prog, _cfg, extraIps, emitted) {
|
|
|
19326
19396
|
ownerParent = parent;
|
|
19327
19397
|
}
|
|
19328
19398
|
if (node2.type === "CallExpression") {
|
|
19329
|
-
const calleeName =
|
|
19399
|
+
const calleeName = nameOf2(ast(node2.callee));
|
|
19330
19400
|
const hit = calleeName === void 0 ? void 0 : PIECE.exec(calleeName);
|
|
19331
19401
|
if (hit !== void 0 && hit !== null) {
|
|
19332
19402
|
const callee = Number(hit[1]);
|
|
19333
19403
|
const args = nodes(node2.arguments);
|
|
19334
|
-
const transformable = current !== void 0 && owner2 !== void 0 && args.length === 3 &&
|
|
19404
|
+
const transformable = current !== void 0 && owner2 !== void 0 && args.length === 3 && nameOf2(args[0]) === "input" && nameOf2(args[2]) === "ctx" && isDirectCallUse(node2, parent, owner2) && isListStatement(owner2, ownerParent);
|
|
19335
19405
|
if (current === void 0 || owner2 === void 0) externalRefs.add(callee);
|
|
19336
19406
|
else {
|
|
19337
19407
|
const call = { caller: current.ip, callee, node: node2, statement: owner2, args, transformable };
|
|
@@ -19506,7 +19576,7 @@ ${nested}
|
|
|
19506
19576
|
const referenced = /* @__PURE__ */ new Set();
|
|
19507
19577
|
const checkRefs = (node2, parent) => {
|
|
19508
19578
|
if (node2.type === "FunctionDeclaration") {
|
|
19509
|
-
const name =
|
|
19579
|
+
const name = nameOf2(ast(node2.id));
|
|
19510
19580
|
if (name !== void 0 && PIECE.test(name)) declared.add(name);
|
|
19511
19581
|
}
|
|
19512
19582
|
if (node2.type === "Identifier" && typeof node2.name === "string" && PIECE.test(node2.name)) {
|
|
@@ -19515,32 +19585,210 @@ ${nested}
|
|
|
19515
19585
|
}
|
|
19516
19586
|
for (const child of children2(node2)) checkRefs(child, node2);
|
|
19517
19587
|
};
|
|
19518
|
-
checkRefs(checked.program);
|
|
19519
|
-
if (declared.size !== functionsAfter || [...referenced].some((name) => !declared.has(name))) {
|
|
19520
|
-
return fallback(emitted, "deleted piece body remains reachable after structured relinking", before);
|
|
19521
|
-
}
|
|
19522
|
-
const largestRegion = [...regionSizes].sort((a, b) => b[1] - a[1])[0];
|
|
19523
|
-
const protocolRegions = {
|
|
19524
|
-
node: [...regionProtocol.values()].filter((bits) => (bits & 1) !== 0).length,
|
|
19525
|
-
repv: [...regionProtocol.values()].filter((bits) => (bits & 2) !== 0).length,
|
|
19526
|
-
nodeAndRepv: [...regionProtocol.values()].filter((bits) => bits === 3).length
|
|
19588
|
+
checkRefs(checked.program);
|
|
19589
|
+
if (declared.size !== functionsAfter || [...referenced].some((name) => !declared.has(name))) {
|
|
19590
|
+
return fallback(emitted, "deleted piece body remains reachable after structured relinking", before);
|
|
19591
|
+
}
|
|
19592
|
+
const largestRegion = [...regionSizes].sort((a, b) => b[1] - a[1])[0];
|
|
19593
|
+
const protocolRegions = {
|
|
19594
|
+
node: [...regionProtocol.values()].filter((bits) => (bits & 1) !== 0).length,
|
|
19595
|
+
repv: [...regionProtocol.values()].filter((bits) => (bits & 2) !== 0).length,
|
|
19596
|
+
nodeAndRepv: [...regionProtocol.values()].filter((bits) => bits === 3).length
|
|
19597
|
+
};
|
|
19598
|
+
return {
|
|
19599
|
+
...emitted,
|
|
19600
|
+
source: candidate,
|
|
19601
|
+
supercompile: {
|
|
19602
|
+
...before,
|
|
19603
|
+
activated: removed > 0,
|
|
19604
|
+
...removed > 0 ? {} : { reason: "no uniquely-owned region bodies" },
|
|
19605
|
+
functionsAfter,
|
|
19606
|
+
pieceCallsAfter: pieceCallsBefore - removed,
|
|
19607
|
+
sourceAfter: candidate.length,
|
|
19608
|
+
regions: roots.length,
|
|
19609
|
+
largestRegionSource: Math.max(0, ...regionSizes.values()),
|
|
19610
|
+
...largestRegion === void 0 ? {} : { largestRegionIp: largestRegion[0] },
|
|
19611
|
+
protocolRegions
|
|
19612
|
+
}
|
|
19613
|
+
};
|
|
19614
|
+
}
|
|
19615
|
+
|
|
19616
|
+
// src/plugin/ir-eval.ts
|
|
19617
|
+
function evalRulesIR(ir) {
|
|
19618
|
+
return evalIR(ir, rules);
|
|
19619
|
+
}
|
|
19620
|
+
function evalCombinatorIR(ir) {
|
|
19621
|
+
const units = evalIR(ir, (opts) => opts.scanSkip);
|
|
19622
|
+
return units?.length === 1 ? units[0] : null;
|
|
19623
|
+
}
|
|
19624
|
+
function evalIR(ir, rulesImpl) {
|
|
19625
|
+
const _tf = (child, src, recognitionOnly = false) => {
|
|
19626
|
+
let fn2;
|
|
19627
|
+
try {
|
|
19628
|
+
fn2 = (0, eval)(`(${src})`);
|
|
19629
|
+
} catch {
|
|
19630
|
+
fn2 = () => {
|
|
19631
|
+
throw new Error("IR transform fn not materialized");
|
|
19632
|
+
};
|
|
19633
|
+
}
|
|
19634
|
+
const t = transform(child, fn2);
|
|
19635
|
+
t._def.fnSrc = src;
|
|
19636
|
+
if (recognitionOnly) t._def.recognitionOnly = true;
|
|
19637
|
+
return t;
|
|
19638
|
+
};
|
|
19639
|
+
const _lf = (child, src, source = false) => {
|
|
19640
|
+
let fn2;
|
|
19641
|
+
try {
|
|
19642
|
+
fn2 = (0, eval)(`(${src})`);
|
|
19643
|
+
} catch {
|
|
19644
|
+
fn2 = () => {
|
|
19645
|
+
throw new Error("IR leaf fn not materialized");
|
|
19646
|
+
};
|
|
19647
|
+
}
|
|
19648
|
+
const l = source ? sourceLeaf(child, fn2) : leaf(child, fn2);
|
|
19649
|
+
l._def.fnSrc = src;
|
|
19650
|
+
return l;
|
|
19651
|
+
};
|
|
19652
|
+
const _nd = (type, child, src, opts, staticError, sigSrc, buildImports, rawUnused) => {
|
|
19653
|
+
if (staticError !== void 0 && staticError.length > 0) {
|
|
19654
|
+
throw new Error(`IR direct node builder for ${type} must be macro-static and self-contained; unsupported binding(s): ${staticError.join(", ")}`);
|
|
19655
|
+
}
|
|
19656
|
+
const n = node(type, child, (() => {
|
|
19657
|
+
throw new Error("IR node build requires static re-lowering");
|
|
19658
|
+
}), opts);
|
|
19659
|
+
n._def.buildSrc = src;
|
|
19660
|
+
if (staticError !== void 0) n._def.buildStaticError = staticError;
|
|
19661
|
+
if (sigSrc !== void 0) n._def.buildSigSrc = sigSrc;
|
|
19662
|
+
if (rawUnused === true) n._def.buildRawUnused = true;
|
|
19663
|
+
if (buildImports !== void 0) n._def.buildImports = buildImports;
|
|
19664
|
+
return n;
|
|
19665
|
+
};
|
|
19666
|
+
const _gch = (items) => {
|
|
19667
|
+
const gateSrcs = [];
|
|
19668
|
+
const arms = items.map((it) => {
|
|
19669
|
+
if (Array.isArray(it)) {
|
|
19670
|
+
const [src, comb] = it;
|
|
19671
|
+
gateSrcs.push(src);
|
|
19672
|
+
let gate2;
|
|
19673
|
+
try {
|
|
19674
|
+
gate2 = (0, eval)(`(${src})`);
|
|
19675
|
+
} catch {
|
|
19676
|
+
gate2 = () => {
|
|
19677
|
+
throw new Error("IR gate fn not materialized");
|
|
19678
|
+
};
|
|
19679
|
+
}
|
|
19680
|
+
return { gate: gate2, combinator: comb };
|
|
19681
|
+
}
|
|
19682
|
+
gateSrcs.push(null);
|
|
19683
|
+
return it;
|
|
19684
|
+
});
|
|
19685
|
+
const c = choice(...arms);
|
|
19686
|
+
const gates = c._def.gates;
|
|
19687
|
+
if (gates && gates.length !== gateSrcs.length) {
|
|
19688
|
+
throw new Error(`_gch: gateSrcs length ${gateSrcs.length} != choice gates length ${gates.length}`);
|
|
19689
|
+
}
|
|
19690
|
+
;
|
|
19691
|
+
c._def.gateSrcs = gateSrcs;
|
|
19692
|
+
return c;
|
|
19527
19693
|
};
|
|
19528
|
-
|
|
19529
|
-
|
|
19530
|
-
|
|
19531
|
-
|
|
19532
|
-
|
|
19533
|
-
|
|
19534
|
-
...removed > 0 ? {} : { reason: "no uniquely-owned region bodies" },
|
|
19535
|
-
functionsAfter,
|
|
19536
|
-
pieceCallsAfter: pieceCallsBefore - removed,
|
|
19537
|
-
sourceAfter: candidate.length,
|
|
19538
|
-
regions: roots.length,
|
|
19539
|
-
largestRegionSource: Math.max(0, ...regionSizes.values()),
|
|
19540
|
-
...largestRegion === void 0 ? {} : { largestRegionIp: largestRegion[0] },
|
|
19541
|
-
protocolRegions
|
|
19694
|
+
const _wc = (src, inner) => {
|
|
19695
|
+
let extra;
|
|
19696
|
+
try {
|
|
19697
|
+
extra = (0, eval)(`(${src})`);
|
|
19698
|
+
} catch {
|
|
19699
|
+
extra = void 0;
|
|
19542
19700
|
}
|
|
19701
|
+
const w = withCtx(extra, inner);
|
|
19702
|
+
w._def.extraSrc = src;
|
|
19703
|
+
return w;
|
|
19543
19704
|
};
|
|
19705
|
+
const fn = new Function(
|
|
19706
|
+
"rules",
|
|
19707
|
+
"ref",
|
|
19708
|
+
"regex",
|
|
19709
|
+
"literal",
|
|
19710
|
+
"keywords",
|
|
19711
|
+
"sequence",
|
|
19712
|
+
"choice",
|
|
19713
|
+
"dispatch",
|
|
19714
|
+
"when",
|
|
19715
|
+
"startsWith",
|
|
19716
|
+
"endsWith",
|
|
19717
|
+
"matches",
|
|
19718
|
+
"otherwise",
|
|
19719
|
+
"routed",
|
|
19720
|
+
"attempt",
|
|
19721
|
+
"many",
|
|
19722
|
+
"oneOrMore",
|
|
19723
|
+
"optional",
|
|
19724
|
+
"sepBy",
|
|
19725
|
+
"keepSeparator",
|
|
19726
|
+
"not",
|
|
19727
|
+
"peek",
|
|
19728
|
+
"node",
|
|
19729
|
+
"parser",
|
|
19730
|
+
"scanTo",
|
|
19731
|
+
"balanced",
|
|
19732
|
+
"token",
|
|
19733
|
+
"leaf",
|
|
19734
|
+
"transform",
|
|
19735
|
+
"trivia",
|
|
19736
|
+
"classifiedTrivia",
|
|
19737
|
+
"label",
|
|
19738
|
+
"field",
|
|
19739
|
+
"expect",
|
|
19740
|
+
"adjacent",
|
|
19741
|
+
"notAdjacent",
|
|
19742
|
+
"_tf",
|
|
19743
|
+
"_lf",
|
|
19744
|
+
"_nd",
|
|
19745
|
+
"_gch",
|
|
19746
|
+
"_wc",
|
|
19747
|
+
`return (${ir})`
|
|
19748
|
+
);
|
|
19749
|
+
return fn(
|
|
19750
|
+
rulesImpl,
|
|
19751
|
+
ref,
|
|
19752
|
+
regex,
|
|
19753
|
+
literal,
|
|
19754
|
+
keywords,
|
|
19755
|
+
sequence,
|
|
19756
|
+
choice,
|
|
19757
|
+
dispatch,
|
|
19758
|
+
when,
|
|
19759
|
+
startsWith,
|
|
19760
|
+
endsWith,
|
|
19761
|
+
matches,
|
|
19762
|
+
otherwise,
|
|
19763
|
+
routed,
|
|
19764
|
+
attempt,
|
|
19765
|
+
many,
|
|
19766
|
+
oneOrMore,
|
|
19767
|
+
optional,
|
|
19768
|
+
sepBy,
|
|
19769
|
+
keepSeparator,
|
|
19770
|
+
not,
|
|
19771
|
+
peek,
|
|
19772
|
+
node,
|
|
19773
|
+
parser,
|
|
19774
|
+
scanTo,
|
|
19775
|
+
balanced,
|
|
19776
|
+
token,
|
|
19777
|
+
leaf,
|
|
19778
|
+
transform,
|
|
19779
|
+
trivia,
|
|
19780
|
+
classifiedTrivia,
|
|
19781
|
+
label,
|
|
19782
|
+
field,
|
|
19783
|
+
expect,
|
|
19784
|
+
adjacent,
|
|
19785
|
+
notAdjacent,
|
|
19786
|
+
_tf,
|
|
19787
|
+
_lf,
|
|
19788
|
+
_nd,
|
|
19789
|
+
_gch,
|
|
19790
|
+
_wc
|
|
19791
|
+
);
|
|
19544
19792
|
}
|
|
19545
19793
|
|
|
19546
19794
|
// src/plugin/index.ts
|
|
@@ -19705,13 +19953,30 @@ function topLevelInit(body, name) {
|
|
|
19705
19953
|
}
|
|
19706
19954
|
return null;
|
|
19707
19955
|
}
|
|
19708
|
-
function
|
|
19956
|
+
function isSymbolFor(n, key) {
|
|
19709
19957
|
if (!n || n.type !== "CallExpression") return false;
|
|
19710
19958
|
const callee = n.callee;
|
|
19711
19959
|
const obj = callee?.object?.name;
|
|
19712
19960
|
const prop = callee?.property?.name;
|
|
19713
19961
|
const arg0 = n.arguments?.[0];
|
|
19714
|
-
return obj === "Symbol" && prop === "for" && arg0?.value ===
|
|
19962
|
+
return obj === "Symbol" && prop === "for" && arg0?.value === key;
|
|
19963
|
+
}
|
|
19964
|
+
var isComposedPiecesSymbol = (n) => isSymbolFor(n, "parseman.composedPieces");
|
|
19965
|
+
var COMBINATOR_IR_KEY = "parseman.combinatorIR";
|
|
19966
|
+
function carriedCombinatorIR(init) {
|
|
19967
|
+
let n = init;
|
|
19968
|
+
while (n.type === "ParenthesizedExpression") n = n.expression;
|
|
19969
|
+
if (n.type !== "CallExpression") return null;
|
|
19970
|
+
const callee = n.callee;
|
|
19971
|
+
const args = n.arguments;
|
|
19972
|
+
if (callee.object?.name !== "Object" || callee.property?.name !== "defineProperty" || !isSymbolFor(args[1], COMBINATOR_IR_KEY)) return null;
|
|
19973
|
+
for (const p of args[2]?.properties ?? []) {
|
|
19974
|
+
const v = p.value;
|
|
19975
|
+
if (propName(p) !== "value") continue;
|
|
19976
|
+
if (v?.type === "Literal" && typeof v.value === "string") return v.value;
|
|
19977
|
+
if (v?.type === "TemplateLiteral" && v.expressions?.length === 0) return v.quasis?.[0]?.value.cooked ?? null;
|
|
19978
|
+
}
|
|
19979
|
+
return null;
|
|
19715
19980
|
}
|
|
19716
19981
|
function findCarriedPiecesLiteral(root) {
|
|
19717
19982
|
let found = null;
|
|
@@ -19727,7 +19992,7 @@ function findCarriedPiecesLiteral(root) {
|
|
|
19727
19992
|
const obj = callee?.object?.name;
|
|
19728
19993
|
const prop = callee?.property?.name;
|
|
19729
19994
|
const args = node2.arguments;
|
|
19730
|
-
if (callee?.type === "Identifier" &&
|
|
19995
|
+
if (callee?.type === "Identifier" && args?.[1]?.type === "ObjectExpression") {
|
|
19731
19996
|
for (const p of args[1].properties ?? []) {
|
|
19732
19997
|
if (p.computed && isComposedPiecesSymbol(p.key) && p.value) {
|
|
19733
19998
|
found = { start: p.value.start, end: p.value.end };
|
|
@@ -19827,13 +20092,14 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19827
20092
|
const allNames = /* @__PURE__ */ new Set();
|
|
19828
20093
|
const importBindings = /* @__PURE__ */ new Map();
|
|
19829
20094
|
const ordinaryImports = [];
|
|
20095
|
+
const isMacroImport = (s) => s.attributes.some((a) => {
|
|
20096
|
+
const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
|
|
20097
|
+
return key === "type" && a.value.value === "macro";
|
|
20098
|
+
});
|
|
19830
20099
|
for (const stmt of body) {
|
|
19831
20100
|
if (stmt.type !== "ImportDeclaration") continue;
|
|
19832
20101
|
const s = stmt;
|
|
19833
|
-
const isMacro = moduleAliases.has(s.source.value) && s
|
|
19834
|
-
const key = a.key.type === "Identifier" ? a.key.name : String(a.key.value);
|
|
19835
|
-
return key === "type" && a.value.value === "macro";
|
|
19836
|
-
});
|
|
20102
|
+
const isMacro = moduleAliases.has(s.source.value) && isMacroImport(s);
|
|
19837
20103
|
if (!isMacro) {
|
|
19838
20104
|
const specifiers = [];
|
|
19839
20105
|
for (const spec of s.specifiers) {
|
|
@@ -19876,7 +20142,209 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19876
20142
|
}
|
|
19877
20143
|
const reducerResolver = createReducerResolver(id, body, code);
|
|
19878
20144
|
setReducerResolver(reducerResolver, code);
|
|
19879
|
-
|
|
20145
|
+
let builderImports = (name) => importBindings.get(name) ?? null;
|
|
20146
|
+
setBuilderImportResolver((name) => builderImports(name));
|
|
20147
|
+
const ownRoot = nearestPackageRoot(id);
|
|
20148
|
+
let ownDir = path2.dirname(id);
|
|
20149
|
+
try {
|
|
20150
|
+
ownDir = fs2.realpathSync(ownDir);
|
|
20151
|
+
} catch {
|
|
20152
|
+
}
|
|
20153
|
+
const rebaseSpecifier = (from, spec) => {
|
|
20154
|
+
if (!spec.startsWith(".")) return spec;
|
|
20155
|
+
const target = path2.resolve(path2.dirname(from), spec);
|
|
20156
|
+
if (ownRoot === null || nearestPackageRoot(target) !== ownRoot) return null;
|
|
20157
|
+
const rel = path2.relative(ownDir, target).split(path2.sep).join("/");
|
|
20158
|
+
return rel.startsWith("../") ? rel : `./${rel}`;
|
|
20159
|
+
};
|
|
20160
|
+
const unresolvedImports = /* @__PURE__ */ new Set();
|
|
20161
|
+
const valueModules = /* @__PURE__ */ new Map();
|
|
20162
|
+
const OPAQUE_IMPORT = "is a default or namespace import, which the macro does not resolve \u2014 import the binding by name";
|
|
20163
|
+
const opaqueImportsOf = (moduleBody) => {
|
|
20164
|
+
const out = /* @__PURE__ */ new Set();
|
|
20165
|
+
for (const st of moduleBody) {
|
|
20166
|
+
if (st.type !== "ImportDeclaration") continue;
|
|
20167
|
+
for (const sp of st.specifiers) {
|
|
20168
|
+
if (sp.type !== "ImportSpecifier") out.add(sp.local.name);
|
|
20169
|
+
}
|
|
20170
|
+
}
|
|
20171
|
+
return out;
|
|
20172
|
+
};
|
|
20173
|
+
const valueModule = (file) => {
|
|
20174
|
+
if (valueModules.has(file)) return valueModules.get(file);
|
|
20175
|
+
const mod = parseModuleCached(file);
|
|
20176
|
+
let out = null;
|
|
20177
|
+
if (mod) {
|
|
20178
|
+
const consts = /* @__PURE__ */ new Map();
|
|
20179
|
+
let stable;
|
|
20180
|
+
for (const st of mod.body) {
|
|
20181
|
+
const vd = unwrapVd(st);
|
|
20182
|
+
if (!vd) continue;
|
|
20183
|
+
const isConst = vd.kind === "const";
|
|
20184
|
+
for (const d of vd.declarations) {
|
|
20185
|
+
const idn = d.id;
|
|
20186
|
+
if (idn.type !== "Identifier" || !idn.name || !d.init) continue;
|
|
20187
|
+
if (isConst || (stable ??= topLevelIsStable(mod.body, mod.src.length))(idn.name)) consts.set(idn.name, d.init);
|
|
20188
|
+
}
|
|
20189
|
+
}
|
|
20190
|
+
out = {
|
|
20191
|
+
file,
|
|
20192
|
+
src: mod.src,
|
|
20193
|
+
body: mod.body,
|
|
20194
|
+
consts,
|
|
20195
|
+
imports: extractImportBindings(mod.body),
|
|
20196
|
+
opaqueImports: opaqueImportsOf(mod.body)
|
|
20197
|
+
};
|
|
20198
|
+
}
|
|
20199
|
+
valueModules.set(file, out);
|
|
20200
|
+
return out;
|
|
20201
|
+
};
|
|
20202
|
+
const resolveValueFile = (from, specifier) => {
|
|
20203
|
+
const source = resolvePrivateSourceModule(from, specifier);
|
|
20204
|
+
if (source) return source;
|
|
20205
|
+
try {
|
|
20206
|
+
return getCompiledResolver().resolveFileSync(from, specifier).path ?? null;
|
|
20207
|
+
} catch {
|
|
20208
|
+
return null;
|
|
20209
|
+
}
|
|
20210
|
+
};
|
|
20211
|
+
const evaluatingConsts = /* @__PURE__ */ new Set();
|
|
20212
|
+
const rebaseCarriedBuilderImports = (combi, from) => {
|
|
20213
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20214
|
+
const walk = (v) => {
|
|
20215
|
+
if (v === null || typeof v !== "object" || seen.has(v)) return null;
|
|
20216
|
+
seen.add(v);
|
|
20217
|
+
const def = v._def;
|
|
20218
|
+
if (def?.buildImports) {
|
|
20219
|
+
const out = [];
|
|
20220
|
+
for (const bi of def.buildImports) {
|
|
20221
|
+
const source = rebaseSpecifier(from, bi.source);
|
|
20222
|
+
if (source === null) return bi;
|
|
20223
|
+
out.push({ ...bi, source });
|
|
20224
|
+
}
|
|
20225
|
+
def.buildImports = out;
|
|
20226
|
+
}
|
|
20227
|
+
for (const child of Object.values(v)) {
|
|
20228
|
+
for (const c of Array.isArray(child) ? child : [child]) {
|
|
20229
|
+
const stuck = walk(c);
|
|
20230
|
+
if (stuck) return stuck;
|
|
20231
|
+
}
|
|
20232
|
+
}
|
|
20233
|
+
return null;
|
|
20234
|
+
};
|
|
20235
|
+
return walk(combi);
|
|
20236
|
+
};
|
|
20237
|
+
const moduleConstValue = (m, name) => {
|
|
20238
|
+
const key = `${m.file}\0${name}`;
|
|
20239
|
+
if (evaluatingConsts.has(key)) return { unresolved: `is part of a declaration cycle in ${m.file}` };
|
|
20240
|
+
evaluatingConsts.add(key);
|
|
20241
|
+
const outerBuilderImports = builderImports;
|
|
20242
|
+
try {
|
|
20243
|
+
const init = m.consts.get(name);
|
|
20244
|
+
const ir = carriedCombinatorIR(init);
|
|
20245
|
+
if (ir !== null) {
|
|
20246
|
+
let combi2 = null;
|
|
20247
|
+
let why = "";
|
|
20248
|
+
try {
|
|
20249
|
+
combi2 = evalCombinatorIR(ir);
|
|
20250
|
+
} catch (e) {
|
|
20251
|
+
why = `: ${e.message}`;
|
|
20252
|
+
}
|
|
20253
|
+
if (!combi2) return { unresolved: `carries combinator IR that does not evaluate (${m.file})${why}` };
|
|
20254
|
+
const stuck = rebaseCarriedBuilderImports(combi2, m.file);
|
|
20255
|
+
return stuck ? { unresolved: `has a node() builder reading \`${stuck.local}\` from '${stuck.source}' inside ${m.file}, which this module cannot import \u2014 import it there by package name` } : { value: { combi: combi2, mfSrcs: [] } };
|
|
20256
|
+
}
|
|
20257
|
+
const scope2 = moduleValueScope(m);
|
|
20258
|
+
reducerResolver.register(m.file);
|
|
20259
|
+
builderImports = (name2) => {
|
|
20260
|
+
const b = m.imports.get(name2);
|
|
20261
|
+
const source = b ? rebaseSpecifier(m.file, b.source) : null;
|
|
20262
|
+
return b && source !== null ? { source, imported: b.imported } : null;
|
|
20263
|
+
};
|
|
20264
|
+
const mfs = [];
|
|
20265
|
+
const combi = evaluateExpr(init, scope2, m.src, mfs);
|
|
20266
|
+
if (combi) return { value: { combi, mfSrcs: mfs } };
|
|
20267
|
+
const factory = evaluateWordFactory(init, scope2, m.src) ?? evaluateWhenFactory(init, scope2, m.src);
|
|
20268
|
+
if (factory) return { value: factory };
|
|
20269
|
+
const value = evaluateStaticValue(init, scope2, m.src);
|
|
20270
|
+
if (value !== null && value !== void 0 || isStaticNullishExpression(init)) return { value };
|
|
20271
|
+
return {
|
|
20272
|
+
unresolved: /\btableRules\b/.test(m.src.slice(init.start, init.end)) ? `is a compiled parser in ${m.file} that carries no combinator IR \u2014 rebuild that module with parseman v${PARSEMAN_VERSION}` : `is not a statically-known combinator or value (${m.file})`
|
|
20273
|
+
};
|
|
20274
|
+
} finally {
|
|
20275
|
+
evaluatingConsts.delete(key);
|
|
20276
|
+
builderImports = outerBuilderImports;
|
|
20277
|
+
}
|
|
20278
|
+
};
|
|
20279
|
+
const moduleValueScope = (m) => m.scope ??= new ModuleScope((name) => {
|
|
20280
|
+
if (m.consts.has(name)) return moduleConstValue(m, name);
|
|
20281
|
+
const binding = m.imports.get(name);
|
|
20282
|
+
if (binding) return importedValue(m.file, binding);
|
|
20283
|
+
return m.opaqueImports.has(name) ? { unresolved: OPAQUE_IMPORT } : null;
|
|
20284
|
+
}, unresolvedImports);
|
|
20285
|
+
const exportedValue = (m, name, depth) => {
|
|
20286
|
+
for (const st of m.body) {
|
|
20287
|
+
if (st.type !== "ExportNamedDeclaration" || !st.source) continue;
|
|
20288
|
+
for (const sp of st.specifiers ?? []) {
|
|
20289
|
+
if (sp.exported.name !== name) continue;
|
|
20290
|
+
const source = st.source.value;
|
|
20291
|
+
const file = depth < 16 ? resolveValueFile(m.file, source) : null;
|
|
20292
|
+
const next = file ? valueModule(file) : null;
|
|
20293
|
+
if (!next) return { unresolved: `is re-exported from '${source}', which does not resolve from ${m.file}` };
|
|
20294
|
+
return exportedValue(next, sp.local.name, depth + 1);
|
|
20295
|
+
}
|
|
20296
|
+
}
|
|
20297
|
+
const local = exportLocalName(m.body, name);
|
|
20298
|
+
if (local === null) {
|
|
20299
|
+
for (const st of m.body) {
|
|
20300
|
+
if (st.type !== "ExportAllDeclaration" || st.exported) continue;
|
|
20301
|
+
const file = depth < 16 ? resolveValueFile(m.file, st.source.value) : null;
|
|
20302
|
+
const next = file ? valueModule(file) : null;
|
|
20303
|
+
if (!next) continue;
|
|
20304
|
+
const r = exportedValue(next, name, depth + 1);
|
|
20305
|
+
if (r !== null && "unresolved" in r && r.unresolved.startsWith("is not exported by ")) continue;
|
|
20306
|
+
return r;
|
|
20307
|
+
}
|
|
20308
|
+
return { unresolved: `is not exported by ${m.file}` };
|
|
20309
|
+
}
|
|
20310
|
+
const scope2 = moduleValueScope(m);
|
|
20311
|
+
if (!scope2.has(local)) {
|
|
20312
|
+
scope2.get(local);
|
|
20313
|
+
return { unresolved: `could not be resolved in ${m.file}` };
|
|
20314
|
+
}
|
|
20315
|
+
return { value: scope2.get(local) };
|
|
20316
|
+
};
|
|
20317
|
+
const importedValue = (from, binding) => {
|
|
20318
|
+
const file = resolveValueFile(from, binding.source);
|
|
20319
|
+
const m = file ? valueModule(file) : null;
|
|
20320
|
+
if (!m) return { unresolved: `is imported from '${binding.source}', which does not resolve from ${from}` };
|
|
20321
|
+
return exportedValue(m, binding.imported, 0);
|
|
20322
|
+
};
|
|
20323
|
+
const deferredLocals = /* @__PURE__ */ new Map();
|
|
20324
|
+
const deferredResults = /* @__PURE__ */ new Map();
|
|
20325
|
+
const mainOpaqueImports = opaqueImportsOf(body);
|
|
20326
|
+
const resolveMainFree = (name) => {
|
|
20327
|
+
const done = deferredResults.get(name);
|
|
20328
|
+
if (done !== void 0) return done;
|
|
20329
|
+
const deferred = deferredLocals.get(name);
|
|
20330
|
+
if (deferred !== void 0) {
|
|
20331
|
+
deferredLocals.delete(name);
|
|
20332
|
+
const outer = [...unresolvedImports];
|
|
20333
|
+
unresolvedImports.clear();
|
|
20334
|
+
const value = evaluateStaticValue(deferred, scope, code);
|
|
20335
|
+
const why = [...unresolvedImports];
|
|
20336
|
+
unresolvedImports.clear();
|
|
20337
|
+
for (const n of outer) unresolvedImports.add(n);
|
|
20338
|
+
const result2 = value !== null && value !== void 0 || isStaticNullishExpression(deferred) ? { value } : why.length > 0 ? { unresolved: `could not be evaluated at build time, because: ${why.join("; ")}` } : null;
|
|
20339
|
+
deferredResults.set(name, result2);
|
|
20340
|
+
return result2;
|
|
20341
|
+
}
|
|
20342
|
+
const binding = importBindings.get(name);
|
|
20343
|
+
if (!binding) return mainOpaqueImports.has(name) ? { unresolved: OPAQUE_IMPORT } : null;
|
|
20344
|
+
const resolved = importedValue(id, binding);
|
|
20345
|
+
if (resolved !== null && "value" in resolved) usedImportedFactories.add(name);
|
|
20346
|
+
return resolved;
|
|
20347
|
+
};
|
|
19880
20348
|
const topLevelFunction = (moduleBody, name) => {
|
|
19881
20349
|
for (const st of moduleBody) {
|
|
19882
20350
|
const decl = st.type === "ExportNamedDeclaration" ? st.declaration : st;
|
|
@@ -19885,19 +20353,17 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19885
20353
|
}
|
|
19886
20354
|
return null;
|
|
19887
20355
|
};
|
|
19888
|
-
const
|
|
19889
|
-
|
|
19890
|
-
const
|
|
19891
|
-
|
|
19892
|
-
const
|
|
19893
|
-
|
|
19894
|
-
|
|
19895
|
-
|
|
19896
|
-
const sourceScopeUntil = (moduleBody, source, until) => {
|
|
19897
|
-
const out = /* @__PURE__ */ new Map();
|
|
20356
|
+
const sourceScopeUntil = (file, moduleBody, source, until) => {
|
|
20357
|
+
const imports = extractImportBindings(moduleBody);
|
|
20358
|
+
const opaque = opaqueImportsOf(moduleBody);
|
|
20359
|
+
const out = new ModuleScope((name) => {
|
|
20360
|
+
const binding = imports.get(name);
|
|
20361
|
+
if (binding) return importedValue(file, binding);
|
|
20362
|
+
return opaque.has(name) ? { unresolved: OPAQUE_IMPORT } : null;
|
|
20363
|
+
}, unresolvedImports);
|
|
19898
20364
|
for (const stmt of moduleBody) {
|
|
19899
20365
|
if (stmt.type === "ImportDeclaration") {
|
|
19900
|
-
if (!
|
|
20366
|
+
if (moduleAliases.has(stmt.source.value) && !isMacroImport(stmt)) return null;
|
|
19901
20367
|
continue;
|
|
19902
20368
|
}
|
|
19903
20369
|
if (stmt.type === "FunctionDeclaration") continue;
|
|
@@ -19950,6 +20416,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19950
20416
|
}
|
|
19951
20417
|
return out;
|
|
19952
20418
|
};
|
|
20419
|
+
const factoryFailures = /* @__PURE__ */ new Map();
|
|
19953
20420
|
const usedImportedFactories = /* @__PURE__ */ new Set();
|
|
19954
20421
|
const markUsedImportedFactories = (names) => {
|
|
19955
20422
|
for (const name of names ?? []) usedImportedFactories.add(name);
|
|
@@ -19962,8 +20429,13 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19962
20429
|
const localFor = exportLocalName(mod.body, binding.imported);
|
|
19963
20430
|
const init = localFor ? topLevelInit(mod.body, localFor) ?? topLevelFunction(mod.body, localFor) : null;
|
|
19964
20431
|
if (!init || init.type !== "ArrowFunctionExpression" && init.type !== "FunctionExpression" && init.type !== "FunctionDeclaration") continue;
|
|
19965
|
-
|
|
19966
|
-
|
|
20432
|
+
unresolvedImports.clear();
|
|
20433
|
+
const factoryScope = sourceScopeUntil(file, mod.body, mod.src, init.start);
|
|
20434
|
+
if (!factoryScope) {
|
|
20435
|
+
if (unresolvedImports.size > 0) factoryFailures.set(localName, [...unresolvedImports]);
|
|
20436
|
+
unresolvedImports.clear();
|
|
20437
|
+
continue;
|
|
20438
|
+
}
|
|
19967
20439
|
factoryDecls.set(localName, {
|
|
19968
20440
|
fn: init,
|
|
19969
20441
|
declaredAt: -1,
|
|
@@ -19973,7 +20445,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19973
20445
|
});
|
|
19974
20446
|
reducerResolver.register(file);
|
|
19975
20447
|
}
|
|
19976
|
-
const scope =
|
|
20448
|
+
const scope = new ModuleScope(resolveMainFree, unresolvedImports);
|
|
19977
20449
|
const replacements = [];
|
|
19978
20450
|
const warnings = [];
|
|
19979
20451
|
beginDegradationCapture();
|
|
@@ -19993,6 +20465,12 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
19993
20465
|
m = /* @__PURE__ */ new Map();
|
|
19994
20466
|
pendingBuilderImports.set(bi.source, m);
|
|
19995
20467
|
}
|
|
20468
|
+
const prev = m.get(bi.local);
|
|
20469
|
+
if (prev !== void 0 && prev !== bi.imported) {
|
|
20470
|
+
throw new Error(
|
|
20471
|
+
`${id} \u2014 parseman will not emit this module: inlined builders read \`${bi.local}\` as both \`${prev}\` and \`${bi.imported}\` from ${JSON.stringify(bi.source)}. The builder source names \`${bi.local}\` verbatim, so one import cannot bind both; import them under different names.`
|
|
20472
|
+
);
|
|
20473
|
+
}
|
|
19996
20474
|
m.set(bi.local, bi.imported);
|
|
19997
20475
|
}
|
|
19998
20476
|
if (def?.tag === "lazy" && v._ruleName === void 0 && typeof def.thunk === "function") {
|
|
@@ -20034,6 +20512,41 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20034
20512
|
anyUnresolved = true;
|
|
20035
20513
|
warnings.push(`${id}:${lineOf(pos)} \u2014 ${msg} (running via the interpreter; add the plugin or simplify the declaration to compile it)`);
|
|
20036
20514
|
};
|
|
20515
|
+
const unevaluable = (pos, what) => {
|
|
20516
|
+
const names = [...unresolvedImports];
|
|
20517
|
+
unresolvedImports.clear();
|
|
20518
|
+
throw new Error(
|
|
20519
|
+
`${id}:${lineOf(pos)} \u2014 ${what} can't be evaluated at build time` + (names.length > 0 ? `; unresolved binding(s):
|
|
20520
|
+
${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/value expression)") + `
|
|
20521
|
+
parseman will not emit this module rather than drop it silently.`
|
|
20522
|
+
);
|
|
20523
|
+
};
|
|
20524
|
+
const requiredOption = (label2, name, value, evaluate) => {
|
|
20525
|
+
if (value === void 0 || isStaticNullishExpression(value)) return void 0;
|
|
20526
|
+
unresolvedImports.clear();
|
|
20527
|
+
const out = evaluate(value);
|
|
20528
|
+
if (out === null) {
|
|
20529
|
+
const id2 = value.type === "Identifier" ? value.name : null;
|
|
20530
|
+
if (id2 !== null && scope.has(id2) && scope.get(id2) == null) return void 0;
|
|
20531
|
+
return unevaluable(value.start, `${label2}: rules({ ${name} })`);
|
|
20532
|
+
}
|
|
20533
|
+
unresolvedImports.clear();
|
|
20534
|
+
return out;
|
|
20535
|
+
};
|
|
20536
|
+
const RULES_OPTIONS = /* @__PURE__ */ new Set(["trivia", "scanSkip", "hostMode", "trackLines"]);
|
|
20537
|
+
const assertPlainOptions = (optExpr, label2) => {
|
|
20538
|
+
for (const p of optExpr?.type === "ObjectExpression" ? optExpr.properties : []) {
|
|
20539
|
+
if (propName(p) !== null) continue;
|
|
20540
|
+
const key = p.type === "Property" ? evaluateStaticValue(p.key, scope, code) : null;
|
|
20541
|
+
if (typeof key !== "string" || RULES_OPTIONS.has(key)) {
|
|
20542
|
+
unevaluable(p.start, `${label2}: an options ${p.type === "Property" ? "computed key" : "spread"}`);
|
|
20543
|
+
}
|
|
20544
|
+
}
|
|
20545
|
+
};
|
|
20546
|
+
const triviaOption = (optExpr, label2) => {
|
|
20547
|
+
assertPlainOptions(optExpr, label2);
|
|
20548
|
+
return requiredOption(label2, "trivia", optionProp(optExpr, "trivia"), (v) => evaluateExpr(v, scope, code, []));
|
|
20549
|
+
};
|
|
20037
20550
|
const evaluateRulesFactory = (init, label2) => {
|
|
20038
20551
|
const args = init.arguments;
|
|
20039
20552
|
const arg0 = args[0];
|
|
@@ -20049,7 +20562,15 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20049
20562
|
const factoryScope = namedFactory?.scope ?? scope;
|
|
20050
20563
|
const factoryCode = namedFactory?.code ?? code;
|
|
20051
20564
|
const importedFactory = namedFactory?.imported === true && factoryArg === namedFactory.fn ? factoryArgRaw.name : void 0;
|
|
20565
|
+
const failedFactory = factoryArgRaw.type === "Identifier" ? factoryFailures.get(factoryArgRaw.name) : void 0;
|
|
20566
|
+
if (failedFactory) {
|
|
20567
|
+
for (const n of failedFactory) unresolvedImports.add(n);
|
|
20568
|
+
unevaluable(init.start, `${label2}: the imported rules() factory \`${factoryArgRaw.name}\``);
|
|
20569
|
+
}
|
|
20052
20570
|
const optionsArg = optionsFirst ? arg0 : arg1;
|
|
20571
|
+
if (optionsArg !== void 0 && optionsArg.type !== "ObjectExpression" && !isStaticNullishExpression(optionsArg)) {
|
|
20572
|
+
unevaluable(optionsArg.start, `${label2}: rules() options`);
|
|
20573
|
+
}
|
|
20053
20574
|
const optionValue = (name) => optionProp(optionsArg, name);
|
|
20054
20575
|
const hostModeValue = optionValue("hostMode");
|
|
20055
20576
|
const gHostMode = hostModeValue?.type === "Literal" ? hostModeValue.value : void 0;
|
|
@@ -20063,11 +20584,16 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20063
20584
|
warn(init.start, `${label2}: rules({ trackLines }) must be a boolean literal`);
|
|
20064
20585
|
return null;
|
|
20065
20586
|
}
|
|
20066
|
-
const
|
|
20067
|
-
const
|
|
20068
|
-
|
|
20069
|
-
|
|
20587
|
+
const gTrivia = triviaOption(optionsArg, label2);
|
|
20588
|
+
const scanSkipArray = requiredOption(label2, "scanSkip", optionValue("scanSkip"), (v) => {
|
|
20589
|
+
const units = evaluateCombinatorArray(v, scope, code);
|
|
20590
|
+
if (units) return units;
|
|
20591
|
+
const value = evaluateStaticValue(v, scope, code);
|
|
20592
|
+
return Array.isArray(value) && value.length === 0 ? [] : null;
|
|
20593
|
+
});
|
|
20594
|
+
const gScanSkip = scanSkipArray?.length ? scanSkipArray : void 0;
|
|
20070
20595
|
const why = {};
|
|
20596
|
+
unresolvedImports.clear();
|
|
20071
20597
|
const ruleMap = evaluateParserFactory(factoryArg, factoryScope, factoryCode, [], why, {
|
|
20072
20598
|
...gTrivia ? { trivia: gTrivia } : {},
|
|
20073
20599
|
...gScanSkip ? { scanSkip: gScanSkip } : {},
|
|
@@ -20075,6 +20601,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20075
20601
|
...gTrackLines === true ? { trackLines: true } : {}
|
|
20076
20602
|
});
|
|
20077
20603
|
if (!ruleMap) {
|
|
20604
|
+
if (unresolvedImports.size > 0) unevaluable(init.start, `${label2}: rules(...) factory`);
|
|
20078
20605
|
warn(init.start, why.reason === void 0 ? `${label2}: rules(...) factory isn't statically evaluable` : `${label2}: rules(...) factory isn't statically evaluable \u2014 ${why.reason}`);
|
|
20079
20606
|
return null;
|
|
20080
20607
|
}
|
|
@@ -20091,6 +20618,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20091
20618
|
if (!evaluated) return null;
|
|
20092
20619
|
const refusals = [];
|
|
20093
20620
|
const compiled = compileRuleMap([...evaluated.ruleMap], { ...evaluated.trivia ? { trivia: evaluated.trivia } : {}, ...evaluated.scanSkip ? { scanSkip: evaluated.scanSkip } : {}, ...evaluated.trackLines ? { trackLines: true } : {}, recovery, coverage: grammarCoverage, refusals });
|
|
20621
|
+
if (compiled !== null) collectBuilderImports([...evaluated.ruleMap]);
|
|
20094
20622
|
if (compiled !== null) usedTableRuntime = true;
|
|
20095
20623
|
return {
|
|
20096
20624
|
replacement: compiled?.replacement ?? null,
|
|
@@ -20152,49 +20680,63 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20152
20680
|
};
|
|
20153
20681
|
const localComposedCarried = /* @__PURE__ */ new Map();
|
|
20154
20682
|
const importedPiecesCache = /* @__PURE__ */ new Map();
|
|
20155
|
-
const resolveModulePieces = (module, exportName, seen) => {
|
|
20683
|
+
const resolveModulePieces = (module, exportName, seen, unresolved, local = false) => {
|
|
20156
20684
|
const { file } = module;
|
|
20157
20685
|
const mod = module.source ? lowerPrivateSourceModule(file, moduleAliases, warnUnloweredRegex, recovery) : parseModuleCached(file);
|
|
20158
20686
|
if (!mod) return null;
|
|
20159
|
-
const localFor = exportLocalName(mod.body, exportName);
|
|
20687
|
+
const localFor = local ? exportName : exportLocalName(mod.body, exportName);
|
|
20160
20688
|
const initNode = localFor ? topLevelInit(mod.body, localFor) : null;
|
|
20161
20689
|
const literalRange = initNode ? findCarriedPiecesLiteral(initNode) : null;
|
|
20162
20690
|
if (!literalRange) return null;
|
|
20163
20691
|
const literal2 = mod.src.slice(literalRange.start, literalRange.end);
|
|
20692
|
+
const fail = (why) => {
|
|
20693
|
+
unresolved.why ??= `${exportName} in ${file}: ${why}`;
|
|
20694
|
+
return null;
|
|
20695
|
+
};
|
|
20164
20696
|
const imports = extractImportBindings(mod.body);
|
|
20165
20697
|
const stubNames = [];
|
|
20166
20698
|
const stubVals = [];
|
|
20167
|
-
const spreadRe = /\.\.\.\s*\(?\s*([A-Za-z_$][\w$]*)\s*\[\s*Symbol\s*\.\s*for\s*\(\s*['"]parseman\.composedPieces['"]/g;
|
|
20699
|
+
const spreadRe = /\.\.\.\s*\(?\s*([A-Za-z_$][\w$]*)\s*\[\s*(?:\/\*[^]*?\*\/\s*)*Symbol\s*\.\s*for\s*\(\s*['"]parseman\.composedPieces['"]/g;
|
|
20168
20700
|
const done = /* @__PURE__ */ new Set();
|
|
20169
20701
|
for (let m; m = spreadRe.exec(literal2); ) {
|
|
20170
|
-
const
|
|
20171
|
-
if (done.has(
|
|
20172
|
-
done.add(
|
|
20173
|
-
const b = imports.get(
|
|
20702
|
+
const local2 = m[1];
|
|
20703
|
+
if (done.has(local2)) continue;
|
|
20704
|
+
done.add(local2);
|
|
20705
|
+
const b = imports.get(local2);
|
|
20174
20706
|
let subPieces = [];
|
|
20175
20707
|
if (b) {
|
|
20176
20708
|
const subModule = resolveGrammarModule(file, b.source);
|
|
20177
|
-
if (subModule
|
|
20178
|
-
|
|
20709
|
+
if (subModule === null) return fail(`its carried pieces spread \`${local2}\` from '${b.source}', a module that could not be found`);
|
|
20710
|
+
if (!seen.has(subModule.file)) {
|
|
20711
|
+
subPieces = resolveModulePieces(subModule, b.imported, new Set(seen).add(subModule.file), unresolved);
|
|
20712
|
+
if (subPieces === null) return fail(`its carried pieces spread \`${local2}\` from '${b.source}', which could not be resolved`);
|
|
20179
20713
|
}
|
|
20714
|
+
} else if (topLevelInit(mod.body, local2) !== null && !seen.has(`${file}#${local2}`)) {
|
|
20715
|
+
subPieces = resolveModulePieces(module, local2, new Set(seen).add(`${file}#${local2}`), unresolved, true);
|
|
20716
|
+
if (subPieces === null) return fail(`its carried pieces spread the inlined binding \`${local2}\`, which carries none`);
|
|
20717
|
+
} else {
|
|
20718
|
+
return fail(`its carried pieces spread \`${local2}\`, which is neither an import nor a top-level binding of the module`);
|
|
20180
20719
|
}
|
|
20181
|
-
stubNames.push(
|
|
20720
|
+
stubNames.push(local2);
|
|
20182
20721
|
stubVals.push({ [COMPOSED_PIECES]: subPieces });
|
|
20183
20722
|
}
|
|
20184
20723
|
try {
|
|
20185
20724
|
const list = new Function(...stubNames, `return (${literal2})`)(...stubVals);
|
|
20186
20725
|
return list;
|
|
20187
|
-
} catch {
|
|
20188
|
-
return
|
|
20726
|
+
} catch (e) {
|
|
20727
|
+
return fail(`its carried pieces literal did not evaluate (${e.message})`);
|
|
20189
20728
|
}
|
|
20190
20729
|
};
|
|
20730
|
+
const unresolvedCompiled = /* @__PURE__ */ new Map();
|
|
20191
20731
|
const importedPieces = (localName) => {
|
|
20192
20732
|
if (importedPiecesCache.has(localName)) return importedPiecesCache.get(localName);
|
|
20193
20733
|
let result2 = null;
|
|
20194
20734
|
const binding = importBindings.get(localName);
|
|
20195
20735
|
if (binding) {
|
|
20196
20736
|
const module = resolveGrammarModule(id, binding.source);
|
|
20197
|
-
|
|
20737
|
+
const unresolved = {};
|
|
20738
|
+
result2 = module ? resolveModulePieces(module, binding.imported, /* @__PURE__ */ new Set([module.file]), unresolved) : null;
|
|
20739
|
+
if (result2 === null && unresolved.why !== void 0) unresolvedCompiled.set(localName, unresolved.why);
|
|
20198
20740
|
}
|
|
20199
20741
|
importedPiecesCache.set(localName, result2);
|
|
20200
20742
|
return result2;
|
|
@@ -20205,7 +20747,8 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20205
20747
|
const add = (item) => {
|
|
20206
20748
|
if (!isIR(item)) return false;
|
|
20207
20749
|
if (item.trackLines === true) trackLines = true;
|
|
20208
|
-
|
|
20750
|
+
const map = evalRulesIR(item.ir);
|
|
20751
|
+
pieces.push({ ns: item.ns, rules: Object.entries(map), recipes: map[RULES_RECIPE] });
|
|
20209
20752
|
return true;
|
|
20210
20753
|
};
|
|
20211
20754
|
for (const item of items) {
|
|
@@ -20232,10 +20775,20 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20232
20775
|
}
|
|
20233
20776
|
return [...winners];
|
|
20234
20777
|
};
|
|
20235
|
-
const mergedCarriedRules = (items) => {
|
|
20778
|
+
const mergedCarriedRules = (items, link) => {
|
|
20236
20779
|
const carriedMaps = carriedRuleMaps(items);
|
|
20237
20780
|
if (carriedMaps === null) return null;
|
|
20238
|
-
|
|
20781
|
+
const linked = linkRules(carriedMaps.pieces.flatMap((p) => p.recipes), link);
|
|
20782
|
+
const rules2 = Object.entries(linked).filter(([, rule]) => {
|
|
20783
|
+
if (rule._def.tag !== "lazy") return true;
|
|
20784
|
+
try {
|
|
20785
|
+
rule._def.thunk();
|
|
20786
|
+
return true;
|
|
20787
|
+
} catch {
|
|
20788
|
+
return false;
|
|
20789
|
+
}
|
|
20790
|
+
});
|
|
20791
|
+
return { rules: rules2, trackLines: carriedMaps.trackLines };
|
|
20239
20792
|
};
|
|
20240
20793
|
const applyComposingTrivia = (ruleMap, composing) => {
|
|
20241
20794
|
for (const [, rule] of ruleMap) {
|
|
@@ -20275,9 +20828,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20275
20828
|
const a0 = rulesArgs[0];
|
|
20276
20829
|
const a1 = rulesArgs[1];
|
|
20277
20830
|
const optExpr = a0?.type === "ObjectExpression" ? a0 : a1?.type === "ObjectExpression" ? a1 : void 0;
|
|
20278
|
-
|
|
20279
|
-
if (!triviaValue) return void 0;
|
|
20280
|
-
return evaluateExpr(triviaValue, scope, code, []) ?? void 0;
|
|
20831
|
+
return triviaOption(optExpr, "compose() element");
|
|
20281
20832
|
};
|
|
20282
20833
|
const composingTrivia = (elements) => {
|
|
20283
20834
|
for (let i = elements.length - 1; i >= 0; i--) {
|
|
@@ -20304,6 +20855,8 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20304
20855
|
}
|
|
20305
20856
|
const elements = arr.elements;
|
|
20306
20857
|
const cOptions = init.arguments[1];
|
|
20858
|
+
if (cOptions !== void 0 && cOptions.type !== "ObjectExpression") unevaluable(cOptions.start, "compose() options");
|
|
20859
|
+
assertPlainOptions(cOptions, "compose()");
|
|
20307
20860
|
const cHostModeValue = optionProp(cOptions, "hostMode");
|
|
20308
20861
|
const cHostMode = cHostModeValue?.type === "Literal" ? cHostModeValue.value : void 0;
|
|
20309
20862
|
if (cHostModeValue !== void 0 && cHostMode !== "ast" && cHostMode !== "cst") {
|
|
@@ -20316,15 +20869,25 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20316
20869
|
for (let i = 0; i < elements.length; i++) {
|
|
20317
20870
|
const r = argPieces(elements[i], `compose${init.start}_${i}`, composing);
|
|
20318
20871
|
if (!r) {
|
|
20872
|
+
const el = elements[i];
|
|
20873
|
+
const name = el.type === "Identifier" ? el.name : void 0;
|
|
20874
|
+
const why = name === void 0 ? void 0 : unresolvedCompiled.get(name);
|
|
20875
|
+
if (why !== void 0) {
|
|
20876
|
+
throw new Error(
|
|
20877
|
+
`${id}:${lineOf(init.start)} \u2014 compose(): argument ${i} (\`${name}\` from '${importBindings.get(name)?.source}') is a build-compiled grammar whose carried pieces could not be resolved: ${why}. A runtime compose() cannot link a build-compiled grammar, so this would throw at import. The usual cause is a bundler rewriting the upstream module (inlining or renaming an ancestor grammar it composes, or reprinting its carried-pieces literal); keep upstream grammar packages external to the bundle.`
|
|
20878
|
+
);
|
|
20879
|
+
}
|
|
20319
20880
|
warn(init.start, `compose(): argument ${i} isn't a build-resolvable grammar; falling back to runtime`);
|
|
20320
20881
|
return null;
|
|
20321
20882
|
}
|
|
20322
20883
|
carried.push(...r.carried);
|
|
20323
20884
|
importedFactories.push(...r.importedFactories ?? []);
|
|
20324
20885
|
}
|
|
20325
|
-
const merged = mergedCarriedRules(carried
|
|
20886
|
+
const merged = mergedCarriedRules(carried, {
|
|
20887
|
+
trivia: composing,
|
|
20888
|
+
...cHostMode ? { hostMode: cHostMode } : {}
|
|
20889
|
+
});
|
|
20326
20890
|
if (merged !== null) {
|
|
20327
|
-
if (composing) applyComposingTrivia(merged.rules, composing);
|
|
20328
20891
|
collectBuilderImports(merged.rules);
|
|
20329
20892
|
const refusals = [];
|
|
20330
20893
|
const compiled = compileRuleMap(merged.rules, {
|
|
@@ -20519,11 +21082,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20519
21082
|
if (d.id.type === "Identifier") {
|
|
20520
21083
|
const varName = d.id.name;
|
|
20521
21084
|
if (!referencesAny(init, allNames, scope)) {
|
|
20522
|
-
|
|
20523
|
-
if (staticValue !== null && staticValue !== void 0 || isStaticNullishExpression(init)) {
|
|
20524
|
-
;
|
|
20525
|
-
scope.set(varName, staticValue);
|
|
20526
|
-
}
|
|
21085
|
+
deferredLocals.set(varName, init);
|
|
20527
21086
|
continue;
|
|
20528
21087
|
}
|
|
20529
21088
|
if (refNames.has(varName)) {
|
|
@@ -20610,6 +21169,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20610
21169
|
continue;
|
|
20611
21170
|
}
|
|
20612
21171
|
const mapFnSources = [];
|
|
21172
|
+
unresolvedImports.clear();
|
|
20613
21173
|
const parser2 = evaluateExpr(init, scope, code, mapFnSources);
|
|
20614
21174
|
if (parser2 === null) {
|
|
20615
21175
|
const wordFactory = evaluateWordFactory(init, scope, code);
|
|
@@ -20642,6 +21202,7 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20642
21202
|
if (exportPrefix) exportedFactories.push({ name: varName, pos: init.start });
|
|
20643
21203
|
continue;
|
|
20644
21204
|
}
|
|
21205
|
+
if (unresolvedImports.size > 0) unevaluable(init.start, `"${varName}"`);
|
|
20645
21206
|
warn(init.start, `"${varName}" references a parseman macro import but isn't a statically-evaluable combinator`);
|
|
20646
21207
|
continue;
|
|
20647
21208
|
}
|
|
@@ -20654,7 +21215,8 @@ function transformMacroImpl(code, id, moduleAliases, warnUnloweredRegex, recover
|
|
|
20654
21215
|
replacements.push({
|
|
20655
21216
|
start: init.start,
|
|
20656
21217
|
end: init.end,
|
|
20657
|
-
replacement: compiled.inlineExpression
|
|
21218
|
+
replacement: compiled.inlineExpression,
|
|
21219
|
+
carry: { name: varName, combi: parser2, exported: exportPrefix !== "" }
|
|
20658
21220
|
});
|
|
20659
21221
|
scope.set(varName, { combi: parser2, mfSrcs: mapFnSources });
|
|
20660
21222
|
} else if (d.id.type === "ObjectPattern") {
|
|
@@ -20721,37 +21283,58 @@ ${which}
|
|
|
20721
21283
|
Drop the \`export\`. The factory is macro-only; \`rules(${exportedFactories[0].name})\` is lowered in place and needs no runtime value.`
|
|
20722
21284
|
);
|
|
20723
21285
|
}
|
|
21286
|
+
const withCombinatorIR = (r) => {
|
|
21287
|
+
if (!r.carry || !r.carry.exported && !referencedNames().live.has(r.carry.name)) return r;
|
|
21288
|
+
let ir = null;
|
|
21289
|
+
try {
|
|
21290
|
+
ir = serializeCombinator(r.carry.combi);
|
|
21291
|
+
} catch {
|
|
21292
|
+
}
|
|
21293
|
+
return ir === null ? r : {
|
|
21294
|
+
...r,
|
|
21295
|
+
replacement: `/* @__PURE__ */ Object.defineProperty(${r.replacement}, Symbol.for('${COMBINATOR_IR_KEY}'), { value: ${JSON.stringify(ir)}, enumerable: false })`
|
|
21296
|
+
};
|
|
21297
|
+
};
|
|
20724
21298
|
const ms = new MagicString(code);
|
|
20725
21299
|
const replacementRanges = runtimeComposeFallback ? [] : replacements.map(({ start, end }) => ({ start, end }));
|
|
20726
21300
|
const isInsideReplacement = (start, end) => replacementRanges.some((r) => start >= r.start && end <= r.end);
|
|
20727
|
-
|
|
20728
|
-
|
|
20729
|
-
|
|
21301
|
+
let referenced = null;
|
|
21302
|
+
const referencedNames = () => {
|
|
21303
|
+
if (referenced !== null) return referenced;
|
|
21304
|
+
const all = /* @__PURE__ */ new Set();
|
|
21305
|
+
const live = /* @__PURE__ */ new Set();
|
|
21306
|
+
const deadRanges = [...[...factoryDecls.values()].filter((f) => !f.imported).map((f) => f.fn), ...anyUnresolved ? [] : defineRemovals];
|
|
21307
|
+
const walk = (node2, inFactory, parent, parentKey) => {
|
|
21308
|
+
if (!node2 || typeof node2 !== "object") return;
|
|
20730
21309
|
const rec = node2;
|
|
20731
|
-
if (rec.type === "ImportDeclaration") return
|
|
20732
|
-
if (typeof rec.start === "number" && typeof rec.end === "number"
|
|
20733
|
-
|
|
20734
|
-
|
|
20735
|
-
|
|
20736
|
-
|
|
20737
|
-
|
|
21310
|
+
if (rec.type === "ImportDeclaration") return;
|
|
21311
|
+
if (typeof rec.start === "number" && typeof rec.end === "number") {
|
|
21312
|
+
if (isInsideReplacement(rec.start, rec.end)) return;
|
|
21313
|
+
inFactory ||= deadRanges.some((f) => rec.start >= f.start && rec.end <= f.end);
|
|
21314
|
+
}
|
|
21315
|
+
if (rec.type === "Identifier" || rec.type === "BindingIdentifier") {
|
|
21316
|
+
const isKey = parentKey === "key" && (parent?.type === "ObjectProperty" || parent?.type === "Property" || parent?.type === "PropertyDefinition") && parent.computed !== true;
|
|
21317
|
+
const isMember = parentKey === "property" && (parent?.type === "StaticMemberExpression" || parent?.type === "MemberExpression" && parent.computed !== true);
|
|
21318
|
+
const isDeclared = parentKey === "id" && parent?.type === "VariableDeclarator";
|
|
21319
|
+
if (!isKey && !isMember && !isDeclared) {
|
|
21320
|
+
all.add(rec.name);
|
|
21321
|
+
if (!inFactory) live.add(rec.name);
|
|
21322
|
+
}
|
|
21323
|
+
return;
|
|
20738
21324
|
}
|
|
20739
21325
|
for (const key of Object.keys(rec)) {
|
|
20740
21326
|
if (key === "type" || key === "start" || key === "end") continue;
|
|
20741
21327
|
const value = rec[key];
|
|
20742
|
-
if (Array.isArray(value))
|
|
20743
|
-
|
|
20744
|
-
} else if (walk(value, rec, key)) {
|
|
20745
|
-
return true;
|
|
20746
|
-
}
|
|
21328
|
+
if (Array.isArray(value)) for (const child of value) walk(child, inFactory, rec, key);
|
|
21329
|
+
else walk(value, inFactory, rec, key);
|
|
20747
21330
|
}
|
|
20748
|
-
return false;
|
|
20749
21331
|
};
|
|
20750
|
-
|
|
21332
|
+
for (const stmt of body) walk(stmt, false);
|
|
21333
|
+
return referenced = { all, live };
|
|
20751
21334
|
};
|
|
20752
21335
|
for (const imp of ordinaryImports) {
|
|
20753
21336
|
if (!runtimeComposeFallback && imp.specifiers.length > 0 && imp.specifiers.every(
|
|
20754
|
-
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !
|
|
21337
|
+
(spec) => spec.type === "ImportSpecifier" && usedImportedFactories.has(spec.local) && !referencedNames().all.has(spec.local)
|
|
20755
21338
|
)) {
|
|
20756
21339
|
ms.remove(imp.start, imp.end);
|
|
20757
21340
|
}
|
|
@@ -20768,7 +21351,7 @@ ${which}
|
|
|
20768
21351
|
ms.overwrite(imp.start, imp.end, stripped);
|
|
20769
21352
|
}
|
|
20770
21353
|
}
|
|
20771
|
-
const applied = runtimeComposeFallback ? [] : replacements;
|
|
21354
|
+
const applied = runtimeComposeFallback ? [] : replacements.map((r) => withCombinatorIR(r));
|
|
20772
21355
|
for (const { start, end, replacement } of applied.slice().sort((a, b) => b.start - a.start)) {
|
|
20773
21356
|
ms.overwrite(start, end, replacement);
|
|
20774
21357
|
}
|