Take advantage of new static info propagated by schema compiler

This commit is contained in:
Tony Garnock-Jones 2022-01-24 09:08:56 +01:00
parent 6f07bfafae
commit faca72d6b3
2 changed files with 12 additions and 16 deletions

View File

@ -83,7 +83,7 @@ function stringifyId(i: Identifier): Items {
return [ { ... i, type: TokenType.STRING, text: JSON.stringify(i.text) } ]; return [ { ... i, type: TokenType.STRING, text: JSON.stringify(i.text) } ];
} }
function binderTypeGuard(ctx: ExpansionContext, t: TemplateFunction): (binder: Binder, index: number) => Items { function binderTypeGuard(t: TemplateFunction): (binder: Binder, index: number) => Items {
return (binder, index) => { return (binder, index) => {
if (binder.id.text[0] === '_') { if (binder.id.text[0] === '_') {
return t`${`/* Ignoring underscore-prefixed binder ${binder.id.text} */`}`; return t`${`/* Ignoring underscore-prefixed binder ${binder.id.text} */`}`;
@ -103,10 +103,12 @@ function binderTypeGuard(ctx: ExpansionContext, t: TemplateFunction): (binder: B
return t`if (typeof (${raw}) !== ${JSON.stringify(typeText)}) return;\n${bind}`; return t`if (typeof (${raw}) !== ${JSON.stringify(typeText)}) return;\n${bind}`;
case 'any': case 'any':
return bind; return bind;
default: default: {
ctx.emitError(`Cannot emit guard for binding of type: ${JSON.stringify(typeText)}`, const intermediate = t`__v_${''+index}`;
getRange(binder.type)); return t`const ${intermediate} = ${binder.type}.__from_preserve__(${raw});
return bind; /* act as if "any", for now */ if (${intermediate} === void 0) return;
const ${[binder.id]} = ${intermediate};`;
}
} }
} }
}; };
@ -158,7 +160,7 @@ export function expand(tree: Items, ctx: ExpansionContext): Items {
observer: __SYNDICATE__.Turn.ref(__SYNDICATE__.assertionFacetObserver( observer: __SYNDICATE__.Turn.ref(__SYNDICATE__.assertionFacetObserver(
(${ctx.argDecl(t, '__vs', '__SYNDICATE__.AnyValue')}) => { (${ctx.argDecl(t, '__vs', '__SYNDICATE__.AnyValue')}) => {
if (Array.isArray(__vs)) { if (Array.isArray(__vs)) {
${joinItems(sa.captureBinders.map(binderTypeGuard(ctx, t)), '\n')} ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
${body} ${body}
} }
} }
@ -231,7 +233,7 @@ ${joinItems(sa.captureBinders.map(binderTypeGuard(ctx, t)), '\n')}
const sa = compilePattern(s.pattern); const sa = compilePattern(s.pattern);
const guardBody = (body: Statement) => t`if (Array.isArray(__vs)) { const guardBody = (body: Statement) => t`if (Array.isArray(__vs)) {
${joinItems(sa.captureBinders.map(binderTypeGuard(ctx, t)), '\n')} ${joinItems(sa.captureBinders.map(binderTypeGuard(t)), '\n')}
${body} ${body}
}`; }`;

View File

@ -4,18 +4,12 @@
import { AnyValue, Ref } from './actor.js'; import { AnyValue, Ref } from './actor.js';
import { Pattern, toPattern } from '../gen/dataspacePatterns.js'; import { Pattern, toPattern } from '../gen/dataspacePatterns.js';
import * as P from './pattern.js'; import * as P from './pattern.js';
import { Value, RecordConstructorInfo, is, Record } from '@preserves/core'; import { RecordConstructorInfo, is, Record } from '@preserves/core';
import { Meta, Type, GenType } from '@preserves/schema'; import { Meta, Type, GenType, SchemaDefinition } from '@preserves/schema';
export type DefinitionOrVariantInfo = {
schema: Value,
imports: unknown,
definitionName: symbol,
};
export type QuasiValueConstructorInfo = export type QuasiValueConstructorInfo =
| { constructorInfo: RecordConstructorInfo<AnyValue, Ref> } | { constructorInfo: RecordConstructorInfo<AnyValue, Ref> }
| { schema(): DefinitionOrVariantInfo } | { schema(): SchemaDefinition }
| { quasiValue(... args: QuasiValue[]): QuasiValue } | { quasiValue(... args: QuasiValue[]): QuasiValue }
; ;