Skip to content

Commit

Permalink
Template for creating a new SDK generator (#4010)
Browse files Browse the repository at this point in the history
* Simple Unit Test Generator

* Generator Code

* Generator LANGUAGE_NAME

* Swift Init

* Writer and Astnode as commons

* More function functionality

* Lang Gen v2

* Lang Gen v3

* Oops

* Polish

* Writer indentation

* Polished imports

* Refined imports

* Template generator notes

* Template Generator
  • Loading branch information
mikemilla authored Jul 9, 2024
1 parent 0201350 commit b7f1df7
Show file tree
Hide file tree
Showing 18 changed files with 605 additions and 10 deletions.
90 changes: 90 additions & 0 deletions .pnp.cjs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 25 additions & 0 deletions generators/commons/src/AstNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Writer } from "./Writer";

export abstract class AstNode {

private indentSize: number;

constructor(indentSize: number) {
this.indentSize = indentSize;
}

/**
* Every AST node knows how to write itself to a string.
*/
public abstract write(writer: Writer): void;

/**
* Writes the node to a string.
*/
public toString(): string {
const writer = new Writer(this.indentSize);
this.write(writer);
return writer.toString();
}

}
64 changes: 64 additions & 0 deletions generators/commons/src/Writer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { AstNode } from "./AstNode";

export declare namespace Writer {
interface Args {
tabSize?: number;
}
}

export class Writer {

private buffer: string;
private indentLevel: number;
private hasWrittenAnything: boolean;
private indentSize: number;

constructor(indentSize: number) {
this.buffer = "";
this.indentLevel = 0;
this.hasWrittenAnything = false;
this.indentSize = indentSize;
}

public write(text: string): void {

if (this.hasWrittenAnything) {
this.buffer += "\n";
}

const indent = this.getIndentString(this.indentSize);
const indentedText = indent + text.replace(/\n/g, `\n${indent}`);

this.buffer += indentedText;

this.hasWrittenAnything = true;

}

public newLine(): void {
this.buffer += "\n";
}

public openIndent(): void {
this.indentLevel++;
}

public closeIndent(): void {
if (this.indentLevel > 0) {
this.indentLevel--;
}
}

public writeNode(node: AstNode): void {
node.write(this);
}

public toString(): string {
return this.buffer;
}

private getIndentString(tabSize: number): string {
return " ".repeat(this.indentLevel * tabSize);
}

}
8 changes: 5 additions & 3 deletions generators/commons/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
export * from "./AbstractGeneratorCli";
export * from "./AbstractGeneratorContext";
export * from "./AstNode";
export * from "./BaseGeneratorConfig";
export * from "./ConfigUtilities";
export * from "./AbstractGeneratorContext";
export * from "./PersistedProject";
export * from "./GeneratorNotificationService";
export * from "./parseGeneratorConfig";
export * from "./AbstractGeneratorCli";
export * from "./PersistedProject";
export * from "./Writer";
28 changes: 21 additions & 7 deletions generators/commons/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
{
"extends": "../../shared/tsconfig.shared.json",
"compilerOptions": { "composite": true, "outDir": "lib", "rootDir": "src" },
"include": ["./src/**/*"],
"compilerOptions": {
"composite": true,
"outDir": "lib",
"rootDir": "src"
},
"include": [
"./src/**/*"
],
"references": [
{ "path": "../../packages/cli/logger" },
{ "path": "../../packages/commons/core-utils" },
{ "path": "../../packages/commons/fs-utils" },
{ "path": "../../packages/commons/logging-execa" }
{
"path": "../../packages/cli/logger"
},
{
"path": "../../packages/commons/core-utils"
},
{
"path": "../../packages/commons/fs-utils"
},
{
"path": "../../packages/commons/logging-execa"
}
]
}
}
1 change: 1 addition & 0 deletions generators/template/codegen/.prettierrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require("fern/.prettierrc");
1 change: 1 addition & 0 deletions generators/template/codegen/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from "../../../shared/jest.config.shared";
48 changes: 48 additions & 0 deletions generators/template/codegen/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
{
"name": "@fern-api/LANGUAGE_NAME-codegen",
"version": "0.0.0",
"repository": {
"type": "git",
"url": "https://github.com/fern-api/fern.git",
"directory": "generators/LANGUAGE_NAME/codegen"
},
"files": [
"lib"
],
"type": "module",
"source": "src/index.ts",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"sideEffects": false,
"scripts": {
"clean": "rm -rf ./lib && tsc --build --clean",
"compile": "tsc --build",
"test": "yarn compile && jest --passWithNoTests",
"lint:eslint": "eslint --max-warnings 0 . --ignore-path=../../../.eslintignore",
"lint:eslint:fix": "yarn lint:eslint --fix",
"format": "prettier --write --ignore-unknown --ignore-path ../../../shared/.prettierignore \"**\"",
"format:check": "prettier --check --ignore-unknown --ignore-path ../../../shared/.prettierignore \"**\"",
"organize-imports": "organize-imports-cli tsconfig.json",
"depcheck": "depcheck"
},
"dependencies": {
"@fern-api/core-utils": "workspace:*",
"@fern-api/fs-utils": "workspace:*",
"@fern-api/generator-commons": "workspace:*",
"@fern-api/logging-execa": "workspace:*",
"@fern-fern/ir-sdk": "^32",
"lodash-es": "^4.17.21",
"ts-node": "^10.9.2",
"zod": "^3.22.3"
},
"devDependencies": {
"@types/jest": "^29.0.3",
"@types/lodash-es": "^4.17.12",
"@types/node": "^18.7.18",
"depcheck": "^1.4.6",
"eslint": "^8.56.0",
"jest": "^29.7.0",
"organize-imports-cli": "^0.10.0",
"typescript": "4.6.4"
}
}
44 changes: 44 additions & 0 deletions generators/template/codegen/src/ast/Class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { AstNode, Writer } from "@fern-api/generator-commons";
import Lang, { Func } from "../lang";

export declare namespace Class {
interface Args {
name: string,
functions: Func[]
}
}

export class Class extends AstNode {

public readonly name: string;
public readonly functions: Func[];

constructor({
name,
functions,
}: Class.Args) {
super(Lang.indentSize);
this.name = name;
this.functions = functions;
}

public write(writer: Writer): void {

writer.write(`class ${this.name} {`);

writer.newLine();

writer.openIndent();

this.functions.forEach(func => {
writer.writeNode(func);
writer.newLine();
});

writer.closeIndent();

writer.write("}");


}
}
Loading

0 comments on commit b7f1df7

Please sign in to comment.