Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

Commit

Permalink
split into multiple files
Browse files Browse the repository at this point in the history
  • Loading branch information
tjjfvi committed Oct 1, 2022
1 parent 1070676 commit 191f2f3
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 43 deletions.
61 changes: 46 additions & 15 deletions codegen/codecVisitor.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,29 @@
import * as M from "../frame_metadata/mod.ts";
import { Decl, getCodecPath, getName, getRawCodecPath, S } from "./utils.ts";
import { Decl, Files, getCodecPath, getName, getRawCodecPath, importSource, S } from "./utils.ts";

export function createCodecVisitor(
tys: M.Ty[],
decls: Decl[],
typeVisitor: M.TyVisitor<S>,
files: Files,
) {
["import { $, $null, $era } from", S.string(importSource)];
const namespaceImports = new Set<string>();
const codecs: S[] = [];

files.set("codecs.ts", {
getContent: () => [
"\n",
["import { ChainError, BitSequence, Era, $, $era, $null } from", S.string(importSource)],
[`import type * as t from "./mod.ts"`],
...codecs,
[
"export const _all: $.AnyCodec[] =",
S.array(tys.map((ty) => getName(getRawCodecPath(ty)))),
],
],
});

export function createCodecVisitor(tys: M.Ty[], decls: Decl[], typeVisitor: M.TyVisitor<S>) {
const compactCodecVisitor = new M.TyVisitor<string | null>(tys, {
unitStruct: () => "$null",
wrapperStruct(_, inner) {
Expand Down Expand Up @@ -59,7 +81,9 @@ export function createCodecVisitor(tys: M.Ty[], decls: Decl[], typeVisitor: M.Ty
},
result(ty, ok, err) {
return addCodecDecl(ty, ["$.result(", this.visit(ok), ",", [
`$.instance(ChainError<${typeVisitor.visit(err)}>, ["value", `,
"$.instance(ChainError<",
fixType(typeVisitor.visit(err)),
`>, ["value", `,
this.visit(err),
"])",
], ")"]);
Expand Down Expand Up @@ -141,22 +165,22 @@ export function createCodecVisitor(tys: M.Ty[], decls: Decl[], typeVisitor: M.Ty
return addCodecDecl(ty, "$era");
},
circular(ty) {
return ["$.deferred(() =>", getRawCodecPath(ty), ")"];
return ["$.deferred(() =>", getName(getRawCodecPath(ty)), ")"];
},
});

function addCodecDecl(ty: M.Ty, value: S) {
const rawPath = getRawCodecPath(ty);
decls.push({
path: "_codec.", // no sorting
code: [
["export const", getName(rawPath)],
": $.Codec<",
typeVisitor.visit(ty),
"> =",
value,
],
});
if (ty.path.length > 1) {
namespaceImports.add(ty.path[0]!);
}
codecs.push([
["export const", getName(rawPath)],
": $.Codec<",
fixType(typeVisitor.visit(ty)),
"> =",
value,
]);
const path = getCodecPath(tys, ty);
if (path !== rawPath && path !== value && !decls.some((x) => x.path === path)) {
decls.push({
Expand All @@ -170,6 +194,13 @@ export function createCodecVisitor(tys: M.Ty[], decls: Decl[], typeVisitor: M.Ty
],
});
}
return rawPath;
return getName(rawPath);
}

function fixType(type: S) {
return S.toString(type).replace(
/\b([\w\$]+\.[\w\.$]+|u\d+|Compact)\b/g,
(x) => "t." + x,
);
}
}
52 changes: 33 additions & 19 deletions codegen/codegen.ts
Original file line number Diff line number Diff line change
@@ -1,55 +1,69 @@
import { tsFormatter } from "../deps/dprint.ts";
import { parse } from "../deps/std/flags.ts";
import * as path from "../deps/std/path.ts";
import * as M from "../frame_metadata/mod.ts";
import { createCodecVisitor } from "./codecVisitor.ts";
import { genMetadata } from "./genMetadata.ts";
import { createTypeVisitor } from "./typeVisitor.ts";
import { Decl, printDecls, S } from "./utils.ts";

const importSource = new URL("../mod.ts", import.meta.url).toString();
import { Decl, Files, importSource, printDecls, S } from "./utils.ts";

if (import.meta.main) {
const args = parse(Deno.args, {
string: ["metadata", "output"],
});
if (args.help || args["?"]) {
console.log("Usage: codegen --metadata <file> --output <file>");
console.log("Usage: codegen --metadata <file> --output <dir>");
Deno.exit(0);
}
if (!args.metadata) throw new Error("Must specify metadata file");
if (!args.output) throw new Error("Must specify output file");
const { metadata: metadataFile, output: outputFile } = args;
const metadata = M.fromPrefixedHex(await Deno.readTextFile(metadataFile!));
if (!args.output) throw new Error("Must specify output dir");
const { metadata: metadataFile, output: outputDir } = args;
const metadata = M.fromPrefixedHex(await Deno.readTextFile(metadataFile));
const output = codegen(metadata);
try {
const formatted = tsFormatter.formatText("gen.ts", output);
await Deno.writeTextFile(outputFile!, formatted);
} catch (e) {
await Deno.writeTextFile(outputFile!, output);
throw e;
const errors = [];
await Deno.mkdir(outputDir, { recursive: true });
for (const [relativePath, file] of output.entries()) {
const outputPath = path.join(outputDir, relativePath);
const content = S.toString(file.getContent());
try {
const formatted = tsFormatter.formatText("gen.ts", content);
await Deno.writeTextFile(outputPath, formatted);
} catch (e) {
await Deno.writeTextFile(outputPath, content);
errors.push(e);
}
}
if (errors.length) {
console.error(errors);
Deno.exit(1);
}
}

export function codegen(metadata: M.Metadata) {
export function codegen(metadata: M.Metadata): Files {
const decls: Decl[] = [];

const { tys } = metadata;

const files: Files = new Map();

decls.push({
path: "_",
code: [
"import { ChainError, BitSequence, Era, $, $null, $era } from",
S.string(importSource),
"\n",
["import { ChainError, BitSequence, Era, $ } from", S.string(importSource)],
[`import * as _codec from "./codecs.ts"`],
],
});

const typeVisitor = createTypeVisitor(tys, decls);
const codecVisitor = createCodecVisitor(tys, decls, typeVisitor);
const codecVisitor = createCodecVisitor(tys, decls, typeVisitor, files);

typeVisitor.tys.map((x) => typeVisitor.visit(x));
codecVisitor.tys.map((x) => codecVisitor.visit(x));

genMetadata(metadata, decls, codecVisitor);
genMetadata(metadata, decls);

files.set("mod.ts", { getContent: () => printDecls(decls) });

return printDecls(decls);
return files;
}
15 changes: 6 additions & 9 deletions codegen/genMetadata.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as M from "../frame_metadata/mod.ts";
import { Decl, getPath, getRawCodecPath, makeDocComment, S } from "./utils.ts";

export function genMetadata(metadata: M.Metadata, decls: Decl[], codecVisitor: M.TyVisitor<S>) {
export function genMetadata(metadata: M.Metadata, decls: Decl[]) {
const { tys, extrinsic, pallets } = metadata;

const isUnitVisitor = new M.TyVisitor<boolean>(tys, {
Expand Down Expand Up @@ -56,11 +56,11 @@ export function genMetadata(metadata: M.Metadata, decls: Decl[], codecVisitor: M
"key",
entry.type === "Map"
? entry.hashers.length === 1
? ["$.tuple(", codecVisitor.visit(entry.key), ")"]
: codecVisitor.visit(entry.key)
? ["$.tuple(", getRawCodecPath(tys[entry.key]!), ")"]
: getRawCodecPath(tys[entry.key]!)
: "[]",
],
["value", codecVisitor.visit(entry.value)],
["value", getRawCodecPath(tys[entry.value]!)],
),
],
});
Expand Down Expand Up @@ -96,15 +96,12 @@ export function genMetadata(metadata: M.Metadata, decls: Decl[], codecVisitor: M

decls.push({
path: "_metadata.types",
code: [
"export const types: $.AnyCodec[] =",
S.array(codecVisitor.tys.map((ty) => getRawCodecPath(ty))),
],
code: "export const types = _codec._all",
});

function getExtrasCodec(xs: [string, number][]) {
return S.array(
xs.filter((x) => !isUnitVisitor.visit(x[1])).map((x) => codecVisitor.visit(x[1])),
xs.filter((x) => !isUnitVisitor.visit(x[1])).map((x) => getRawCodecPath(tys[x[1]]!)),
);
}
}
6 changes: 6 additions & 0 deletions codegen/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import * as M from "../frame_metadata/mod.ts";

export const importSource = new URL("../mod.ts", import.meta.url).toString();

export type File = { getContent: () => S };
export type Files = Map<string, File>;

export type S = string | number | S[];

export namespace S {
Expand Down

0 comments on commit 191f2f3

Please sign in to comment.