[Kotlin] Fix Spring Kotlin generation of array/map models (#7829)

* Fix Spring Kotlin generation of array/map models

* update doc

Co-authored-by: William Cheng <wing328hk@gmail.com>
This commit is contained in:
Christophe Bornet 2020-10-31 10:38:37 +01:00 committed by GitHub
parent 4f1934c3c7
commit ca3fcd882e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 25 additions and 48 deletions

View File

@ -47,7 +47,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|kotlin.Array|
|array|kotlin.collections.ArrayList|
|list|kotlin.collections.ArrayList|
|map|kotlin.collections.HashMap|

View File

@ -57,7 +57,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|kotlin.Array|
|array|kotlin.collections.ArrayList|
|list|kotlin.collections.ArrayList|
|map|kotlin.collections.HashMap|

View File

@ -41,7 +41,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|kotlin.Array|
|array|kotlin.collections.ArrayList|
|list|kotlin.collections.ArrayList|
|map|kotlin.collections.HashMap|

View File

@ -49,7 +49,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
| Type/Alias | Instantiated By |
| ---------- | --------------- |
|array|kotlin.Array|
|array|kotlin.collections.ArrayList|
|list|kotlin.collections.ArrayList|
|map|kotlin.collections.HashMap|

View File

@ -19,6 +19,7 @@ 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.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
@ -163,7 +164,7 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
typeMapping.put("Date", "java.time.LocalDate");
typeMapping.put("DateTime", "java.time.LocalDateTime");
instantiationTypes.put("array", "kotlin.Array");
instantiationTypes.put("array", "kotlin.collections.ArrayList");
instantiationTypes.put("list", "kotlin.collections.ArrayList");
instantiationTypes.put("map", "kotlin.collections.HashMap");
@ -308,15 +309,23 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
*/
@Override
public String getTypeDeclaration(Schema p) {
if (ModelUtils.isArraySchema(p)) {
return getArrayTypeDeclaration((ArraySchema) p);
} else if (ModelUtils.isMapSchema(p)) {
Schema inner = getAdditionalProperties(p);
// Maps will be keyed only by primitive Kotlin string
return getSchemaType(p) + "<kotlin.String, " + getTypeDeclaration(inner) + ">";
Schema<?> schema = ModelUtils.unaliasSchema(this.openAPI, p, importMapping);
Schema<?> target = ModelUtils.isGenerateAliasAsModel() ? p : schema;
if (ModelUtils.isArraySchema(target)) {
Schema<?> items = getSchemaItems((ArraySchema) schema);
return getSchemaType(target) + "<" + getTypeDeclaration(items) + ">";
} else if (ModelUtils.isMapSchema(target)) {
// Note: ModelUtils.isMapSchema(p) returns true when p is a composed schema that also defines
// additionalproperties: true
Schema<?> inner = getAdditionalProperties(target);
if (inner == null) {
LOGGER.error("`{}` (map property) does not have a proper inner type defined. Default to type:string", p.getName());
inner = new StringSchema().description("TODO default missing map inner type to string");
p.setAdditionalProperties(inner);
}
return getSchemaType(target) + "<kotlin.String, " + getTypeDeclaration(inner) + ">";
}
return super.getTypeDeclaration(p);
return super.getTypeDeclaration(target);
}
@Override
@ -548,14 +557,6 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
return sanitizeKotlinSpecificNames(modified);
}
@Override
public String toInstantiationType(Schema p) {
if (ModelUtils.isArraySchema(p)) {
return getArrayTypeDeclaration((ArraySchema) p);
}
return super.toInstantiationType(p);
}
@Override
public String toApiName(String name) {
if (name.length() == 0) {
@ -671,30 +672,6 @@ public abstract class AbstractKotlinCodegen extends DefaultCodegen implements Co
return toModelName(name);
}
/**
* Provides a strongly typed declaration for simple arrays of some type and arrays of arrays of some type.
*
* @param arr Array schema
* @return type declaration of array
*/
private String getArrayTypeDeclaration(ArraySchema arr) {
// TODO: collection type here should be fully qualified namespace to avoid model conflicts
// This supports arrays of arrays.
String arrayType;
if (ModelUtils.isSet(arr)) {
arrayType = typeMapping.get("set");
} else {
arrayType = typeMapping.get("array");
}
StringBuilder instantiationType = new StringBuilder(arrayType);
Schema items = arr.getItems();
String nestedType = getTypeDeclaration(items);
additionalProperties.put("nestedType", nestedType);
// TODO: We may want to differentiate here between generics and primitive arrays.
instantiationType.append("<").append(nestedType).append(">");
return instantiationType.toString();
}
/**
* Sanitize against Kotlin specific naming conventions, which may differ from those required by {@link DefaultCodegen#sanitizeName}.
*

View File

@ -5,13 +5,13 @@
{{/vars}}
*/{{#discriminator}}
{{>typeInfoAnnotation}}{{/discriminator}}
{{#discriminator}}interface {{classname}}{{/discriminator}}{{^discriminator}}data class {{classname}}(
{{#discriminator}}interface {{classname}}{{/discriminator}}{{^discriminator}}{{#hasVars}}data {{/hasVars}}class {{classname}}(
{{#requiredVars}}
{{>dataClassReqVar}}{{^-last}},
{{/-last}}{{/requiredVars}}{{#hasRequired}}{{#hasOptional}},
{{/hasOptional}}{{/hasRequired}}{{#optionalVars}}{{>dataClassOptVar}}{{^-last}},
{{/-last}}{{/optionalVars}}
) {{/discriminator}}{{#parent}}: {{{parent}}}{{/parent}}{
) {{/discriminator}}{{#parent}}: {{{parent}}}(){{/parent}}{
{{#discriminator}}
{{#requiredVars}}
{{>interfaceReqVar}}

View File

@ -1 +1 @@
@javax.annotation.Generated(value = "{{generatorClass}}"{{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}})
@javax.annotation.Generated(value = ["{{generatorClass}}"]{{^hideGenerationTimestamp}}, date = "{{generatedDate}}"{{/hideGenerationTimestamp}})