import {TsArrayFactory} from "./TsArrayFactory"; import {TsObjectFactory} from "./TsObjectFactory"; import {InternalFileContext} from "../syntax/syntax"; import {TsChainFunction} from "../interface/TsChainFunction"; import {TsImport} from "../interface/TsImport"; import {TsIf} from "../interface/TsIf"; import { TsAbstractDeclaration, TsDeclaration, TsExportDeclaration, TsScopeDeclaration } from "../interface/TsDeclaration"; import {TsArray} from "../interface/TsArray"; import {TsObject} from "../interface/TsObject"; import {ITsBodyNodeFactory} from "../interface/TsNode"; import {TsFunctionDeclaration} from "../interface/TsFunctionDeclaration"; export abstract class TsNodeFactory { protected isConditionTrue: boolean = true protected isEmit:boolean = true public createCode(config: CreateCodeConfig): string { return this.createCodeLines(config).join(config.EOL) } protected abstract _createCodeLines(config: CreateCodeConfig): string[] createCodeLines(config: CreateCodeConfig): string[] { if(!this.isEmit){ return [] } else { return this._createCodeLines(config) } } if(condition: boolean) :T { this.isConditionTrue = condition return this } endif() : T { this.isConditionTrue = true return this } else() : T { this.isConditionTrue = !this.isConditionTrue return this } emitWhen(condition: boolean): T { this.isEmit = condition return this } loads(plugin: (self) => void): T { plugin(this) return this } } export abstract class TsMultilineNodeFactory extends TsNodeFactory{ public isMultiline:boolean = false @If multiline() : T{ this.isMultiline = true return this } @If singleline() : T{ this.isMultiline = false return this } } export abstract class TsBodyNodeFactory extends TsMultilineNodeFactory implements ITsBodyNodeFactory{ abstract push(...tsNodes:TsNode[]) abstract remove(tsNode:TsNode) context:InternalFileContext } export interface CreateCodeConfig { indent?: string EOL?: string, baseIndent?:string // default is '' } /** * Annotation to let TsNodeFactory can generate content according to condition * @param target * @param {string} propertyKey * @param {PropertyDescriptor} descriptor * @constructor */ export function If(target: any, propertyKey: string, descriptor: PropertyDescriptor) { const originMethod = descriptor.value descriptor.value = function (...args) { if (this.isConditionTrue) { originMethod.apply(this, args) } return this } }; export type TsInterface = TsChainFunction | TsFunctionDeclaration | TsImport | TsIf | TsDeclaration | TsExportDeclaration | TsScopeDeclaration | TsAbstractDeclaration | TsAbstractDeclaration | TsArray | TsObject export type TsNodeElem = TsInterface | TsNodeFactory | string | number | boolean | undefined | null export type TsNode = TsNodeElem | TsNodeElem[] | { [key: string]: TsNodeElem } export type TsNodeBody = TsNode | Function