parseman 0.61.3 → 0.61.4
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/diagnostics.js +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/index.js +1 -1
- package/dist/plugin/index.d.ts +22 -3
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +49 -23
- package/dist/plugin/index.js.map +1 -1
- package/dist/table/index.js +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/plugin/index.ts +76 -23
- package/src/version.ts +1 -1
package/dist/cli/index.js
CHANGED
package/dist/index.js
CHANGED
package/dist/plugin/index.d.ts
CHANGED
|
@@ -83,13 +83,29 @@ export type ParsecraftPluginOptions = {
|
|
|
83
83
|
};
|
|
84
84
|
/** A corpus a build parses to rank selective-assembly sites — see `assemblyProfile`. */
|
|
85
85
|
export type AssemblyProfile = {
|
|
86
|
-
/** The rule each corpus file is parsed from, e.g. `'Stylesheet'`. A grammar
|
|
87
|
-
*
|
|
86
|
+
/** The rule each corpus file is parsed from, e.g. `'Stylesheet'`. A grammar without
|
|
87
|
+
* this rule keeps the static ranking. A build fails when grammars were profiled and
|
|
88
|
+
* none has the rule. A direct `transformMacro` caller gets `assemblyProfile:
|
|
89
|
+
* 'no-entry'` on the result instead, and has to read it. */
|
|
88
90
|
readonly entry: string;
|
|
89
91
|
/** Paths of representative inputs. At least one must have content, and each that
|
|
90
92
|
* does has to parse in full without recovery, or the build fails. A file with only
|
|
91
|
-
* whitespace counts as empty.
|
|
93
|
+
* whitespace counts as empty. A callback the corpus doesn't reach is never run, so
|
|
94
|
+
* nothing checks it. */
|
|
92
95
|
readonly files: readonly string[];
|
|
96
|
+
/**
|
|
97
|
+
* The values of names a grammar's reducers and gates import, for the corpus run.
|
|
98
|
+
* Their source runs at build time with no module around it, so a grammar whose
|
|
99
|
+
* callbacks read imported helpers passes those helpers here. See
|
|
100
|
+
* `docs/guide/macro-mode.md` for what this does and doesn't cover.
|
|
101
|
+
*
|
|
102
|
+
* It's one flat namespace, so two modules can't bind one name to different helpers.
|
|
103
|
+
* A name that's already a global fails the build. A helper named like a global and
|
|
104
|
+
* left out of `scope` silently uses the global. A direct `node()` builder doesn't
|
|
105
|
+
* run in the corpus run: a plain node stands in for it, so a helper only a builder
|
|
106
|
+
* reads is neither needed here nor checked.
|
|
107
|
+
*/
|
|
108
|
+
readonly scope?: Readonly<Record<string, unknown>>;
|
|
93
109
|
};
|
|
94
110
|
declare const _default: import("unplugin").UnpluginInstance<ParsecraftPluginOptions, boolean>;
|
|
95
111
|
export default _default;
|
|
@@ -98,6 +114,9 @@ export type TransformMacroResult = {
|
|
|
98
114
|
map: ReturnType<MagicString['generateMap']>;
|
|
99
115
|
/** Diagnostics for macro-referencing shapes that fell back to the interpreter. */
|
|
100
116
|
warnings: string[];
|
|
117
|
+
/** With an `assemblyProfile`: `'ran'` when a grammar here parsed the corpus,
|
|
118
|
+
* `'no-entry'` when the grammars that could have don't have its `entry` rule. */
|
|
119
|
+
assemblyProfile?: 'ran' | 'no-entry';
|
|
101
120
|
/** The sites the module's `assemblyBudget` bought, by program offset, in rank order. */
|
|
102
121
|
assemblySites: number[];
|
|
103
122
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AA0BA,OAAO,WAAW,MAAM,cAAc,CAAA;AActC,OAAO,EAAsC,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAA;AA6BxF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AACzE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAAE,CAAA;AAChH,kDAAkD;AAClD,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC,MAAM,EAAE,eAAe,EAAE,CAAC,CAAA;AACxD,eAAO,MAAM,sBAAsB,mBAAmB,CAAA;AAQtD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD;AA+BD,MAAM,MAAM,uBAAuB,GAAG;IACpC,8DAA8D;IAC9D,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;8CAC0C;IAC1C,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB,CAAA;AAED,wFAAwF;AACxF,MAAM,MAAM,eAAe,GAAG;IAC5B;;;gEAG4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB;;;4BAGwB;IACxB,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC;;;;;;;;;;;OAWG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAA;CACnD,CAAA;;;AA4lBD,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC,CAAA;IAC3C,kFAAkF;IAClF,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB;qFACiF;IACjF,eAAe,CAAC,EAAE,KAAK,GAAG,UAAU,CAAA;IACpC,wFAAwF;IACxF,aAAa,EAAE,MAAM,EAAE,CAAA;CACxB,CAAA;AA0CD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,EACV,aAAa,cAA6B,EAC1C,kBAAkB,UAAQ,EAC1B,QAAQ,UAAQ,EAChB,eAAe,UAAQ,EACvB,eAAe,CAAC,EAAE,eAAe,EACjC,cAAc,SAA0B,EACxC,WAAW,CAAC,EAAE,WAAW,GACxB,oBAAoB,GAAG,IAAI,CAW7B"}
|
package/dist/plugin/index.js
CHANGED
|
@@ -5622,7 +5622,7 @@ function sourceLeaf(root, fn) {
|
|
|
5622
5622
|
}
|
|
5623
5623
|
|
|
5624
5624
|
// src/version.ts
|
|
5625
|
-
var PARSEMAN_VERSION = "0.61.
|
|
5625
|
+
var PARSEMAN_VERSION = "0.61.4";
|
|
5626
5626
|
|
|
5627
5627
|
// src/table/lex-body.ts
|
|
5628
5628
|
function buildLexBodyRecognizer(spec, constants) {
|
|
@@ -23293,6 +23293,7 @@ async function emitCarriedSidecars(sinks, bundle) {
|
|
|
23293
23293
|
var SIDECAR_FRAMEWORKS = /* @__PURE__ */ new Set(["rollup", "rolldown", "vite"]);
|
|
23294
23294
|
var plugin_default = createUnplugin((opts = {}, meta) => {
|
|
23295
23295
|
const sinks = SIDECAR_FRAMEWORKS.has(meta.framework) ? /* @__PURE__ */ new Map() : void 0;
|
|
23296
|
+
const profiled = /* @__PURE__ */ new Map();
|
|
23296
23297
|
const generateBundle = sinks === void 0 ? void 0 : {
|
|
23297
23298
|
generateBundle: {
|
|
23298
23299
|
order: "post",
|
|
@@ -23311,8 +23312,15 @@ var plugin_default = createUnplugin((opts = {}, meta) => {
|
|
|
23311
23312
|
transformInclude(id) {
|
|
23312
23313
|
return /\.[jt]sx?$/.test(id) && !id.includes("node_modules");
|
|
23313
23314
|
},
|
|
23315
|
+
buildEnd(error) {
|
|
23316
|
+
if (error) return;
|
|
23317
|
+
const ids = [...this.getModuleIds?.() ?? profiled.keys()].filter((id) => profiled.has(id));
|
|
23318
|
+
if (ids.length === 0 || ids.some((id) => profiled.get(id) === "ran")) return;
|
|
23319
|
+
throw new Error(`assemblyProfile: no grammar has rule "${opts.assemblyProfile?.entry}", so the corpus never ran (${ids.join(", ")})`);
|
|
23320
|
+
},
|
|
23314
23321
|
transform(code, id) {
|
|
23315
23322
|
sinks?.delete(id);
|
|
23323
|
+
profiled.delete(id);
|
|
23316
23324
|
if (!code.includes("parseman")) return null;
|
|
23317
23325
|
if (!code.includes("macro")) return null;
|
|
23318
23326
|
for (const file of opts.assemblyProfile?.files ?? []) this?.addWatchFile?.(file);
|
|
@@ -23320,6 +23328,7 @@ var plugin_default = createUnplugin((opts = {}, meta) => {
|
|
|
23320
23328
|
const sink = sinks && /* @__PURE__ */ new Map();
|
|
23321
23329
|
const result = transformMacro(code, id, moduleAliases, opts.warnUnloweredRegex === true, opts.recovery === true, opts.grammarCoverage === true, opts.assemblyProfile, opts.assemblyBudget, sink);
|
|
23322
23330
|
if (sinks && sink && sink.size > 0) sinks.set(id, sink);
|
|
23331
|
+
if (result?.assemblyProfile !== void 0) profiled.set(id, result.assemblyProfile);
|
|
23323
23332
|
if (result?.warnings.length) {
|
|
23324
23333
|
for (const w of result.warnings) {
|
|
23325
23334
|
if (typeof this?.warn === "function") this.warn(`[parseman] ${w}`);
|
|
@@ -24384,8 +24393,14 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
24384
24393
|
assemblySites.push(...sites);
|
|
24385
24394
|
return sites;
|
|
24386
24395
|
};
|
|
24396
|
+
let profileOutcome;
|
|
24387
24397
|
const profileOf = (compiled) => {
|
|
24388
|
-
if (assemblyProfile === void 0 || compiled.hostMode !== "ast" || compiled.prog.lines === 1
|
|
24398
|
+
if (assemblyProfile === void 0 || compiled.hostMode !== "ast" || compiled.prog.lines === 1) return void 0;
|
|
24399
|
+
if (!(assemblyProfile.entry in compiled.prog.rules)) {
|
|
24400
|
+
profileOutcome ??= "no-entry";
|
|
24401
|
+
return void 0;
|
|
24402
|
+
}
|
|
24403
|
+
profileOutcome = "ran";
|
|
24389
24404
|
const refuse = (why) => {
|
|
24390
24405
|
throw new Error(`${id} \u2014 assemblyProfile: ${why}`);
|
|
24391
24406
|
};
|
|
@@ -24405,26 +24420,36 @@ ${names.map((n) => ` - ${n}`).join("\n")}` : " (it is not a static combinator/v
|
|
|
24405
24420
|
}
|
|
24406
24421
|
});
|
|
24407
24422
|
});
|
|
24408
|
-
|
|
24409
|
-
|
|
24410
|
-
|
|
24411
|
-
|
|
24412
|
-
|
|
24413
|
-
|
|
24414
|
-
|
|
24415
|
-
|
|
24416
|
-
|
|
24417
|
-
|
|
24418
|
-
|
|
24419
|
-
|
|
24420
|
-
|
|
24421
|
-
|
|
24422
|
-
|
|
24423
|
-
|
|
24424
|
-
|
|
24425
|
-
|
|
24426
|
-
|
|
24427
|
-
|
|
24423
|
+
const scope3 = assemblyProfile.scope ?? {};
|
|
24424
|
+
const names = Object.keys(scope3);
|
|
24425
|
+
for (const name of names) {
|
|
24426
|
+
if (name in globalThis) refuse(`\`scope\` name "${name}" is already a global; a callback couldn't tell which one it reads`);
|
|
24427
|
+
}
|
|
24428
|
+
try {
|
|
24429
|
+
for (const name of names) Object.defineProperty(globalThis, name, { value: scope3[name], configurable: true });
|
|
24430
|
+
return countSiteVisits(compiled.prog, (rules3) => {
|
|
24431
|
+
const entry = rules3[assemblyProfile.entry];
|
|
24432
|
+
corpusTexts(assemblyProfile).forEach((text, i) => {
|
|
24433
|
+
const file = assemblyProfile.files[i];
|
|
24434
|
+
if (text.trim() === "") return;
|
|
24435
|
+
let result2;
|
|
24436
|
+
try {
|
|
24437
|
+
result2 = run(entry, text);
|
|
24438
|
+
} catch (e) {
|
|
24439
|
+
const source = String(thrower).replace(/\s+/g, " ").slice(0, 200);
|
|
24440
|
+
throw new Error(`${id} \u2014 assemblyProfile: ${thrower === void 0 ? "the parse" : `gate or reducer \`${source}\``} threw on ${file}: ${String(e)}`, { cause: e });
|
|
24441
|
+
}
|
|
24442
|
+
if (!result2.ok || result2.unconsumedFrom !== null) {
|
|
24443
|
+
refuse(`${file} does not parse from rule "${assemblyProfile.entry}": it stops at offset ${result2.ok ? result2.unconsumedFrom : result2.span.end}`);
|
|
24444
|
+
}
|
|
24445
|
+
if (result2.errors.length > 0) {
|
|
24446
|
+
refuse(`${file} parses only by recovering from ${result2.errors.length} error(s), first at offset ${result2.errors[0].span.start}`);
|
|
24447
|
+
}
|
|
24448
|
+
});
|
|
24449
|
+
}, fns);
|
|
24450
|
+
} finally {
|
|
24451
|
+
for (const name of names) Reflect.deleteProperty(globalThis, name);
|
|
24452
|
+
}
|
|
24428
24453
|
};
|
|
24429
24454
|
const assembledReplacement = (compiled, metadata, select) => select.size === 0 ? compiled.replacementWithMetadata(metadata) : supercompileRuleMapReplacement(compiled.prog, compiled.replacementWithMetadata(metadata, { select }), select);
|
|
24430
24455
|
const compileComposeLeafCall = (init) => {
|
|
@@ -24937,7 +24962,8 @@ ${lines2.join("\n")}`);
|
|
|
24937
24962
|
assemblySites: applied.length > 0 ? assemblySites : [],
|
|
24938
24963
|
code: ms.toString(),
|
|
24939
24964
|
map: ms.generateMap({ hires: true }),
|
|
24940
|
-
warnings
|
|
24965
|
+
warnings,
|
|
24966
|
+
...profileOutcome === void 0 ? {} : { assemblyProfile: profileOutcome }
|
|
24941
24967
|
};
|
|
24942
24968
|
}
|
|
24943
24969
|
export {
|