JsonRPC/src/compile.ts

85 lines
2.3 KiB
TypeScript

import * as FS from "fs";
import * as FSE from "fs-extra"
import * as Path from "path";
import {
EnumDefinition,
IR,
ServiceDefinition,
Step,
TypeDefinition,
} from "./ir";
export abstract class CompileTarget<T = any> {
abstract name: string;
constructor(private outputFolder: string, protected options: T) {
if (!FS.existsSync(outputFolder)) {
FS.mkdirSync(outputFolder, {
recursive: true,
});
}
}
abstract start(): void;
abstract generateType(definition: TypeDefinition): void;
abstract generateEnum(definition: EnumDefinition): void;
abstract generateService(definition: ServiceDefinition): void;
abstract finalize(steps: Step[]): void;
protected writeFile(name: string, content: string | Promise<string>) {
if (content instanceof Promise) {
content.then((res) =>
FS.writeFileSync(Path.join(this.outputFolder, name), res)
);
} else {
FS.writeFileSync(Path.join(this.outputFolder, name), content);
}
}
protected getTemplate(name: string): string {
let path = Path.join(__dirname, "../templates/" + name);
let file = FS.readFileSync(path, "utf-8");
const splitted = file.split("\n");
let res = [];
let ignore = false;
for (const line of splitted) {
if (ignore) {
ignore = false;
} else if (line.trim().startsWith("//@template-ignore")) {
ignore = true;
} else {
res.push(line);
}
}
return res.join("\n");
}
protected loadTemplateFolder(name:string) {
let root = Path.join(__dirname, "../templates/", name);
FSE.copySync(root, this.outputFolder, {
});
}
}
export default function compile(ir: IR, target: CompileTarget) {
// Types are verified. They are now ready to be compiled to targets
// setState("Building for target: " + target.name);
target.start();
ir.steps.forEach((step) => {
const [type, def] = step;
if (type == "type") target.generateType(def as TypeDefinition);
else if (type == "enum") target.generateEnum(def as EnumDefinition);
else if (type == "service")
target.generateService(def as ServiceDefinition);
});
if (target.finalize) target.finalize(ir.steps);
}