Refactor recursive build mechanism
This commit is contained in:
parent
5b359dbbfe
commit
2d938dd309
11 changed files with 153 additions and 105 deletions
|
@ -1,6 +1,69 @@
|
|||
export class RecursiveBuildFilter {
|
||||
constructor(glyphIdFilter) {
|
||||
this.glyphIdFilter = glyphIdFilter;
|
||||
}
|
||||
glyphIsNeeded(id) {
|
||||
return this.glyphIdFilter.has(id);
|
||||
}
|
||||
}
|
||||
|
||||
export class DependencyManager {
|
||||
constructor() {
|
||||
this.glyphToGlyph = new WeakMap();
|
||||
this.glyphToBlock = new WeakMap();
|
||||
}
|
||||
addDependency(dependent, dependency) {
|
||||
let s = this.glyphToGlyph.get(dependent);
|
||||
if (!s) {
|
||||
s = new Set();
|
||||
this.glyphToGlyph.set(dependent, s);
|
||||
}
|
||||
s.add(dependency);
|
||||
}
|
||||
traverseDependencies(glyphs) {
|
||||
let state = new Map();
|
||||
const PENDING = 1,
|
||||
CHECKED = 2;
|
||||
for (const glyph of glyphs) state.set(glyph, PENDING);
|
||||
|
||||
for (;;) {
|
||||
let found = false;
|
||||
for (const [glyph, s] of state) {
|
||||
if (s !== PENDING) continue;
|
||||
const deps = this.glyphToGlyph.get(glyph);
|
||||
if (deps) {
|
||||
for (const g of deps) state.set(g, PENDING);
|
||||
found = true;
|
||||
}
|
||||
state.set(glyph, CHECKED);
|
||||
}
|
||||
if (!found) break;
|
||||
}
|
||||
|
||||
let glyphIdFilter = new Set();
|
||||
for (const g of state.keys()) {
|
||||
if (g.identifier) glyphIdFilter.add(g.identifier);
|
||||
}
|
||||
return new RecursiveBuildFilter(glyphIdFilter);
|
||||
}
|
||||
}
|
||||
|
||||
export class GlyphBlockExecState {
|
||||
constructor() {
|
||||
this.currentBlockName = null;
|
||||
this.dependencyManager = new DependencyManager();
|
||||
}
|
||||
setGlyphToBlockDependency(glyph) {
|
||||
if (this.currentBlockName) {
|
||||
this.dependencyManager.glyphToBlock.set(glyph, this.currentBlockName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class GlyphBlock {
|
||||
constructor(capture, blockName, body) {
|
||||
constructor(capture, execState, blockName, body) {
|
||||
this.capture = capture;
|
||||
this.execState = execState;
|
||||
this.blockName = blockName;
|
||||
this.body = body;
|
||||
this.resolved = false;
|
||||
|
@ -8,6 +71,10 @@ export class GlyphBlock {
|
|||
}
|
||||
resolve() {
|
||||
if (this.resolved) return this.exports;
|
||||
|
||||
const prevBlockName = this.execState.currentBlockName;
|
||||
this.execState.currentBlockName = this.blockName;
|
||||
|
||||
this.resolved = true;
|
||||
const pendingApplications = [];
|
||||
const ExportCapture = fnObj => {
|
||||
|
@ -19,6 +86,8 @@ export class GlyphBlock {
|
|||
};
|
||||
this.body(this.capture, ExportCapture);
|
||||
for (const f of pendingApplications) f();
|
||||
|
||||
this.execState.currentBlockName = prevBlockName;
|
||||
return this.exports;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue