From bb3aecfbe47dfb77cb59dfc52abde3566774a6d9 Mon Sep 17 00:00:00 2001 From: David Arrufat Date: Mon, 27 Apr 2026 01:38:43 +0200 Subject: [PATCH] [swift6] fix map nullable values (#17996) Swift6 generator ignores `nullable: true` on `additionalProperties` values, producing `[String: String]` instead of `[String: String?]`. This causes `DecodingError` at runtime when the JSON payload contains null values inside dictionaries. Mirrors the fix applied to the Kotlin generator in #23074. --- .../languages/Swift6ClientCodegen.java | 8 ++++++- .../swift6/Swift6ClientCodegenTest.java | 17 ++++++++++++++ .../3_0/swift6/issue17996-nullable-map.yaml | 22 +++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/swift6/issue17996-nullable-map.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift6ClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift6ClientCodegen.java index 536d74211ae0..1816801476bf 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift6ClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift6ClientCodegen.java @@ -754,11 +754,17 @@ public String getTypeDeclaration(Schema p) { return ModelUtils.isSet(p) ? "Set<" + getTypeDeclaration(inner) + ">" : "[" + getTypeDeclaration(inner) + "]"; } else if (ModelUtils.isMapSchema(p)) { Schema inner = ModelUtils.getAdditionalProperties(p); - return "[String: " + getTypeDeclaration(inner) + "]"; + return "[String: " + getItemsTypeDeclaration(inner) + "]"; } return super.getTypeDeclaration(p); } + private String getItemsTypeDeclaration(Schema items) { + String itemsTypeDeclaration = getTypeDeclaration(items); + String nullable = items.getNullable() != null && items.getNullable() && !itemsTypeDeclaration.endsWith("?") ? "?" : ""; + return itemsTypeDeclaration + nullable; + } + @Override public String getSchemaType(Schema p) { String openAPIType = super.getSchemaType(p); diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift6/Swift6ClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift6/Swift6ClientCodegenTest.java index 1bba4234b30f..3039c886d2d3 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift6/Swift6ClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift6/Swift6ClientCodegenTest.java @@ -19,6 +19,7 @@ import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.Operation; +import io.swagger.v3.oas.models.media.Schema; import org.openapitools.codegen.*; import org.openapitools.codegen.config.CodegenConfigurator; import org.openapitools.codegen.languages.Swift6ClientCodegen; @@ -401,4 +402,20 @@ public void oneOfDiscriminatorFirstDecodingTest() throws IOException { output.deleteOnExit(); } } + + @Test(description = "Issue #17996") + public void testNullableMap() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/swift6/issue17996-nullable-map.yaml"); + + Schema test1 = openAPI.getComponents().getSchemas().get("NullMapNotNullMap"); + CodegenModel cm1 = swiftCodegen.fromModel("NullMapNotNullMap", test1); + + // Assert the dataType properly generated + CodegenProperty nullableMap = cm1.vars.get(0); + CodegenProperty notNullableMap = cm1.vars.get(1); + CodegenProperty defaultMap = cm1.vars.get(2); + Assert.assertEquals(nullableMap.getDataType(), "[String: String?]"); + Assert.assertEquals(notNullableMap.getDataType(), "[String: String]"); + Assert.assertEquals(defaultMap.getDataType(), "[String: String]"); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/swift6/issue17996-nullable-map.yaml b/modules/openapi-generator/src/test/resources/3_0/swift6/issue17996-nullable-map.yaml new file mode 100644 index 000000000000..87f2456e6cc6 --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/swift6/issue17996-nullable-map.yaml @@ -0,0 +1,22 @@ +openapi: 3.0.0 +info: + title: 'Issue 17996 Nullable map' + version: latest +components: + schemas: + NullMapNotNullMap: + properties: + nullableMap: + type: object + additionalProperties: + type: string + nullable: true + notNullableMap: + type: object + additionalProperties: + type: string + nullable: false + defaultMap: + type: object + additionalProperties: + type: string