diff --git a/implementations/javascript/packages/schema/src/compiler/genunconverter.ts b/implementations/javascript/packages/schema/src/compiler/genunconverter.ts index a8259e0..9a9065d 100644 --- a/implementations/javascript/packages/schema/src/compiler/genunconverter.ts +++ b/implementations/javascript/packages/schema/src/compiler/genunconverter.ts @@ -1,10 +1,7 @@ import { refPosition } from '../reader'; import * as M from '../meta'; -import { block, brackets, formatItems, Item, parens, seq } from './block'; +import { block, brackets, Item, parens, seq } from './block'; import { FunctionContext } from "./context"; -import { FieldType, SimpleType } from '../type'; -import { typeFor, typeForIntersection } from '../gentype'; -import { renderType } from "./rendertype"; export function unconverterForDefinition( ctx: FunctionContext, @@ -17,17 +14,16 @@ export function unconverterForDefinition( ... [def.pattern0, def.pattern1, ... def.patternN].map(p => seq(`case `, JSON.stringify(p.variantLabel), `: `, ctx.block(() => { const hasValueField = p.pattern._variant === 'SimplePattern'; - return [seq(`return `, unconverterForPattern( + return [seq(`return `, unconverterFor( ctx, p.pattern, hasValueField ? `${src}.value` : src))]; })))))]; case 'and': { const ps = [def.pattern0, def.pattern1, ... def.patternN]; - const t = typeForIntersection(ctx.mod.resolver(), ps); const cs = ps.flatMap(p => { if (p._variant === 'anonymous' && p.value._variant === 'SimplePattern') { return []; } else { - return [unconverterForNamed(ctx, p, src, t)]; + return [unconverterForNamed(ctx, p, src)]; } }); return [seq(`return `, (cs.length === 1) @@ -35,31 +31,11 @@ export function unconverterForDefinition( : seq(`_.merge`, parens(`(a, b) => (a === b) ? a : void 0`, ... cs)))]; } case 'Pattern': - return [seq(`return `, unconverterForPattern(ctx, def.value, `${src}`))]; + return [seq(`return `, unconverterFor(ctx, def.value, `${src}`))]; } } -function unconverterForPattern(ctx: FunctionContext, a: M.Pattern, src: string): Item -{ - return unconverterFor(ctx, a, src, typeFor(ctx.mod.resolver(), a)); -} - -function stepSource( - src: string, - t: SimpleType, - key: string): { steppedSrc: string, steppedType: FieldType } -{ - if (t.kind !== 'record' || !t.fields.has(key)) { - throw new Error( - `Internal error: attempt to step type ${JSON.stringify(t)} with key ${key}`); - } - return { - steppedSrc: `${src}[${JSON.stringify(key)}]`, - steppedType: t.fields.get(key)! - }; -} - -function unconverterFor(ctx: FunctionContext, p: M.Pattern, src: string, t: SimpleType): Item { +function unconverterFor(ctx: FunctionContext, p: M.Pattern, src: string): Item { switch (p._variant) { case 'SimplePattern': return ((p: M.SimplePattern) => { @@ -91,82 +67,77 @@ function unconverterFor(ctx: FunctionContext, p: M.Pattern, src: string, t: Simp switch (p._variant) { case 'rec': return seq(`_.Record`, parens( - unconverterForNamed(ctx, p.label, src, t), - unconverterForNamed(ctx, p.fields, src, t))); + unconverterForNamed(ctx, p.label, src), + unconverterForNamed(ctx, p.fields, src))); case 'tuple': return brackets(... p.patterns.map(pp => - unconverterForNamed(ctx, pp, src, t))); + unconverterForNamed(ctx, pp, src))); case 'tuple*': { let varexp: Item; if (p.variable._variant === 'named') { - const { steppedSrc, steppedType } = - stepSource(src, t, p.variable.value.name.description!); - if (steppedType.kind !== 'array') { - throw new Error( - `Internal error: attempt to visit element type of ` + - `${formatItems([renderType(steppedType)])} after ` + - `stepping by key ${p.variable.value.name.description!}`); - } + const steppedSrc = stepSource(src, p.variable.value.name.description!); varexp = seq(steppedSrc, `.map`, parens( seq(`v => `, unconverterFor( ctx, M.Pattern.SimplePattern(p.variable.value.pattern), - `v`, - steppedType.type)))); + `v`)))); } else { - if (t.kind !== 'array') throw new Error("Internal error"); varexp = seq(src, `.map`, parens( seq(`v => `, unconverterFor( ctx, M.Pattern.SimplePattern(p.variable.value), - `v`, - t.type)))); + `v`)))); } if (p.fixed.length === 0) { return varexp; } else { return brackets( - ... p.fixed.map(pp => unconverterForNamed(ctx, pp, src, t)), + ... p.fixed.map(pp => unconverterForNamed(ctx, pp, src)), seq(`... `, varexp)); } } case 'setof': return seq(`new _.Set<_embedded>`, parens( `_.Array.from(${src}.values()).map(v => `, - unconverterFor(ctx, M.Pattern.SimplePattern(p.pattern), 'v', t), + unconverterFor(ctx, M.Pattern.SimplePattern(p.pattern), 'v'), `)`)); case 'dictof': return seq(`new _.Dictionary<_embedded>`, parens(seq( `_.Array.from(${src}.entries()).map(([k, v]) => `, brackets( - unconverterFor(ctx, M.Pattern.SimplePattern(p.key), 'k', t), - unconverterFor(ctx, M.Pattern.SimplePattern(p.value), 'v', t)), + unconverterFor(ctx, M.Pattern.SimplePattern(p.key), 'k'), + unconverterFor(ctx, M.Pattern.SimplePattern(p.value), 'v')), `)`))); case 'dict': return seq(`new _.Dictionary<_embedded>`, parens( brackets(... Array.from(p.entries.entries()).map(([k, n]) => brackets( ctx.mod.literal(k), - unconverterForNamedSimple(ctx, M.addNameIfAbsent(n, k), src, t)))))); + unconverterForNamedSimple(ctx, M.addNameIfAbsent(n, k), src)))))); } })(p.value); } } -function unconverterForNamed(ctx: FunctionContext, p: M.NamedPattern, src: string, t: SimpleType): Item { +function stepSource(src: string, key: string): string +{ + return `${src}[${JSON.stringify(key)}]`; +} + +function unconverterForNamed(ctx: FunctionContext, p: M.NamedPattern, src: string): Item { if (p._variant === 'named') { - const { steppedSrc, steppedType } = stepSource(src, t, p.value.name.description!); - return unconverterFor(ctx, M.Pattern.SimplePattern(p.value.pattern), steppedSrc, steppedType); + const steppedSrc = stepSource(src, p.value.name.description!); + return unconverterFor(ctx, M.Pattern.SimplePattern(p.value.pattern), steppedSrc); } else { - return unconverterFor(ctx, p.value, src, t); + return unconverterFor(ctx, p.value, src); } } -function unconverterForNamedSimple(ctx: FunctionContext, p: M.NamedSimplePattern, src: string, t: SimpleType): Item { +function unconverterForNamedSimple(ctx: FunctionContext, p: M.NamedSimplePattern, src: string): Item { if (p._variant === 'named') { - const { steppedSrc, steppedType } = stepSource(src, t, p.value.name.description!); - return unconverterFor(ctx, M.Pattern.SimplePattern(p.value.pattern), steppedSrc, steppedType); + const steppedSrc = stepSource(src, p.value.name.description!); + return unconverterFor(ctx, M.Pattern.SimplePattern(p.value.pattern), steppedSrc); } else { - return unconverterFor(ctx, M.Pattern.SimplePattern(p.value), src, t); + return unconverterFor(ctx, M.Pattern.SimplePattern(p.value), src); } }