Refactor type.ts
This commit is contained in:
parent
c8b752a73b
commit
1c07573178
|
@ -3,6 +3,24 @@ import * as M from "../meta";
|
|||
import { anglebrackets, braces, Item, keyvalue, opseq, seq } from "./block";
|
||||
import { ModuleContext, variantFor, variantInitFor } from "./context";
|
||||
|
||||
export function typeForDefinition(mod: ModuleContext, d: M.Definition): Item {
|
||||
if (d.label === M.$or) {
|
||||
return opseq('never', ' | ', ... d[0].map(a => typeForAlternative(mod, a[1], a[0])));
|
||||
} else {
|
||||
return typeForAlternative(mod, d, void 0);
|
||||
}
|
||||
}
|
||||
|
||||
function typeForAlternative(mod: ModuleContext, a: M.Alternative, variantName: string | undefined): Item {
|
||||
if (a.label === M.$and) {
|
||||
return opseq('_val', ' & ',
|
||||
... variantName === void 0 ? [] : [braces(variantFor(variantName))],
|
||||
...a[0].map(p => typeFor(mod, M.unname(p))));
|
||||
} else {
|
||||
return typeFor(mod, a, variantName);
|
||||
}
|
||||
}
|
||||
|
||||
export function typeFor(mod: ModuleContext, p: M.Pattern, variantName?: string): Item {
|
||||
let typeItem: Item;
|
||||
|
||||
|
@ -68,14 +86,6 @@ function typeForSimple(mod: ModuleContext, p: M.SimplePattern): Item {
|
|||
}
|
||||
}
|
||||
|
||||
function typeField(mod: ModuleContext, n: M.NamedPattern): Item[] {
|
||||
return (n.label === M.$named)
|
||||
? [keyvalue(n[0].description!, typeForSimple(mod, n[1]))]
|
||||
: (M.isCompoundPattern(n)
|
||||
? typeForCompound(mod, n)
|
||||
: []);
|
||||
}
|
||||
|
||||
function typeForCompound(mod: ModuleContext, p: M.CompoundPattern): Item[] {
|
||||
switch (p.label) {
|
||||
case M.$rec:
|
||||
|
@ -92,40 +102,19 @@ function typeForCompound(mod: ModuleContext, p: M.CompoundPattern): Item[] {
|
|||
}
|
||||
case M.$setof:
|
||||
case M.$dictof:
|
||||
return [];
|
||||
throw new Error('Internal error: setof and dictof are handled in typeFor()');
|
||||
case M.$dict:
|
||||
return Array.from(p[0]).flatMap(([k, n]) => {
|
||||
if (n.label === M.$named) {
|
||||
return typeField(mod, n);
|
||||
} else {
|
||||
const s = M.namelike(k);
|
||||
if (s !== void 0) {
|
||||
return [keyvalue(s, typeForSimple(mod, n))];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
});
|
||||
return Array.from(p[0]).flatMap(([k, n]) => typeField(mod, M.addNameIfAbsent(n, k)));
|
||||
default:
|
||||
((_p: never) => {})(p);
|
||||
throw new Error("Unreachable");
|
||||
}
|
||||
}
|
||||
|
||||
export function typeForDefinition(mod: ModuleContext, d: M.Definition): Item {
|
||||
if (d.label === M.$or) {
|
||||
return opseq('never', ' | ', ... d[0].map(a => typeForAlternative(mod, a[1], a[0])));
|
||||
} else {
|
||||
return typeForAlternative(mod, d, void 0);
|
||||
}
|
||||
}
|
||||
|
||||
function typeForAlternative(mod: ModuleContext, a: M.Alternative, variantName: string | undefined): Item {
|
||||
if (a.label === M.$and) {
|
||||
return opseq('_val', ' & ',
|
||||
... variantName === void 0 ? [] : [braces(variantFor(variantName))],
|
||||
...a[0].map(p => typeFor(mod, M.unname(p))));
|
||||
} else {
|
||||
return typeFor(mod, a, variantName);
|
||||
}
|
||||
function typeField(mod: ModuleContext, n: M.NamedPattern): Item[] {
|
||||
return (n.label === M.$named)
|
||||
? [keyvalue(n[0].description!, typeForSimple(mod, n[1]))]
|
||||
: (M.isCompoundPattern(n)
|
||||
? typeForCompound(mod, n)
|
||||
: []);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue