Skip to content

Commit 1603ad7

Browse files
committed
fix generics
1 parent 45066ed commit 1603ad7

File tree

4 files changed

+71
-42
lines changed

4 files changed

+71
-42
lines changed

generators/src/main/java/com/algolia/codegen/AlgoliaSwiftGenerator.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,14 +310,14 @@ public void processOpenAPI(OpenAPI openAPI) {
310310
public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<ModelMap> models) {
311311
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
312312
Helpers.removeHelpers(operations);
313-
GenericPropagator.propagateGenericsToOperations(operations, models);
313+
GenericPropagator.propagateGenericsToOperations("swift", CLIENT, operations, models);
314314
return operations;
315315
}
316316

317317
@Override
318318
public Map<String, ModelsMap> postProcessAllModels(Map<String, ModelsMap> objs) {
319319
Map<String, ModelsMap> models = super.postProcessAllModels(objs);
320-
GenericPropagator.propagateGenericsToModels(models);
320+
GenericPropagator.propagateGenericsToModels("swift", CLIENT, models);
321321
OneOf.updateModelsOneOf(models, modelPackage);
322322
OneOf.addOneOfMetadata(models);
323323
return models;

generators/src/main/java/com/algolia/codegen/utils/GenericPropagator.java

Lines changed: 66 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.algolia.codegen.utils;
22

3+
import com.algolia.codegen.AlgoliaSwiftGenerator;
34
import java.util.*;
45
import java.util.function.Function;
56
import org.openapitools.codegen.*;
@@ -43,18 +44,19 @@ private static void setHasChildGeneric(IJsonSchemaValidationProperties property)
4344
* x-has-child-generic
4445
*/
4546
private static boolean hasGeneric(IJsonSchemaValidationProperties property) {
46-
if (property instanceof CodegenModel) {
47-
return (
48-
(boolean) ((CodegenModel) property).vendorExtensions.getOrDefault("x-propagated-generic", false) ||
49-
(boolean) ((CodegenModel) property).vendorExtensions.getOrDefault("x-has-child-generic", false)
50-
);
51-
} else if (property instanceof CodegenProperty) {
52-
return (
53-
(boolean) ((CodegenProperty) property).vendorExtensions.getOrDefault("x-propagated-generic", false) ||
54-
(boolean) ((CodegenProperty) property).vendorExtensions.getOrDefault("x-has-child-generic", false)
55-
);
47+
Map<String, Object> vendorExtensions;
48+
if (property instanceof CodegenModel model) {
49+
vendorExtensions = model.vendorExtensions;
50+
} else if (property instanceof CodegenProperty prop) {
51+
vendorExtensions = prop.vendorExtensions;
52+
} else {
53+
return false;
5654
}
57-
return false;
55+
return (
56+
(boolean) vendorExtensions.getOrDefault("x-propagated-generic", false) ||
57+
(boolean) vendorExtensions.getOrDefault("x-has-child-generic", false) ||
58+
(boolean) vendorExtensions.getOrDefault("x-is-generic", false)
59+
);
5860
}
5961

6062
private static CodegenModel propertyToModel(Map<String, CodegenModel> models, CodegenProperty prop) {
@@ -78,16 +80,13 @@ private static boolean markPropagatedGeneric(
7880
}
7981
// if items itself isn't generic, we recurse on its items and properties until we reach the
8082
// end or find a generic property
81-
if (
82-
items != null &&
83-
((boolean) items.vendorExtensions.getOrDefault("x-is-generic", false) || markPropagatedGeneric(items, getVar, skipOneOf))
84-
) {
83+
if (items != null && (hasGeneric(items) || markPropagatedGeneric(items, getVar, skipOneOf))) {
8584
setPropagatedGeneric(model);
8685
return true;
8786
}
8887
for (CodegenProperty variable : getVar.apply(model)) {
8988
// same thing for the variable, if it's not a generic, we recurse on it until we find one
90-
if ((boolean) variable.vendorExtensions.getOrDefault("x-is-generic", false) || markPropagatedGeneric(variable, getVar, skipOneOf)) {
89+
if (hasGeneric(items) || markPropagatedGeneric(variable, getVar, skipOneOf)) {
9190
setPropagatedGeneric(model);
9291
return true;
9392
}
@@ -122,12 +121,17 @@ private static boolean propagateGenericRecursive(
122121
return false;
123122
}
124123

125-
private static void setGenericToComposedSchema(Map<String, CodegenModel> models, List<CodegenProperty> composedSchemas) {
124+
private static void setGenericToComposedSchema(
125+
Map<String, CodegenModel> models,
126+
CodegenModel model,
127+
List<CodegenProperty> composedSchemas
128+
) {
126129
if (composedSchemas == null) {
127130
return;
128131
}
129132
for (CodegenProperty prop : composedSchemas) {
130-
if (hasGeneric(propertyToModel(models, prop))) {
133+
if (hasGeneric(prop) || hasGeneric(propertyToModel(models, prop))) {
134+
setHasChildGeneric(model);
131135
setHasChildGeneric(prop);
132136
}
133137
}
@@ -138,62 +142,86 @@ private static void propagateToComposedSchema(Map<String, CodegenModel> models,
138142
if (composedSchemas == null) {
139143
return;
140144
}
141-
setGenericToComposedSchema(models, composedSchemas.getOneOf());
142-
setGenericToComposedSchema(models, composedSchemas.getAllOf());
143-
setGenericToComposedSchema(models, composedSchemas.getAnyOf());
145+
setGenericToComposedSchema(models, model, composedSchemas.getOneOf());
146+
setGenericToComposedSchema(models, model, composedSchemas.getAllOf());
147+
setGenericToComposedSchema(models, model, composedSchemas.getAnyOf());
144148
}
145149

146-
private static Map<String, CodegenModel> convertToMap(Map<String, ModelsMap> models) {
150+
private static Map<String, CodegenModel> convertToMap(String language, String client, Map<String, ModelsMap> models) {
147151
Map<String, CodegenModel> modelsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
148152
for (ModelsMap modelMap : models.values()) {
149153
// modelContainers always have 1 and only 1 model in our specs
150154
CodegenModel model = modelMap.getModels().get(0).getModel();
151-
modelsMap.put(model.name, model);
155+
String modelName = model.name;
156+
if (language.equals("swift") && !client.equals("search")) {
157+
modelName = AlgoliaSwiftGenerator.prefixReservedModelName(modelName, client);
158+
}
159+
modelsMap.put(modelName, model);
152160
}
153161
return modelsMap;
154162
}
155163

156-
private static Map<String, CodegenModel> convertToMap(List<ModelMap> models) {
164+
private static Map<String, CodegenModel> convertToMap(String language, String client, List<ModelMap> models) {
157165
Map<String, CodegenModel> modelsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
158166
for (ModelMap modelMap : models) {
159167
CodegenModel model = modelMap.getModel();
160-
modelsMap.put(model.name, model);
168+
String modelName = model.name;
169+
if (language.equals("swift") && !client.equals("search")) {
170+
modelName = AlgoliaSwiftGenerator.prefixReservedModelName(modelName, client);
171+
}
172+
modelsMap.put(modelName, model);
161173
}
162174
return modelsMap;
163175
}
164176

165177
/**
166178
* Models and their members will be marked with either x-propagated-generic or x-has-child-generic
167179
*/
168-
public static void propagateGenericsToModels(Map<String, ModelsMap> modelsMap, boolean skipOneOf) {
180+
public static void propagateGenericsToModels(String language, String client, Map<String, ModelsMap> modelsMap, boolean skipOneOf) {
169181
// We propagate generics in two phases:
170182
// 1. We mark the direct parent of the generic model to replace it with T
171183
// 2. We tell each parent with generic properties to pass that generic type all the way down
172184

173-
Map<String, CodegenModel> models = convertToMap(modelsMap);
185+
Map<String, CodegenModel> models = convertToMap(language, client, modelsMap);
174186

175-
for (CodegenModel model : models.values()) {
176-
markPropagatedGeneric(model, m -> m.getVars(), skipOneOf);
177-
markPropagatedGeneric(model, m -> m.getRequiredVars(), skipOneOf);
178-
}
187+
// we don't know in which order the model will come, so we iterate multiple times to make sure
188+
// models at any depth are propagated
189+
for (int i = 0; i < 5; i++) {
190+
for (CodegenModel model : models.values()) {
191+
markPropagatedGeneric(model, m -> m.getVars(), skipOneOf);
192+
markPropagatedGeneric(model, m -> m.getRequiredVars(), skipOneOf);
193+
}
179194

180-
for (CodegenModel model : models.values()) {
181-
propagateGenericRecursive(models, model, m -> m.getVars());
182-
propagateGenericRecursive(models, model, m -> m.getRequiredVars());
183-
}
195+
for (CodegenModel model : models.values()) {
196+
propagateGenericRecursive(models, model, m -> m.getVars());
197+
propagateGenericRecursive(models, model, m -> m.getRequiredVars());
198+
}
184199

185-
for (CodegenModel model : models.values()) {
186-
propagateToComposedSchema(models, model);
200+
for (CodegenModel model : models.values()) {
201+
propagateToComposedSchema(models, model);
202+
}
187203
}
188204
}
189205

190206
public static void propagateGenericsToModels(Map<String, ModelsMap> modelsMap) {
191207
propagateGenericsToModels(modelsMap, false);
192208
}
193209

210+
public static void propagateGenericsToModels(Map<String, ModelsMap> modelsMap, boolean skipOneOf) {
211+
propagateGenericsToModels("dontcare", "dontcare", modelsMap, false);
212+
}
213+
214+
public static void propagateGenericsToModels(String language, String client, Map<String, ModelsMap> modelsMap) {
215+
propagateGenericsToModels(language, client, modelsMap, false);
216+
}
217+
194218
/** Mark operations with a generic return type with x-is-generic */
195219
public static void propagateGenericsToOperations(OperationsMap operations, List<ModelMap> allModels) {
196-
Map<String, CodegenModel> models = convertToMap(allModels);
220+
propagateGenericsToOperations("dontcare", "dontcare", operations, allModels);
221+
}
222+
223+
public static void propagateGenericsToOperations(String language, String client, OperationsMap operations, List<ModelMap> allModels) {
224+
Map<String, CodegenModel> models = convertToMap(language, client, allModels);
197225
for (CodegenOperation ope : operations.getOperations().getOperation()) {
198226
if (ope.returnType == null) {
199227
continue;

specs/recommend/paths/batchRecommendRules.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ post:
2727
title: rules
2828
type: array
2929
description: Recommend rules.
30-
additionalProperties: false
3130
items:
3231
$ref: '../common/schemas/RecommendRule.yml#/RecommendRule'
3332

templates/javascript/clients/client/model/types/isGeneric.mustache

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
{{#vendorExtensions.x-has-child-generic}}
33
<T = Record<string, unknown>>
44
{{/vendorExtensions.x-has-child-generic}}
5+
{{^vendorExtensions.x-has-child-generic}}
56
{{#vendorExtensions.x-is-generic}}
67
<T = Record<string, unknown>>
7-
{{/vendorExtensions.x-is-generic}}
8+
{{/vendorExtensions.x-is-generic}}
9+
{{/vendorExtensions.x-has-child-generic}}

0 commit comments

Comments
 (0)