parseman 0.61.1 → 0.61.2
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 +3 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +33 -11
- 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 +30 -13
- package/src/version.ts +1 -1
package/dist/table/index.js
CHANGED
package/dist/version.d.ts
CHANGED
|
@@ -13,5 +13,5 @@
|
|
|
13
13
|
* Kept in sync with `package.json` by `test/unit/version-sync.test.ts`, which fails
|
|
14
14
|
* the build if this constant drifts from the published version.
|
|
15
15
|
*/
|
|
16
|
-
export declare const PARSEMAN_VERSION = "0.61.
|
|
16
|
+
export declare const PARSEMAN_VERSION = "0.61.2";
|
|
17
17
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
package/src/plugin/index.ts
CHANGED
|
@@ -184,7 +184,9 @@ export type AssemblyProfile = {
|
|
|
184
184
|
/** The rule each corpus file is parsed from, e.g. `'Stylesheet'`. A grammar
|
|
185
185
|
* without this rule keeps the static ranking. */
|
|
186
186
|
readonly entry: string
|
|
187
|
-
/** Paths of representative inputs.
|
|
187
|
+
/** Paths of representative inputs. At least one must have content, and each that
|
|
188
|
+
* does has to parse in full without recovery, or the build fails. A file with only
|
|
189
|
+
* whitespace counts as empty. */
|
|
188
190
|
readonly files: readonly string[]
|
|
189
191
|
}
|
|
190
192
|
|
|
@@ -2376,29 +2378,44 @@ function transformMacroImpl(
|
|
|
2376
2378
|
return sites
|
|
2377
2379
|
}
|
|
2378
2380
|
/** Measured site calls over the optional corpus, or `undefined` for the static
|
|
2379
|
-
* ranking. A
|
|
2381
|
+
* ranking. A corpus that cannot run fails the build: a static ranking standing in
|
|
2382
|
+
* for the measured one configured is a slower parser that nothing reports. */
|
|
2380
2383
|
const profileOf = (compiled: CompiledRuleMapTable): Int32Array | undefined => {
|
|
2381
2384
|
// Only the default AST/no-lines table carries an assembly, so only it is profiled.
|
|
2382
2385
|
if (assemblyProfile === undefined || compiled.hostMode !== 'ast' || compiled.prog.lines === 1
|
|
2383
2386
|
|| !(assemblyProfile.entry in compiled.prog.rules)) return undefined
|
|
2384
|
-
|
|
2387
|
+
const refuse = (why: string): never => { throw new Error(`${id} — assemblyProfile: ${why}`) }
|
|
2388
|
+
if (corpusTexts(assemblyProfile).every(text => text.trim() === '')) refuse('`files` has no non-empty file')
|
|
2389
|
+
let thrower: unknown
|
|
2385
2390
|
// A builder re-lowered from carried IR is inert at build time; for COUNTING
|
|
2386
2391
|
// only, a plain node stands in for it, so the corpus can run past it.
|
|
2387
2392
|
const fns = compiled.prog.fns.map(fn => {
|
|
2388
2393
|
const type = (fn as { [INERT_BUILDER]?: string } | null)?.[INERT_BUILDER]
|
|
2389
|
-
|
|
2390
|
-
|
|
2394
|
+
if (type !== undefined) return (children: unknown, _fields: unknown, span: unknown) => ({ type, span, children })
|
|
2395
|
+
return typeof fn !== 'function' ? fn : new Proxy(fn, {
|
|
2396
|
+
apply(target, self, args) {
|
|
2397
|
+
try { return Reflect.apply(target, self, args) as unknown } catch (e) { thrower ??= target; throw e }
|
|
2398
|
+
},
|
|
2399
|
+
})
|
|
2391
2400
|
})
|
|
2392
|
-
|
|
2401
|
+
return countSiteVisits(compiled.prog, rules => {
|
|
2393
2402
|
const entry = rules[assemblyProfile.entry]!
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2403
|
+
corpusTexts(assemblyProfile).forEach((text, i) => {
|
|
2404
|
+
const file = assemblyProfile.files[i]!
|
|
2405
|
+
if (text.trim() === '') return
|
|
2406
|
+
let result
|
|
2407
|
+
try { result = run(entry, text) } catch (e) {
|
|
2408
|
+
const source = String(thrower).replace(/\s+/g, ' ').slice(0, 200)
|
|
2409
|
+
throw new Error(`${id} — assemblyProfile: ${thrower === undefined ? 'the parse' : `gate or reducer \`${source}\``} threw on ${file}: ${String(e)}`, { cause: e })
|
|
2410
|
+
}
|
|
2411
|
+
if (!result.ok || result.unconsumedFrom !== null) {
|
|
2412
|
+
refuse(`${file} does not parse from rule "${assemblyProfile.entry}": it stops at offset ${result.ok ? result.unconsumedFrom : result.span.end}`)
|
|
2413
|
+
}
|
|
2414
|
+
if (result.errors.length > 0) {
|
|
2415
|
+
refuse(`${file} parses only by recovering from ${result.errors.length} error(s), first at offset ${result.errors[0]!.span.start}`)
|
|
2416
|
+
}
|
|
2417
|
+
})
|
|
2397
2418
|
}, fns)
|
|
2398
|
-
if (parsed > 0) return counts
|
|
2399
|
-
// Not `warn()`: nothing fell back to the interpreter — the build is only untuned.
|
|
2400
|
-
warnings.push(`${id} — assemblyProfile: no corpus file parsed from rule "${assemblyProfile.entry}"; using the static ranking`)
|
|
2401
|
-
return undefined
|
|
2402
2419
|
}
|
|
2403
2420
|
/** The fused table's replacement, with its selective default assembly if any. */
|
|
2404
2421
|
const assembledReplacement = (compiled: CompiledRuleMapTable, metadata: string, select: ReadonlySet<number>): string =>
|
package/src/version.ts
CHANGED