From c1a1280c7f02653e6edf16b4dff4b9b929fbba36 Mon Sep 17 00:00:00 2001 From: Wiebren Braakman Date: Fri, 4 Sep 2026 22:19:04 +0200 Subject: [PATCH] [swift5] fix: reserve type names the generated client declares or uses from Foundation A schema named Locale generates Models/Locale.swift, which shadows Foundation.Locale inside the generated module and breaks the client's own OpenISO8601DateFormatter/Extensions support files; a schema named ValidationError is an invalid redeclaration of Validation.swift's generic ValidationError. reservedWords already covers ErrorResponse/Response and URL/Data for exactly this reason, but not the rest of the names the generated code declares at module scope or references unqualified from Foundation. Complete the list so such models are renamed Model, the same mechanism a model named Response already gets. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01CxDNCjqJycKTfzVWg2SeTJ --- docs/generators/swift5.md | 66 +++++++++++++++++++ .../languages/Swift5ClientCodegen.java | 30 ++++++++- .../swift5/Swift5ClientCodegenTest.java | 25 +++++++ 3 files changed, 119 insertions(+), 2 deletions(-) diff --git a/docs/generators/swift5.md b/docs/generators/swift5.md index 7c3052b6e4c9..d04ae8e878e0 100644 --- a/docs/generators/swift5.md +++ b/docs/generators/swift5.md @@ -113,45 +113,92 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • #line
  • #selector
  • #sourceLocation
  • +
  • APIHelper
  • +
  • AlamofireDecodableRequestBuilder
  • +
  • AlamofireRequestBuilder
  • +
  • AlamofireRequestBuilderFactory
  • Any
  • +
  • AnyHashable
  • AnyObject
  • +
  • AnyResponseSerializer
  • Array
  • +
  • ArrayRule
  • +
  • ArrayValidationErrorKind
  • Bool
  • COLUMN
  • +
  • Calendar
  • +
  • CaseIterableDefaultsLast
  • Character
  • Class
  • ClosedRange
  • Codable
  • +
  • CodableHelper
  • +
  • Configuration
  • CountableClosedRange
  • CountableRange
  • Data
  • +
  • DateFormatter
  • Decodable
  • +
  • DecodableRequestBuilderError
  • Dictionary
  • +
  • DispatchQueue
  • Double
  • +
  • DownloadException
  • Encodable
  • Error
  • ErrorResponse
  • FILE
  • FUNCTION
  • +
  • FileManager
  • Float
  • Float32
  • Float64
  • Float80
  • +
  • HTTPMethod
  • +
  • HTTPURLResponse
  • Int
  • Int16
  • Int32
  • Int64
  • Int8
  • +
  • JSONDataEncoding
  • +
  • JSONDecoder
  • +
  • JSONEncodable
  • +
  • JSONEncoder
  • +
  • JSONEncodingHelper
  • +
  • KeyedDecodingContainerProtocol
  • +
  • KeyedEncodingContainerProtocol
  • LINE
  • +
  • Locale
  • +
  • NSCoder
  • +
  • NSDecimalNumber
  • +
  • NSNumber
  • +
  • NSObject
  • +
  • NSRecursiveLock
  • +
  • NSRegularExpression
  • +
  • NSString
  • +
  • NullEncodable
  • +
  • NumericRule
  • +
  • NumericValidationErrorKind
  • +
  • OpenISO8601DateFormatter
  • OptionSet
  • Optional
  • +
  • ParameterEncoding
  • +
  • Progress
  • Protocol
  • Range
  • +
  • RequestBuilder
  • +
  • RequestBuilderFactory
  • +
  • RequestTask
  • Response
  • Self
  • Set
  • StaticString
  • String
  • +
  • StringRule
  • +
  • StringValidationErrorKind
  • +
  • SynchronizedDictionary
  • +
  • TimeZone
  • Type
  • UInt
  • UInt16
  • @@ -159,7 +206,26 @@ These options may be applied as additional-properties (cli) or configOptions (pl
  • UInt64
  • UInt8
  • URL
  • +
  • URLAuthenticationChallenge
  • +
  • URLComponents
  • +
  • URLCredential
  • +
  • URLQueryItem
  • +
  • URLRequest
  • +
  • URLResponse
  • +
  • URLSession
  • +
  • URLSessionConfiguration
  • +
  • URLSessionDataTask
  • +
  • URLSessionDataTaskProtocol
  • +
  • URLSessionDecodableRequestBuilder
  • +
  • URLSessionProtocol
  • +
  • URLSessionRequestBuilder
  • +
  • URLSessionRequestBuilderFactory
  • +
  • URLSessionTask
  • +
  • URLSessionTaskDelegate
  • Unicode
  • +
  • UnknownCaseCheckable
  • +
  • ValidationError
  • +
  • Validator
  • Void
  • _
  • as
  • diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift5ClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift5ClientCodegen.java index 7d2a1d9d5154..f7b9eb82c3e0 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift5ClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/Swift5ClientCodegen.java @@ -213,8 +213,22 @@ public Swift5ClientCodegen() { reservedWords = new HashSet<>( Arrays.asList( - // name used by swift client + // Types declared by the generated code itself (support files and + // per-library implementations). A model with one of these names + // would be an invalid redeclaration of the client's own type. "ErrorResponse", "Response", + "APIHelper", "AlamofireDecodableRequestBuilder", "AlamofireRequestBuilder", + "AlamofireRequestBuilderFactory", "AnyResponseSerializer", "ArrayRule", + "ArrayValidationErrorKind", "CaseIterableDefaultsLast", "CodableHelper", + "Configuration", "DecodableRequestBuilderError", "DownloadException", + "HTTPMethod", "JSONDataEncoding", "JSONEncodable", "JSONEncodingHelper", + "NullEncodable", "NumericRule", "NumericValidationErrorKind", + "OpenISO8601DateFormatter", "ParameterEncoding", "RequestBuilder", + "RequestBuilderFactory", "RequestTask", "StringRule", + "StringValidationErrorKind", "SynchronizedDictionary", "UnknownCaseCheckable", + "URLSessionDataTaskProtocol", "URLSessionDecodableRequestBuilder", + "URLSessionProtocol", "URLSessionRequestBuilder", + "URLSessionRequestBuilderFactory", "ValidationError", "Validator", // Swift keywords. This list is taken from here: // https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/LexicalStructure.html#//apple_ref/doc/uid/TP40014097-CH30-ID410 @@ -251,8 +265,20 @@ public Swift5ClientCodegen() { // Collections "Array", "Dictionary", "Set", "OptionSet", "CountableRange", "CountableClosedRange", - // The following are commonly-used Foundation types + // The following are commonly-used Foundation (and stdlib) types that + // the generated support files reference unqualified: a model with one + // of these names would shadow the real type inside the generated + // module and break the client's own code. "URL", "Data", "Codable", "Encodable", "Decodable", + "AnyHashable", "Calendar", "DateFormatter", "DispatchQueue", "FileManager", + "HTTPURLResponse", "JSONDecoder", "JSONEncoder", + "KeyedDecodingContainerProtocol", "KeyedEncodingContainerProtocol", + "Locale", "NSCoder", "NSDecimalNumber", "NSNumber", "NSObject", + "NSRecursiveLock", "NSRegularExpression", "NSString", "Progress", + "TimeZone", "URLAuthenticationChallenge", "URLComponents", "URLCredential", + "URLQueryItem", "URLRequest", "URLResponse", "URLSession", + "URLSessionConfiguration", "URLSessionDataTask", "URLSessionTask", + "URLSessionTaskDelegate", // The following are other words we want to reserve "Void", "AnyObject", "Class", "dynamicType", "COLUMN", "FILE", "FUNCTION", "LINE" diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift5/Swift5ClientCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift5/Swift5ClientCodegenTest.java index ec64a91269d1..8f965c076159 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift5/Swift5ClientCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/swift5/Swift5ClientCodegenTest.java @@ -163,6 +163,31 @@ public void dateWithoutTimeTest() { Assert.assertEquals(op.bodyParam.dataType, "OpenAPIDateWithoutTime"); } + @Test(description = "model names colliding with types declared by the generated client are renamed", enabled = true) + public void reservedTypeNamesDeclaredByClientTest() { + final DefaultCodegen codegen = new Swift5ClientCodegen(); + + // Names declared by the generated support files (Validation.swift, Models.swift, ...): + // a model with such a name would be an invalid redeclaration of the client's own type. + Assert.assertEquals(codegen.toModelName("ValidationError"), "ModelValidationError"); + Assert.assertEquals(codegen.toModelName("Validator"), "ModelValidator"); + Assert.assertEquals(codegen.toModelName("Configuration"), "ModelConfiguration"); + Assert.assertEquals(codegen.toModelName("RequestBuilder"), "ModelRequestBuilder"); + } + + @Test(description = "model names shadowing Foundation types used by the generated client are renamed", enabled = true) + public void reservedFoundationTypeNamesTest() { + final DefaultCodegen codegen = new Swift5ClientCodegen(); + + // Foundation types the generated support files reference unqualified + // (e.g. OpenISO8601DateFormatter.swift assigns `formatter.locale = Locale(...)`): + // a model with such a name would shadow the Foundation type inside the module. + Assert.assertEquals(codegen.toModelName("Locale"), "ModelLocale"); + Assert.assertEquals(codegen.toModelName("DateFormatter"), "ModelDateFormatter"); + Assert.assertEquals(codegen.toModelName("TimeZone"), "ModelTimeZone"); + Assert.assertEquals(codegen.toModelName("URLSession"), "ModelURLSession"); + } + @Test(description = "type from languageSpecificPrimitives should not be prefixed", enabled = true) public void prefixExceptionTest() { final DefaultCodegen codegen = new Swift5ClientCodegen();