refactor: track all the 'prior types' of a type as types are installed
These are exactly the types that might match before the given type, and hence which require to have their template instantiations defined when an instantiation with the given type is made.
This commit is contained in:
parent
883a351aa8
commit
d4a4d8f331
@ -31,6 +31,13 @@ export default class PocomathInstance {
|
||||
*/
|
||||
this.Types = {any: anySpec, T: anySpec}
|
||||
this._subtypes = {} // For each type, gives all of its (in)direct subtypes
|
||||
/* The following gives for each type, a set of all types that could
|
||||
* match in typed-function's dispatch algorithm before the given type.
|
||||
* This is important because if we instantiate a template, we must
|
||||
* instantiate it for all prior types as well, or else the wrong instance
|
||||
* might match.
|
||||
*/
|
||||
this._priorTypes = {}
|
||||
this._usedTypes = new Set() // all types that have occurred in a signature
|
||||
this._doomed = new Set() // for detecting circular reference
|
||||
this._config = {predictable: false}
|
||||
@ -170,7 +177,12 @@ export default class PocomathInstance {
|
||||
const mod = await import(modName)
|
||||
this.install(mod)
|
||||
} catch (err) {
|
||||
// No such module, but that's OK
|
||||
if (!(err.message.includes('find'))) {
|
||||
// Not just a error because module doesn't exist
|
||||
// So take it seriously
|
||||
throw err
|
||||
}
|
||||
// We don't care if a module doesn't exist, so merely proceed
|
||||
}
|
||||
}
|
||||
doneSet.add(name)
|
||||
@ -235,6 +247,7 @@ export default class PocomathInstance {
|
||||
}
|
||||
this._typed.addTypes([{name: type, test: testFn}], beforeType)
|
||||
this.Types[type] = spec
|
||||
this._priorTypes[type] = new Set()
|
||||
/* Now add conversions to this type */
|
||||
for (const from in (spec.from || {})) {
|
||||
if (from in this.Types) {
|
||||
@ -243,6 +256,7 @@ export default class PocomathInstance {
|
||||
while (nextSuper) {
|
||||
this._typed.addConversion(
|
||||
{from, to: nextSuper, convert: spec.from[from]})
|
||||
this._priorTypes[nextSuper].add(from)
|
||||
nextSuper = this.Types[nextSuper].refines
|
||||
}
|
||||
}
|
||||
@ -261,21 +275,24 @@ export default class PocomathInstance {
|
||||
to: nextSuper,
|
||||
convert: this.Types[to].from[type]
|
||||
})
|
||||
this._priorTypes[nextSuper].add(type)
|
||||
nextSuper = this.Types[nextSuper].refines
|
||||
}
|
||||
}
|
||||
}
|
||||
if (spec.refines) {
|
||||
this._typed.addConversion(
|
||||
{from: type, to: spec.refines, convert: x => x})
|
||||
}
|
||||
// Update all the subtype sets of supertypes up the chain, and
|
||||
// while we are at it add trivial conversions from subtypes to supertypes
|
||||
// to help typed-function match signatures properly:
|
||||
this._subtypes[type] = new Set()
|
||||
// Update all the subtype sets of supertypes up the chain:
|
||||
let nextSuper = spec.refines
|
||||
while (nextSuper) {
|
||||
this._typed.addConversion(
|
||||
{from: type, to: nextSuper, convert: x => x})
|
||||
this._priorTypes[nextSuper].add(type)
|
||||
this._subtypes[nextSuper].add(type)
|
||||
nextSuper = this.Types[nextSuper].refines
|
||||
}
|
||||
|
||||
// rebundle anything that uses the new type:
|
||||
this._invalidateDependents(':' + type)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user