2023-01-25 13:42:23 +00:00
|
|
|
import "reflect-metadata"
|
|
|
|
import { reflect, type CallSite } from 'typescript-rtti'
|
|
|
|
|
2022-12-06 17:10:18 +00:00
|
|
|
/* A Dispatcher is a collection of operations that do run-time
|
|
|
|
* dispatch on the types of their arguments. Thus, every individual
|
|
|
|
* method is like a typed-function (from the library by that name),
|
|
|
|
* but they can depend on one another and on ona another's implementations
|
|
|
|
* for specific types (including their own).
|
|
|
|
*/
|
|
|
|
|
2022-12-07 01:21:05 +00:00
|
|
|
// First helper types and functions for the Dispatcher
|
|
|
|
|
2022-12-06 17:10:18 +00:00
|
|
|
type TypeName = string
|
|
|
|
type Parameter = TypeName
|
|
|
|
type Signature = Parameter[]
|
2023-01-22 01:34:57 +00:00
|
|
|
type DependenciesType = Record<string, Function>
|
2022-12-06 17:10:18 +00:00
|
|
|
|
2023-01-22 01:34:57 +00:00
|
|
|
// A "canned" dependency for a builtin function:
|
2022-12-06 17:10:18 +00:00
|
|
|
export type typeOfDependency = {typeOf: (x: unknown) => TypeName}
|
|
|
|
|
2023-01-22 01:34:57 +00:00
|
|
|
// Utility needed in type definitions
|
2022-12-06 17:10:18 +00:00
|
|
|
//dummy implementation for now
|
|
|
|
export function joinTypes(a: TypeName, b: TypeName) {
|
|
|
|
if (a === b) return a
|
|
|
|
return 'any'
|
|
|
|
}
|
|
|
|
|
2022-12-07 01:21:05 +00:00
|
|
|
// Now types used in the Dispatcher class itself
|
2022-12-06 17:10:18 +00:00
|
|
|
|
|
|
|
type TypeSpecification = {
|
|
|
|
before?: TypeName[],
|
|
|
|
test: ((x: unknown) => boolean)
|
|
|
|
| ((d: DependenciesType) => (x: unknown) => boolean),
|
2022-12-07 01:21:05 +00:00
|
|
|
from: Record<TypeName, Function>,
|
2022-12-06 17:10:18 +00:00
|
|
|
infer?: (d: DependenciesType) => (z: unknown) => TypeName
|
|
|
|
}
|
|
|
|
|
|
|
|
type SpecObject = Record<string, Function | TypeSpecification>
|
2022-12-07 01:21:05 +00:00
|
|
|
type SpecificationsGroup = Record<string, SpecObject>
|
2022-12-06 17:10:18 +00:00
|
|
|
|
|
|
|
export class Dispatcher {
|
|
|
|
installSpecification(
|
|
|
|
name: string,
|
|
|
|
signature: Signature,
|
2022-12-07 01:21:05 +00:00
|
|
|
returns: TypeName,
|
2022-12-06 17:10:18 +00:00
|
|
|
dependencies: Record<string, Signature>,
|
|
|
|
behavior: Function // possible todo: constrain this type based
|
|
|
|
// on the signature, return type, and dependencies. Not sure if
|
|
|
|
// that's really possible, though.
|
|
|
|
) {
|
|
|
|
console.log('Pretending to install', name, signature, '=>', returns)
|
2023-01-25 13:42:23 +00:00
|
|
|
|
|
|
|
// @ts-ignore
|
|
|
|
console.log(name, 'signature', reflect(signature))
|
|
|
|
console.log(name, 'dependencies', reflect(dependencies))
|
2022-12-06 17:10:18 +00:00
|
|
|
//TODO: implement me
|
|
|
|
}
|
|
|
|
installType(name: TypeName, typespec: TypeSpecification) {
|
|
|
|
console.log('Pretending to install type', name, typespec)
|
|
|
|
//TODO: implement me
|
|
|
|
}
|
|
|
|
constructor(collection: SpecificationsGroup) {
|
2022-12-07 01:21:05 +00:00
|
|
|
for (const key in collection) {
|
2022-12-06 17:10:18 +00:00
|
|
|
console.log('Working on', key)
|
2022-12-07 01:21:05 +00:00
|
|
|
for (const identifier in collection[key]) {
|
2022-12-06 17:10:18 +00:00
|
|
|
console.log('Handling', key, ':', identifier)
|
|
|
|
const parts = identifier.split('_')
|
|
|
|
if (parts[parts.length - 1] === 'type') {
|
|
|
|
parts.pop()
|
|
|
|
const name = parts.join('_')
|
2022-12-07 01:21:05 +00:00
|
|
|
this.installType(
|
|
|
|
name, collection[key][identifier] as TypeSpecification)
|
2022-12-06 17:10:18 +00:00
|
|
|
} else {
|
|
|
|
const name = parts[0]
|
2022-12-07 01:21:05 +00:00
|
|
|
this.installSpecification(
|
|
|
|
name, ['dunno'], 'unsure', {},
|
|
|
|
collection[key][identifier] as Function)
|
2022-12-06 17:10:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|