Skip to content

Commit

Permalink
feat!: refactors generators to use the same arg types (#1505)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennethaasan authored Sep 14, 2023
1 parent 35d1b6c commit 7db1bd7
Show file tree
Hide file tree
Showing 15 changed files with 418 additions and 254 deletions.
43 changes: 30 additions & 13 deletions src/generators/AbstractGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,25 @@ export const defaultGeneratorOptions: CommonGeneratorOptions = {
}
};

export interface AbstractGeneratorRenderArgs<
Options extends CommonGeneratorOptions,
ConstrainedModel = ConstrainedMetaModel
> {
constrainedModel: ConstrainedModel;
inputModel: InputMetaModel;
options?: DeepPartial<Options>;
}

export interface AbstractGeneratorRenderCompleteModelArgs<
Options extends CommonGeneratorOptions,
RenderCompleteModelOptions
> {
constrainedModel: ConstrainedMetaModel;
inputModel: InputMetaModel;
completeOptions: Partial<RenderCompleteModelOptions>;
options?: DeepPartial<Options>;
}

/**
* Abstract generator which must be implemented by each language
*/
Expand All @@ -56,15 +75,13 @@ export abstract class AbstractGenerator<
) {}

public abstract render(
model: MetaModel,
inputModel: InputMetaModel,
options?: DeepPartial<Options>
args: AbstractGeneratorRenderArgs<Options>
): Promise<RenderOutput>;
public abstract renderCompleteModel(
model: MetaModel,
inputModel: InputMetaModel,
completeOptions: Partial<RenderCompleteModelOptions>,
options?: DeepPartial<Options>
args: AbstractGeneratorRenderCompleteModelArgs<
Options,
RenderCompleteModelOptions
>
): Promise<RenderOutput>;
public abstract constrainToMetaModel(
model: MetaModel,
Expand Down Expand Up @@ -186,12 +203,12 @@ export abstract class AbstractGenerator<
return Promise.all(
this.getConstrainedModels(inputModel).map(
async ({ constrainedModel, dependencyManager }) => {
const renderedOutput = await this.renderCompleteModel(
const renderedOutput = await this.renderCompleteModel({
constrainedModel,
inputModel,
completeOptions,
{ dependencyManager } as DeepPartial<Options>
);
options: { dependencyManager } as DeepPartial<Options>
});
return OutputModel.toOutputModel({
result: renderedOutput.result,
modelName: renderedOutput.renderedName,
Expand All @@ -213,13 +230,13 @@ export abstract class AbstractGenerator<
return Promise.all(
this.getConstrainedModels(inputModel).map(
async ({ constrainedModel, dependencyManager }) => {
const renderedOutput = await this.render(
const renderedOutput = await this.render({
constrainedModel,
inputModel,
{
options: {
dependencyManager
} as DeepPartial<Options>
);
});
return OutputModel.toOutputModel({
result: renderedOutput.result,
modelName: renderedOutput.renderedName,
Expand Down
55 changes: 34 additions & 21 deletions src/generators/cplusplus/CplusplusGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
AbstractGenerator,
AbstractGeneratorRenderArgs,
AbstractGeneratorRenderCompleteModelArgs,
CommonGeneratorOptions,
defaultGeneratorOptions
} from '../AbstractGenerator';
Expand Down Expand Up @@ -121,26 +123,32 @@ export class CplusplusGenerator extends AbstractGenerator<
* @param inputModel
*/
render(
model: ConstrainedMetaModel,
inputModel: InputMetaModel,
options?: DeepPartial<CplusplusOptions>
args: AbstractGeneratorRenderArgs<CplusplusOptions>
): Promise<RenderOutput> {
const optionsToUse = CplusplusGenerator.getOptions({
...this.options,
...options
...args.options
});
if (isReservedCplusplusKeyword(optionsToUse.namespace)) {
throw new Error(
`You cannot use reserved C++ keyword (${optionsToUse.namespace}) as namespace, please use another.`
);
}
if (model instanceof ConstrainedObjectModel) {
return this.renderClass(model, inputModel, optionsToUse);
} else if (model instanceof ConstrainedEnumModel) {
return this.renderEnum(model, inputModel, optionsToUse);
if (args.constrainedModel instanceof ConstrainedObjectModel) {
return this.renderClass(
args.constrainedModel,
args.inputModel,
optionsToUse
);
} else if (args.constrainedModel instanceof ConstrainedEnumModel) {
return this.renderEnum(
args.constrainedModel,
args.inputModel,
optionsToUse
);
}
Logger.warn(
`C++ generator, cannot generate this type of model, ${model.name}`
`C++ generator, cannot generate this type of model, ${args.constrainedModel.name}`
);
return Promise.resolve(
RenderOutput.toRenderOutput({
Expand All @@ -161,30 +169,35 @@ export class CplusplusGenerator extends AbstractGenerator<
* @param options used to render the full output
*/
async renderCompleteModel(
model: ConstrainedMetaModel,
inputModel: InputMetaModel,
completeModelOptions: Partial<CplusplusRenderCompleteModelOptions>,
options: DeepPartial<CplusplusOptions>
args: AbstractGeneratorRenderCompleteModelArgs<
CplusplusOptions,
CplusplusRenderCompleteModelOptions
>
): Promise<RenderOutput> {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const completeModelOptionsToUse = mergePartialAndDefault(
CplusplusGenerator.defaultCompleteModelOptions,
completeModelOptions
args.completeOptions
) as CplusplusRenderCompleteModelOptions;
const optionsToUse = CplusplusGenerator.getOptions({
...this.options,
...options
...args.options
});
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);

const outputModel = await this.render(model, inputModel, {
...optionsToUse,
dependencyManager: dependencyManagerToUse
const outputModel = await this.render({
...args,
options: {
...optionsToUse,
dependencyManager: dependencyManagerToUse
}
});

const imports = model.getNearestDependencies().map((model) => {
return `#include "${model.name}.hpp"`;
});
const imports = args.constrainedModel
.getNearestDependencies()
.map((model) => {
return `#include "${model.name}.hpp"`;
});
const formattedOutputResult = FormatHelpers.indent(
outputModel.result,
2,
Expand Down
49 changes: 32 additions & 17 deletions src/generators/csharp/CSharpGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
AbstractGenerator,
AbstractGeneratorRenderArgs,
AbstractGeneratorRenderCompleteModelArgs,
CommonGeneratorOptions,
defaultGeneratorOptions
} from '../AbstractGenerator';
Expand Down Expand Up @@ -146,26 +148,29 @@ export class CSharpGenerator extends AbstractGenerator<
* @param options used to render the full output
*/
async renderCompleteModel(
model: ConstrainedMetaModel,
inputModel: InputMetaModel,
completeModelOptions: DeepPartial<CSharpRenderCompleteModelOptions>,
options: DeepPartial<CSharpOptions>
args: AbstractGeneratorRenderCompleteModelArgs<
CSharpOptions,
CSharpRenderCompleteModelOptions
>
): Promise<RenderOutput> {
const completeModelOptionsToUse = mergePartialAndDefault(
CSharpGenerator.defaultCompleteModelOptions,
completeModelOptions
args.completeOptions
) as CSharpRenderCompleteModelOptions;
const optionsToUse = CSharpGenerator.getCSharpOptions({
...this.options,
...options
...args.options
});
if (isReservedCSharpKeyword(completeModelOptionsToUse.namespace)) {
throw new Error(
`You cannot use reserved CSharp keyword (${completeModelOptionsToUse.namespace}) as namespace, please use another.`
);
}

const outputModel = await this.render(model, inputModel);
const outputModel = await this.render({
...args,
options: optionsToUse
});

const outputDependencies =
outputModel.dependencies.length === 0
Expand All @@ -189,24 +194,34 @@ ${FormatHelpers.indent(
}

render(
model: ConstrainedMetaModel,
inputModel: InputMetaModel,
options?: DeepPartial<CSharpOptions>
args: AbstractGeneratorRenderArgs<CSharpOptions>
): Promise<RenderOutput> {
const optionsToUse = CSharpGenerator.getCSharpOptions({
...this.options,
...options
...args.options
});
if (model instanceof ConstrainedObjectModel) {
if (args.constrainedModel instanceof ConstrainedObjectModel) {
if (this.options.modelType === 'record') {
return this.renderRecord(model, inputModel, optionsToUse);
return this.renderRecord(
args.constrainedModel,
args.inputModel,
optionsToUse
);
}
return this.renderClass(model, inputModel, optionsToUse);
} else if (model instanceof ConstrainedEnumModel) {
return this.renderEnum(model, inputModel, optionsToUse);
return this.renderClass(
args.constrainedModel,
args.inputModel,
optionsToUse
);
} else if (args.constrainedModel instanceof ConstrainedEnumModel) {
return this.renderEnum(
args.constrainedModel,
args.inputModel,
optionsToUse
);
}
Logger.warn(
`C# generator, cannot generate this type of model, ${model.name}`
`C# generator, cannot generate this type of model, ${args.constrainedModel.name}`
);
return Promise.resolve(
RenderOutput.toRenderOutput({
Expand Down
42 changes: 25 additions & 17 deletions src/generators/dart/DartGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import {
AbstractGenerator,
AbstractGeneratorRenderArgs,
AbstractGeneratorRenderCompleteModelArgs,
CommonGeneratorOptions,
defaultGeneratorOptions
} from '../AbstractGenerator';
Expand Down Expand Up @@ -121,21 +123,27 @@ export class DartGenerator extends AbstractGenerator<
* @param inputModel
*/
render(
model: ConstrainedMetaModel,
inputModel: InputMetaModel,
options?: DeepPartial<DartOptions>
args: AbstractGeneratorRenderArgs<DartOptions>
): Promise<RenderOutput> {
const optionsToUse = DartGenerator.getDartOptions({
...this.options,
...options
...args.options
});
if (model instanceof ConstrainedObjectModel) {
return this.renderClass(model, inputModel, optionsToUse);
} else if (model instanceof ConstrainedEnumModel) {
return this.renderEnum(model, inputModel, optionsToUse);
if (args.constrainedModel instanceof ConstrainedObjectModel) {
return this.renderClass(
args.constrainedModel,
args.inputModel,
optionsToUse
);
} else if (args.constrainedModel instanceof ConstrainedEnumModel) {
return this.renderEnum(
args.constrainedModel,
args.inputModel,
optionsToUse
);
}
Logger.warn(
`Dart generator, cannot generate this type of model, ${model.name}`
`Dart generator, cannot generate this type of model, ${args.constrainedModel.name}`
);
return Promise.resolve(
RenderOutput.toRenderOutput({
Expand All @@ -156,18 +164,18 @@ export class DartGenerator extends AbstractGenerator<
* @param options used to render the full output
*/
async renderCompleteModel(
model: ConstrainedMetaModel,
inputModel: InputMetaModel,
completeModelOptions: Partial<DartRenderCompleteModelOptions>,
options: DeepPartial<DartOptions>
args: AbstractGeneratorRenderCompleteModelArgs<
DartOptions,
DartRenderCompleteModelOptions
>
): Promise<RenderOutput> {
const completeModelOptionsToUse = mergePartialAndDefault(
DartGenerator.defaultCompleteModelOptions,
completeModelOptions
args.completeOptions
) as DartRenderCompleteModelOptions;
const optionsToUse = DartGenerator.getDartOptions({
...this.options,
...options
...args.options
});
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
if (isReservedDartKeyword(completeModelOptionsToUse.packageName)) {
Expand All @@ -176,9 +184,9 @@ export class DartGenerator extends AbstractGenerator<
);
}

const outputModel = await this.render(model, inputModel, optionsToUse);
const outputModel = await this.render({ ...args, options: optionsToUse });
const modelDependencies = dependencyManagerToUse.renderAllModelDependencies(
model,
args.constrainedModel,
completeModelOptionsToUse.packageName
);
const outputContent = `${modelDependencies}
Expand Down
Loading

0 comments on commit 7db1bd7

Please sign in to comment.