preserves/implementations/javascript/packages/schema/src/compiler/genctor.ts

56 lines
2.0 KiB
TypeScript

import * as M from '../meta';
import { block, braces, Item, parens, seq } from "./block";
import { FieldType, SimpleType, Type } from "./type";
import { renderType } from "./rendertype";
import { ModuleContext, buildProduct } 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) && (arg.kind !== 'unit');
}
const initializers = formals.map(([n, _t]) => ({ fieldName: n, sourceExpr: 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 `,
(simpleValue
? 'value'
: buildProduct(definitionName, variant, 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)})`],
)))),
];
}