Repair constructor generation; attach schemas
This commit is contained in:
parent
4c0bd3b9d7
commit
7178fb0d9b
|
@ -1,4 +1,5 @@
|
||||||
import { EncodableDictionary, KeyedDictionary, Dictionary, Value, is, Record, Float, Bytes, isEmbedded, isSequence, Set, Atom, Embedded, merge as plainMerge, Preservable, PreserveWritable, _iterMap, stringify } from '@preserves/core';
|
import { EncodableDictionary, KeyedDictionary, Dictionary, Value, is, Record, Float, Bytes, isEmbedded, isSequence, Set, Atom, Embedded, merge as plainMerge, Preservable, PreserveWritable, _iterMap, stringify, fromJS } from '@preserves/core';
|
||||||
|
import { SchemaDefinition } from './reflection';
|
||||||
import * as M from './meta';
|
import * as M from './meta';
|
||||||
import * as H from './host';
|
import * as H from './host';
|
||||||
|
|
||||||
|
@ -15,12 +16,9 @@ export type BindingName = string;
|
||||||
export type Bindings<V> = { [key: BindingName]: Parsed<V> };
|
export type Bindings<V> = { [key: BindingName]: Parsed<V> };
|
||||||
export type TopBindings<V> = Bindings<V> & Top<V>;
|
export type TopBindings<V> = Bindings<V> & Top<V>;
|
||||||
|
|
||||||
export type SingleConstructor<V> = (input: any) => Parsed<V>;
|
export type SingleConstructor<V> = ((input: any) => Parsed<V>) & { schema(): SchemaDefinition };
|
||||||
export type MultipleConstructors<V> = { [key: string]: SingleConstructor<V> };
|
export type MultipleConstructors<V> = { [key: string]: SingleConstructor<V> };
|
||||||
export type DefinitionConstructors<V> =
|
export type DefinitionConstructors<V> = SingleConstructor<V> | MultipleConstructors<V>;
|
||||||
| { single: SingleConstructor<V> }
|
|
||||||
| { multiple: MultipleConstructors<V> }
|
|
||||||
;
|
|
||||||
|
|
||||||
export namespace Bindings {
|
export namespace Bindings {
|
||||||
export function empty<V>(): Bindings<V> {
|
export function empty<V>(): Bindings<V> {
|
||||||
|
@ -111,14 +109,18 @@ export class SchemaInterpreter<V> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_lookup<R>(modulePath: M.ModulePath, name: symbol, f: (d: M.Definition<V>) => R): R {
|
_lookup<R>(
|
||||||
|
modulePath: M.ModulePath,
|
||||||
|
name: symbol,
|
||||||
|
f: (d: M.Definition<V>, schema: M.Schema<V>) => R,
|
||||||
|
): R {
|
||||||
const { resolved, schema } = this._findModule(modulePath);
|
const { resolved, schema } = this._findModule(modulePath);
|
||||||
return this._withModule(resolved, () => {
|
return this._withModule(resolved, () => {
|
||||||
const definition = schema.definitions.get(name);
|
const definition = schema.definitions.get(name);
|
||||||
if (definition === void 0) {
|
if (definition === void 0) {
|
||||||
throw new Error(`No such preserves-schema definition: ${[... modulePath, name].map(s => s.description!).join('.')}`);
|
throw new Error(`No such preserves-schema definition: ${[... modulePath, name].map(s => s.description!).join('.')}`);
|
||||||
}
|
}
|
||||||
return f(definition);
|
return f(definition, schema);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,7 +136,20 @@ export class SchemaInterpreter<V> {
|
||||||
modulePath: M.ModulePath,
|
modulePath: M.ModulePath,
|
||||||
name: symbol,
|
name: symbol,
|
||||||
): DefinitionConstructors<V> {
|
): DefinitionConstructors<V> {
|
||||||
return this._lookup(modulePath, name, (definition): DefinitionConstructors<V> => {
|
return this._lookup(modulePath, name, (definition, schema): DefinitionConstructors<V> => {
|
||||||
|
function attachSchema(
|
||||||
|
f: (input: any) => Parsed<V>,
|
||||||
|
variant?: symbol,
|
||||||
|
): SingleConstructor<V> {
|
||||||
|
const g = f as SingleConstructor<V>;
|
||||||
|
g.schema = () => ({
|
||||||
|
schema: fromJS(schema),
|
||||||
|
imports: {}, // TODO
|
||||||
|
definitionName: name,
|
||||||
|
variant,
|
||||||
|
});
|
||||||
|
return g;
|
||||||
|
}
|
||||||
const ty = H.definitionType(definition);
|
const ty = H.definitionType(definition);
|
||||||
if (ty._variant === 'union') {
|
if (ty._variant === 'union') {
|
||||||
const multiple: MultipleConstructors<V> = {};
|
const multiple: MultipleConstructors<V> = {};
|
||||||
|
@ -142,27 +157,38 @@ export class SchemaInterpreter<V> {
|
||||||
const _variant = v.label.description!;
|
const _variant = v.label.description!;
|
||||||
switch (v.type._variant) {
|
switch (v.type._variant) {
|
||||||
case 'Field':
|
case 'Field':
|
||||||
multiple[_variant] = (value: any) =>
|
multiple[_variant] = attachSchema(
|
||||||
this.makeTop(modulePath, name, { _variant, value });
|
(value: any) => this.makeTop(modulePath, name, { _variant, value }),
|
||||||
|
v.label);
|
||||||
break;
|
break;
|
||||||
case 'Record':
|
case 'Record':
|
||||||
multiple[_variant] = (fields: object) =>
|
multiple[_variant] = attachSchema(
|
||||||
this.makeTop(modulePath, name, { _variant, ... fields });
|
(fields: object) => this.makeTop(modulePath, name, { _variant, ... fields }),
|
||||||
|
v.label);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return { multiple };
|
return multiple;
|
||||||
} else {
|
} else {
|
||||||
const flatName = M.formatModulePath([... modulePath, name]);
|
const flatName = M.formatModulePath([... modulePath, name]);
|
||||||
switch (ty.value._variant) {
|
switch (ty.value._variant) {
|
||||||
case 'Field': {
|
case 'Field': {
|
||||||
const tmp = { [flatName]: (value: any) => value };
|
const tmp = { [flatName]: (value: any) => value };
|
||||||
return { single: tmp[flatName] };
|
return attachSchema(tmp[flatName]);
|
||||||
}
|
}
|
||||||
case 'Record': {
|
case 'Record': {
|
||||||
const tmp = { [flatName]: (fields: Bindings<V>) =>
|
const rec = ty.value.value;
|
||||||
this.makeTop(modulePath, name, fields) };
|
if (rec.fields.length > 1) {
|
||||||
return { single: tmp[flatName] };
|
const tmp = { [flatName]: (fields: Bindings<V>) =>
|
||||||
|
this.makeTop(modulePath, name, fields) };
|
||||||
|
return attachSchema(tmp[flatName]);
|
||||||
|
} else {
|
||||||
|
const tmp = { [flatName]: (field: Parsed<V>) =>
|
||||||
|
this.makeTop(modulePath, name, {
|
||||||
|
[M.jsId(rec.fields[0].name.description!)]: field,
|
||||||
|
}) };
|
||||||
|
return attachSchema(tmp[flatName]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue