Skip to content

Commit c5f54ea

Browse files
authored
Merge pull request #1156 from nextcloud/fix/dynamite/allOf_primitive_types
2 parents 01e9c53 + 19e7fe6 commit c5f54ea

File tree

6 files changed

+678
-49
lines changed

6 files changed

+678
-49
lines changed

packages/dynamite/dynamite/lib/src/builder/ofs_builder.dart

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,37 +22,42 @@ TypeResult resolveAllOf(
2222

2323
if (state.resolvedTypes.add(result)) {
2424
final interfaces = <TypeResultObject>{};
25+
final methods = ListBuilder<Method>();
2526

2627
for (final s in schema.allOf!) {
27-
final TypeResultObject interfaceClass;
28-
if (s.ref != null) {
29-
final object = resolveType(
28+
if (s.properties != null) {
29+
final interfaceClass = resolveInterface(
3030
spec,
3131
state,
32-
identifier,
32+
'${identifier}_${schema.allOf!.indexOf(s)}',
3333
s,
34-
nullable: nullable,
3534
);
36-
37-
if (object is! TypeResultObject) {
38-
throw StateError('allOf does only allow objects. Please change $identifier');
39-
}
40-
41-
interfaceClass = object;
35+
interfaces.add(interfaceClass);
4236
} else {
43-
interfaceClass = resolveInterface(
37+
final object = resolveType(
4438
spec,
4539
state,
46-
'${identifier}_${schema.allOf!.indexOf(s)}',
40+
identifier,
4741
s,
42+
nullable: nullable,
4843
);
49-
}
5044

51-
interfaces.add(interfaceClass);
45+
if (object is TypeResultObject) {
46+
interfaces.add(object);
47+
} else {
48+
final property = generateProperty(
49+
object,
50+
object.className,
51+
s.formattedDescription,
52+
);
53+
54+
methods.add(property);
55+
}
56+
}
5257
}
5358

5459
state.output.add(
55-
buildInterface(identifier, interfaces: interfaces),
60+
buildInterface(identifier, interfaces: interfaces, methods: methods.build()),
5661
);
5762

5863
state.output.add(

packages/dynamite/dynamite/lib/src/builder/resolve_interface.dart

Lines changed: 51 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ TypeResultObject resolveInterface(
1414
final String identifier,
1515
final openapi.Schema schema,
1616
) {
17+
final properties = schema.properties?.entries;
18+
19+
if (properties == null || properties.isEmpty) {
20+
throw StateError('The schema must have a non empty properties field.');
21+
}
22+
1723
final result = TypeResultObject(
1824
identifier,
1925
);
@@ -22,40 +28,29 @@ TypeResultObject resolveInterface(
2228
final $interface = buildInterface(
2329
identifier,
2430
methods: BuiltList.build((final b) {
25-
for (final property in schema.properties!.entries) {
26-
b.add(
27-
Method(
28-
(final b) {
29-
final propertyName = property.key;
30-
final propertySchema = property.value;
31-
final result = resolveType(
32-
spec,
33-
state,
34-
'${identifier}_${toDartName(propertyName, uppercaseFirstCharacter: true)}',
35-
propertySchema,
36-
nullable: isDartParameterNullable(
37-
schema.required.contains(propertyName),
38-
propertySchema,
39-
),
40-
);
31+
b.addAll(
32+
properties.map((final property) {
33+
final propertyName = property.key;
34+
final propertySchema = property.value;
4135

42-
b
43-
..name = toDartName(propertyName)
44-
..returns = refer(result.nullableName)
45-
..type = MethodType.getter
46-
..docs.addAll(propertySchema.formattedDescription);
36+
final result = resolveType(
37+
spec,
38+
state,
39+
'${identifier}_${toDartName(propertyName, uppercaseFirstCharacter: true)}',
40+
propertySchema,
41+
nullable: isDartParameterNullable(
42+
schema.required.contains(propertyName),
43+
propertySchema,
44+
),
45+
);
4746

48-
if (toDartName(propertyName) != propertyName) {
49-
b.annotations.add(
50-
refer('BuiltValueField').call([], {
51-
'wireName': literalString(propertyName),
52-
}),
53-
);
54-
}
55-
},
56-
),
57-
);
58-
}
47+
return generateProperty(
48+
result,
49+
propertyName,
50+
propertySchema.formattedDescription,
51+
);
52+
}),
53+
);
5954
}),
6055
);
6156

@@ -65,6 +60,30 @@ TypeResultObject resolveInterface(
6560
return result;
6661
}
6762

63+
Method generateProperty(
64+
final TypeResult type,
65+
final String propertyName,
66+
final Iterable<String> description,
67+
) =>
68+
Method(
69+
(final b) {
70+
final name = toFieldName(toDartName(propertyName), type.name);
71+
b
72+
..name = name
73+
..returns = refer(type.nullableName)
74+
..type = MethodType.getter
75+
..docs.addAll(description);
76+
77+
if (name != propertyName) {
78+
b.annotations.add(
79+
refer('BuiltValueField').call([], {
80+
'wireName': literalString(propertyName),
81+
}),
82+
);
83+
}
84+
},
85+
);
86+
6887
Spec buildInterface(
6988
final String identifier, {
7089
final BuiltList<Method>? methods,

packages/dynamite/dynamite_end_to_end_test/lib/all_of.openapi.dart

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,82 @@ abstract class OneObjectAllOf implements OneObjectAllOfInterface, Built<OneObjec
7979
static Serializer<OneObjectAllOf> get serializer => _$oneObjectAllOfSerializer;
8080
}
8181

82+
@BuiltValue(instantiable: false)
83+
abstract interface class PrimitiveAllOfInterface {
84+
@BuiltValueField(wireName: 'int')
85+
int get $int;
86+
@BuiltValueField(wireName: 'String')
87+
String get string;
88+
}
89+
90+
abstract class PrimitiveAllOf implements PrimitiveAllOfInterface, Built<PrimitiveAllOf, PrimitiveAllOfBuilder> {
91+
factory PrimitiveAllOf([final void Function(PrimitiveAllOfBuilder)? b]) = _$PrimitiveAllOf;
92+
93+
const PrimitiveAllOf._();
94+
95+
factory PrimitiveAllOf.fromJson(final Map<String, dynamic> json) =>
96+
_jsonSerializers.deserializeWith(serializer, json)!;
97+
98+
Map<String, dynamic> toJson() => _jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>;
99+
100+
static Serializer<PrimitiveAllOf> get serializer => _$primitiveAllOfSerializer;
101+
}
102+
103+
@BuiltValue(instantiable: false)
104+
abstract interface class MixedAllOf_1Interface {
105+
@BuiltValueField(wireName: 'attribute-allOf')
106+
String get attributeAllOf;
107+
}
108+
109+
@BuiltValue(instantiable: false)
110+
abstract interface class MixedAllOfInterface implements MixedAllOf_1Interface {
111+
@BuiltValueField(wireName: 'String')
112+
String get string;
113+
}
114+
115+
abstract class MixedAllOf implements MixedAllOfInterface, Built<MixedAllOf, MixedAllOfBuilder> {
116+
factory MixedAllOf([final void Function(MixedAllOfBuilder)? b]) = _$MixedAllOf;
117+
118+
const MixedAllOf._();
119+
120+
factory MixedAllOf.fromJson(final Map<String, dynamic> json) => _jsonSerializers.deserializeWith(serializer, json)!;
121+
122+
Map<String, dynamic> toJson() => _jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>;
123+
124+
static Serializer<MixedAllOf> get serializer => _$mixedAllOfSerializer;
125+
}
126+
127+
@BuiltValue(instantiable: false)
128+
abstract interface class OneValueAllOfInterface {
129+
@BuiltValueField(wireName: 'String')
130+
String get string;
131+
}
132+
133+
abstract class OneValueAllOf implements OneValueAllOfInterface, Built<OneValueAllOf, OneValueAllOfBuilder> {
134+
factory OneValueAllOf([final void Function(OneValueAllOfBuilder)? b]) = _$OneValueAllOf;
135+
136+
const OneValueAllOf._();
137+
138+
factory OneValueAllOf.fromJson(final Map<String, dynamic> json) =>
139+
_jsonSerializers.deserializeWith(serializer, json)!;
140+
141+
Map<String, dynamic> toJson() => _jsonSerializers.serializeWith(serializer, this)! as Map<String, dynamic>;
142+
143+
static Serializer<OneValueAllOf> get serializer => _$oneValueAllOfSerializer;
144+
}
145+
82146
// coverage:ignore-start
83147
final Serializers _serializers = (Serializers().toBuilder()
84148
..addBuilderFactory(const FullType(ObjectAllOf), ObjectAllOf.new)
85149
..add(ObjectAllOf.serializer)
86150
..addBuilderFactory(const FullType(OneObjectAllOf), OneObjectAllOf.new)
87-
..add(OneObjectAllOf.serializer))
151+
..add(OneObjectAllOf.serializer)
152+
..addBuilderFactory(const FullType(PrimitiveAllOf), PrimitiveAllOf.new)
153+
..add(PrimitiveAllOf.serializer)
154+
..addBuilderFactory(const FullType(MixedAllOf), MixedAllOf.new)
155+
..add(MixedAllOf.serializer)
156+
..addBuilderFactory(const FullType(OneValueAllOf), OneValueAllOf.new)
157+
..add(OneValueAllOf.serializer))
88158
.build();
89159

90160
final Serializers _jsonSerializers = (_serializers.toBuilder()

0 commit comments

Comments
 (0)