forked from loafle/openapi-generator-original
Added support for enums in Dart. (#6516)
* Added support for enums in Dart. * Pick non-private names for enum values. The _ prefix denotes a private member in Dart, so avoid generating enum values starting with this character. * Properly encode enum values into query paramters. * Various cleanups. * Add support for x-enum-values extension. Use class instead of enum for better ergonomy. Better generated enum names. * Fixed test. * Support enum descriptions.
This commit is contained in:
@@ -3,27 +3,35 @@ package io.swagger.codegen.languages;
|
||||
import io.swagger.codegen.CliOption;
|
||||
import io.swagger.codegen.CodegenConfig;
|
||||
import io.swagger.codegen.CodegenConstants;
|
||||
import io.swagger.codegen.CodegenModel;
|
||||
import io.swagger.codegen.CodegenProperty;
|
||||
import io.swagger.codegen.CodegenType;
|
||||
import io.swagger.codegen.DefaultCodegen;
|
||||
import io.swagger.codegen.SupportingFile;
|
||||
import io.swagger.models.Model;
|
||||
import io.swagger.models.properties.ArrayProperty;
|
||||
import io.swagger.models.properties.MapProperty;
|
||||
import io.swagger.models.properties.Property;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
public static final String BROWSER_CLIENT = "browserClient";
|
||||
public static final String PUB_NAME = "pubName";
|
||||
public static final String PUB_VERSION = "pubVersion";
|
||||
public static final String PUB_DESCRIPTION = "pubDescription";
|
||||
public static final String USE_ENUM_EXTENSION = "useEnumExtension";
|
||||
protected boolean browserClient = true;
|
||||
protected String pubName = "swagger";
|
||||
protected String pubVersion = "1.0.0";
|
||||
protected String pubDescription = "Swagger API client";
|
||||
protected boolean useEnumExtension = false;
|
||||
protected String sourceFolder = "";
|
||||
protected String apiDocPath = "docs/";
|
||||
protected String modelDocPath = "docs/";
|
||||
@@ -95,6 +103,7 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
cliOptions.add(new CliOption(PUB_NAME, "Name in generated pubspec"));
|
||||
cliOptions.add(new CliOption(PUB_VERSION, "Version in generated pubspec"));
|
||||
cliOptions.add(new CliOption(PUB_DESCRIPTION, "Description in generated pubspec"));
|
||||
cliOptions.add(new CliOption(USE_ENUM_EXTENSION, "Allow the 'x-enum-values' extension for enums"));
|
||||
cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "source folder for generated code"));
|
||||
}
|
||||
|
||||
@@ -145,6 +154,13 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
additionalProperties.put(PUB_DESCRIPTION, pubDescription);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(USE_ENUM_EXTENSION)) {
|
||||
this.setUseEnumExtension(convertPropertyToBooleanAndWriteBack(USE_ENUM_EXTENSION));
|
||||
} else {
|
||||
// Not set, use to be passed to template.
|
||||
additionalProperties.put(USE_ENUM_EXTENSION, useEnumExtension);
|
||||
}
|
||||
|
||||
if (additionalProperties.containsKey(CodegenConstants.SOURCE_FOLDER)) {
|
||||
this.setSourceFolder((String) additionalProperties.get(CodegenConstants.SOURCE_FOLDER));
|
||||
}
|
||||
@@ -177,16 +193,11 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String escapeReservedWord(String name) {
|
||||
if(this.reservedWordsMappings().containsKey(name)) {
|
||||
return this.reservedWordsMappings().get(name);
|
||||
}
|
||||
return "_" + name;
|
||||
public String escapeReservedWord(String name) {
|
||||
return name + "_";
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -223,8 +234,11 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
// pet_id => petId
|
||||
name = camelize(name, true);
|
||||
|
||||
// for reserved word or word starting with number, append _
|
||||
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||
if (name.matches("^\\d.*")) {
|
||||
name = "n" + name;
|
||||
}
|
||||
|
||||
if (isReservedWord(name)) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
|
||||
@@ -300,6 +314,117 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
return toModelName(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||
return postProcessModelsEnum(objs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> postProcessModelsEnum(Map<String, Object> objs) {
|
||||
List<Object> models = (List<Object>) objs.get("models");
|
||||
for (Object _mo : models) {
|
||||
Map<String, Object> mo = (Map<String, Object>) _mo;
|
||||
CodegenModel cm = (CodegenModel) mo.get("model");
|
||||
boolean succes = buildEnumFromVendorExtension(cm) ||
|
||||
buildEnumFromValues(cm);
|
||||
for (CodegenProperty var : cm.vars) {
|
||||
updateCodegenPropertyEnum(var);
|
||||
}
|
||||
}
|
||||
return objs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the set of enum members from their declared value.
|
||||
*
|
||||
* @return {@code true} if the enum was built
|
||||
*/
|
||||
private boolean buildEnumFromValues(CodegenModel cm) {
|
||||
if (!cm.isEnum || cm.allowableValues == null) {
|
||||
return false;
|
||||
}
|
||||
Map<String, Object> allowableValues = cm.allowableValues;
|
||||
List<Object> values = (List<Object>) allowableValues.get("values");
|
||||
List<Map<String, String>> enumVars =
|
||||
new ArrayList<Map<String, String>>();
|
||||
String commonPrefix = findCommonPrefixOfVars(values);
|
||||
int truncateIdx = commonPrefix.length();
|
||||
for (Object value : values) {
|
||||
Map<String, String> enumVar = new HashMap<String, String>();
|
||||
String enumName;
|
||||
if (truncateIdx == 0) {
|
||||
enumName = value.toString();
|
||||
} else {
|
||||
enumName = value.toString().substring(truncateIdx);
|
||||
if ("".equals(enumName)) {
|
||||
enumName = value.toString();
|
||||
}
|
||||
}
|
||||
enumVar.put("name", toEnumVarName(enumName, cm.dataType));
|
||||
enumVar.put("value", toEnumValue(value.toString(), cm.dataType));
|
||||
enumVars.add(enumVar);
|
||||
}
|
||||
cm.allowableValues.put("enumVars", enumVars);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds the set of enum members from a vendor extension.
|
||||
*
|
||||
* @return {@code true} if the enum was built
|
||||
*/
|
||||
private boolean buildEnumFromVendorExtension(CodegenModel cm) {
|
||||
if (!cm.isEnum || cm.allowableValues == null ||
|
||||
!useEnumExtension ||
|
||||
!cm.vendorExtensions.containsKey("x-enum-values")) {
|
||||
return false;
|
||||
}
|
||||
Object extension = cm.vendorExtensions.get("x-enum-values");
|
||||
List<Map<String, Object>> values =
|
||||
(List<Map<String, Object>>) extension;
|
||||
List<Map<String, String>> enumVars =
|
||||
new ArrayList<Map<String, String>>();
|
||||
for (Map<String, Object> value : values) {
|
||||
Map<String, String> enumVar = new HashMap<String, String>();
|
||||
String name = camelize((String) value.get("identifier"), true);
|
||||
if (isReservedWord(name)) {
|
||||
name = escapeReservedWord(name);
|
||||
}
|
||||
enumVar.put("name", name);
|
||||
enumVar.put("value", toEnumValue(
|
||||
value.get("numericValue").toString(), cm.dataType));
|
||||
if (value.containsKey("description")) {
|
||||
enumVar.put("description", value.get("description").toString());
|
||||
}
|
||||
enumVars.add(enumVar);
|
||||
}
|
||||
cm.allowableValues.put("enumVars", enumVars);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toEnumVarName(String value, String datatype) {
|
||||
if (value.length() == 0) {
|
||||
return "empty";
|
||||
}
|
||||
String var = value.replaceAll("\\W+", "_");
|
||||
if ("number".equalsIgnoreCase(datatype) ||
|
||||
"int".equalsIgnoreCase(datatype)) {
|
||||
var = "Number" + var;
|
||||
}
|
||||
return escapeReservedWord(camelize(var, true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toEnumValue(String value, String datatype) {
|
||||
if ("number".equalsIgnoreCase(datatype) ||
|
||||
"int".equalsIgnoreCase(datatype)) {
|
||||
return value;
|
||||
} else {
|
||||
return "\"" + escapeText(value) + "\"";
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toOperationId(String operationId) {
|
||||
// method name cannot use reserved keyword, e.g. return
|
||||
@@ -328,6 +453,10 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
|
||||
this.pubDescription = pubDescription;
|
||||
}
|
||||
|
||||
public void setUseEnumExtension(boolean useEnumExtension) {
|
||||
this.useEnumExtension = useEnumExtension;
|
||||
}
|
||||
|
||||
public void setSourceFolder(String sourceFolder) {
|
||||
this.sourceFolder = sourceFolder;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user