JsonRPC/src/compile.ts

75 lines
2.0 KiB
TypeScript

import * as FS from "fs";
import * as Path from "path";
import {
EnumDefinition,
IR,
ServiceDefinition,
Step,
TypeDefinition,
} from "./ir";
export abstract class CompileTarget {
abstract name: string;
constructor(private outputFolder: string) {
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");
}
}
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);
ir.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);
}