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

48 lines
1.6 KiB
TypeScript

import * as M from '../meta';
import { block, braces, Item, keyvalue, parens, seq } from "./block";
import { FieldType, SimpleType } from "../type";
import { renderType } from "./rendertype";
export function genConstructor(
name: string,
variant: string | undefined,
arg: SimpleType,
resultType: 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(f[1])))))]
: formals.map(f => seq(M.jsId(f[0]), ': ', renderType(f[1])));
return seq(`export function ${M.jsId(name)}`,
parens(... declArgs),
': ', resultType, ' ', block(
seq(`return `,
((arg.kind === 'unit' && initializers.length === 0)
? 'null'
: (simpleValue
? 'value'
: braces(... initializers))))));
}