parseman 0.50.0 → 0.50.1
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 +24 -7
- package/dist/analysis/diagnostics.js.map +1 -1
- package/dist/cli/index.js +24 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/index.js +25 -8
- package/dist/index.js.map +1 -1
- package/dist/plugin/index.js +25 -8
- package/dist/plugin/index.js.map +1 -1
- package/dist/table/encode.d.ts.map +1 -1
- package/dist/table/index.js +24 -7
- package/dist/table/index.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/table/encode.ts +30 -10
- package/src/version.ts +1 -1
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.50.
|
|
16
|
+
export declare const PARSEMAN_VERSION = "0.50.1";
|
|
17
17
|
//# sourceMappingURL=version.d.ts.map
|
package/package.json
CHANGED
package/src/table/encode.ts
CHANGED
|
@@ -145,6 +145,22 @@ class Encoder {
|
|
|
145
145
|
private choiceRollbackMasks = new Map<number, number>()
|
|
146
146
|
private nonCommittingChoiceSites = new Set<number>()
|
|
147
147
|
private failureRollbackCleanSites = new Set<number>()
|
|
148
|
+
/**
|
|
149
|
+
* `hasSideWriter` memo for `failureNeedsRollback`, shared across every call
|
|
150
|
+
* for the lifetime of this `Encoder`. A cached entry is written only when
|
|
151
|
+
* `complete` is true, which means the answer is a path-independent fact
|
|
152
|
+
* about that combinator node — it does not depend on which root's traversal
|
|
153
|
+
* asked, only on the node's own reachable subgraph. Scoping the memo per call
|
|
154
|
+
* (as a local inside `failureNeedsRollback`) was correct but discarded that
|
|
155
|
+
* fact after every arm, so a grammar with many ordered-choice arms / optional
|
|
156
|
+
* / attempt sites re-walked the SAME shared rule graph from scratch for each
|
|
157
|
+
* site — O(sites × graph size) instead of O(graph size). Measured on the
|
|
158
|
+
* scss-parser grammar (composed CSS-base superset, the deepest/largest of the
|
|
159
|
+
* four grammars): 47-50s for one `compileRuleMap` with the per-call memo,
|
|
160
|
+
* versus the whole macro transform completing in under a second once this
|
|
161
|
+
* memo is hoisted here.
|
|
162
|
+
*/
|
|
163
|
+
private sideWriterMemo = new Map<Combinator<unknown>, boolean>()
|
|
148
164
|
labels: readonly string[] | undefined = undefined
|
|
149
165
|
/** Trivia table in scope at the row being encoded — codegen's `ctx.activeTrivia`. */
|
|
150
166
|
activeTrivia: Combinator<unknown> | undefined = undefined
|
|
@@ -633,16 +649,19 @@ class Encoder {
|
|
|
633
649
|
const refName = (p as unknown as { _ruleName?: string })._ruleName
|
|
634
650
|
const winner = refName === undefined ? undefined : this.winners?.[refName]
|
|
635
651
|
const root = winner !== undefined && !winnerWrapsReference(winner, p) ? winner : p
|
|
636
|
-
const sideWriterMemo =
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
652
|
+
const sideWriterMemo = this.sideWriterMemo
|
|
653
|
+
// A single mutable `seen` set threaded through the whole call, rather than
|
|
654
|
+
// copied at every recursion level: this DFS visits children strictly
|
|
655
|
+
// sequentially, so marking `current` in progress before recursing and
|
|
656
|
+
// clearing it once its subtree is fully explored reproduces the exact same
|
|
657
|
+
// ancestor-path membership an immutable copy-per-level would have computed,
|
|
658
|
+
// without the O(depth) allocation on every node.
|
|
659
|
+
const seen = new Set<Combinator<unknown>>()
|
|
660
|
+
const hasSideWriter = (current: Combinator<unknown>): { found: boolean; complete: boolean } => {
|
|
641
661
|
const cached = sideWriterMemo.get(current)
|
|
642
662
|
if (cached !== undefined) return { found: cached, complete: true }
|
|
643
663
|
if (seen.has(current)) return { found: false, complete: false }
|
|
644
|
-
|
|
645
|
-
next.add(current)
|
|
664
|
+
seen.add(current)
|
|
646
665
|
const def = current._def
|
|
647
666
|
let result: { found: boolean; complete: boolean }
|
|
648
667
|
switch (def.tag) {
|
|
@@ -657,10 +676,10 @@ class Encoder {
|
|
|
657
676
|
const name = (current as unknown as { _ruleName?: string })._ruleName
|
|
658
677
|
const resolvedWinner = name === undefined ? undefined : this.winners?.[name]
|
|
659
678
|
if (resolvedWinner !== undefined && !winnerWrapsReference(resolvedWinner, current)) {
|
|
660
|
-
result = hasSideWriter(resolvedWinner
|
|
679
|
+
result = hasSideWriter(resolvedWinner)
|
|
661
680
|
break
|
|
662
681
|
}
|
|
663
|
-
try { result = hasSideWriter(def.thunk()
|
|
682
|
+
try { result = hasSideWriter(def.thunk()) }
|
|
664
683
|
catch { result = { found: true, complete: true } }
|
|
665
684
|
break
|
|
666
685
|
}
|
|
@@ -668,7 +687,7 @@ class Encoder {
|
|
|
668
687
|
let complete = true
|
|
669
688
|
result = { found: false, complete: true }
|
|
670
689
|
for (const child of childrenOf(def)) {
|
|
671
|
-
const childResult = hasSideWriter(child
|
|
690
|
+
const childResult = hasSideWriter(child)
|
|
672
691
|
if (childResult.found) {
|
|
673
692
|
result = { found: true, complete: true }
|
|
674
693
|
break
|
|
@@ -678,6 +697,7 @@ class Encoder {
|
|
|
678
697
|
if (!result.found) result = { found: false, complete }
|
|
679
698
|
}
|
|
680
699
|
}
|
|
700
|
+
seen.delete(current)
|
|
681
701
|
if (result.found || result.complete) sideWriterMemo.set(current, result.found)
|
|
682
702
|
return result
|
|
683
703
|
}
|
package/src/version.ts
CHANGED