Skip to content

Commit

Permalink
Fixed remaining issues with dependency managers
Browse files Browse the repository at this point in the history
  • Loading branch information
jonaslagoni committed Jan 17, 2023
1 parent ee4113e commit 5ab42aa
Show file tree
Hide file tree
Showing 30 changed files with 255 additions and 178 deletions.
16 changes: 14 additions & 2 deletions docs/generators.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,26 @@

## Generator's options

Each generator extends default options for the generator. It means that the generator can also have additional options.
For Modelina, there exist 3 types of options for the generation process.
1. Default options, are the default options the rest overwrite.
2. Generator options, are used as the baseline that is by default used for each model render.
3. Render options, are the last resort to specialize options for the individual rendering of a model, that overwrite the generator options.

Options are passed as the first argument to the generator's constructor. Check the example:
Generator options are passed as the first argument to the generator's constructor. Check the example:

```ts
const generator = new TypeScriptGenerator({ ...options });
```

Render options are passed as the first argument to the generator's render function. Check the example:

```ts
const generator = ...
const model = ...
const inputModel = ...
generator.render(model, inputModel, { ...options });
```

Default generator options (common to all generators) are as follows:

| Option | Type | Description | Default value |
Expand Down
21 changes: 21 additions & 0 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@ For more specific integration options, please check out the [integration documen

<!-- tocstop -->

## Generator's options

For Modelina, there exist 3 types of options for the generation process.
1. Default options, are the default options the rest overwrite.
2. Generator options, are used as the baseline options used for each model rendering, unless otherwise specified.
3. Render options, are the last options to specify before the rendering of a model, this is used to specialize the options for individual rendering of a model.

Generator options are passed as the first argument to the generator's constructor. Check the example:

```ts
const generator = new TypeScriptGenerator({ ...options });
```

Render options are passed as the first argument to the generator's render function. Check the example:

```ts
const generator = ...
generator.render(model, inputModel, { ...options });

```

## Understanding the output format

The output format is designed for you to use the generated models in further contexts. It might be part of a larger code generation such as AsyncAPI templates. This means that you can glue multiple models together into one large file, or split it out as you see fit.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class ObjProperty:

exports[`Should be able to render python models and should generate \`implicit\` or \`explicit\` imports for models implementing referenced types: root-model-explicit-import 1`] = `
Array [
"from .ObjProperty import ObjProperty
"from ObjProperty import ObjProperty
class Root:
def __init__(self, input):
Expand Down
2 changes: 1 addition & 1 deletion src/generators/AbstractDependencyManager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export abstract class AbstractDependencyManager {
export class AbstractDependencyManager {
constructor(
public dependencies: string[] = []
) {}
Expand Down
15 changes: 8 additions & 7 deletions src/generators/AbstractGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ export abstract class AbstractGenerator<
public abstract render(model: MetaModel, inputModel: InputMetaModel, options?: DeepPartial<Options>): Promise<RenderOutput>;
public abstract renderCompleteModel(model: MetaModel, inputModel: InputMetaModel, completeOptions: Partial<RenderCompleteModelOptions>, options?: DeepPartial<Options>): Promise<RenderOutput>;
public abstract constrainToMetaModel(model: MetaModel, options: DeepPartial<Options>): ConstrainedMetaModel;
public abstract getDependencyManager(options: Options): AbstractDependencyManager;
public abstract splitMetaModel(model: MetaModel): MetaModel[];

public process(input: Record<string, unknown>): Promise<InputMetaModel> {
return InputProcessor.processor.process(input, this.options.processorOptions);
}

/**
* This function returns an instance of the dependency manager.
* This function returns an instance of the dependency manager which is either a factory or an instance.
*/
protected getDependencyManagerInstance(options: Options): AbstractDependencyManager {
if (options.dependencyManager === undefined) {
Expand All @@ -71,9 +72,9 @@ export abstract class AbstractGenerator<
public async generateCompleteModels(input: any | InputMetaModel, completeOptions: Partial<RenderCompleteModelOptions>): Promise<OutputModel[]> {
const inputModel = await this.processInput(input);
const renders = Object.values(inputModel.models).map(async (model) => {
const dependencyManager = this.getDependencyManagerInstance(this.options);
const constrainedModel = this.constrainToMetaModel(model, {dependencyManager} as any);
const renderedOutput = await this.renderCompleteModel(constrainedModel, inputModel, completeOptions, {dependencyManager} as any);
const dependencyManager = this.getDependencyManager(this.options);
const constrainedModel = this.constrainToMetaModel(model, {dependencyManager} as DeepPartial<Options>);
const renderedOutput = await this.renderCompleteModel(constrainedModel, inputModel, completeOptions, {dependencyManager} as DeepPartial<Options>);
return OutputModel.toOutputModel({
result: renderedOutput.result,
modelName: renderedOutput.renderedName,
Expand All @@ -91,9 +92,9 @@ export abstract class AbstractGenerator<
public async generate(input: any | InputMetaModel): Promise<OutputModel[]> {
const inputModel = await this.processInput(input);
const renders = Object.values(inputModel.models).map(async (model) => {
const dependencyManager = this.getDependencyManagerInstance(this.options);
const constrainedModel = this.constrainToMetaModel(model, dependencyManager as any);
const renderedOutput = await this.render(constrainedModel, inputModel, {dependencyManager} as any);
const dependencyManager = this.getDependencyManager(this.options);
const constrainedModel = this.constrainToMetaModel(model, {dependencyManager} as DeepPartial<Options>);
const renderedOutput = await this.render(constrainedModel, inputModel, {dependencyManager} as DeepPartial<Options>);
return OutputModel.toOutputModel({
result: renderedOutput.result,
modelName: renderedOutput.renderedName,
Expand Down
2 changes: 1 addition & 1 deletion src/generators/AbstractRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { FormatHelpers, IndentationTypes } from '../helpers';
*/
export abstract class AbstractRenderer<
O extends CommonGeneratorOptions = CommonGeneratorOptions,
G extends AbstractGenerator = AbstractGenerator,
G extends AbstractGenerator<any, any> = AbstractGenerator<any, any>,
RendererModelType extends ConstrainedMetaModel = ConstrainedMetaModel
> {
constructor(
Expand Down
7 changes: 4 additions & 3 deletions src/generators/csharp/CSharpConstrainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { TypeMapping } from '../../helpers';
import { defaultEnumKeyConstraints, defaultEnumValueConstraints } from './constrainer/EnumConstrainer';
import { defaultModelNameConstraints } from './constrainer/ModelNameConstrainer';
import { defaultPropertyKeyConstraints } from './constrainer/PropertyKeyConstrainer';
import { CSharpTypeMapping } from './CSharpGenerator';
import { CSharpOptions, CSharpTypeMapping } from './CSharpGenerator';
import { CSharpDependencyManager } from './CSharpDependencyManager';

function getFullTypeDefinition(typeName: string, partOfProperty: ConstrainedObjectPropertyModel | undefined) {
return partOfProperty?.required ?? true
Expand All @@ -29,7 +30,7 @@ const fromEnumValueToType = (enumValueModel: ConstrainedEnumValueModel): string
}
};

export const CSharpDefaultTypeMapping: TypeMapping<CSharpOptions> = {
export const CSharpDefaultTypeMapping: TypeMapping<CSharpOptions, CSharpDependencyManager> = {
Object({ constrainedModel, partOfProperty }): string {
return getFullTypeDefinition(constrainedModel.name, partOfProperty);
},
Expand Down Expand Up @@ -79,7 +80,7 @@ export const CSharpDefaultTypeMapping: TypeMapping<CSharpOptions> = {
return getFullTypeDefinition(typeForValues, partOfProperty);
},
Union({ partOfProperty }): string {
//BecauserenderPrivateType( CSharp , partOfProperty) have no notion of unions (and no custom implementation), we have to render it as any value.
//Because renderPrivateType( CSharp , partOfProperty) have no notion of unions (and no custom implementation), we have to render it as any value.

return getFullTypeDefinition('dynamic', partOfProperty);
},
Expand Down
8 changes: 4 additions & 4 deletions src/generators/csharp/CSharpGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export class CSharpGenerator extends AbstractGenerator<CSharpOptions, CSharpRend
/**
* Wrapper to get an instance of the dependency manager
*/
getCSharpDependencyManager(options: CSharpOptions): CSharpDependencyManager {
getDependencyManager(options: CSharpOptions): CSharpDependencyManager {
return this.getDependencyManagerInstance(options) as CSharpDependencyManager;
}

Expand All @@ -84,7 +84,7 @@ export class CSharpGenerator extends AbstractGenerator<CSharpOptions, CSharpRend

constrainToMetaModel(model: MetaModel, options: DeepPartial<CSharpOptions>): ConstrainedMetaModel {
const optionsToUse = CSharpGenerator.getCSharpOptions({...this.options, ...options});
const dependencyManagerToUse = this.getCSharpDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
return constrainMetaModel<CSharpOptions, CSharpDependencyManager>(
this.options.typeMapping,
this.options.constraints,
Expand Down Expand Up @@ -138,7 +138,7 @@ ${FormatHelpers.indent(outputDependencies + outputModel.result, optionsToUse.ind

async renderEnum(model: ConstrainedEnumModel, inputModel: InputMetaModel, options?: Partial<CSharpOptions>): Promise<RenderOutput> {
const optionsToUse = CSharpGenerator.getCSharpOptions({...this.options, ...options});
const dependencyManagerToUse = this.getCSharpDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
const presets = this.getPresets('enum');
const renderer = new EnumRenderer(this.options, this, presets, model, inputModel, dependencyManagerToUse);
const result = await renderer.runSelfPreset();
Expand All @@ -147,7 +147,7 @@ ${FormatHelpers.indent(outputDependencies + outputModel.result, optionsToUse.ind

async renderClass(model: ConstrainedObjectModel, inputModel: InputMetaModel, options?: Partial<CSharpOptions>): Promise<RenderOutput> {
const optionsToUse = CSharpGenerator.getCSharpOptions({...this.options, ...options});
const dependencyManagerToUse = this.getCSharpDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
const presets = this.getPresets('class');
const renderer = new ClassRenderer(this.options, this, presets, model, inputModel, dependencyManagerToUse);
const result = await renderer.runSelfPreset();
Expand Down
12 changes: 6 additions & 6 deletions src/generators/dart/DartGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class DartGenerator extends AbstractGenerator<DartOptions, DartRenderComp
constructor(
options?: DeepPartial<DartOptions>,
) {
const realizedOptions = mergePartialAndDefault(DartGenerator.defaultOptions, options) as DartOptions;
const realizedOptions = DartGenerator.getDartOptions(options);
super('Dart', realizedOptions);
}

Expand All @@ -61,7 +61,7 @@ export class DartGenerator extends AbstractGenerator<DartOptions, DartRenderComp
/**
* Wrapper to get an instance of the dependency manager
*/
getDartDependencyManager(options: DartOptions): DartDependencyManager {
getDependencyManager(options: DartOptions): DartDependencyManager {
return this.getDependencyManagerInstance(options) as DartDependencyManager;
}

Expand All @@ -76,7 +76,7 @@ export class DartGenerator extends AbstractGenerator<DartOptions, DartRenderComp

constrainToMetaModel(model: MetaModel, options: DeepPartial<DartOptions>): ConstrainedMetaModel {
const optionsToUse = DartGenerator.getDartOptions({...this.options, ...options});
const dependencyManagerToUse = this.getDartDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
return constrainMetaModel<DartOptions, DartDependencyManager>(
this.options.typeMapping,
this.options.constraints,
Expand Down Expand Up @@ -121,7 +121,7 @@ export class DartGenerator extends AbstractGenerator<DartOptions, DartRenderComp
options: DeepPartial<DartOptions>): Promise<RenderOutput> {
const completeModelOptionsToUse = mergePartialAndDefault(DartGenerator.defaultCompleteModelOptions, completeModelOptions) as DartRenderCompleteModelOptions;
const optionsToUse = DartGenerator.getDartOptions({...this.options, ...options});
const dependencyManagerToUse = this.getDartDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
if (isReservedDartKeyword(completeModelOptionsToUse.packageName)) {
throw new Error(`You cannot use reserved Dart keyword (${completeModelOptionsToUse.packageName}) as package name, please use another.`);
}
Expand All @@ -142,7 +142,7 @@ export class DartGenerator extends AbstractGenerator<DartOptions, DartRenderComp

async renderClass(model: ConstrainedObjectModel, inputModel: InputMetaModel, options?: DeepPartial<DartOptions>): Promise<RenderOutput> {
const optionsToUse = DartGenerator.getDartOptions({...this.options, ...options});
const dependencyManagerToUse = this.getDartDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
const presets = this.getPresets('class');
const renderer = new ClassRenderer(optionsToUse, this, presets, model, inputModel, dependencyManagerToUse);
const result = await renderer.runSelfPreset();
Expand All @@ -151,7 +151,7 @@ export class DartGenerator extends AbstractGenerator<DartOptions, DartRenderComp

async renderEnum(model: ConstrainedEnumModel, inputModel: InputMetaModel, options?: DeepPartial<DartOptions>): Promise<RenderOutput> {
const optionsToUse = DartGenerator.getDartOptions({...this.options, ...options});
const dependencyManagerToUse = this.getDartDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
const presets = this.getPresets('enum');
const renderer = new EnumRenderer(optionsToUse, this, presets, model, inputModel, dependencyManagerToUse);
const result = await renderer.runSelfPreset();
Expand Down
10 changes: 5 additions & 5 deletions src/generators/go/GoGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class GoGenerator extends AbstractGenerator<GoOptions, GoRenderCompleteMo
constructor(
options?: DeepPartial<GoOptions>,
) {
const realizedOptions = mergePartialAndDefault(GoGenerator.defaultOptions, options) as GoOptions;
const realizedOptions = GoGenerator.getGoOptions(options);
super('Go', realizedOptions);
}

Expand All @@ -61,7 +61,7 @@ export class GoGenerator extends AbstractGenerator<GoOptions, GoRenderCompleteMo
/**
* Wrapper to get an instance of the dependency manager
*/
getGoDependencyManager(options: GoOptions): GoDependencyManager {
getDependencyManager(options: GoOptions): GoDependencyManager {
return this.getDependencyManagerInstance(options) as GoDependencyManager;
}

Expand All @@ -76,7 +76,7 @@ export class GoGenerator extends AbstractGenerator<GoOptions, GoRenderCompleteMo

constrainToMetaModel(model: MetaModel, options: DeepPartial<GoOptions>): ConstrainedMetaModel {
const optionsToUse = GoGenerator.getGoOptions({...this.options, ...options});
const dependencyManagerToUse = this.getGoDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
return constrainMetaModel<GoOptions, GoDependencyManager>(
this.options.typeMapping,
this.options.constraints,
Expand Down Expand Up @@ -131,7 +131,7 @@ ${outputModel.result}`;

async renderEnum(model: ConstrainedEnumModel, inputModel: InputMetaModel, options?: DeepPartial<GoOptions>): Promise<RenderOutput> {
const optionsToUse = GoGenerator.getGoOptions({...this.options, ...options});
const dependencyManagerToUse = this.getGoDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
const presets = this.getPresets('enum');
const renderer = new EnumRenderer(optionsToUse, this, presets, model, inputModel, dependencyManagerToUse);
const result = await renderer.runSelfPreset();
Expand All @@ -140,7 +140,7 @@ ${outputModel.result}`;

async renderStruct(model: ConstrainedObjectModel, inputModel: InputMetaModel, options?: DeepPartial<GoOptions>): Promise<RenderOutput> {
const optionsToUse = GoGenerator.getGoOptions({...this.options, ...options});
const dependencyManagerToUse = this.getGoDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
const presets = this.getPresets('struct');
const renderer = new StructRenderer(optionsToUse, this, presets, model, inputModel, dependencyManagerToUse);
const result = await renderer.runSelfPreset();
Expand Down
12 changes: 6 additions & 6 deletions src/generators/java/JavaGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export class JavaGenerator extends AbstractGenerator<JavaOptions, JavaRenderComp
constructor(
options?: DeepPartial<JavaOptions>,
) {
const realizedOptions = mergePartialAndDefault(JavaGenerator.defaultOptions, options) as JavaOptions;
const realizedOptions = JavaGenerator.getJavaOptions(options);
super('Java', realizedOptions);
}

Expand All @@ -60,7 +60,7 @@ export class JavaGenerator extends AbstractGenerator<JavaOptions, JavaRenderComp
/**
* Wrapper to get an instance of the dependency manager
*/
getJavaDependencyManager(options: JavaOptions): JavaDependencyManager {
getDependencyManager(options: JavaOptions): JavaDependencyManager {
return this.getDependencyManagerInstance(options) as JavaDependencyManager;
}

Expand All @@ -75,7 +75,7 @@ export class JavaGenerator extends AbstractGenerator<JavaOptions, JavaRenderComp

constrainToMetaModel(model: MetaModel, options: DeepPartial<JavaOptions>): ConstrainedMetaModel {
const optionsToUse = JavaGenerator.getJavaOptions({...this.options, ...options});
const dependencyManagerToUse = this.getJavaDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
return constrainMetaModel<JavaOptions, JavaDependencyManager>(
this.options.typeMapping,
this.options.constraints,
Expand Down Expand Up @@ -119,7 +119,7 @@ export class JavaGenerator extends AbstractGenerator<JavaOptions, JavaRenderComp
options: DeepPartial<JavaOptions>): Promise<RenderOutput> {
const completeModelOptionsToUse = mergePartialAndDefault(JavaGenerator.defaultCompleteModelOptions, completeModelOptions) as JavaRenderCompleteModelOptions;
const optionsToUse = JavaGenerator.getJavaOptions({...this.options, ...options});
const dependencyManagerToUse = this.getJavaDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);

if (isReservedJavaKeyword(completeModelOptionsToUse.packageName)) {
throw new Error(`You cannot use reserved Java keyword (${completeModelOptionsToUse.packageName}) as package name, please use another.`);
Expand All @@ -138,7 +138,7 @@ ${outputModel.result}`;

async renderClass(model: ConstrainedObjectModel, inputModel: InputMetaModel, options?: DeepPartial<JavaOptions>): Promise<RenderOutput> {
const optionsToUse = JavaGenerator.getJavaOptions({...this.options, ...options});
const dependencyManagerToUse = this.getJavaDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
const presets = this.getPresets('class');
const renderer = new ClassRenderer(optionsToUse, this, presets, model, inputModel, dependencyManagerToUse);
const result = await renderer.runSelfPreset();
Expand All @@ -147,7 +147,7 @@ ${outputModel.result}`;

async renderEnum(model: ConstrainedEnumModel, inputModel: InputMetaModel, options?: DeepPartial<JavaOptions>): Promise<RenderOutput> {
const optionsToUse = JavaGenerator.getJavaOptions({...this.options, ...options});
const dependencyManagerToUse = this.getJavaDependencyManager(optionsToUse);
const dependencyManagerToUse = this.getDependencyManager(optionsToUse);
const presets = this.getPresets('enum');
const renderer = new EnumRenderer(optionsToUse, this, presets, model, inputModel, dependencyManagerToUse);
const result = await renderer.runSelfPreset();
Expand Down
Loading

0 comments on commit 5ab42aa

Please sign in to comment.