From 7679550e66108f35490f2a499da7381c93f42f55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Urba=C5=84czyk?= Date: Wed, 24 Feb 2021 14:12:01 +0100 Subject: [PATCH] fix: update JavaRenderer and remove unnecessary code from presets (#103) --- src/generators/java/JavaRenderer.ts | 35 +++++++++++----- .../java/renderers/ClassRenderer.ts | 21 +++++----- src/generators/java/renderers/EnumRenderer.ts | 11 ++--- .../javascript/renderers/ClassRenderer.ts | 15 +++---- .../typescript/TypeScriptRenderer.ts | 26 ++++++++---- .../typescript/renderers/ClassRenderer.ts | 41 ++++++++++--------- .../typescript/renderers/EnumRenderer.ts | 11 ++--- .../typescript/renderers/InterfaceRenderer.ts | 8 ++-- .../typescript/renderers/TypeRenderer.ts | 5 ++- src/models/Preset.ts | 2 - test/generators/java/JavaGenerator.spec.ts | 23 ++++++----- .../typescript/TypeScriptGenerator.spec.ts | 16 ++++---- 12 files changed, 123 insertions(+), 91 deletions(-) diff --git a/src/generators/java/JavaRenderer.ts b/src/generators/java/JavaRenderer.ts index c640b532ae..f7bb24d842 100644 --- a/src/generators/java/JavaRenderer.ts +++ b/src/generators/java/JavaRenderer.ts @@ -26,7 +26,8 @@ export abstract class JavaRenderer extends AbstractRenderer { if (model.$ref !== undefined) { return model.$ref; } - return this.toClassType(this.toJavaType(model.type, model)); + const format = model.getFromSchema('format'); + return this.toClassType(this.toJavaType(format || model.type, model)); } toJavaType(type: string | undefined, model: CommonModel): string { @@ -83,16 +84,28 @@ export abstract class JavaRenderer extends AbstractRenderer { } } - renderAnnotation(annotation: any): string; - renderAnnotation(annotations: Array): string; - renderAnnotation(annotation: Array | any): string { - if (Array.isArray(annotation)) { - return annotation.map(ann => this.renderAnnotation(ann)).join(' '); - } - const name = `@${FormatHelpers.upperFirst(annotation.name)}`; - if (annotation.body) { - return `${name}(${annotation.body})`; + renderComments(lines: string | string[]): string { + lines = FormatHelpers.breakLines(lines); + return `/** +${lines.map(line => ` * ${line}`).join('\n')} + */`; + } + + renderAnnotation(annotationName: string, value?: any | Record): string { + const name = `@${FormatHelpers.upperFirst(annotationName)}`; + let values = undefined; + if (value !== undefined) { + if (typeof value === 'object') { + values = Object.entries(value || {}).map(([paramName, value]) => { + if (paramName && value !== undefined) { + return `${paramName}=${value}`; + } + return value; + }).filter(v => v !== undefined).join(', '); + } else { + values = `${value}`; + } } - return name; + return values !== undefined ? `${name}(${values})` : name; } } diff --git a/src/generators/java/renderers/ClassRenderer.ts b/src/generators/java/renderers/ClassRenderer.ts index 10ca8b3d69..e723e92bc5 100644 --- a/src/generators/java/renderers/ClassRenderer.ts +++ b/src/generators/java/renderers/ClassRenderer.ts @@ -17,7 +17,8 @@ export class ClassRenderer extends JavaRenderer { await this.runAdditionalContentPreset(), ]; - return `public class ${this.model.$id} { + const formattedName = this.model.$id && FormatHelpers.toPascalCase(this.model.$id); + return `public class ${formattedName} { ${this.indent(this.renderBlock(content, 2))} }`; } @@ -31,15 +32,15 @@ ${this.indent(this.renderBlock(content, 2))} const content: string[] = []; for (const [propertyName, property] of Object.entries(properties)) { - const rendererProperty = await this.runPropertyPreset(propertyName, property, this.model); + const rendererProperty = await this.runPropertyPreset(propertyName, property); content.push(rendererProperty); } return this.renderBlock(content); } - async runPropertyPreset(propertyName: string, property: CommonModel, parentModel: CommonModel): Promise { - return this.runPreset('property', { propertyName, property, parentModel }); + async runPropertyPreset(propertyName: string, property: CommonModel): Promise { + return this.runPreset('property', { propertyName, property }); } async renderAccessors(): Promise { @@ -47,20 +48,20 @@ ${this.indent(this.renderBlock(content, 2))} const content: string[] = []; for (const [propertyName, property] of Object.entries(properties)) { - const getter = await this.runGetterPreset(propertyName, property, this.model); - const setter = await this.runSetterPreset(propertyName, property, this.model); + const getter = await this.runGetterPreset(propertyName, property); + const setter = await this.runSetterPreset(propertyName, property); content.push(this.renderBlock([getter, setter])); } return this.renderBlock(content, 2); } - async runGetterPreset(propertyName: string, property: CommonModel, parentModel: CommonModel): Promise { - return this.runPreset('getter', { propertyName, property, parentModel }); + async runGetterPreset(propertyName: string, property: CommonModel): Promise { + return this.runPreset('getter', { propertyName, property }); } - async runSetterPreset(propertyName: string, property: CommonModel, parentModel: CommonModel): Promise { - return this.runPreset('setter', { propertyName, property, parentModel }); + async runSetterPreset(propertyName: string, property: CommonModel): Promise { + return this.runPreset('setter', { propertyName, property }); } } diff --git a/src/generators/java/renderers/EnumRenderer.ts b/src/generators/java/renderers/EnumRenderer.ts index f58f30dda6..9c3563d638 100644 --- a/src/generators/java/renderers/EnumRenderer.ts +++ b/src/generators/java/renderers/EnumRenderer.ts @@ -1,6 +1,6 @@ import { JavaRenderer } from '../JavaRenderer'; -import { CommonModel, EnumPreset } from '../../../models'; +import { EnumPreset } from '../../../models'; import { FormatHelpers } from '../../../helpers'; /** @@ -15,7 +15,8 @@ export class EnumRenderer extends JavaRenderer { await this.runAdditionalContentPreset(), ]; - return `public enum ${this.model.$id} { + const formattedName = this.model.$id && FormatHelpers.toPascalCase(this.model.$id); + return `public enum ${formattedName} { ${this.indent(this.renderBlock(content, 2))} }`; } @@ -25,7 +26,7 @@ ${this.indent(this.renderBlock(content, 2))} const items: string[] = []; for (const value of enums) { - const renderedItem = await this.runItemPreset(value, this.model); + const renderedItem = await this.runItemPreset(value); items.push(renderedItem); } @@ -55,8 +56,8 @@ ${this.indent(this.renderBlock(content, 2))} } } - async runItemPreset(item: any, parentModel: CommonModel): Promise { - return this.runPreset('item', { item, parentModel }); + async runItemPreset(item: any): Promise { + return this.runPreset('item', { item }); } } diff --git a/src/generators/javascript/renderers/ClassRenderer.ts b/src/generators/javascript/renderers/ClassRenderer.ts index 76a5f39616..3889883138 100644 --- a/src/generators/javascript/renderers/ClassRenderer.ts +++ b/src/generators/javascript/renderers/ClassRenderer.ts @@ -17,7 +17,8 @@ export class ClassRenderer extends JavaScriptRenderer { await this.runAdditionalContentPreset(), ]; - return `class ${this.model.$id} { + const formattedName = this.model.$id && FormatHelpers.toPascalCase(this.model.$id); + return `class ${formattedName} { ${this.indent(this.renderBlock(content, 2))} }`; } @@ -31,20 +32,20 @@ ${this.indent(this.renderBlock(content, 2))} const content: string[] = []; for (const [propertyName, property] of Object.entries(properties)) { - const getter = await this.runGetterPreset(propertyName, property, this.model); - const setter = await this.runSetterPreset(propertyName, property, this.model); + const getter = await this.runGetterPreset(propertyName, property); + const setter = await this.runSetterPreset(propertyName, property); content.push(this.renderBlock([getter, setter])); } return this.renderBlock(content, 2); } - async runGetterPreset(propertyName: string, property: CommonModel, parentModel: CommonModel): Promise { - return this.runPreset('getter', { propertyName, property, parentModel }); + async runGetterPreset(propertyName: string, property: CommonModel): Promise { + return this.runPreset('getter', { propertyName, property }); } - async runSetterPreset(propertyName: string, property: CommonModel, parentModel: CommonModel): Promise { - return this.runPreset('setter', { propertyName, property, parentModel }); + async runSetterPreset(propertyName: string, property: CommonModel): Promise { + return this.runPreset('setter', { propertyName, property }); } } diff --git a/src/generators/typescript/TypeScriptRenderer.ts b/src/generators/typescript/TypeScriptRenderer.ts index 823eae09e7..c689807c0e 100644 --- a/src/generators/typescript/TypeScriptRenderer.ts +++ b/src/generators/typescript/TypeScriptRenderer.ts @@ -36,7 +36,7 @@ export abstract class TypeScriptRenderer extends AbstractRenderer ` * ${line}`).join('\n')} const content: string[] = []; for (const [propertyName, property] of Object.entries(properties)) { - const rendererProperty = await this.runPropertyPreset(propertyName, property, this.model); + const rendererProperty = await this.runPropertyPreset(propertyName, property); content.push(rendererProperty); } return this.renderBlock(content); } - renderProperty(propertyName: string, property: CommonModel, parentModel: CommonModel): string { + renderProperty(propertyName: string, property: CommonModel): string { const name = FormatHelpers.toCamelCase(propertyName); - const signature = this.renderTypeSignature(property, parentModel.isRequired(propertyName)); + const signature = this.renderTypeSignature(property, { isRequired: this.model.isRequired(propertyName) }); return `${name}${signature};`; } - async runPropertyPreset(propertyName: string, property: CommonModel, parentModel: CommonModel): Promise { - return this.runPreset('property', { propertyName, property, parentModel }); + async runPropertyPreset(propertyName: string, property: CommonModel): Promise { + return this.runPreset('property', { propertyName, property }); } } diff --git a/src/generators/typescript/renderers/ClassRenderer.ts b/src/generators/typescript/renderers/ClassRenderer.ts index 50c91f191a..91b722b4dd 100644 --- a/src/generators/typescript/renderers/ClassRenderer.ts +++ b/src/generators/typescript/renderers/ClassRenderer.ts @@ -17,7 +17,8 @@ export class ClassRenderer extends TypeScriptRenderer { await this.runAdditionalContentPreset(), ]; - return `class ${this.model.$id} { + const formattedName = this.model.$id && FormatHelpers.toPascalCase(this.model.$id); + return `class ${formattedName} { ${this.indent(this.renderBlock(content, 2))} }`; } @@ -31,20 +32,20 @@ ${this.indent(this.renderBlock(content, 2))} const content: string[] = []; for (const [propertyName, property] of Object.entries(properties)) { - const getter = await this.runGetterPreset(propertyName, property, this.model); - const setter = await this.runSetterPreset(propertyName, property, this.model); + const getter = await this.runGetterPreset(propertyName, property); + const setter = await this.runSetterPreset(propertyName, property); content.push(this.renderBlock([getter, setter])); } return this.renderBlock(content, 2); } - runGetterPreset(propertyName: string, property: CommonModel, parentModel: CommonModel): Promise { - return this.runPreset('getter', { propertyName, property, parentModel }); + runGetterPreset(propertyName: string, property: CommonModel): Promise { + return this.runPreset('getter', { propertyName, property }); } - runSetterPreset(propertyName: string, property: CommonModel, parentModel: CommonModel): Promise { - return this.runPreset('setter', { propertyName, property, parentModel }); + runSetterPreset(propertyName: string, property: CommonModel): Promise { + return this.runPreset('setter', { propertyName, property }); } } @@ -60,7 +61,7 @@ export const TS_DEFAULT_CLASS_PRESET: ClassPreset = { }); const ctorProperties: string[] = []; for (const [propertyName, property] of Object.entries(properties)) { - const rendererProperty = renderer.renderProperty(propertyName, property, model).replace(';', ','); + const rendererProperty = renderer.renderProperty(propertyName, property).replace(';', ','); ctorProperties.push(rendererProperty); } @@ -70,18 +71,20 @@ ${renderer.indent(renderer.renderBlock(ctorProperties))} ${renderer.indent(renderer.renderBlock(assigments))} }`; }, - property({ renderer, propertyName, property, parentModel }) { - return `private _${renderer.renderProperty(propertyName, property, parentModel)}`; + property({ renderer, propertyName, property }) { + return `private _${renderer.renderProperty(propertyName, property)}`; }, - getter({ renderer, propertyName, property }) { - propertyName = FormatHelpers.toCamelCase(propertyName); - const signature = renderer.renderTypeSignature(property); - return `get ${propertyName}()${signature} { return this._${propertyName}; }`; + getter({ renderer, model, propertyName, property }) { + const isRequired = model.isRequired(propertyName); + const formattedName = FormatHelpers.toCamelCase(propertyName); + const signature = renderer.renderTypeSignature(property, { orUndefined: !isRequired }); + return `get ${formattedName}()${signature} { return this._${formattedName}; }`; }, - setter({ renderer, propertyName, property }) { - propertyName = FormatHelpers.toCamelCase(propertyName); - const signature = renderer.renderTypeSignature(property); - const arg = `${propertyName}${signature}`; - return `set ${propertyName}(${arg}) { this._${propertyName} = ${propertyName}; }`; + setter({ renderer, model, propertyName, property }) { + const isRequired = model.isRequired(propertyName); + const formattedName = FormatHelpers.toCamelCase(propertyName); + const signature = renderer.renderTypeSignature(property, { orUndefined: !isRequired }); + const arg = `${formattedName}${signature}`; + return `set ${formattedName}(${arg}) { this._${formattedName} = ${formattedName}; }`; }, }; diff --git a/src/generators/typescript/renderers/EnumRenderer.ts b/src/generators/typescript/renderers/EnumRenderer.ts index ca377aeaa5..adc0606e06 100644 --- a/src/generators/typescript/renderers/EnumRenderer.ts +++ b/src/generators/typescript/renderers/EnumRenderer.ts @@ -1,6 +1,6 @@ import { TypeScriptRenderer } from '../TypeScriptRenderer'; -import { CommonModel, EnumPreset } from '../../../models'; +import { EnumPreset } from '../../../models'; import { FormatHelpers } from '../../../helpers'; /** @@ -15,7 +15,8 @@ export class EnumRenderer extends TypeScriptRenderer { await this.runAdditionalContentPreset(), ]; - return `enum ${this.model.$id} { + const formattedName = this.model.$id && FormatHelpers.toPascalCase(this.model.$id); + return `enum ${formattedName} { ${this.indent(this.renderBlock(content, 2))} }`; } @@ -25,15 +26,15 @@ ${this.indent(this.renderBlock(content, 2))} const items: string[] = []; for (const item of enums) { - const renderedItem = await this.runItemPreset(item, this.model); + const renderedItem = await this.runItemPreset(item); items.push(renderedItem); } return this.renderBlock(items); } - runItemPreset(item: any, parentModel: CommonModel): Promise { - return this.runPreset('item', { item, parentModel }); + runItemPreset(item: any): Promise { + return this.runPreset('item', { item }); } } diff --git a/src/generators/typescript/renderers/InterfaceRenderer.ts b/src/generators/typescript/renderers/InterfaceRenderer.ts index 63433f5d30..f40113b6a8 100644 --- a/src/generators/typescript/renderers/InterfaceRenderer.ts +++ b/src/generators/typescript/renderers/InterfaceRenderer.ts @@ -1,6 +1,7 @@ import { TypeScriptRenderer } from '../TypeScriptRenderer'; import { InterfacePreset } from '../../../models'; +import { FormatHelpers } from '../../../helpers'; /** * Renderer for TypeScript's `interface` type @@ -14,7 +15,8 @@ export class InterfaceRenderer extends TypeScriptRenderer { await this.runAdditionalContentPreset(), ]; - return `interface ${this.model.$id} { + const formattedName = this.model.$id && FormatHelpers.toPascalCase(this.model.$id); + return `interface ${formattedName} { ${this.indent(this.renderBlock(content, 2))} }`; } @@ -24,7 +26,7 @@ export const TS_DEFAULT_INTERFACE_PRESET: InterfacePreset = { async self({ renderer }) { return `export ${await renderer.defaultSelf()}`; }, - property({ renderer, propertyName, property, parentModel }) { - return renderer.renderProperty(propertyName, property, parentModel); + property({ renderer, propertyName, property }) { + return renderer.renderProperty(propertyName, property); }, }; diff --git a/src/generators/typescript/renderers/TypeRenderer.ts b/src/generators/typescript/renderers/TypeRenderer.ts index e54cb65508..24b5401889 100644 --- a/src/generators/typescript/renderers/TypeRenderer.ts +++ b/src/generators/typescript/renderers/TypeRenderer.ts @@ -1,7 +1,7 @@ import { TypeScriptRenderer } from '../TypeScriptRenderer'; -import { TypeHelpers, ModelKind } from '../../../helpers'; import { TypePreset } from '../TypeScriptPreset'; +import { FormatHelpers, TypeHelpers, ModelKind } from '../../../helpers'; /** * Renderer for TypeScript's `type` type @@ -11,7 +11,8 @@ import { TypePreset } from '../TypeScriptPreset'; export class TypeRenderer extends TypeScriptRenderer { async defaultSelf(): Promise { const body = await this.renderTypeBody(); - return `type ${this.model.$id} = ${body};`; + const formattedName = this.model.$id && FormatHelpers.toPascalCase(this.model.$id); + return `type ${formattedName} = ${body};`; } async renderTypeBody(): Promise { diff --git a/src/models/Preset.ts b/src/models/Preset.ts index 8e97989c5b..5cf45f5c2c 100644 --- a/src/models/Preset.ts +++ b/src/models/Preset.ts @@ -16,7 +16,6 @@ export interface CommonPreset { return this._arrayType; } set arrayType(arrayType: Array) { this._arrayType = arrayType; } }`; const inputModel = await generator.process(doc); - const model = inputModel.models["Address"]; + const model = inputModel.models["_address"]; let classModel = await generator.renderClass(model, inputModel); expect(classModel).toEqual(expected); @@ -98,8 +98,8 @@ describe('TypeScriptGenerator', function() { this._property = input.property; } - get property(): string { return this._property; } - set property(property: string) { this._property = property; } + get property(): string | undefined { return this._property; } + set property(property: string | undefined) { this._property = property; } }`; generator = new TypeScriptGenerator({ presets: [