2021-05-24 10:05:02 +00:00
|
|
|
import { SimpleType, Type } from "./type";
|
2021-03-18 10:15:10 +00:00
|
|
|
import { anglebrackets, braces, Item, keyvalue, opseq, seq } from "./block";
|
2021-10-11 10:56:53 +00:00
|
|
|
import { ModuleContext } from "./context";
|
2021-03-18 10:15:10 +00:00
|
|
|
|
2021-03-19 22:42:43 +00:00
|
|
|
export function variantInitFor(variantName: string | undefined) : Item[] {
|
|
|
|
return variantName === void 0 ? [] : [variantFor(variantName)];
|
|
|
|
}
|
2021-03-18 10:15:10 +00:00
|
|
|
|
2021-03-19 22:42:43 +00:00
|
|
|
export function variantFor(variantName: string): Item {
|
|
|
|
return keyvalue('_variant', JSON.stringify(variantName));
|
2021-03-18 10:15:10 +00:00
|
|
|
}
|
|
|
|
|
2022-01-22 22:25:16 +00:00
|
|
|
function simpleTypeFields(ctxt: ModuleContext, baseType: Type, t: SimpleType): Item[] {
|
2021-03-19 22:42:43 +00:00
|
|
|
switch (t.kind) {
|
|
|
|
case 'unit':
|
2022-01-22 22:25:16 +00:00
|
|
|
return [];
|
2021-03-19 22:42:43 +00:00
|
|
|
case 'ref':
|
|
|
|
case 'set':
|
|
|
|
case 'dictionary':
|
|
|
|
case 'array':
|
2022-01-22 22:25:16 +00:00
|
|
|
return [keyvalue('value', renderType(ctxt, t))];
|
2021-03-19 22:42:43 +00:00
|
|
|
case 'record':
|
2022-01-22 22:25:16 +00:00
|
|
|
return Array.from(t.fields).map(([nn, tt]) => keyvalue(nn, renderType(ctxt, tt)));
|
2021-03-18 10:15:10 +00:00
|
|
|
default:
|
2021-03-19 22:42:43 +00:00
|
|
|
((_: never) => {})(t);
|
2021-03-18 10:15:10 +00:00
|
|
|
throw new Error("Unreachable");
|
|
|
|
}
|
2022-01-22 22:25:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export function renderVariant(
|
|
|
|
ctxt: ModuleContext,
|
|
|
|
baseType: Type,
|
|
|
|
[variantName, t]: [string, SimpleType],
|
|
|
|
): Item {
|
|
|
|
let fields = simpleTypeFields(ctxt, baseType, t);
|
2021-03-19 22:42:43 +00:00
|
|
|
return braces(variantFor(variantName), ... fields);
|
2021-03-18 10:15:10 +00:00
|
|
|
}
|
|
|
|
|
2021-10-11 10:56:53 +00:00
|
|
|
export function renderType(ctxt: ModuleContext, t: Type): Item {
|
2021-03-19 22:42:43 +00:00
|
|
|
switch (t.kind) {
|
|
|
|
case 'union': return opseq('never', ' | ', ...
|
2022-01-22 22:25:16 +00:00
|
|
|
Array.from(t.variants).flatMap(entry => renderVariant(ctxt, t, entry)));
|
|
|
|
case 'unit': return braces(... simpleTypeFields(ctxt, t, t));
|
2021-10-11 10:56:53 +00:00
|
|
|
case 'ref':
|
|
|
|
if (t.ref === null && t.typeName === '_embedded') {
|
|
|
|
return t.typeName;
|
|
|
|
} else {
|
|
|
|
return seq(t.typeName, ctxt.genericArgsFor(t));
|
|
|
|
}
|
2021-03-19 22:42:43 +00:00
|
|
|
case 'set': return seq('_.KeyedSet', anglebrackets(
|
2021-10-11 10:56:53 +00:00
|
|
|
renderType(ctxt, t.type),
|
2021-05-17 12:54:06 +00:00
|
|
|
'_embedded'));
|
2021-03-19 22:42:43 +00:00
|
|
|
case 'dictionary': return seq('_.KeyedDictionary', anglebrackets(
|
2021-10-11 10:56:53 +00:00
|
|
|
renderType(ctxt, t.key),
|
|
|
|
renderType(ctxt, t.value),
|
2021-05-17 12:54:06 +00:00
|
|
|
'_embedded'));
|
2021-10-11 10:56:53 +00:00
|
|
|
case 'array': return seq('Array', anglebrackets(renderType(ctxt, t.type)));
|
2022-01-22 22:25:16 +00:00
|
|
|
case 'record': return braces(... simpleTypeFields(ctxt, t, t));
|
2021-03-18 10:15:10 +00:00
|
|
|
default:
|
2021-03-19 22:42:43 +00:00
|
|
|
((_: never) => {})(t);
|
2021-03-18 10:15:10 +00:00
|
|
|
throw new Error("Unreachable");
|
|
|
|
}
|
|
|
|
}
|