From b56a9d907c342fbb23cffd27ed851998478b57a3 Mon Sep 17 00:00:00 2001 From: Andrew Emery Date: Thu, 24 Oct 2019 03:50:41 +1100 Subject: [PATCH] Fixes Kotlin client property names that include a dollar sign (#4229) Property names that include a dollar sign are being interpreted by Kotlin as a string template. This fix escapes such instances. https://github.com/OpenAPITools/openapi-generator/issues/4228 --- .../languages/KotlinClientCodegen.java | 29 +++++++++++++++++++ .../kotlin-client/data_class_opt_var.mustache | 6 ++-- .../kotlin-client/data_class_req_var.mustache | 6 ++-- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java index 4f41bf090bc..77156c7f827 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/KotlinClientCodegen.java @@ -19,7 +19,9 @@ package org.openapitools.codegen.languages; import org.openapitools.codegen.CliOption; import org.openapitools.codegen.CodegenConstants; +import org.openapitools.codegen.CodegenModel; import org.openapitools.codegen.CodegenOperation; +import org.openapitools.codegen.CodegenProperty; import org.openapitools.codegen.CodegenType; import org.openapitools.codegen.SupportingFile; @@ -38,6 +40,8 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen { public static final String DATE_LIBRARY = "dateLibrary"; public static final String COLLECTION_TYPE = "collectionType"; + protected static final String VENDOR_EXTENSION_BASE_NAME_LITERAL = "x-base-name-literal"; + protected String dateLibrary = DateLibrary.JAVA8.value; protected String collectionType = CollectionType.ARRAY.value; @@ -253,6 +257,31 @@ public class KotlinClientCodegen extends AbstractKotlinCodegen { return getLibrary() != null && (getLibrary().contains(JVM_OKHTTP4) || getLibrary().contains(JVM_OKHTTP3)); } + @Override + public Map postProcessModels(Map objs) { + Map objects = super.postProcessModels(objs); + @SuppressWarnings("unchecked") List models = (List) objs.get("models"); + + for (Object model : models) { + @SuppressWarnings("unchecked") Map mo = (Map) model; + CodegenModel cm = (CodegenModel) mo.get("model"); + + // escape the variable base name for use as a string literal + if (cm.requiredVars != null) { + for (CodegenProperty var : cm.requiredVars) { + var.vendorExtensions.put(VENDOR_EXTENSION_BASE_NAME_LITERAL, var.baseName.replace("$", "\\$")); + } + } + if (cm.optionalVars != null) { + for (CodegenProperty var : cm.optionalVars) { + var.vendorExtensions.put(VENDOR_EXTENSION_BASE_NAME_LITERAL, var.baseName.replace("$", "\\$")); + } + } + } + + return objects; + } + @Override @SuppressWarnings("unchecked") public Map postProcessOperationsWithModels(Map objs, List allModels) { diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/data_class_opt_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/data_class_opt_var.mustache index 5ec0214d6c9..9a32aebeb5d 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/data_class_opt_var.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/data_class_opt_var.mustache @@ -3,10 +3,10 @@ {{/description}} {{#jvm}} {{#moshi}} - @Json(name = "{{{baseName}}}") + @Json(name = "{{{vendorExtensions.x-base-name-literal}}}") {{/moshi}} {{#gson}} - @SerializedName("{{name}}") + @SerializedName("{{{vendorExtensions.x-base-name-literal}}}") {{/gson}} {{/jvm}} - {{#multiplatform}}@SerialName(value = "{{baseName}}") {{/multiplatform}}val {{{name}}}: {{#isEnum}}{{#isListContainer}}{{#isList}}kotlin.collections.List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{classname}}.{{{nameInCamelCase}}}>{{/isListContainer}}{{^isListContainer}}{{classname}}.{{{nameInCamelCase}}}{{/isListContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}} \ No newline at end of file + {{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") {{/multiplatform}}val {{{name}}}: {{#isEnum}}{{#isListContainer}}{{#isList}}kotlin.collections.List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{classname}}.{{{nameInCamelCase}}}>{{/isListContainer}}{{^isListContainer}}{{classname}}.{{{nameInCamelCase}}}{{/isListContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}? = {{#defaultvalue}}{{defaultvalue}}{{/defaultvalue}}{{^defaultvalue}}null{{/defaultvalue}} \ No newline at end of file diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/data_class_req_var.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/data_class_req_var.mustache index a60f1baf24a..c03711b6884 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-client/data_class_req_var.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-client/data_class_req_var.mustache @@ -3,10 +3,10 @@ {{/description}} {{#jvm}} {{#moshi}} - @Json(name = "{{{baseName}}}") + @Json(name = "{{{vendorExtensions.x-base-name-literal}}}") {{/moshi}} {{#gson}} - @SerializedName("{{name}}") + @SerializedName("{{{vendorExtensions.x-base-name-literal}}}") {{/gson}} {{/jvm}} - {{#multiplatform}}@SerialName(value = "{{baseName}}") @Required {{/multiplatform}}val {{{name}}}: {{#isEnum}}{{#isListContainer}}{{#isList}}kotlin.collections.List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{classname}}.{{{nameInCamelCase}}}>{{/isListContainer}}{{^isListContainer}}{{classname}}.{{{nameInCamelCase}}}{{/isListContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}} \ No newline at end of file + {{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") @Required {{/multiplatform}}val {{{name}}}: {{#isEnum}}{{#isListContainer}}{{#isList}}kotlin.collections.List{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{classname}}.{{{nameInCamelCase}}}>{{/isListContainer}}{{^isListContainer}}{{classname}}.{{{nameInCamelCase}}}{{/isListContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}} \ No newline at end of file