75 lines
2.0 KiB
TypeScript
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);
|
||
|
}
|