Skip to content

Commit 9fc2259

Browse files
authored
fix model generation for class hierarchies (#76) (#77)
1 parent 9f6e5e9 commit 9fc2259

File tree

3 files changed

+152
-19
lines changed

3 files changed

+152
-19
lines changed

src/main/java/cd/connect/openapi/DartV3ApiGenerator.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.Map;
1616
import java.util.Map.Entry;
1717
import java.util.Set;
18+
import java.util.Comparator;
1819
import java.util.regex.Matcher;
1920
import java.util.regex.Pattern;
2021
import java.util.stream.Collectors;
@@ -454,8 +455,23 @@ public Map<String, Object> updateAllModels(Map<String, Object> objs) {
454455

455456

456457

457-
// TODO: check with multiple levels of hierarchy
458458
private void updateModelsWithAllOfInheritance(Map<String, CodegenModel> models) {
459+
// Workaround for https://github.com/OpenAPITools/openapi-generator/issues/11846
460+
for (CodegenModel cm : models.values()) {
461+
CodegenModel parent = cm;
462+
Set<String> properties = cm.vars.stream().map(CodegenProperty::getName).collect(Collectors.toSet());
463+
while ((parent = parent.parentModel) != null) {
464+
for (CodegenProperty cp : parent.vars) {
465+
if (!properties.contains(cp.getName())) {
466+
properties.add(cp.getName());
467+
468+
cm.vars.add(cp.clone());
469+
cm.hasVars = true;
470+
}
471+
}
472+
}
473+
}
474+
459475
for (CodegenModel cm : models.values()) {
460476
if (cm.getParent() != null) {
461477
CodegenModel parent = models.get(cm.getParent());
@@ -473,7 +489,13 @@ private void updateModelsWithAllOfInheritance(Map<String, CodegenModel> models)
473489
v.vendorExtensions.put("x-dart-inherited", Boolean.TRUE);
474490
}
475491
});
492+
Comparator<CodegenProperty> cmp = Comparator.comparing(cp -> cp.vendorExtensions.containsKey("x-dart-inherited"));
493+
cm.getVars().sort(cmp.reversed());
476494
}
495+
496+
List<CodegenProperty> ownVars = cm.getVars().stream().filter(cp -> !cp.vendorExtensions.containsKey("x-dart-inherited")).collect(Collectors.toList());
497+
cm.vendorExtensions.put("x-dart-ownVars", ownVars);
498+
cm.vendorExtensions.put("x-dart-hasOwnVars", !ownVars.isEmpty());
477499
}
478500
}
479501

src/main/resources/dart2-v3template/class.mustache

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@ class {{classname}}{{#parent}} extends {{parent}}{{/parent}} {
2424
{{/allowableValues}}
2525
{{/vendorExtensions.x-dart-inherited}}
2626
{{/vars}}
27-
{{^hasVars}}
27+
{{^hasVars}}{{^parent}}
2828
{{#required}}{{#nullSafe}}late {{/nullSafe}}{{/required}}dynamic{{^required}}{{/required}} json;
29-
{{/hasVars}}
30-
{{classname}}({ {{#vars}}{{#required}}{{#nullSafe}}{{^vendorExtensions.x-ns-default-val}}required {{/vendorExtensions.x-ns-default-val}}{{/nullSafe}}{{/required}}{{#vendorExtensions.x-ns-default-val}}{{{dataType}}}{{#nullSafe}}?{{/nullSafe}} {{{name}}}{{/vendorExtensions.x-ns-default-val}}{{^vendorExtensions.x-ns-default-val}}this.{{{name}}}{{/vendorExtensions.x-ns-default-val}},
31-
{{/vars}} }){{#vendorExtensions.x-has-ns-default-vals}} : {{#vendorExtensions.x-ns-default-vals}}this.{{{name}}} = {{{name}}} ?? []{{^-last}}, {{/-last}}{{/vendorExtensions.x-ns-default-vals}}{{/vendorExtensions.x-has-ns-default-vals}};
29+
{{/parent}}{{/hasVars}}
30+
{{classname}}({{#hasVars}}{ {{#vars}}{{#required}}{{#nullSafe}}{{^vendorExtensions.x-ns-default-val}}required {{/vendorExtensions.x-ns-default-val}}{{/nullSafe}}{{/required}}{{#vendorExtensions.x-ns-default-val}}{{{dataType}}}{{#nullSafe}}?{{/nullSafe}} {{{name}}}{{/vendorExtensions.x-ns-default-val}}{{^vendorExtensions.x-ns-default-val}}{{^vendorExtensions.x-dart-inherited}}this.{{/vendorExtensions.x-dart-inherited}}{{{name}}}{{/vendorExtensions.x-ns-default-val}},
31+
{{/vars}} }{{/hasVars}}){{#vendorExtensions.x-has-ns-default-vals}} : {{#vendorExtensions.x-ns-default-vals}}{{^vendorExtensions.x-dart-inherited}}this.{{/vendorExtensions.x-dart-inherited}}{{{name}}} = {{{name}}} ?? []{{^-last}}, {{/-last}}{{/vendorExtensions.x-ns-default-vals}}{{/vendorExtensions.x-has-ns-default-vals}}
32+
{{#parent}} : super({{#vars}}{{#vendorExtensions.x-dart-inherited}}{{name}}: {{name}},{{/vendorExtensions.x-dart-inherited}}{{/vars}}) {{/parent}}
33+
;
3234

3335
@override
3436
String toString() {
@@ -48,7 +50,7 @@ class {{classname}}{{#parent}} extends {{parent}}{{/parent}} {
4850
{{#hasVars}}
4951
fromJson(Map<String, dynamic>{{#nullSafe}}?{{/nullSafe}} json) {
5052
if (json == null) return;
51-
{{#parent}}super.fromJson(json);{{/parent}}
53+
{{#parentModel}}{{#hasVars}}super{{/hasVars}}{{^hasVars}}{{classname}}{{/hasVars}}.fromJson(json);{{/parentModel}}
5254
{{#nullSafe}}
5355
{{#vars}}
5456
{{^vendorExtensions.x-dart-inherited}}
@@ -75,7 +77,7 @@ class {{classname}}{{#parent}} extends {{parent}}{{/parent}} {
7577
}
7678

7779
Map<String, dynamic> toJson() {
78-
final json = <String, dynamic>{};
80+
final json = {{#parent}}super.toJson();{{/parent}}{{^parent}}<String, dynamic>{};{{/parent}}
7981
{{#vars}}
8082
{{^vendorExtensions.x-dart-inherited}}
8183
{{^required}}
@@ -142,8 +144,8 @@ class {{classname}}{{#parent}} extends {{parent}}{{/parent}} {
142144
}
143145

144146
if (__other is {{classname}} && runtimeType == __other.runtimeType) {
145-
{{#hasVars}}
146-
return {{^hasVars}}json?.equals(__other.json);{{/hasVars}}{{#vars}}{{^vendorExtensions.x-dart-inherited}}
147+
148+
{{#hasVars}}return {{#vendorExtensions.x-dart-ownVars}}
147149
{{#complexType}}
148150
{{#isArray}}
149151
const ListEquality().equals({{{name}}}, __other.{{{name}}}){{^-last}} &&
@@ -168,18 +170,18 @@ class {{classname}}{{#parent}} extends {{parent}}{{/parent}} {
168170
{{{name}}} == __other.{{{name}}}{{^-last}} &&
169171
{{/-last}}
170172
{{/isArray}}
171-
{{/complexType}}{{/vendorExtensions.x-dart-inherited}}{{/vars}}
172-
{{#parent}} &&
173+
{{/complexType}}{{/vendorExtensions.x-dart-ownVars}}
174+
{{#parent}} {{#vendorExtensions.x-dart-hasOwnVars}}&&{{/vendorExtensions.x-dart-hasOwnVars}}
173175
super==__other{{/parent}};{{/hasVars}}{{^hasVars}}
174-
return {{#parent}}super==__other{{/parent}}{{^parent}}true{{/parent}};{{/hasVars}}
176+
return {{#parent}}super==__other{{/parent}}{{^parent}}json?.equals(__other.json){{/parent}};{{/hasVars}}
175177
}
176178

177179
return false;
178180
}
179181

180182
@override
181183
int get hashCode {
182-
var hashCode = runtimeType.hashCode;
184+
var hashCode = {{#parent}}super.hashCode{{/parent}}{{^parent}}runtimeType.hashCode{{/parent}};
183185

184186
{{#hasVars}}
185187
{{#vars}}{{^vendorExtensions.x-dart-inherited}}
@@ -213,9 +215,9 @@ class {{classname}}{{#parent}} extends {{parent}}{{/parent}} {
213215
{{/nullSafe}}
214216
{{/vendorExtensions.x-ns-default-val}}
215217

216-
{{/vendorExtensions.x-dart-inherited}}{{/vars}}{{/hasVars}}{{^hasVars}}if (json != null) { hashCode = hashCode ^ json.hashCode; }{{/hasVars}}
218+
{{/vendorExtensions.x-dart-inherited}}{{/vars}}{{/hasVars}}{{^hasVars}}{{^parent}}if (json != null) { hashCode = hashCode ^ json.hashCode; }{{/parent}}{{/hasVars}}
217219

218-
return hashCode{{#parent}} ^ super.hashCode{{/parent}};
220+
return hashCode;
219221
}
220222

221223
{{classname}} copyWith({{#hasVars}}{
@@ -224,10 +226,11 @@ class {{classname}}{{#parent}} extends {{parent}}{{/parent}} {
224226
{{/vars}}
225227
}{{/hasVars}}) {
226228
227-
{{#vars}}{{^vendorExtensions.x-dart-inherited}}{{{name}}} ??= this.{{{name}}};
228-
{{/vendorExtensions.x-dart-inherited}}{{/vars}}
229229
{{#vars}}
230-
{{^vendorExtensions.x-dart-inherited}}
230+
{{{name}}} ??= this.{{{name}}};
231+
{{/vars}}
232+
233+
{{#vars}}
231234
{{#nullSafe}}
232235
{{#required}}
233236
{{#isArray}}{{>_complex_copy_required}}{{/isArray}}{{#isMap}}{{>_complex_copy_required}}{{/isMap}}{{^items}}final _copy_{{{name}}} = {{^isModel}}{{{name}}}{{/isModel}}{{#isModel}}{{{name}}}.copyWith(){{/isModel}};{{/items}}
@@ -244,7 +247,7 @@ class {{classname}}{{#parent}} extends {{parent}}{{/parent}} {
244247
{{^nullSafe}}
245248
{{#isArray}}{{>_complex_copy}}{{/isArray}}{{#isMap}}{{>_complex_copy}}{{/isMap}}{{^items}}final _copy_{{{name}}} = {{^isModel}}{{{name}}}{{/isModel}}{{#isModel}}{{{name}}}?.copyWith(){{/isModel}};{{/items}}
246249
{{/nullSafe}}
247-
{{/vendorExtensions.x-dart-inherited}}{{/vars}}
250+
{{/vars}}
248251

249252
return {{{classname}}}(
250253
{{#vars}}{{{name}}}: _copy_{{{name}}},{{/vars}});

src/test/resources/inheritance.yaml

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
openapi: 3.0.1
2+
info:
3+
title: Inheritance examples
4+
version: 1.0.0
5+
paths:
6+
/inheritance:
7+
get:
8+
tags:
9+
- InheritanceService
10+
operationId: "inheritance"
11+
responses:
12+
"200":
13+
description: "Description"
14+
content:
15+
application/json:
16+
schema:
17+
$ref: "#/components/schemas/Entity4"
18+
19+
"201":
20+
description: "Description"
21+
content:
22+
application/json:
23+
schema:
24+
$ref: "#/components/schemas/Empty"
25+
components:
26+
schemas:
27+
Entity:
28+
type: object
29+
properties:
30+
id:
31+
type: integer
32+
nullable: false
33+
name:
34+
type: string
35+
nullable: true
36+
discriminator:
37+
propertyName: type
38+
additionalProperties: false
39+
40+
Entity2:
41+
type: object
42+
allOf:
43+
- $ref: '#/components/schemas/Entity'
44+
properties:
45+
description:
46+
type: string
47+
nullable: true
48+
additionalProperties: false
49+
50+
Entity3:
51+
type: object
52+
allOf:
53+
- $ref: '#/components/schemas/Entity2'
54+
properties:
55+
summary:
56+
type: string
57+
nullable: true
58+
additionalProperties: false
59+
60+
Entity4:
61+
type: object
62+
allOf:
63+
- $ref: '#/components/schemas/Entity3'
64+
properties:
65+
notes:
66+
type: string
67+
nullable: true
68+
moreNotes:
69+
type: string
70+
nullable: true
71+
additionalProperties: false
72+
73+
Empty:
74+
type: object
75+
discriminator:
76+
propertyName: type
77+
allOf:
78+
- type: object
79+
80+
additionalProperties: false
81+
82+
Empty2:
83+
type: object
84+
allOf:
85+
- $ref: '#/components/schemas/Empty'
86+
additionalProperties: false
87+
88+
Empty3:
89+
type: object
90+
allOf:
91+
- $ref: '#/components/schemas/Empty2'
92+
additionalProperties: false
93+
94+
EmptyEntity:
95+
type: object
96+
allOf:
97+
- $ref: '#/components/schemas/Entity'
98+
additionalProperties: false
99+
100+
Named:
101+
type: object
102+
allOf:
103+
- $ref: '#/components/schemas/Empty3'
104+
properties:
105+
name:
106+
type: string
107+
nullable: true
108+
additionalProperties: false

0 commit comments

Comments
 (0)