This commit is contained in:
Dylan Pizzo 2024-11-23 14:18:52 -08:00
parent 9593e21f3c
commit 25687860cc
8 changed files with 104 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
examples/*
!*.gen.ts
!*.gen.js

View File

@ -1,2 +1,7 @@
# codegen
Use:
```sh
deno run --allow-read --allow-write src/codegen.ts
```

12
deno.json Normal file
View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"lib": ["deno.ns", "DOM"],
"strict": true
},
"include": ["src"],
"tasks": {},
"imports": {},
"fmt": {
"useTabs": true
}
}

19
deno.lock generated Normal file
View File

@ -0,0 +1,19 @@
{
"version": "4",
"specifiers": {
"jsr:@std/fs@*": "1.0.6",
"jsr:@std/path@*": "1.0.8",
"jsr:@std/path@^1.0.8": "1.0.8"
},
"jsr": {
"@std/fs@1.0.6": {
"integrity": "42b56e1e41b75583a21d5a37f6a6a27de9f510bcd36c0c85791d685ca0b85fa2",
"dependencies": [
"jsr:@std/path@^1.0.8"
]
},
"@std/path@1.0.8": {
"integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be"
}
}
}

3
examples/sample.gen.ts Normal file
View File

@ -0,0 +1,3 @@
export default () => {
return `console.log("Hello, World!");`;
};

View File

@ -0,0 +1,3 @@
export default () => {
return `export const five = 5;`;
};

View File

@ -0,0 +1,4 @@
export default async (context: any) => {
const { five } = await context.import("./somethingEarly.ts");
return five.toString();
};

55
src/codegen.ts Normal file
View File

@ -0,0 +1,55 @@
import * as path from "jsr:@std/path";
const root = Deno.cwd();
const getAllFiles = async (dir: string) => {
const localEntries = await Array.fromAsync(Deno.readDir(dir));
const entries = localEntries.filter((e) => e.isFile).map((e) => e.name);
for (const entry of localEntries) {
if (
entry.isDirectory &&
!entry.isSymlink &&
!entry.name.startsWith(".")
) {
entries.push(
...(await getAllFiles(entry.name)).map((fname) =>
path.join(entry.name, fname)
)
);
}
}
return entries;
};
const getFilesToGenFrom = async () => {
const allFiles = await getAllFiles(root);
return allFiles
.filter(
(fname) => fname.endsWith(".gen.ts") || fname.endsWith(".gen.js")
)
.map((fname) => path.join(root, fname));
};
const filesBeingGenned: Record<string, Promise<void>> = {};
const genFromFile = async (fname: string) => {
const context = {
async import(moduleName: string) {
const fullname = path.resolve(path.dirname(fname), moduleName);
await filesBeingGenned[fullname];
return import(fullname);
},
};
type CodegenContext = typeof context;
const brain: (context: CodegenContext) => string | Promise<string> = (
await import(fname)
).default;
const fileToWrite = fname.replace(/\.gen\.[tj]sx?$/, (ext) =>
ext.slice(".gen".length)
);
Deno.writeTextFile(fileToWrite, await brain(context));
};
for (const file of await getFilesToGenFrom()) {
filesBeingGenned[file] = genFromFile(file);
}