Skip to content

Commit

Permalink
fix duplicate models
Browse files Browse the repository at this point in the history
  • Loading branch information
millotp committed Jul 29, 2024
1 parent ef75be7 commit c6688ca
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import com.algolia.codegen.exceptions.*;
import com.algolia.codegen.utils.*;
import com.algolia.codegen.utils.OneOf;
import com.google.common.collect.ImmutableMap.Builder;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Mustache.Lambda;
Expand Down Expand Up @@ -98,6 +97,7 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap objs, List<Mo
OperationsMap operations = super.postProcessOperationsWithModels(objs, models);
Helpers.removeHelpers(operations);
GenericPropagator.propagateGenericsToOperations(operations, models);
OrphanDestroyer.removeOrphans(this, operations, models);
return operations;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ public class AlgoliaSwiftGenerator extends Swift5ClientCodegen {
"facetordering",
"facets",
"facetsstats",
"forbidden",
"highlightresult",
"highlightresultoption",
"ignoreplurals",
Expand All @@ -83,10 +84,11 @@ public class AlgoliaSwiftGenerator extends Swift5ClientCodegen {
"promoteobjectids",
"querysuggestionsconfiguration",
"querytype",
"range",
"rankinginfo",
"redirect",
"redirectruleindexmetadata",
"redirectruleindexmetadatadata",
"redirectruleindexdata",
"redirecturl",
"region",
"removestopwords",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ public static void propagateGenericsToModels(Map<String, ModelsMap> modelsMap, b
}
}

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

/** Mark operations with a generic return type with x-is-generic */
public static void propagateGenericsToOperations(OperationsMap operations, List<ModelMap> allModels) {
Map<String, CodegenModel> models = convertToMap(allModels);
Expand All @@ -207,8 +211,4 @@ public static void propagateGenericsToOperations(OperationsMap operations, List<
}
}
}

public static void propagateGenericsToModels(Map<String, ModelsMap> modelsMap) {
propagateGenericsToModels(modelsMap, false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.algolia.codegen.utils;

import java.io.File;
import java.util.*;
import org.openapitools.codegen.*;
import org.openapitools.codegen.model.ModelMap;
import org.openapitools.codegen.model.OperationsMap;

public class OrphanDestroyer {

private static Set<String> primitiveModels = new HashSet<>(Arrays.asList("object", "array", "string", "boolean", "integer"));
private static Set<String> helperModels = new HashSet<>(
Arrays.asList("apiKeyOperation", "securedApiKeyRestrictions", "replaceAllObjectsResponse")
);

private Map<String, CodegenModel> models;
private HashSet<String> visitedModels;

private OrphanDestroyer(Map<String, CodegenModel> models) {
this.visitedModels = new HashSet<>();
this.models = models;
}

private CodegenModel getModel(String name) {
// openapi generator returns some weird error when looking for primitive type, so we filter them
// by hand
if (primitiveModels.contains(name)) {
return null;
}

return models.get(name);
}

private CodegenModel propertyToModel(CodegenProperty prop) {
return prop == null ? null : getModel(prop.openApiType);
}

private void exploreProperties(CodegenModel model, List<CodegenProperty> properties) {
for (CodegenProperty property : properties) {
CodegenModel propModel = propertyToModel(property);
if (propModel != null && !visitedModels.contains(propModel.name)) {
System.out.println("Visiting property: " + propModel.name + " from " + model.name);
visitModelRecursive(propModel);
visitedModels.add(propModel.name);
}
CodegenModel itemsModel = propertyToModel(property.items);
if (itemsModel != null && !visitedModels.contains(itemsModel.name)) {
System.out.println("Visiting item: " + itemsModel.name + " from " + model.name);
visitedModels.add(itemsModel.name);
visitModelRecursive(itemsModel);
}
}
}

private void visitModelRecursive(CodegenModel model) {
exploreProperties(model, model.getVars());
if (model.getComposedSchemas() != null && model.getComposedSchemas().getOneOf() != null) {
exploreProperties(model, model.getComposedSchemas().getOneOf());
}
}

private static Map<String, CodegenModel> convertToMap(List<ModelMap> models) {
Map<String, CodegenModel> modelsMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (ModelMap modelMap : models) {
CodegenModel model = modelMap.getModel();
modelsMap.put(model.name, model);
}
return modelsMap;
}

private void exploreGraph(OperationsMap operations) {
for (CodegenModel model : models.values()) {
visitModelRecursive(model);
}

for (CodegenOperation ope : operations.getOperations().getOperation()) {
if (ope.returnType != null) {
String modelName = ope.returnType;
if (modelName.startsWith("List<")) {
modelName = modelName.substring(5, modelName.length() - 1);
} else if (modelName.startsWith("Map<")) {
modelName = modelName.substring(4, modelName.length() - 1).split(",")[1].trim();
}

System.out.println("Visiting return type: " + modelName);
CodegenModel returnType = getModel(modelName);
if (returnType != null) {
visitedModels.add(returnType.name);
}
}
for (CodegenParameter param : ope.allParams) {
CodegenModel paramType = getModel(param.dataType);
if (paramType != null) {
visitedModels.add(paramType.name);
}
CodegenModel itemsModel = propertyToModel(param.items);
if (itemsModel != null) {
visitedModels.add(itemsModel.name);
}
}
}
}

/** remove all the unused models, most likely the sub models of allOf */
public static void removeOrphans(CodegenConfig config, OperationsMap operations, List<ModelMap> allModels) {
// visit all the models that are accessible from:
// - the properties of a model (needs recursive search)
// - the return type of an operation
// - the parameters of an operation

OrphanDestroyer orphanDestroyer = new OrphanDestroyer(convertToMap(allModels));

orphanDestroyer.exploreGraph(operations);

List<String> toRemove = new ArrayList<>();
for (String modelName : orphanDestroyer.models.keySet()) {
if (!helperModels.contains(modelName) && !orphanDestroyer.visitedModels.contains(modelName)) {
toRemove.add(modelName);
}
}

String templateName = config.modelTemplateFiles().keySet().iterator().next();

for (String modelName : toRemove) {
String filename = config.modelFilename(templateName, modelName);
File file = new File(filename);
if (file.exists()) {
file.delete();
System.out.println("Removed orphan model: " + modelName);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {
AlternativesAsExact,
Anchoring,
AroundPrecision,
AroundPrecisionFromValueInner,
AroundRadius,
AroundRadiusAll,
AutomaticFacetFilter,
Expand Down Expand Up @@ -55,11 +54,12 @@ import {
PromoteObjectID,
PromoteObjectIDs,
QueryType,
Range,
RankingInfo,
ReRankingApplyFilter,
Redirect,
RedirectRuleIndexMetadata,
RedirectRuleIndexMetadataData,
RedirectRuleIndexData,
RedirectURL,
RemoveStopWords,
RemoveWordsIfNoResults,
Expand Down Expand Up @@ -97,7 +97,6 @@ export {
AlternativesAsExact,
Anchoring,
AroundPrecision,
AroundPrecisionFromValueInner,
AroundRadius,
AroundRadiusAll,
AutomaticFacetFilter,
Expand Down Expand Up @@ -141,11 +140,12 @@ export {
PromoteObjectID,
PromoteObjectIDs,
QueryType,
Range,
RankingInfo,
ReRankingApplyFilter,
Redirect,
RedirectRuleIndexMetadata,
RedirectRuleIndexMetadataData,
RedirectRuleIndexData,
RedirectURL,
RemoveStopWords,
RemoveWordsIfNoResults,
Expand Down

0 comments on commit c6688ca

Please sign in to comment.