various minor improvements to nim generator (#3883)

This commit is contained in:
William Cheng 2019-09-13 16:48:18 +08:00 committed by GitHub
parent f15f814d9b
commit 95c4a05b70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 288 additions and 266 deletions

View File

@ -38,7 +38,7 @@ The following generators are available:
* [jmeter](generators/jmeter)
* [kotlin](generators/kotlin)
* [lua](generators/lua)
* [nim](generators/nim)
* [nim (beta)](generators/nim)
* [objc](generators/objc)
* [ocaml](generators/ocaml)
* [perl](generators/perl)

View File

@ -1,9 +1,27 @@
/*
* Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openapitools.codegen.languages;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
import org.openapitools.codegen.*;
import org.openapitools.codegen.meta.GeneratorMetadata;
import org.openapitools.codegen.meta.Stability;
import org.openapitools.codegen.utils.ModelUtils;
import org.openapitools.codegen.utils.StringUtils;
import org.slf4j.Logger;
@ -16,294 +34,298 @@ import static org.openapitools.codegen.utils.StringUtils.camelize;
import static org.openapitools.codegen.utils.StringUtils.underscore;
public class NimClientCodegen extends DefaultCodegen implements CodegenConfig {
static Logger LOGGER = LoggerFactory.getLogger(NimClientCodegen.class);
static Logger LOGGER = LoggerFactory.getLogger(NimClientCodegen.class);
public static final String PROJECT_NAME = "projectName";
public static final String PROJECT_NAME = "projectName";
protected String packageName = "openapiclient";
protected String packageVersion = "1.0.0";
protected String packageName = "openapiclient";
protected String packageVersion = "1.0.0";
public CodegenType getTag() {
return CodegenType.CLIENT;
}
public String getName() {
return "nim";
}
public String getHelp() {
return "Generates a nim client.";
}
public NimClientCodegen() {
super();
outputFolder = "generated-code" + File.separator + "nim";
modelTemplateFiles.put("model.mustache", ".nim");
apiTemplateFiles.put("api.mustache", ".nim");
embeddedTemplateDir = templateDir = "nim-client";
apiPackage = File.separator + packageName + File.separator + "apis";
modelPackage = File.separator + packageName + File.separator + "models";
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("sample_client.mustache", "", "sample_client.nim"));
supportingFiles.add(new SupportingFile("config.mustache", "", "config.nim"));
setReservedWordsLowerCase(
Arrays.asList(
"addr", "and", "as", "asm",
"bind", "block", "break",
"case", "cast", "concept", "const", "continue", "converter",
"defer", "discard", "distinct", "div", "do",
"elif", "else", "end", "enum", "except", "export",
"finally", "for", "from", "func",
"if", "import", "in", "include", "interface", "is", "isnot", "iterator",
"let",
"macro", "method", "mixin", "mod",
"nil", "not", "notin",
"object", "of", "or", "out",
"proc", "ptr",
"raise", "ref", "return",
"shl", "shr", "static",
"template", "try", "tuple", "type",
"using",
"var",
"when", "while",
"xor",
"yield"
)
);
defaultIncludes = new HashSet<String>(
Arrays.asList(
"array"
)
);
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"int",
"int8",
"int16",
"int32",
"int64",
"uint",
"uint8",
"uint16",
"uint32",
"uint64",
"float",
"float32",
"float64",
"bool",
"char",
"string",
"cstring",
"pointer")
);
typeMapping.clear();
typeMapping.put("integer", "int");
typeMapping.put("long", "int64");
typeMapping.put("number", "float");
typeMapping.put("float", "float");
typeMapping.put("double", "float64");
typeMapping.put("boolean", "bool");
typeMapping.put("UUID", "string");
typeMapping.put("URI", "string");
typeMapping.put("date", "string");
typeMapping.put("DateTime", "string");
typeMapping.put("password", "string");
typeMapping.put("file", "string");
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
return postProcessModelsEnum(objs);
}
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
public CodegenType getTag() {
return CodegenType.CLIENT;
}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
public String getName() {
return "nim";
}
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
apiPackage = File.separator + packageName + File.separator + "apis";
modelPackage = File.separator + packageName + File.separator + "models";
supportingFiles.add(new SupportingFile("lib.mustache", "", packageName + ".nim"));
}
@Override
public String escapeReservedWord(String name) {
LOGGER.warn("A reserved word \"" + name + "\" is used. Consider renaming the field name");
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "`" + name + "`";
}
@Override
public String escapeQuotationMark(String input) {
return input.replace("\"", "");
}
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String toModelImport(String name) {
name = name.replaceAll("-", "_");
if (importMapping.containsKey(name)) {
return "model_" + StringUtils.underscore(importMapping.get(name));
} else {
return "model_" + StringUtils.underscore(name);
}
}
@Override
public String toApiImport(String name) {
name = name.replaceAll("-", "_");
if (importMapping.containsKey(name)) {
return "api_" + StringUtils.underscore(importMapping.get(name));
} else {
return "api_" + StringUtils.underscore(name);
}
}
@Override
public String toModelFilename(String name) {
name = name.replaceAll("-", "_");
return "model_" + StringUtils.underscore(name);
}
@Override
public String toApiFilename(String name) {
name = name.replaceAll("-", "_");
return "api_" + StringUtils.underscore(name);
}
@Override
public String toOperationId(String operationId) {
String sanitizedOperationId = sanitizeName(operationId);
if (isReservedWord(sanitizedOperationId)) {
sanitizedOperationId = "call" + StringUtils.camelize(sanitizedOperationId, false);
public String getHelp() {
return "Generates a nim client (beta).";
}
return StringUtils.camelize(sanitizedOperationId, true);
}
public NimClientCodegen() {
super();
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
@SuppressWarnings("unchecked")
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations");
@SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation operation : operations) {
operation.httpMethod = operation.httpMethod.toLowerCase(Locale.ROOT);
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
.stability(Stability.BETA)
.build();
outputFolder = "generated-code" + File.separator + "nim";
modelTemplateFiles.put("model.mustache", ".nim");
apiTemplateFiles.put("api.mustache", ".nim");
embeddedTemplateDir = templateDir = "nim-client";
apiPackage = File.separator + packageName + File.separator + "apis";
modelPackage = File.separator + packageName + File.separator + "models";
supportingFiles.add(new SupportingFile("README.mustache", "", "README.md"));
supportingFiles.add(new SupportingFile("sample_client.mustache", "", "sample_client.nim"));
supportingFiles.add(new SupportingFile("config.mustache", "", "config.nim"));
setReservedWordsLowerCase(
Arrays.asList(
"addr", "and", "as", "asm",
"bind", "block", "break",
"case", "cast", "concept", "const", "continue", "converter",
"defer", "discard", "distinct", "div", "do",
"elif", "else", "end", "enum", "except", "export",
"finally", "for", "from", "func",
"if", "import", "in", "include", "interface", "is", "isnot", "iterator",
"let",
"macro", "method", "mixin", "mod",
"nil", "not", "notin",
"object", "of", "or", "out",
"proc", "ptr",
"raise", "ref", "return",
"shl", "shr", "static",
"template", "try", "tuple", "type",
"using",
"var",
"when", "while",
"xor",
"yield"
)
);
defaultIncludes = new HashSet<String>(
Arrays.asList(
"array"
)
);
languageSpecificPrimitives = new HashSet<String>(
Arrays.asList(
"int",
"int8",
"int16",
"int32",
"int64",
"uint",
"uint8",
"uint16",
"uint32",
"uint64",
"float",
"float32",
"float64",
"bool",
"char",
"string",
"cstring",
"pointer")
);
typeMapping.clear();
typeMapping.put("integer", "int");
typeMapping.put("long", "int64");
typeMapping.put("number", "float");
typeMapping.put("float", "float");
typeMapping.put("double", "float64");
typeMapping.put("boolean", "bool");
typeMapping.put("UUID", "string");
typeMapping.put("URI", "string");
typeMapping.put("date", "string");
typeMapping.put("DateTime", "string");
typeMapping.put("password", "string");
typeMapping.put("file", "string");
}
return objs;
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
if (inner == null) {
return null;
}
return "seq[" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = ModelUtils.getAdditionalProperties(p);
if (inner == null) {
inner = new StringSchema();
}
return "Table[string, " + getTypeDeclaration(inner) + "]";
public void setPackageName(String packageName) {
this.packageName = packageName;
}
String schemaType = getSchemaType(p);
if (typeMapping.containsKey(schemaType)) {
return typeMapping.get(schemaType);
public void setPackageVersion(String packageVersion) {
this.packageVersion = packageVersion;
}
if (schemaType.matches("\\d.*")) { // starts with number
return "`" + schemaType + "`";
} else {
return schemaType;
}
}
@Override
public String toVarName(String name) {
if (isReservedWord(name)) {
name = escapeReservedWord(name);
@Override
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
return postProcessModelsEnum(objs);
}
if (name.matches("^\\d.*")) {
name = "`" + name + "`";
@Override
public void processOpts() {
super.processOpts();
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) {
setPackageName((String) additionalProperties.get(CodegenConstants.PACKAGE_NAME));
}
if (additionalProperties.containsKey(CodegenConstants.PACKAGE_VERSION)) {
setPackageVersion((String) additionalProperties.get(CodegenConstants.PACKAGE_VERSION));
}
additionalProperties.put(CodegenConstants.PACKAGE_NAME, packageName);
additionalProperties.put(CodegenConstants.PACKAGE_VERSION, packageVersion);
apiPackage = File.separator + packageName + File.separator + "apis";
modelPackage = File.separator + packageName + File.separator + "models";
supportingFiles.add(new SupportingFile("lib.mustache", "", packageName + ".nim"));
}
return name;
}
@Override
public String toParamName(String name) {
return toVarName(name);
}
@Override
protected boolean needToImport(String type) {
if (defaultIncludes.contains(type)) {
return false;
} else if (languageSpecificPrimitives.contains(type)) {
return false;
} else if (typeMapping.containsKey(type) && languageSpecificPrimitives.contains(typeMapping.get(type))) {
return false;
@Override
public String escapeReservedWord(String name) {
LOGGER.warn("A reserved word \"" + name + "\" is used. Consider renaming the field name");
if (this.reservedWordsMappings().containsKey(name)) {
return this.reservedWordsMappings().get(name);
}
return "`" + name + "`";
}
return true;
}
@Override
public String toEnumName(CodegenProperty property) {
String name = StringUtils.camelize(property.name, false);
if (name.matches("\\d.*")) { // starts with number
return "`" + name + "`";
} else {
return name;
@Override
public String escapeQuotationMark(String input) {
return input.replace("\"", "");
}
}
@Override
public String toEnumVarName(String name, String datatype) {
name = name.replace(" ", "_");
name = StringUtils.camelize(name, false);
if (name.matches("\\d.*")) { // starts with number
return "`" + name + "`";
} else {
return name;
@Override
public String escapeUnsafeCharacters(String input) {
return input.replace("*/", "*_/").replace("/*", "/_*");
}
@Override
public String toModelImport(String name) {
name = name.replaceAll("-", "_");
if (importMapping.containsKey(name)) {
return "model_" + StringUtils.underscore(importMapping.get(name));
} else {
return "model_" + StringUtils.underscore(name);
}
}
@Override
public String toApiImport(String name) {
name = name.replaceAll("-", "_");
if (importMapping.containsKey(name)) {
return "api_" + StringUtils.underscore(importMapping.get(name));
} else {
return "api_" + StringUtils.underscore(name);
}
}
@Override
public String toModelFilename(String name) {
name = name.replaceAll("-", "_");
return "model_" + StringUtils.underscore(name);
}
@Override
public String toApiFilename(String name) {
name = name.replaceAll("-", "_");
return "api_" + StringUtils.underscore(name);
}
@Override
public String toOperationId(String operationId) {
String sanitizedOperationId = sanitizeName(operationId);
if (isReservedWord(sanitizedOperationId)) {
sanitizedOperationId = "call" + StringUtils.camelize(sanitizedOperationId, false);
}
return StringUtils.camelize(sanitizedOperationId, true);
}
@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
@SuppressWarnings("unchecked")
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations");
@SuppressWarnings("unchecked")
List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation operation : operations) {
operation.httpMethod = operation.httpMethod.toLowerCase(Locale.ROOT);
}
return objs;
}
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
ArraySchema ap = (ArraySchema) p;
Schema inner = ap.getItems();
if (inner == null) {
return null;
}
return "seq[" + getTypeDeclaration(inner) + "]";
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = ModelUtils.getAdditionalProperties(p);
if (inner == null) {
inner = new StringSchema();
}
return "Table[string, " + getTypeDeclaration(inner) + "]";
}
String schemaType = getSchemaType(p);
if (typeMapping.containsKey(schemaType)) {
return typeMapping.get(schemaType);
}
if (schemaType.matches("\\d.*")) { // starts with number
return "`" + schemaType + "`";
} else {
return schemaType;
}
}
@Override
public String toVarName(String name) {
if (isReservedWord(name)) {
name = escapeReservedWord(name);
}
if (name.matches("^\\d.*")) {
name = "`" + name + "`";
}
return name;
}
@Override
public String toParamName(String name) {
return toVarName(name);
}
@Override
protected boolean needToImport(String type) {
if (defaultIncludes.contains(type)) {
return false;
} else if (languageSpecificPrimitives.contains(type)) {
return false;
} else if (typeMapping.containsKey(type) && languageSpecificPrimitives.contains(typeMapping.get(type))) {
return false;
}
return true;
}
@Override
public String toEnumName(CodegenProperty property) {
String name = StringUtils.camelize(property.name, false);
if (name.matches("\\d.*")) { // starts with number
return "`" + name + "`";
} else {
return name;
}
}
@Override
public String toEnumVarName(String name, String datatype) {
name = name.replace(" ", "_");
name = StringUtils.camelize(name, false);
if (name.matches("\\d.*")) { // starts with number
return "`" + name + "`";
} else {
return name;
}
}
}
}