Skip to content

Commit 968f998

Browse files
[kotlin-client] preserve nullable list item types (#23655)
The kotlin-client mustache templates dropped `?` on nullable items inside List/Array generics. With `items: { type: string, nullable: true }`, properties now render as `List<kotlin.String?>` instead of `List<kotlin.String>`, matching kotlin-spring server behavior. Adds two regression sample configs (jvm-okhttp/moshi and multiplatform/ kotlinx-serialization) plus their generated samples.
1 parent 7219956 commit 968f998

70 files changed

Lines changed: 2983 additions & 4 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/samples-kotlin-client.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ jobs:
5353
- samples/client/petstore/kotlin-enum-integers-multiplatform
5454
- samples/client/petstore/kotlin-array-simple-string-jvm-okhttp4
5555
- samples/client/petstore/kotlin-array-simple-string-multiplatform
56+
- samples/client/petstore/kotlin-array-nullable-items
57+
- samples/client/petstore/kotlin-array-nullable-items-multiplatform
5658
- samples/client/petstore/kotlin-bigdecimal-default-multiplatform
5759
- samples/client/petstore/kotlin-bigdecimal-default-okhttp4
5860
- samples/client/petstore/kotlin-jvm-jackson
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
generatorName: kotlin
2+
outputDir: samples/client/petstore/kotlin-array-nullable-items-multiplatform
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/kotlin-array-nullable-items.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/kotlin-client
5+
additionalProperties:
6+
artifactId: kotlin-array-nullable-items-multiplatform
7+
library: multiplatform
8+
dateLibrary: kotlinx-datetime
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
generatorName: kotlin
2+
outputDir: samples/client/petstore/kotlin-array-nullable-items
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/kotlin/kotlin-array-nullable-items.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/kotlin-client
5+
additionalProperties:
6+
artifactId: kotlin-array-nullable-items

modules/openapi-generator/src/main/resources/kotlin-client/data_class_opt_var.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
{{#deprecated}}
2222
@Deprecated(message = "This property is deprecated.")
2323
{{/deprecated}}
24-
{{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") {{/multiplatform}}{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInPascalCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInPascalCase}}}{{/isArray}}{{/isEnum}}? = {{^defaultValue}}null{{/defaultValue}}{{#defaultValue}}{{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{^multiplatform}}{{{dataType}}}("{{{defaultValue}}}"){{/multiplatform}}{{#multiplatform}}({{{defaultValue}}}).toDouble(){{/multiplatform}}{{/isNumber}}{{/defaultValue}}
24+
{{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") {{/multiplatform}}{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInPascalCase}}}{{/items.isEnum}}{{#items.isNullable}}?{{/items.isNullable}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInPascalCase}}}{{/isArray}}{{/isEnum}}? = {{^defaultValue}}null{{/defaultValue}}{{#defaultValue}}{{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{^multiplatform}}{{{dataType}}}("{{{defaultValue}}}"){{/multiplatform}}{{#multiplatform}}({{{defaultValue}}}).toDouble(){{/multiplatform}}{{/isNumber}}{{/defaultValue}}

modules/openapi-generator/src/main/resources/kotlin-client/data_class_req_var.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
{{#deprecated}}
2222
@Deprecated(message = "This property is deprecated.")
2323
{{/deprecated}}
24-
{{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") @Required {{/multiplatform}}{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInPascalCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInPascalCase}}}{{/isArray}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{^multiplatform}}{{{dataType}}}("{{{defaultValue}}}"){{/multiplatform}}{{#multiplatform}}({{{defaultValue}}}).toDouble(){{/multiplatform}}{{/isNumber}}{{/defaultValue}}
24+
{{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") @Required {{/multiplatform}}{{#isInherited}}override {{/isInherited}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInPascalCase}}}{{/items.isEnum}}{{#items.isNullable}}?{{/items.isNullable}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInPascalCase}}}{{/isArray}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}{{#defaultValue}} = {{^isNumber}}{{{defaultValue}}}{{/isNumber}}{{#isNumber}}{{^multiplatform}}{{{dataType}}}("{{{defaultValue}}}"){{/multiplatform}}{{#multiplatform}}({{{defaultValue}}}).toDouble(){{/multiplatform}}{{/isNumber}}{{/defaultValue}}

modules/openapi-generator/src/main/resources/kotlin-client/interface_opt_var.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@
1515
{{^isEnum}}{{^isArray}}{{^isPrimitiveType}}{{^isModel}}@Contextual {{/isModel}}{{/isPrimitiveType}}{{/isArray}}{{/isEnum}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}")
1616
{{/kotlinx_serialization}}
1717
{{/multiplatform}}
18-
{{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") abstract {{/multiplatform}}{{#kotlinx_serialization}}abstract {{/kotlinx_serialization}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInPascalCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInPascalCase}}}{{/isArray}}{{/isEnum}}?
18+
{{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") abstract {{/multiplatform}}{{#kotlinx_serialization}}abstract {{/kotlinx_serialization}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInPascalCase}}}{{/items.isEnum}}{{#items.isNullable}}?{{/items.isNullable}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInPascalCase}}}{{/isArray}}{{/isEnum}}?

modules/openapi-generator/src/main/resources/kotlin-client/interface_req_var.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@
1515
{{^isEnum}}{{^isArray}}{{^isPrimitiveType}}{{^isModel}}@Contextual {{/isModel}}{{/isPrimitiveType}}{{/isArray}}{{/isEnum}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}")
1616
{{/kotlinx_serialization}}
1717
{{/multiplatform}}
18-
{{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") @Required abstract {{/multiplatform}}{{#kotlinx_serialization}}abstract {{/kotlinx_serialization}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInPascalCase}}}{{/items.isEnum}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInPascalCase}}}{{/isArray}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}
18+
{{#multiplatform}}@SerialName(value = "{{{vendorExtensions.x-base-name-literal}}}") @Required abstract {{/multiplatform}}{{#kotlinx_serialization}}abstract {{/kotlinx_serialization}}{{>modelMutable}} {{{name}}}: {{#isArray}}{{#isList}}kotlin.collections.{{#modelMutable}}Mutable{{/modelMutable}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isList}}{{^isList}}kotlin.Array{{/isList}}<{{^items.isEnum}}{{^items.isPrimitiveType}}{{^items.isModel}}{{#kotlinx_serialization}}@Contextual {{/kotlinx_serialization}}{{/items.isModel}}{{/items.isPrimitiveType}}{{{items.dataType}}}{{/items.isEnum}}{{#items.isEnum}}{{classname}}.{{{nameInPascalCase}}}{{/items.isEnum}}{{#items.isNullable}}?{{/items.isNullable}}>{{/isArray}}{{^isEnum}}{{^isArray}}{{{dataType}}}{{/isArray}}{{/isEnum}}{{#isEnum}}{{^isArray}}{{classname}}.{{{nameInPascalCase}}}{{/isArray}}{{/isEnum}}{{#isNullable}}?{{/isNullable}}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
openapi: 3.0.0
2+
info:
3+
title: 'Kotlin client — nullable array items'
4+
description: Regression spec for nullable items inside list/array properties.
5+
version: latest
6+
paths:
7+
'/':
8+
get:
9+
operationId: getModel
10+
responses:
11+
'200':
12+
description: Success
13+
content:
14+
application/json:
15+
schema:
16+
$ref: '#/components/schemas/ArrayWithNullableItemsModel'
17+
components:
18+
schemas:
19+
ArrayWithNullableItemsModel:
20+
type: object
21+
required:
22+
- requiredItems
23+
properties:
24+
requiredItems:
25+
type: array
26+
items:
27+
type: string
28+
nullable: true
29+
optionalItems:
30+
type: array
31+
items:
32+
type: string
33+
nullable: true
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
README.md
2+
build.gradle.kts
3+
docs/ArrayWithNullableItemsModel.md
4+
docs/DefaultApi.md
5+
gradle/wrapper/gradle-wrapper.jar
6+
gradle/wrapper/gradle-wrapper.properties
7+
gradlew
8+
gradlew.bat
9+
settings.gradle.kts
10+
src/commonMain/kotlin/org/openapitools/client/apis/DefaultApi.kt
11+
src/commonMain/kotlin/org/openapitools/client/auth/ApiKeyAuth.kt
12+
src/commonMain/kotlin/org/openapitools/client/auth/Authentication.kt
13+
src/commonMain/kotlin/org/openapitools/client/auth/HttpBasicAuth.kt
14+
src/commonMain/kotlin/org/openapitools/client/auth/HttpBearerAuth.kt
15+
src/commonMain/kotlin/org/openapitools/client/auth/OAuth.kt
16+
src/commonMain/kotlin/org/openapitools/client/infrastructure/ApiAbstractions.kt
17+
src/commonMain/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
18+
src/commonMain/kotlin/org/openapitools/client/infrastructure/Base64ByteArray.kt
19+
src/commonMain/kotlin/org/openapitools/client/infrastructure/HttpResponse.kt
20+
src/commonMain/kotlin/org/openapitools/client/infrastructure/OctetByteArray.kt
21+
src/commonMain/kotlin/org/openapitools/client/infrastructure/PartConfig.kt
22+
src/commonMain/kotlin/org/openapitools/client/infrastructure/RequestConfig.kt
23+
src/commonMain/kotlin/org/openapitools/client/infrastructure/RequestMethod.kt
24+
src/commonMain/kotlin/org/openapitools/client/models/ArrayWithNullableItemsModel.kt

0 commit comments

Comments
 (0)