Repair quasipattern parameter passing for union types

This commit is contained in:
Tony Garnock-Jones 2022-04-30 14:54:56 +03:00
parent 7668dbb401
commit 5b835dc13a
1 changed files with 15 additions and 6 deletions

View File

@ -101,10 +101,12 @@ export function ctor(info: QuasiValueConstructorInfo, ... items: QuasiValue[]):
const definfo = info.schema();
const schema = Meta.asSchema(definfo.schema);
const def = schema.definitions.get(definfo.definitionName)!;
const defType = GenType.typeForDefinition(r => Type.Type.ref(r.name.description!, null), def);
const defNameStr = definfo.definitionName.description!;
const ctorArgs = items.slice();
let defType = GenType.typeForDefinition(r => Type.Type.ref(r.name.description!, null), def);
// ^ defType is updated when we are facing a variant in a union
function qLiteral(p: Meta.NamedPattern): AnyValue {
if (p._variant === 'anonymous' &&
p.value._variant === 'SimplePattern' &&
@ -213,12 +215,15 @@ export function ctor(info: QuasiValueConstructorInfo, ... items: QuasiValue[]):
function qTopPattern(p: Meta.Pattern): QuasiValue {
switch (p._variant) {
case 'SimplePattern': {
if (ctorArgs.length === 0) {
throw new Error(`Missing argument to ${defNameStr}`);
case 'SimplePattern':
if (defType.kind === 'unit') {
return qSimple(p.value);
} else {
if (ctorArgs.length === 0) {
throw new Error(`Missing argument to ${defNameStr}`);
}
return ctorArgs[0];
}
return ctorArgs[0];
}
case 'CompoundPattern':
return qCompound(p.value);
}
@ -230,8 +235,12 @@ export function ctor(info: QuasiValueConstructorInfo, ... items: QuasiValue[]):
if (variant === void 0) {
throw new Error("Cannot use union definition as pattern");
}
if (defType.kind !== 'union') {
throw new Error(`Non-union type for union definition ${defNameStr}`);
}
for (const p of [def.pattern0, def.pattern1, ...def.patternN]) {
if (p.variantLabel === variant) {
defType = defType.variants.get(variant)!;
return qTopPattern(p.pattern);
}
}