diff --git a/.github/workflows/publish_to_npm.yaml b/.github/workflows/publish_to_npm.yaml new file mode 100644 index 0000000..95ead10 --- /dev/null +++ b/.github/workflows/publish_to_npm.yaml @@ -0,0 +1,18 @@ +on: + push: + branches: master + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-node@v3 + with: + node-version: "18" + - run: npm ci + - run: npm run build + - run: npm test + - uses: JS-DevTools/npm-publish@v2 + with: + token: ${{ secrets.NPM_TOKEN }} diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..96c2b4a --- /dev/null +++ b/.npmignore @@ -0,0 +1,7 @@ +test +src +public + +webpack.config.js +tsconfig.json +jest.config.js \ No newline at end of file diff --git a/index.html b/index.html deleted file mode 100644 index 44a9335..0000000 --- a/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Vite + TS - - -
- - - diff --git a/src/ExpressionGenerator.ts b/src/ExpressionGenerator.ts deleted file mode 100644 index bfc9f1b..0000000 --- a/src/ExpressionGenerator.ts +++ /dev/null @@ -1,7 +0,0 @@ -import * as ts from "typescript"; - -export class ExpressionGenerator { - public static orExpression(expr1: ts.Expression, expr2: ts.Expression) { - return ts.factory.createBinaryExpression(expr1, ts.SyntaxKind.BarBarToken, expr2); - } -} \ No newline at end of file diff --git a/src/HeritageClauseHandler.ts b/src/HeritageClauseHandler.ts index a2bfeb5..24fd54c 100644 --- a/src/HeritageClauseHandler.ts +++ b/src/HeritageClauseHandler.ts @@ -12,15 +12,12 @@ export class HeritageClauseGenerator { addIdentifier(name: string): this { if (!this._token) throw new Error("HeritageClauseGenerator.addIdentifier | At first you should detiemine the token for HeritageClause"); - console.log("333333333333333333", name) const identifier = ts.factory.createIdentifier(name) - console.log("333333334444444444", name) if (this._token === ts.SyntaxKind.ExtendsKeyword) this._identifiers = [identifier]; else this._identifiers.push(identifier) - console.log("4444444444444", name) return this; } diff --git a/src/TypeParameterDelarationGenerator.ts b/src/TypeParameterDelarationGenerator.ts deleted file mode 100644 index b68021a..0000000 --- a/src/TypeParameterDelarationGenerator.ts +++ /dev/null @@ -1,31 +0,0 @@ -import * as ts from "typescript"; -import { ModifierHandler } from "../modifiers" - -export class TypeParameterDelarationGenerator { - private _name: string; - private _modifiers: ModifierHandler = new ModifierHandler(); - private _constraint: ts.TypeNode; - private _defaultType: ts.TypeNode; - - constructor(name: string) { - this._name = name; - } - - setConstraint(constraint: ts.TypeNode): TypeParameterDelarationGenerator { - this._constraint = constraint; - return this; - } - setDefaultType(defaultType: ts.TypeNode): TypeParameterDelarationGenerator { - this._defaultType = defaultType; - return this; - } - - generate(): ts.TypeParameterDeclaration { - return ts.factory.createTypeParameterDeclaration( - this._modifiers.toArray(), - this._name, - this._constraint, - this._defaultType - ) - } -} \ No newline at end of file diff --git a/src/api.ts b/src/api.ts deleted file mode 100644 index d5b8536..0000000 --- a/src/api.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ClassGenerator } from "./classGenerator"; -import * as ts from "typescript"; - - -export function nodeText(n: ts.Node): string { - const resultFile = ts.createSourceFile( - 'testddddddddddddddddd.ts', - '', - ts.ScriptTarget.Latest, - false, - ts.ScriptKind.TS, - ); - const printer = ts.createPrinter({ - newLine: ts.NewLineKind.LineFeed, - }); - const result = printer.printNode( - ts.EmitHint.Unspecified, - n, - resultFile, - ); - return result; -} \ No newline at end of file diff --git a/src/assignmentGenerator.ts b/src/assignmentGenerator.ts deleted file mode 100644 index 8c6fcbf..0000000 --- a/src/assignmentGenerator.ts +++ /dev/null @@ -1,11 +0,0 @@ -import * as ts from "typescript"; - -export class AssignmentGenerator { - public static assignToClassProperty(propertyName: string, expresion: ts.Expression): ts.AssignmentExpression { - const property = ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier("this"), - ts.factory.createIdentifier(propertyName) - ); - return ts.factory.createAssignment(property, expresion); - } -} \ No newline at end of file diff --git a/src/bodyGenerator.ts b/src/bodyGenerator.ts index 006be74..4ce83db 100644 --- a/src/bodyGenerator.ts +++ b/src/bodyGenerator.ts @@ -1,10 +1,27 @@ import * as ts from "typescript"; +import { statementFromExpression } from "./statements"; +import { getPropertyOfClassExpression } from "./expressions"; export class BodyGenerator { - generate() { - // ts.factory.createBlock( + private _statements: ts.Statement[] = [] - // ) + + addStatement(statement: ts.Statement): this { + this._statements.push(statement); + return this; + } + addExpression(expression: ts.Expression): this { + this._statements.push(statementFromExpression(expression)); + return this; + } + + returnsProperty(name: string | ts.Identifier): this { + this._statements.push(ts.factory.createReturnStatement(getPropertyOfClassExpression(name))) + return this; + } + + generate(): ts.Block { + return ts.factory.createBlock(this._statements, true); } } \ No newline at end of file diff --git a/src/classGenerator.ts b/src/classGenerator.ts index 1256d8e..3f2fd48 100644 --- a/src/classGenerator.ts +++ b/src/classGenerator.ts @@ -1,7 +1,11 @@ import * as ts from "typescript"; -import { ModifierLikeHandler } from "./generator/modifiers"; -import { TypeParameterDelarationGenerator } from "./generator/type"; +import { ModifierLikeHandler } from "./modifiers"; +import { TypeParameterDelarationGenerator } from "./types"; + import { HeritageClauseGenerator } from "./HeritageClauseHandler"; +import { ConstructorGenerator } from "./constructorGenerator"; +import { PropertyGenerator } from "./properties"; +import { GetterGenerator } from "./functions"; export class ClassGenerator { @@ -13,14 +17,14 @@ export class ClassGenerator { private _extended_heritageClause: HeritageClauseGenerator; private _implemented_heritageClause: HeritageClauseGenerator; - constructor(className: string) { - this._name = className; - } + private _constructor: ConstructorGenerator; + private _properties: PropertyGenerator[] = []; + private _getters: GetterGenerator[] = []; - addMember(element: ts.ClassElement): this { - this._members.push(element); - return this; + + constructor(className: string) { + this._name = className; } extends(baseClass: string): this { @@ -51,6 +55,14 @@ export class ClassGenerator { extimp.push(this._extended_heritageClause.generate()); if (this._implemented_heritageClause) extimp.push(this._implemented_heritageClause.generate()); + + // add all properties to members + this._properties.forEach(p => this._members.push(p.generate())); + this._getters.forEach(p => this._members.push(p.generate())); + + // add constructor to the members + if (this._constructor) this._members.push(this._constructor.generate()); + return ts.factory.createClassDeclaration( this._modifiers.toArray(), this._name, @@ -59,4 +71,23 @@ export class ClassGenerator { this._members ) } + + setConstructor(): ConstructorGenerator { + if (this._constructor) return this._constructor; + this._constructor = new ConstructorGenerator(); + return this._constructor; + } + + addProperty(name: string): PropertyGenerator { + const result = new PropertyGenerator(name); + this._properties.push(result); + return result; + } + + addGetter(name: string | ts.Identifier) { + const result = new GetterGenerator(name); + this._getters.push(result); + return result; + } + } \ No newline at end of file diff --git a/src/constructorGenerator.ts b/src/constructorGenerator.ts index 63c5f03..af753f9 100644 --- a/src/constructorGenerator.ts +++ b/src/constructorGenerator.ts @@ -1,12 +1,13 @@ import * as ts from "typescript"; -import { ModifierLikeHandler } from "../modifiers"; -import { ParameterGenerator } from "./ParameterGenerator"; +import { ModifierLikeHandler } from "./modifiers"; +import { ParameterGenerator } from "./parameters"; +import { BodyGenerator } from "./bodyGenerator"; export class ConstructorGenerator { private _modifiers: ModifierLikeHandler = new ModifierLikeHandler(); private _parameters: ParameterGenerator[] = []; - + private _block: BodyGenerator; addParameter(name: string): ParameterGenerator { const result = new ParameterGenerator(name); @@ -18,8 +19,14 @@ export class ConstructorGenerator { return ts.factory.createConstructorDeclaration( this._modifiers.toArray(), this._parameters.map(p => p.generate()), - undefined + this._block.generate(), ) } + setBody() { + if (this._block) return this._block; + this._block = new BodyGenerator(); + return this._block; + } + } \ No newline at end of file diff --git a/src/enumGenerator.ts b/src/enums.ts similarity index 100% rename from src/enumGenerator.ts rename to src/enums.ts diff --git a/src/expressions.ts b/src/expressions.ts new file mode 100644 index 0000000..85d03ab --- /dev/null +++ b/src/expressions.ts @@ -0,0 +1,29 @@ +import * as ts from "typescript"; +import { statementFromExpression } from "./statements"; + +export function or(expr1: ts.Expression, expr2: ts.Expression): ts.BinaryExpression { + return ts.factory.createBinaryExpression(expr1, ts.SyntaxKind.BarBarToken, expr2); +} + +export function expOrNull(expr: ts.Expression): ts.BinaryExpression { + return ts.factory.createBinaryExpression(expr, ts.SyntaxKind.BarBarToken, ts.factory.createNull()) +} + +export function assignToClassProperty(name: string | ts.Identifier, expresion: ts.Expression): ts.AssignmentExpression { + const property = getPropertyOfClassExpression(name); + return ts.factory.createAssignment(property, expresion); +} + +export function getPropertyOfClassExpression(name: string | ts.Identifier): ts.Expression { + return ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier("this"), + typeof name === "string" + ? ts.factory.createIdentifier(name) + : name + ); +} + + +export function expressionToStatement(expr: ts.Expression): ts.Statement { + return statementFromExpression(expr); +} \ No newline at end of file diff --git a/src/functions.ts b/src/functions.ts new file mode 100644 index 0000000..0e4121f --- /dev/null +++ b/src/functions.ts @@ -0,0 +1,54 @@ +import * as ts from "typescript"; +import { ModifierLikeHandler } from "./modifiers"; +import { BodyGenerator } from "./bodyGenerator"; +import { ParameterGenerator } from "./parameters"; + +export class GetterGenerator { + private _name: string; + private _modifiers: ModifierLikeHandler = new ModifierLikeHandler(); + private _parameters: ParameterGenerator[] = []; + private _identifier: ts.Identifier; + private _block: BodyGenerator; + private _type: ts.TypeNode; + + + constructor(name: string | ts.Identifier) { + if (typeof name === "string") { + this._name = name; + this._identifier = ts.factory.createIdentifier(name); + } else { + this._name = name.text; + this._identifier = name; + } + } + + readonly(): this { + this._modifiers.readonly(); + return this; + } + + private(): this { + this._modifiers.private(); + return this; + } + + setType(typeNode: ts.TypeNode): this { this._type = typeNode; return this; } + + + generate(): ts.GetAccessorDeclaration { + return ts.factory.createGetAccessorDeclaration( + this._modifiers.toArray(), + this._name, + this._parameters.map(p => p.generate()), + this._type, + this._block.generate() + ); + } + + setBody() { + if (this._block) return this._block; + this._block = new BodyGenerator(); + return this._block; + } + +} \ No newline at end of file diff --git a/src/generator.ts b/src/generator.ts deleted file mode 100644 index 8a49bdc..0000000 --- a/src/generator.ts +++ /dev/null @@ -1,41 +0,0 @@ -import * as ts from "typescript"; -import { TypeGenerator } from "../typeGenerator"; -import { EnumGenerator } from "./enumGenerator"; - -export class Generator { - private file: ts.SourceFile; - private program: ts.Program; - private printer: ts.Printer; - constructor(fileNames: string[], options: ts.CompilerOptions) { - this.file = ts.createSourceFile("fileName", "", ts.ScriptTarget.ES2022, false, ts.ScriptKind.TS) - this.program = ts.createProgram(fileNames, options); - this.printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); - } - - - enum() { - - const e = new EnumGenerator("eeeeeeeeeeeeeeeeeeeeeeee"); - e.Modifiers.export(); - e.addMember("a1"); - e.addMember("a2"); - - return this.printer.printNode(ts.EmitHint.Unspecified, e.generate(), this.file); - } - simpleType() { - const stringTypeReference = ts.factory.createTypeReferenceNode("string"); - - - const tg = new TypeGenerator("NNNNNNNNNname"); - tg.Modifiers.export(); - tg.setLiteralType(stringTypeReference); - tg.addTypeParameter("pppppppppppppp") - tg.addTypeParameter("qqqqqqqqqqqqqqq") - - - - return this.printer.printNode(ts.EmitHint.Unspecified, tg.generate(), this.file); - } - - -} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index 34ed4ae..9595691 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,13 @@ -export * from "./generator/identifier"; -export * from "./generator/type"; -export * from "./generator/class"; -export * from "./generator/body"; - -export * from "./api"; - -export * from "./initTs"; \ No newline at end of file +export * from "./IdentifierGenerator"; +export * from "./bodyGenerator"; +export * from "./classGenerator"; +export * from "./constructorGenerator"; +export * from "./enums"; +export * from "./expressions"; +export * from "./HeritageClauseHandler"; +export * from "./modifiers"; +export * from "./parameters"; +export * from "./properties"; +export * from "./statements"; +export * from "./types"; +export * from "./writer"; \ No newline at end of file diff --git a/src/initTs.ts b/src/initTs.ts deleted file mode 100644 index 7a6ccb1..0000000 --- a/src/initTs.ts +++ /dev/null @@ -1,10 +0,0 @@ -import * as tssss from "typescript"; - -type TsType = typeof tssss; - -export let ts: TsType = null; - - -export function init(tss: TsType) { - ts = tss; -} \ No newline at end of file diff --git a/src/modiferHandler.ts b/src/modiferHandler.ts deleted file mode 100644 index 3329ec5..0000000 --- a/src/modiferHandler.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as ts from "typescript"; - -export class ModifierHandler { - private _modifiers: ts.Modifier[] = []; - - private addModifier(modifier: ts.Modifier) { - if (this._modifiers.find(m => m.kind === modifier.kind)) return; - this._modifiers.push(modifier); - } - - export(): ModifierHandler { - this.addModifier(ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)); - return this; - } - - - - toArray(): ts.Modifier[] { - return this._modifiers - } - - -} \ No newline at end of file diff --git a/src/modiferlikeHandler.ts b/src/modiferlikeHandler.ts deleted file mode 100644 index abf2a6a..0000000 --- a/src/modiferlikeHandler.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as ts from "typescript"; - -export class ModifierLikeHandler { - private _modifiers: ts.ModifierLike[] = []; - - private addModifier(modifier: ts.Modifier) { - if (this._modifiers.find(m => m.kind === modifier.kind)) return; - this._modifiers.push(modifier); - } - - export(): ModifierLikeHandler { - this.addModifier(ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)); - return this; - } - - - - toArray(): ts.ModifierLike[] { - return this._modifiers - } - - -} \ No newline at end of file diff --git a/src/modifiers.ts b/src/modifiers.ts new file mode 100644 index 0000000..b92b36f --- /dev/null +++ b/src/modifiers.ts @@ -0,0 +1,54 @@ +import * as ts from "typescript"; + +export class ModifierLikeHandler { + private _modifiers: ts.ModifierLike[] = []; + + private addModifier(modifier: ts.Modifier) { + if (this._modifiers.find(m => m.kind === modifier.kind)) return; + this._modifiers.push(modifier); + } + + export(): this { + this.addModifier(ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)); + return this; + } + + private(): this { + this.addModifier(ts.factory.createModifier(ts.SyntaxKind.PrivateKeyword)); + return this; + } + + readonly(): this { + this.addModifier(ts.factory.createModifier(ts.SyntaxKind.ReadonlyKeyword)); + return this; + } + + toArray(): ts.ModifierLike[] { + return this._modifiers + } + + +} + + +export class ModifierHandler { + private _modifiers: ts.Modifier[] = []; + + private addModifier(modifier: ts.Modifier) { + if (this._modifiers.find(m => m.kind === modifier.kind)) return; + this._modifiers.push(modifier); + } + + export(): ModifierHandler { + this.addModifier(ts.factory.createModifier(ts.SyntaxKind.ExportKeyword)); + return this; + } + + + + toArray(): ts.Modifier[] { + return this._modifiers + } + + +} \ No newline at end of file diff --git a/src/ParameterGenerator.ts b/src/parameters.ts similarity index 73% rename from src/ParameterGenerator.ts rename to src/parameters.ts index 3be144d..cc6dd0f 100644 --- a/src/ParameterGenerator.ts +++ b/src/parameters.ts @@ -1,5 +1,5 @@ import * as ts from "typescript"; -import { ModifierLikeHandler } from "../modifiers"; +import { ModifierLikeHandler } from "./modifiers"; export class ParameterGenerator { private _name: string; @@ -9,12 +9,19 @@ export class ParameterGenerator { private _isSpread: boolean = false; private _isOptional: boolean = false; - + private _identifier: ts.Identifier; private _initial: ts.Expression; - - constructor(name: string) { - this._name = name; + get Identifier(): ts.Identifier { return this._identifier } + + constructor(name: string | ts.Identifier) { + if (typeof name === "string") { + this._name = name; + this._identifier = ts.factory.createIdentifier(name); + } else { + this._name = name.text; + this._identifier = name; + } } spread(): this { this._isSpread = true; return this; } @@ -39,4 +46,5 @@ export class ParameterGenerator { } + } \ No newline at end of file diff --git a/src/propertyGenerator.ts b/src/properties.ts similarity index 62% rename from src/propertyGenerator.ts rename to src/properties.ts index e433883..9e5477b 100644 --- a/src/propertyGenerator.ts +++ b/src/properties.ts @@ -1,6 +1,6 @@ import * as ts from "typescript"; -import { ModifierLikeHandler } from "../modifiers"; -import { AssignmentGenerator } from "../body/assignmentGenerator"; +import { ModifierLikeHandler } from "./modifiers"; +import { assignToClassProperty } from "./expressions"; export class PropertyGenerator { private _name: string; @@ -9,16 +9,24 @@ export class PropertyGenerator { private _isOptional: boolean = false; private _type: ts.TypeNode; private _initial: ts.Expression; + private _identifier: ts.Identifier; - constructor(name: string) { - this._name = name; + get Identifier(): ts.Identifier { return this._identifier; } + constructor(name: string | ts.Identifier) { + if (typeof name === "string") { + this._name = name; + this._identifier = ts.factory.createIdentifier(name); + } else { + this._name = name.text; + this._identifier = name; + } } optional(): this { this._isOptional = true; return this; } required(): this { this._isOptional = false; return this; } setType(typeNode: ts.TypeNode): this { this._type = typeNode; return this; } init(expression: ts.Expression): this { this._initial = expression; return this; } - + private(): this { this._modifiers.private(); return this; } generate(): ts.PropertyDeclaration { return ts.factory.createPropertyDeclaration( @@ -31,6 +39,6 @@ export class PropertyGenerator { } toBeAssigned(expression: ts.Expression): ts.AssignmentExpression { - return AssignmentGenerator.assignToClassProperty(this._name, expression); + return assignToClassProperty(this._name, expression); } } \ No newline at end of file diff --git a/src/statementGenerator.ts b/src/statementGenerator.ts deleted file mode 100644 index aeac511..0000000 --- a/src/statementGenerator.ts +++ /dev/null @@ -1,19 +0,0 @@ -import * as ts from "typescript"; - -export class StatementGenerator { - - - generate() { - // return ts.factory.createPropertyAssignment("akbar", ts.factory.createIdentifier("adasdasdasd")) // { a: sdasd} - ts.factory.createArrayLiteralExpression([]); - - const thisis = ts.factory.createPropertyAccessExpression( - ts.factory.createIdentifier("this"), - ts.factory.createIdentifier("name") - ) - - return ts.factory.createAssignment( - thisis, - ts.factory.createIdentifier("adasdasdasd")) // { a: sdasd} - } -} \ No newline at end of file diff --git a/src/statements.ts b/src/statements.ts new file mode 100644 index 0000000..292c116 --- /dev/null +++ b/src/statements.ts @@ -0,0 +1,7 @@ +import * as ts from "typescript"; + + +export function statementFromExpression(expr: ts.Expression): ts.Statement { + return ts.factory.createExpressionStatement(expr); +} + \ No newline at end of file diff --git a/src/typeGenerator.ts b/src/typeGenerator.ts deleted file mode 100644 index 092f1c3..0000000 --- a/src/typeGenerator.ts +++ /dev/null @@ -1,55 +0,0 @@ -import * as ts from "typescript"; -import { ModifierLikeHandler } from "../modifiers/modiferlikeHandler"; -import { ModifierHandler } from "./modiferHandler"; -import { TypeParameterDelarationGenerator } from "./TypeParameterDelarationGenerator"; - -export type TypeType = { - -} - -export class TypeGenerator { - private _typeName: string; - private _identifier: ts.Identifier; - private _reference: ts.TypeReferenceNode; - private _modifiers: ModifierLikeHandler = new ModifierLikeHandler(); - private _literalType: ts.TypeNode; - private _typeParameters: TypeParameterDelarationGenerator[] = []; - - get Modifiers(): ModifierLikeHandler { return this._modifiers; } - get Identifier(): ts.Identifier { return this._identifier; } - get Refrence(): ts.TypeNode { - if (this._reference) return this._reference; - return (this._reference = ts.factory.createTypeReferenceNode(this._identifier)); - } - constructor(typeName: string) { - this._typeName = typeName; - this._identifier = ts.factory.createIdentifier(this._typeName); - } - - setLiteralType(typeNode: ts.TypeNode) { - this._literalType = typeNode; - } - - addTypeParameter(name: string) { - const tp = new TypeParameterDelarationGenerator(name); - this._typeParameters.push(tp); - } - - generate(): ts.TypeAliasDeclaration { - // that type which is going to be used as type of this type `type yourtype: reference type;` - const result = ts.factory.createTypeAliasDeclaration( - this._modifiers.toArray(), // modifiers - this._identifier, - this._typeParameters.map(t => t.generate()), // type parameters - this._literalType // aliased type - ); - - return result; - } - - toArrayTypeNode(): ts.ArrayTypeNode { - return ts.factory.createArrayTypeNode(this.Refrence) - } - - -} \ No newline at end of file diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..3d3aa94 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,86 @@ +import * as ts from "typescript"; +import { ModifierLikeHandler, ModifierHandler } from "./modifiers"; + +export class TypeParameterDelarationGenerator { + private _name: string; + private _modifiers: ModifierHandler = new ModifierHandler(); + private _constraint: ts.TypeNode; + private _defaultType: ts.TypeNode; + + constructor(name: string) { + this._name = name; + } + + setConstraint(constraint: ts.TypeNode): TypeParameterDelarationGenerator { + this._constraint = constraint; + return this; + } + setDefaultType(defaultType: ts.TypeNode): TypeParameterDelarationGenerator { + this._defaultType = defaultType; + return this; + } + + generate(): ts.TypeParameterDeclaration { + return ts.factory.createTypeParameterDeclaration( + this._modifiers.toArray(), + this._name, + this._constraint, + this._defaultType + ) + } +} + +export class TypeGenerator { + private _name: string; + private _identifier: ts.Identifier; + private _reference: ts.TypeReferenceNode; + private _modifiers: ModifierLikeHandler = new ModifierLikeHandler(); + private _type: ts.TypeNode; + private _typeParameters: TypeParameterDelarationGenerator[] = []; + + get Modifiers(): ModifierLikeHandler { return this._modifiers; } + get Identifier(): ts.Identifier { return this._identifier; } + get Refrence(): ts.TypeNode { + if (this._reference) return this._reference; + return (this._reference = ts.factory.createTypeReferenceNode(this._identifier)); + } + constructor(name: string | ts.Identifier) { + if (typeof name === "string") { + this._name = name; + this._identifier = ts.factory.createIdentifier(name); + } else { + this._name = name.text; + this._identifier = name; + } + } + + setType(typeNode: ts.TypeNode) { + this._type = typeNode; + } + + addTypeParameter(name: string) { + const tp = new TypeParameterDelarationGenerator(name); + this._typeParameters.push(tp); + } + + generate(): ts.TypeAliasDeclaration { + // that type which is going to be used as type of this type `type yourtype: reference type;` + const result = ts.factory.createTypeAliasDeclaration( + this._modifiers.toArray(), // modifiers + this._identifier, + this._typeParameters.map(t => t.generate()), // type parameters + this._type // aliased type + ); + return result; + } + + toArrayTypeNode(): ts.ArrayTypeNode { + return ts.factory.createArrayTypeNode(this.Refrence) + } +} + + + + +export const stringType = ts.factory.createTypeReferenceNode("string") +export const numberType = ts.factory.createTypeReferenceNode("string") \ No newline at end of file diff --git a/src/writer.ts b/src/writer.ts new file mode 100644 index 0000000..e65ea5e --- /dev/null +++ b/src/writer.ts @@ -0,0 +1,24 @@ +import ts from "typescript"; + +export class Writer { + + private _printer: ts.Printer; + private _nodes: Array = []; + + constructor(...nodes: Array) { + this._nodes = nodes || this._nodes; + this._printer = ts.createPrinter({ newLine: ts.NewLineKind.CarriageReturnLineFeed }); + } + + setNodes(...nodes: Array) { + this._nodes = nodes || this._nodes; + } + + print(): string { + const result: Array = []; + this._nodes.forEach(n => + result.push(this._printer.printNode(ts.EmitHint.Unspecified, n, undefined)) + ) + return result.join("\n\n") + } +} \ No newline at end of file diff --git a/test/compilerAPI.spec.ts b/test/compilerAPI.spec.ts index 091d959..1e58198 100644 --- a/test/compilerAPI.spec.ts +++ b/test/compilerAPI.spec.ts @@ -1,13 +1,12 @@ - // import "ts-polyfill"; -import { SyntaxKind, factory } from "typescript"; -import { nodeText, ConstructorGenerator, IdentifierGenerator, TypeGenerator, ParameterGenerator, StatementGenerator } from "../src"; +import ts, { SyntaxKind, factory } from "typescript"; +import { IdentifierGenerator, TypeGenerator, ClassGenerator, stringType, assignToClassProperty, expOrNull, numberType, Writer } from "../src"; describe("test typescript compiler API directly", () => { test("idendifier Generatore", () => { const cg = new IdentifierGenerator("hamid"); - expect(nodeText(cg.generate())).toEqual("hamid") + expect(new Writer(cg.generate()).print()).toEqual("hamid") }); test("TypeGenerator testing", () => { @@ -19,22 +18,39 @@ describe("test typescript compiler API directly", () => { const arrayString = factory.createArrayTypeNode(string); const cg = new TypeGenerator("MyType"); - cg.setLiteralType(arrayString); + cg.setType(arrayString); - expect(nodeText(cg.generate())).toEqual("type MyType = string[];") + expect(new Writer(cg.generate()).print()).toEqual("type MyType = string[];") const f = new TypeGenerator("IfcText"); f.Modifiers.export(); - f.setLiteralType(cg.toArrayTypeNode()) - expect(nodeText(f.generate())).toEqual("export type IfcText = MyType[];") + f.setType(cg.toArrayTypeNode()) + expect(new Writer(f.generate()).print()).toEqual("export type IfcText = MyType[];") }); + test("class Generator", () => { + + const ifcText = new TypeGenerator("IfcText"); + ifcText.Modifiers.export(); + ifcText.setType(stringType); + + const c = new ClassGenerator("IfcElement"); + c.extends("Elements") + const property = c.addProperty("_height").private().setType(numberType); + const o = c.setConstructor(); + const param1 = o.addParameter("height").setType(ifcText.Refrence).optional(); + + const body = o.setBody(); + body.addExpression(assignToClassProperty(property.Identifier, expOrNull(param1.Identifier))) - test("Statement Generator", () => { - const s = new StatementGenerator(); - console.log(nodeText(s.generate())); + c.addGetter("Height") + .setType(ifcText.Refrence) + .readonly().private() + .setBody() + .returnsProperty(property.Identifier); + console.log(new Writer(c.generate()).print()); }) }); \ No newline at end of file