64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
import * as M from '../meta';
|
|
import { block, braces, Item, keyvalue, parens, seq } from "./block";
|
|
import { FieldType, SimpleType, Type } from "./type";
|
|
import { renderType } from "./rendertype";
|
|
import { ModuleContext } from './context';
|
|
|
|
export function genConstructor(
|
|
mod: ModuleContext,
|
|
definitionName: string,
|
|
name: string,
|
|
variant: string | undefined,
|
|
arg: SimpleType,
|
|
resultType: Type,
|
|
resultTypeItem: Item,
|
|
): Item[] {
|
|
const formals: Array<[string, FieldType]> = [];
|
|
let simpleValue = false;
|
|
|
|
function examine(t: FieldType, name: string): void {
|
|
if (t.kind !== 'unit') {
|
|
formals.push([name, t]);
|
|
}
|
|
}
|
|
|
|
if (arg.kind === 'record') {
|
|
arg.fields.forEach(examine);
|
|
} else {
|
|
examine(arg, 'value');
|
|
simpleValue = variant === void 0;
|
|
}
|
|
|
|
const initializers: Item[] = (variant !== void 0)
|
|
? [keyvalue('_variant', JSON.stringify(variant))]
|
|
: [];
|
|
formals.forEach(([n, _t]) => initializers.push(seq(JSON.stringify(n), ': ', M.jsId(n))));
|
|
|
|
const declArgs: Array<Item> = (formals.length > 1)
|
|
? [seq(braces(...formals.map(f => M.jsId(f[0]))), ': ',
|
|
braces(...formals.map(f => seq(M.jsId(f[0]), ': ', renderType(mod, f[1])))))]
|
|
: formals.map(f => seq(M.jsId(f[0]), ': ', renderType(mod, f[1])));
|
|
|
|
return [
|
|
seq(`export function ${M.jsId(name)}`, mod.genericParametersFor(resultType),
|
|
parens(...declArgs),
|
|
': ', resultTypeItem, ' ', block(
|
|
seq(`return `,
|
|
((arg.kind === 'unit' && initializers.length === 0)
|
|
? 'null'
|
|
: (simpleValue
|
|
? 'value'
|
|
: braces(...initializers)))))),
|
|
seq(`${M.jsId(name)}.schema = function () `, block(
|
|
seq(`return `, braces(
|
|
`schema: _schema()`,
|
|
`imports: _imports`,
|
|
`definitionName: _.Symbol.for(${JSON.stringify(definitionName)})`,
|
|
... (variant === void 0) ? [] : [`variant: _.Symbol.for(${JSON.stringify(variant)})`],
|
|
`unparse: from${definitionName}`,
|
|
`parse: to${definitionName}`,
|
|
`cast: as${definitionName}`,
|
|
)))),
|
|
];
|
|
}
|