diff --git a/implementations/javascript/packages/schema/src/compiler.ts b/implementations/javascript/packages/schema/src/compiler.ts index f052f2f..2e14d65 100644 --- a/implementations/javascript/packages/schema/src/compiler.ts +++ b/implementations/javascript/packages/schema/src/compiler.ts @@ -1,13 +1,14 @@ -import { stringify } from "@preserves/core"; +import { encode, stringify } from "@preserves/core"; import * as M from "./meta"; import { CompilerOptions, ModuleContext } from "./compiler/context"; -import { Formatter, block, seq } from "./compiler/block"; +import { Formatter, block, seq, braces } from "./compiler/block"; import { typeForDefinition } from "./compiler/gentype"; import { converterForDefinition } from "./compiler/genconverter"; import { renderType } from "./compiler/rendertype"; import { genConstructor } from "./compiler/genctor"; import { unconverterForDefinition } from "./compiler/genunconverter"; import { sourceCodeFor } from "./compiler/value"; +import { fromSchema } from "./meta"; export function compile( env: M.Environment, @@ -17,6 +18,12 @@ export function compile( ): string { const mod = new ModuleContext(env, modulePath, schema, options); + mod.definePreamble(`let __schema: _.Value | null = null;`); + mod.definePreamble(seq(`export function _schema() `, block( + seq(`if (__schema === null) `, block( + `__schema = _.decode(_.Bytes.fromHex("${encode(fromSchema(schema)).toHex()}"))`)), + `return __schema`))); + const embeddedName = schema.embeddedType; if (embeddedName._variant !== 'false') { mod.defineType(seq(`export type _embedded = `, mod.embeddedType, `;`)); @@ -34,11 +41,11 @@ export function compile( mod.defineFunctions(_ctx => [seq(`export namespace ${nameStr} `, block( ... Array.from(t.variants).flatMap(([vn, vt]) => - genConstructor(mod, vn, vn, vt, t, resultTypeItem)) + genConstructor(mod, nameStr, vn, vn, vt, t, resultTypeItem)) ))]); } else { mod.defineFunctions(_ctx => - genConstructor(mod, nameStr, void 0, t, t, resultTypeItem)); + genConstructor(mod, nameStr, nameStr, void 0, t, t, resultTypeItem)); } } @@ -68,9 +75,14 @@ export function compile( ctx.block(() => unconverterForDefinition(ctx, def, `_v`)))]); } + mod.definePreamble( + seq(`export const _imports = `, braces(... Array.from(mod.imports.values()).map( + ([modulePath, identifier, _path]) => + seq(stringify(M.formatModulePath(modulePath)), ': ', identifier))))); + const f = new Formatter(); f.write(`import * as _ from ${JSON.stringify(options.preservesModule ?? '@preserves/core')};\n`); - mod.imports.forEach(([identifier, path]) => { + mod.imports.forEach(([_modulePath, identifier, path]) => { f.write(`import * as ${identifier} from ${JSON.stringify(path)};\n`); }); f.newline(); @@ -82,6 +94,13 @@ export function compile( } f.newline(); + mod.preamble.forEach(i => { + f.write(i); + f.newline(); + f.newline(); + }); + f.newline(); + mod.typedefs.forEach(t => { f.write(t); f.newline(); diff --git a/implementations/javascript/packages/schema/src/compiler/context.ts b/implementations/javascript/packages/schema/src/compiler/context.ts index d0451dd..abe26cc 100644 --- a/implementations/javascript/packages/schema/src/compiler/context.ts +++ b/implementations/javascript/packages/schema/src/compiler/context.ts @@ -28,9 +28,10 @@ export class ModuleContext { readonly embeddedType: Item; readonly literals = new Dictionary(); + readonly preamble: Item[] = []; readonly typedefs: Item[] = []; readonly functiondefs: Item[] = []; - readonly imports = new KeyedSet<[string, string]>(); + readonly imports = new KeyedSet<[M.ModulePath, string, string]>(); constructor( env: M.Environment, @@ -71,14 +72,19 @@ export class ModuleContext { p.value._variant === 'SimplePattern' && p.value.value._variant === 'Ref') { - return this.lookup(p.value.value.value, - (p, _t) => this.derefPattern(p, refCount + 1), - (_modId, _modPath, pp, _tt) => this.derefPattern(pp ?? p, refCount + 1)); + return this.lookup( + p.value.value.value, + (p, _t) => this.derefPattern(p, refCount + 1), + (_modPath, _modId, _modFile, pp, _tt) => this.derefPattern(pp ?? p, refCount + 1)); } else { return p; } } + definePreamble(i: Item): void { + this.preamble.push(i); + } + defineType(f: Item): void { this.typedefs.push(f); } @@ -88,38 +94,43 @@ export class ModuleContext { } resolver(modulePath?: M.ModulePath): (ref: M.Ref) => RefType { - return (ref) => this.lookup(ref, - (_p, _t) => Type.ref(ref.name.description!, ref), - (modId, modPath, _p, _t) => { - this.imports.add([modId, modPath]); - return Type.ref(`${modId}.${ref.name.description!}`, ref); - }, - modulePath); + return (ref) => this.lookup( + ref, + (_p, _t) => Type.ref(ref.name.description!, ref), + (modPath, modId, modFile, _p, _t) => { + this.imports.add([modPath, modId, modFile]); + return Type.ref(`${modId}.${ref.name.description!}`, ref); + }, + modulePath); } lookupType(name: M.Ref, modulePath?: M.ModulePath): Type | null { - const t = this.lookup(name, (_p, t) => t, (_modId, _modPath, _p, t) => t, modulePath); + const t = this.lookup(name, (_p, t) => t, (_modPath, _modId, _modFile, _p, t) => t, modulePath); return t ? t() : null; } lookup(name: M.Ref, kLocal: (p: M.Definition, t: () => Type) => R, - kOther: (modId: string, modPath: string, p: M.Definition | null, t: (() => Type) | null) => R, - modulePath?: M.ModulePath): R - { + kOther: (modPath: M.ModulePath, + modId: string, + modFile: string, + p: M.Definition | null, + t: (() => Type) | null) => R, + modulePath?: M.ModulePath) + : R { const soughtModule = name.module.length ? name.module : (modulePath ?? this.modulePath); for (const e of this.env) { if (is(e.schemaModulePath, soughtModule)) { if (e.schema === null) { // It's an artificial module, not from a schema. Assume the identifier is present. - return kOther(M.modsymFor(e), e.typescriptModulePath, null, null); + return kOther(soughtModule, M.modsymFor(e), e.typescriptModulePath, null, null); } else { const p = e.schema.definitions.get(name.name); if (p !== void 0) { let t = () => typeForDefinition(this.resolver(soughtModule), p); if (name.module.length) { - return kOther(M.modsymFor(e), e.typescriptModulePath, p, t); + return kOther(soughtModule, M.modsymFor(e), e.typescriptModulePath, p, t); } else { return kLocal(p, t); } diff --git a/implementations/javascript/packages/schema/src/compiler/genconverter.ts b/implementations/javascript/packages/schema/src/compiler/genconverter.ts index 6da657b..5a427ca 100644 --- a/implementations/javascript/packages/schema/src/compiler/genconverter.ts +++ b/implementations/javascript/packages/schema/src/compiler/genconverter.ts @@ -183,12 +183,13 @@ export function converterForSimple( seq(`break`)]))]; }))]; case 'Ref': - return ctx.mod.lookup(p.value, - (_p, _t) => [`${dest} = to${p.value.name.description!}(${src})`], - (modId, modPath, _p, _t) => { - ctx.mod.imports.add([modId, modPath]); - return [`${dest} = ${modId}.to${p.value.name.description!}(${src})`]; - }); + return ctx.mod.lookup( + p.value, + (_p, _t) => [`${dest} = to${p.value.name.description!}(${src})`], + (modPath, modId, modFile, _p, _t) => { + ctx.mod.imports.add([modPath, modId, modFile]); + return [`${dest} = ${modId}.to${p.value.name.description!}(${src})`]; + }); default: ((_p: never) => {})(p); throw new Error("Unreachable"); diff --git a/implementations/javascript/packages/schema/src/compiler/genctor.ts b/implementations/javascript/packages/schema/src/compiler/genctor.ts index 6feacff..b8b55a8 100644 --- a/implementations/javascript/packages/schema/src/compiler/genctor.ts +++ b/implementations/javascript/packages/schema/src/compiler/genctor.ts @@ -6,6 +6,7 @@ import { ModuleContext } from './context'; export function genConstructor( mod: ModuleContext, + definitionName: string, name: string, variant: string | undefined, arg: SimpleType, @@ -38,13 +39,25 @@ export function genConstructor( braces(...formals.map(f => seq(M.jsId(f[0]), ': ', renderType(mod, f[1])))))] : formals.map(f => seq(M.jsId(f[0]), ': ', renderType(mod, f[1]))); - return [seq(`export function ${M.jsId(name)}`, mod.genericParametersFor(resultType), - parens(...declArgs), - ': ', resultTypeItem, ' ', block( - seq(`return `, - ((arg.kind === 'unit' && initializers.length === 0) - ? 'null' - : (simpleValue - ? 'value' - : braces(...initializers))))))]; + return [ + seq(`export function ${M.jsId(name)}`, mod.genericParametersFor(resultType), + parens(...declArgs), + ': ', resultTypeItem, ' ', block( + seq(`return `, + ((arg.kind === 'unit' && initializers.length === 0) + ? 'null' + : (simpleValue + ? 'value' + : braces(...initializers)))))), + seq(`${M.jsId(name)}.schema = function () `, block( + seq(`return `, braces( + `schema: _schema()`, + `imports: _imports`, + `definitionName: _.Symbol.for(${JSON.stringify(definitionName)})`, + ... (variant === void 0) ? [] : [`variant: _.Symbol.for(${JSON.stringify(variant)})`], + `unparse: from${definitionName}`, + `parse: to${definitionName}`, + `cast: as${definitionName}`, + )))), + ]; } diff --git a/implementations/javascript/packages/schema/src/compiler/genunconverter.ts b/implementations/javascript/packages/schema/src/compiler/genunconverter.ts index 3424b35..fd89548 100644 --- a/implementations/javascript/packages/schema/src/compiler/genunconverter.ts +++ b/implementations/javascript/packages/schema/src/compiler/genunconverter.ts @@ -65,12 +65,13 @@ function unconverterFor(ctx: FunctionContext, p: M.Pattern, src: string): Item { unconverterFor(ctx, M.Pattern.SimplePattern(p.value), 'v')), `)`))); case 'Ref': - return ctx.mod.lookup(p.value, - (_p, _t) => `from${p.value.name.description!}${ctx.mod.genericArgs()}(${src})`, - (modId, modPath, _p, _t) => { - ctx.mod.imports.add([modId, modPath]); - return `${modId}.from${p.value.name.description!}${ctx.mod.genericArgs()}(${src})`; - }); + return ctx.mod.lookup( + p.value, + (_p, _t) => `from${p.value.name.description!}${ctx.mod.genericArgs()}(${src})`, + (modPath, modId, modFile, _p, _t) => { + ctx.mod.imports.add([modPath, modId, modFile]); + return `${modId}.from${p.value.name.description!}${ctx.mod.genericArgs()}(${src})`; + }); } })(p.value); case 'CompoundPattern': diff --git a/implementations/javascript/packages/schema/src/compiler/value.ts b/implementations/javascript/packages/schema/src/compiler/value.ts index b072cbe..3811a20 100644 --- a/implementations/javascript/packages/schema/src/compiler/value.ts +++ b/implementations/javascript/packages/schema/src/compiler/value.ts @@ -12,7 +12,7 @@ export function sourceCodeFor(v: Value): Item { bytes(b: Bytes): Item { return seq(`Uint8Array.from(`, brackets(... Array.from(b).map(b => b.toString())), `)`); }, - symbol(s: symbol): Item { return `Symbol.for(${JSON.stringify(s.description!)})`; }, + symbol(s: symbol): Item { return `_.Symbol.for(${JSON.stringify(s.description!)})`; }, record(r: Record, Tuple>, M.InputEmbedded>, k: Fold): Item { return seq(`_.Record<_.Value<_embedded>, _.Tuple<_.Value<_embedded>>, _embedded>`, parens(k(r.label), brackets(... r.map(k)))); diff --git a/implementations/javascript/packages/schema/src/gen/schema.ts b/implementations/javascript/packages/schema/src/gen/schema.ts index 4367a28..bd26719 100644 --- a/implementations/javascript/packages/schema/src/gen/schema.ts +++ b/implementations/javascript/packages/schema/src/gen/schema.ts @@ -1,35 +1,47 @@ import * as _ from "@preserves/core"; export const $1 = 1; -export const $Boolean = Symbol.for("Boolean"); -export const $ByteString = Symbol.for("ByteString"); -export const $Double = Symbol.for("Double"); -export const $Float = Symbol.for("Float"); -export const $SignedInteger = Symbol.for("SignedInteger"); -export const $String = Symbol.for("String"); -export const $Symbol = Symbol.for("Symbol"); -export const $and = Symbol.for("and"); -export const $any = Symbol.for("any"); -export const $atom = Symbol.for("atom"); -export const $bundle = Symbol.for("bundle"); -export const $definitions = Symbol.for("definitions"); -export const $dict = Symbol.for("dict"); -export const $dictof = Symbol.for("dictof"); -export const $embedded = Symbol.for("embedded"); -export const $embeddedType = Symbol.for("embeddedType"); -export const $lit = Symbol.for("lit"); -export const $named = Symbol.for("named"); -export const $or = Symbol.for("or"); -export const $rec = Symbol.for("rec"); -export const $ref = Symbol.for("ref"); -export const $schema = Symbol.for("schema"); -export const $seqof = Symbol.for("seqof"); -export const $setof = Symbol.for("setof"); -export const $tuple = Symbol.for("tuple"); -export const $tuplePrefix = Symbol.for("tuplePrefix"); -export const $version = Symbol.for("version"); +export const $Boolean = _.Symbol.for("Boolean"); +export const $ByteString = _.Symbol.for("ByteString"); +export const $Double = _.Symbol.for("Double"); +export const $Float = _.Symbol.for("Float"); +export const $SignedInteger = _.Symbol.for("SignedInteger"); +export const $String = _.Symbol.for("String"); +export const $Symbol = _.Symbol.for("Symbol"); +export const $and = _.Symbol.for("and"); +export const $any = _.Symbol.for("any"); +export const $atom = _.Symbol.for("atom"); +export const $bundle = _.Symbol.for("bundle"); +export const $definitions = _.Symbol.for("definitions"); +export const $dict = _.Symbol.for("dict"); +export const $dictof = _.Symbol.for("dictof"); +export const $embedded = _.Symbol.for("embedded"); +export const $embeddedType = _.Symbol.for("embeddedType"); +export const $lit = _.Symbol.for("lit"); +export const $named = _.Symbol.for("named"); +export const $or = _.Symbol.for("or"); +export const $rec = _.Symbol.for("rec"); +export const $ref = _.Symbol.for("ref"); +export const $schema = _.Symbol.for("schema"); +export const $seqof = _.Symbol.for("seqof"); +export const $setof = _.Symbol.for("setof"); +export const $tuple = _.Symbol.for("tuple"); +export const $tuplePrefix = _.Symbol.for("tuplePrefix"); +export const $version = _.Symbol.for("version"); export const __lit6 = false; +let __schema: _.Value | null = null; + +export function _schema() { + if (__schema === null) { + __schema = _.decode(_.Bytes.fromHex("b4b306736368656d61b7b30776657273696f6e91b30b646566696e6974696f6e73b7b303526566b4b303726563b4b3036c6974b30372656684b4b3057475706c65b5b4b3056e616d6564b3066d6f64756c65b4b303726566b584b30a4d6f64756c65506174688484b4b3056e616d6564b3046e616d65b4b30461746f6db30653796d626f6c8484848484b30642756e646c65b4b303726563b4b3036c6974b30662756e646c6584b4b3057475706c65b5b4b3056e616d6564b3076d6f64756c6573b4b303726566b584b3074d6f64756c65738484848484b306536368656d61b4b303726563b4b3036c6974b306736368656d6184b4b3057475706c65b5b4b30464696374b7b30776657273696f6eb4b3056e616d6564b30776657273696f6eb4b303726566b584b30756657273696f6e8484b30b646566696e6974696f6e73b4b3056e616d6564b30b646566696e6974696f6e73b4b303726566b584b30b446566696e6974696f6e738484b30c656d62656464656454797065b4b3056e616d6564b30c656d62656464656454797065b4b303726566b584b310456d626564646564547970654e616d6584848484848484b30742696e64696e67b4b303726563b4b3036c6974b3056e616d656484b4b3057475706c65b5b4b3056e616d6564b3046e616d65b4b30461746f6db30653796d626f6c8484b4b3056e616d6564b3077061747465726eb4b303726566b584b30d53696d706c655061747465726e8484848484b3074d6f64756c6573b4b306646963746f66b4b303726566b584b30a4d6f64756c655061746884b4b303726566b584b306536368656d618484b3075061747465726eb4b3026f72b5b5b10d53696d706c655061747465726eb4b303726566b584b30d53696d706c655061747465726e8484b5b10f436f6d706f756e645061747465726eb4b303726566b584b30f436f6d706f756e645061747465726e84848484b30756657273696f6eb4b3036c69749184b30841746f6d4b696e64b4b3026f72b5b5b107426f6f6c65616eb4b3036c6974b307426f6f6c65616e8484b5b105466c6f6174b4b3036c6974b305466c6f61748484b5b106446f75626c65b4b3036c6974b306446f75626c658484b5b10d5369676e6564496e7465676572b4b3036c6974b30d5369676e6564496e74656765728484b5b106537472696e67b4b3036c6974b306537472696e678484b5b10a42797465537472696e67b4b3036c6974b30a42797465537472696e678484b5b10653796d626f6cb4b3036c6974b30653796d626f6c84848484b30a446566696e6974696f6eb4b3026f72b5b5b1026f72b4b303726563b4b3036c6974b3026f7284b4b3057475706c65b5b4b30b7475706c65507265666978b5b4b3056e616d6564b3087061747465726e30b4b303726566b584b3104e616d6564416c7465726e61746976658484b4b3056e616d6564b3087061747465726e31b4b303726566b584b3104e616d6564416c7465726e6174697665848484b4b3056e616d6564b3087061747465726e4eb4b3057365716f66b4b303726566b584b3104e616d6564416c7465726e61746976658484848484848484b5b103616e64b4b303726563b4b3036c6974b303616e6484b4b3057475706c65b5b4b30b7475706c65507265666978b5b4b3056e616d6564b3087061747465726e30b4b303726566b584b30c4e616d65645061747465726e8484b4b3056e616d6564b3087061747465726e31b4b303726566b584b30c4e616d65645061747465726e848484b4b3056e616d6564b3087061747465726e4eb4b3057365716f66b4b303726566b584b30c4e616d65645061747465726e8484848484848484b5b1075061747465726eb4b303726566b584b3075061747465726e84848484b30a4d6f64756c6550617468b4b3057365716f66b4b30461746f6db30653796d626f6c8484b30b446566696e6974696f6e73b4b306646963746f66b4b30461746f6db30653796d626f6c84b4b303726566b584b30a446566696e6974696f6e8484b30c4e616d65645061747465726eb4b3026f72b5b5b1056e616d6564b4b303726566b584b30742696e64696e678484b5b109616e6f6e796d6f7573b4b303726566b584b3075061747465726e84848484b30d53696d706c655061747465726eb4b3026f72b5b5b103616e79b4b3036c6974b303616e798484b5b10461746f6db4b303726563b4b3036c6974b30461746f6d84b4b3057475706c65b5b4b3056e616d6564b30861746f6d4b696e64b4b303726566b584b30841746f6d4b696e64848484848484b5b108656d626564646564b4b303726563b4b3036c6974b308656d62656464656484b4b3057475706c65b5b4b3056e616d6564b309696e74657266616365b4b303726566b584b30d53696d706c655061747465726e848484848484b5b1036c6974b4b303726563b4b3036c6974b3036c697484b4b3057475706c65b5b4b3056e616d6564b30576616c7565b303616e798484848484b5b1057365716f66b4b303726563b4b3036c6974b3057365716f6684b4b3057475706c65b5b4b3056e616d6564b3077061747465726eb4b303726566b584b30d53696d706c655061747465726e848484848484b5b1057365746f66b4b303726563b4b3036c6974b3057365746f6684b4b3057475706c65b5b4b3056e616d6564b3077061747465726eb4b303726566b584b30d53696d706c655061747465726e848484848484b5b106646963746f66b4b303726563b4b3036c6974b306646963746f6684b4b3057475706c65b5b4b3056e616d6564b3036b6579b4b303726566b584b30d53696d706c655061747465726e8484b4b3056e616d6564b30576616c7565b4b303726566b584b30d53696d706c655061747465726e848484848484b5b103526566b4b303726566b584b30352656684848484b30f436f6d706f756e645061747465726eb4b3026f72b5b5b103726563b4b303726563b4b3036c6974b30372656384b4b3057475706c65b5b4b3056e616d6564b3056c6162656cb4b303726566b584b30c4e616d65645061747465726e8484b4b3056e616d6564b3066669656c6473b4b303726566b584b30c4e616d65645061747465726e848484848484b5b1057475706c65b4b303726563b4b3036c6974b3057475706c6584b4b3057475706c65b5b4b3056e616d6564b3087061747465726e73b4b3057365716f66b4b303726566b584b30c4e616d65645061747465726e84848484848484b5b10b7475706c65507265666978b4b303726563b4b3036c6974b30b7475706c6550726566697884b4b3057475706c65b5b4b3056e616d6564b3056669786564b4b3057365716f66b4b303726566b584b30c4e616d65645061747465726e848484b4b3056e616d6564b3087661726961626c65b4b303726566b584b3124e616d656453696d706c655061747465726e848484848484b5b10464696374b4b303726563b4b3036c6974b3046469637484b4b3057475706c65b5b4b3056e616d6564b307656e7472696573b4b303726566b584b31144696374696f6e617279456e74726965738484848484848484b310456d626564646564547970654e616d65b4b3026f72b5b5b103526566b4b303726566b584b3035265668484b5b10566616c7365b4b3036c69748084848484b3104e616d6564416c7465726e6174697665b4b3057475706c65b5b4b3056e616d6564b30c76617269616e744c6162656cb4b30461746f6db306537472696e678484b4b3056e616d6564b3077061747465726eb4b303726566b584b3075061747465726e84848484b31144696374696f6e617279456e7472696573b4b306646963746f66b303616e79b4b303726566b584b3124e616d656453696d706c655061747465726e8484b3124e616d656453696d706c655061747465726eb4b3026f72b5b5b1056e616d6564b4b303726566b584b30742696e64696e678484b5b109616e6f6e796d6f7573b4b303726566b584b30d53696d706c655061747465726e8484848484b30c656d62656464656454797065808484")); + }; + return __schema; +} + +export const _imports = {} + + export type Bundle<_embedded = _.GenericEmbedded> = {"modules": Modules<_embedded>}; export type Modules<_embedded = _.GenericEmbedded> = _.KeyedDictionary, _embedded>; @@ -130,8 +142,30 @@ export type ModulePath = Array; export function Bundle<_embedded = _.GenericEmbedded>(modules: Modules<_embedded>): Bundle<_embedded> {return {"modules": modules};} +Bundle.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Bundle"), + unparse: fromBundle, + parse: toBundle, + cast: asBundle + }; +} + export function Modules<_embedded = _.GenericEmbedded>(value: _.KeyedDictionary, _embedded>): Modules<_embedded> {return value;} +Modules.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Modules"), + unparse: fromModules, + parse: toModules, + cast: asModules + }; +} + export function Schema<_embedded = _.GenericEmbedded>( {version, embeddedType, definitions}: { version: Version, @@ -142,15 +176,70 @@ export function Schema<_embedded = _.GenericEmbedded>( return {"version": version, "embeddedType": embeddedType, "definitions": definitions}; } +Schema.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Schema"), + unparse: fromSchema, + parse: toSchema, + cast: asSchema + }; +} + export function Version(): Version {return null;} +Version.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Version"), + unparse: fromVersion, + parse: toVersion, + cast: asVersion + }; +} + export namespace EmbeddedTypeName { export function Ref(value: Ref): EmbeddedTypeName {return {"_variant": "Ref", "value": value};}; + Ref.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("EmbeddedTypeName"), + variant: _.Symbol.for("Ref"), + unparse: fromEmbeddedTypeName, + parse: toEmbeddedTypeName, + cast: asEmbeddedTypeName + }; + }; export function $false(): EmbeddedTypeName {return {"_variant": "false"};}; + $false.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("EmbeddedTypeName"), + variant: _.Symbol.for("false"), + unparse: fromEmbeddedTypeName, + parse: toEmbeddedTypeName, + cast: asEmbeddedTypeName + }; + }; } export function Definitions<_embedded = _.GenericEmbedded>(value: _.KeyedDictionary, _embedded>): Definitions<_embedded> {return value;} +Definitions.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Definitions"), + unparse: fromDefinitions, + parse: toDefinitions, + cast: asDefinitions + }; +} + export namespace Definition { export function or<_embedded = _.GenericEmbedded>( {pattern0, pattern1, patternN}: { @@ -166,6 +255,17 @@ export namespace Definition { "patternN": patternN }; }; + or.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Definition"), + variant: _.Symbol.for("or"), + unparse: fromDefinition, + parse: toDefinition, + cast: asDefinition + }; + }; export function and<_embedded = _.GenericEmbedded>( {pattern0, pattern1, patternN}: { pattern0: NamedPattern<_embedded>, @@ -180,68 +280,420 @@ export namespace Definition { "patternN": patternN }; }; + and.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Definition"), + variant: _.Symbol.for("and"), + unparse: fromDefinition, + parse: toDefinition, + cast: asDefinition + }; + }; export function Pattern<_embedded = _.GenericEmbedded>(value: Pattern<_embedded>): Definition<_embedded> {return {"_variant": "Pattern", "value": value};}; + Pattern.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Definition"), + variant: _.Symbol.for("Pattern"), + unparse: fromDefinition, + parse: toDefinition, + cast: asDefinition + }; + }; } export namespace Pattern { export function SimplePattern<_embedded = _.GenericEmbedded>(value: SimplePattern<_embedded>): Pattern<_embedded> {return {"_variant": "SimplePattern", "value": value};}; + SimplePattern.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Pattern"), + variant: _.Symbol.for("SimplePattern"), + unparse: fromPattern, + parse: toPattern, + cast: asPattern + }; + }; export function CompoundPattern<_embedded = _.GenericEmbedded>(value: CompoundPattern<_embedded>): Pattern<_embedded> {return {"_variant": "CompoundPattern", "value": value};}; + CompoundPattern.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Pattern"), + variant: _.Symbol.for("CompoundPattern"), + unparse: fromPattern, + parse: toPattern, + cast: asPattern + }; + }; } export namespace SimplePattern { export function any<_embedded = _.GenericEmbedded>(): SimplePattern<_embedded> {return {"_variant": "any"};}; + any.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("SimplePattern"), + variant: _.Symbol.for("any"), + unparse: fromSimplePattern, + parse: toSimplePattern, + cast: asSimplePattern + }; + }; export function atom<_embedded = _.GenericEmbedded>(atomKind: AtomKind): SimplePattern<_embedded> {return {"_variant": "atom", "atomKind": atomKind};}; + atom.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("SimplePattern"), + variant: _.Symbol.for("atom"), + unparse: fromSimplePattern, + parse: toSimplePattern, + cast: asSimplePattern + }; + }; export function embedded<_embedded = _.GenericEmbedded>($interface: SimplePattern<_embedded>): SimplePattern<_embedded> {return {"_variant": "embedded", "interface": $interface};}; + embedded.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("SimplePattern"), + variant: _.Symbol.for("embedded"), + unparse: fromSimplePattern, + parse: toSimplePattern, + cast: asSimplePattern + }; + }; export function lit<_embedded = _.GenericEmbedded>(value: _.Value<_embedded>): SimplePattern<_embedded> {return {"_variant": "lit", "value": value};}; + lit.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("SimplePattern"), + variant: _.Symbol.for("lit"), + unparse: fromSimplePattern, + parse: toSimplePattern, + cast: asSimplePattern + }; + }; export function seqof<_embedded = _.GenericEmbedded>(pattern: SimplePattern<_embedded>): SimplePattern<_embedded> {return {"_variant": "seqof", "pattern": pattern};}; + seqof.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("SimplePattern"), + variant: _.Symbol.for("seqof"), + unparse: fromSimplePattern, + parse: toSimplePattern, + cast: asSimplePattern + }; + }; export function setof<_embedded = _.GenericEmbedded>(pattern: SimplePattern<_embedded>): SimplePattern<_embedded> {return {"_variant": "setof", "pattern": pattern};}; + setof.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("SimplePattern"), + variant: _.Symbol.for("setof"), + unparse: fromSimplePattern, + parse: toSimplePattern, + cast: asSimplePattern + }; + }; export function dictof<_embedded = _.GenericEmbedded>({key, value}: {key: SimplePattern<_embedded>, value: SimplePattern<_embedded>}): SimplePattern<_embedded> {return {"_variant": "dictof", "key": key, "value": value};}; + dictof.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("SimplePattern"), + variant: _.Symbol.for("dictof"), + unparse: fromSimplePattern, + parse: toSimplePattern, + cast: asSimplePattern + }; + }; export function Ref<_embedded = _.GenericEmbedded>(value: Ref): SimplePattern<_embedded> {return {"_variant": "Ref", "value": value};}; + Ref.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("SimplePattern"), + variant: _.Symbol.for("Ref"), + unparse: fromSimplePattern, + parse: toSimplePattern, + cast: asSimplePattern + }; + }; } export namespace CompoundPattern { export function rec<_embedded = _.GenericEmbedded>( {label, fields}: {label: NamedPattern<_embedded>, fields: NamedPattern<_embedded>} ): CompoundPattern<_embedded> {return {"_variant": "rec", "label": label, "fields": fields};}; + rec.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("CompoundPattern"), + variant: _.Symbol.for("rec"), + unparse: fromCompoundPattern, + parse: toCompoundPattern, + cast: asCompoundPattern + }; + }; export function tuple<_embedded = _.GenericEmbedded>(patterns: Array>): CompoundPattern<_embedded> {return {"_variant": "tuple", "patterns": patterns};}; + tuple.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("CompoundPattern"), + variant: _.Symbol.for("tuple"), + unparse: fromCompoundPattern, + parse: toCompoundPattern, + cast: asCompoundPattern + }; + }; export function tuplePrefix<_embedded = _.GenericEmbedded>( {fixed, variable}: {fixed: Array>, variable: NamedSimplePattern<_embedded>} ): CompoundPattern<_embedded> {return {"_variant": "tuplePrefix", "fixed": fixed, "variable": variable};}; + tuplePrefix.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("CompoundPattern"), + variant: _.Symbol.for("tuplePrefix"), + unparse: fromCompoundPattern, + parse: toCompoundPattern, + cast: asCompoundPattern + }; + }; export function dict<_embedded = _.GenericEmbedded>(entries: DictionaryEntries<_embedded>): CompoundPattern<_embedded> {return {"_variant": "dict", "entries": entries};}; + dict.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("CompoundPattern"), + variant: _.Symbol.for("dict"), + unparse: fromCompoundPattern, + parse: toCompoundPattern, + cast: asCompoundPattern + }; + }; } export function DictionaryEntries<_embedded = _.GenericEmbedded>( value: _.KeyedDictionary<_.Value<_embedded>, NamedSimplePattern<_embedded>, _embedded> ): DictionaryEntries<_embedded> {return value;} +DictionaryEntries.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("DictionaryEntries"), + unparse: fromDictionaryEntries, + parse: toDictionaryEntries, + cast: asDictionaryEntries + }; +} + export namespace AtomKind { export function Boolean(): AtomKind {return {"_variant": "Boolean"};}; + Boolean.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("AtomKind"), + variant: _.Symbol.for("Boolean"), + unparse: fromAtomKind, + parse: toAtomKind, + cast: asAtomKind + }; + }; export function Float(): AtomKind {return {"_variant": "Float"};}; + Float.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("AtomKind"), + variant: _.Symbol.for("Float"), + unparse: fromAtomKind, + parse: toAtomKind, + cast: asAtomKind + }; + }; export function Double(): AtomKind {return {"_variant": "Double"};}; + Double.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("AtomKind"), + variant: _.Symbol.for("Double"), + unparse: fromAtomKind, + parse: toAtomKind, + cast: asAtomKind + }; + }; export function SignedInteger(): AtomKind {return {"_variant": "SignedInteger"};}; + SignedInteger.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("AtomKind"), + variant: _.Symbol.for("SignedInteger"), + unparse: fromAtomKind, + parse: toAtomKind, + cast: asAtomKind + }; + }; export function String(): AtomKind {return {"_variant": "String"};}; + String.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("AtomKind"), + variant: _.Symbol.for("String"), + unparse: fromAtomKind, + parse: toAtomKind, + cast: asAtomKind + }; + }; export function ByteString(): AtomKind {return {"_variant": "ByteString"};}; + ByteString.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("AtomKind"), + variant: _.Symbol.for("ByteString"), + unparse: fromAtomKind, + parse: toAtomKind, + cast: asAtomKind + }; + }; export function Symbol(): AtomKind {return {"_variant": "Symbol"};}; + Symbol.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("AtomKind"), + variant: _.Symbol.for("Symbol"), + unparse: fromAtomKind, + parse: toAtomKind, + cast: asAtomKind + }; + }; } export function NamedAlternative<_embedded = _.GenericEmbedded>({variantLabel, pattern}: {variantLabel: string, pattern: Pattern<_embedded>}): NamedAlternative<_embedded> {return {"variantLabel": variantLabel, "pattern": pattern};} +NamedAlternative.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("NamedAlternative"), + unparse: fromNamedAlternative, + parse: toNamedAlternative, + cast: asNamedAlternative + }; +} + export namespace NamedSimplePattern { export function named<_embedded = _.GenericEmbedded>(value: Binding<_embedded>): NamedSimplePattern<_embedded> {return {"_variant": "named", "value": value};}; + named.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("NamedSimplePattern"), + variant: _.Symbol.for("named"), + unparse: fromNamedSimplePattern, + parse: toNamedSimplePattern, + cast: asNamedSimplePattern + }; + }; export function anonymous<_embedded = _.GenericEmbedded>(value: SimplePattern<_embedded>): NamedSimplePattern<_embedded> {return {"_variant": "anonymous", "value": value};}; + anonymous.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("NamedSimplePattern"), + variant: _.Symbol.for("anonymous"), + unparse: fromNamedSimplePattern, + parse: toNamedSimplePattern, + cast: asNamedSimplePattern + }; + }; } export namespace NamedPattern { export function named<_embedded = _.GenericEmbedded>(value: Binding<_embedded>): NamedPattern<_embedded> {return {"_variant": "named", "value": value};}; + named.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("NamedPattern"), + variant: _.Symbol.for("named"), + unparse: fromNamedPattern, + parse: toNamedPattern, + cast: asNamedPattern + }; + }; export function anonymous<_embedded = _.GenericEmbedded>(value: Pattern<_embedded>): NamedPattern<_embedded> {return {"_variant": "anonymous", "value": value};}; + anonymous.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("NamedPattern"), + variant: _.Symbol.for("anonymous"), + unparse: fromNamedPattern, + parse: toNamedPattern, + cast: asNamedPattern + }; + }; } export function Binding<_embedded = _.GenericEmbedded>({name, pattern}: {name: symbol, pattern: SimplePattern<_embedded>}): Binding<_embedded> {return {"name": name, "pattern": pattern};} +Binding.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Binding"), + unparse: fromBinding, + parse: toBinding, + cast: asBinding + }; +} + export function Ref({module, name}: {module: ModulePath, name: symbol}): Ref {return {"module": module, "name": name};} +Ref.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("Ref"), + unparse: fromRef, + parse: toRef, + cast: asRef + }; +} + export function ModulePath(value: Array): ModulePath {return value;} +ModulePath.schema = function () { + return { + schema: _schema(), + imports: _imports, + definitionName: _.Symbol.for("ModulePath"), + unparse: fromModulePath, + parse: toModulePath, + cast: asModulePath + }; +} + export function asBundle<_embedded = _.GenericEmbedded>(v: _.Value<_embedded>): Bundle<_embedded> { let result = toBundle(v); if (result === void 0) throw new TypeError(`Invalid Bundle: ${_.stringify(v)}`); diff --git a/implementations/javascript/packages/schema/src/meta.ts b/implementations/javascript/packages/schema/src/meta.ts index aaa4c6a..a4b762e 100644 --- a/implementations/javascript/packages/schema/src/meta.ts +++ b/implementations/javascript/packages/schema/src/meta.ts @@ -54,6 +54,10 @@ export function modsymFor(e: SchemaEnvEntry): string { return '_i_' + e.schemaModulePath.map(s => s.description!).join('$'); } +export function formatModulePath(p: M.ModulePath): string { + return p.map(s => s.description!).join('.'); +} + export function formatRef(r: M.Ref): string { return [... r.module, r.name].map(s => s.description!).join('.'); }