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 { abstract name: string; constructor(private outputFolder: string, protected options: T & { use_messagepack: boolean }) { 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) { 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); }