[swift5] fix: reserve type names the generated client declares or uses from Foundation - #24870
Open
wiebren wants to merge 1 commit into
Open
Conversation
…s 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<T>. 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<Name>, the same mechanism a model named Response already gets. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CxDNCjqJycKTfzVWg2SeTJ
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A spec that declares a schema named after a type the generated client itself declares — or
after a Foundation type the client's own support files use unqualified — generates swift5
code that cannot compile. Two examples from a real production spec:
A schema named
Locale("a locale that can be used in brand templates") generatesModels/Locale.swift, and inside the generated module that struct wins name resolutionover
Foundation.Locale. The client's own support files then stop compiling:A schema named
ValidationErrorgenerates a struct that collides with the genericValidationError<T>thatValidation.swiftships in the same module:The cause
Swift5ClientCodegen.reservedWordsalready exists for exactly this:ErrorResponseandResponsehead the list as "name used by swift client", andURL/Dataare reserved as"commonly-used Foundation types". But the list was never completed — none of the
Validation.swiftnames, none of the other support-file classes (CodableHelper,Configuration,RequestBuilder, …), and none of the other Foundation types the supportfiles reference unqualified (
Locale,DateFormatter,TimeZone,URLSession, …) are init.
The fix
Complete
reservedWordsalong the two principles the list already encodes, derived byauditing every swift5 template:
urlsession/alamofire/vapor library implementations) — a model with such a name is an
invalid redeclaration of the client's own type;
such a name shadows the real type inside the module and breaks the client's own code
(the
Localecase above).A model with a reserved name is renamed
Model<Name>(ModelLocale,ModelValidationError), which is the established mechanism: it is exactly what a modelnamed
ResponseorErrorResponsealready gets today. Naming impact: specs thatdeclare models with these names (e.g.
Configuration,ValidationError) will see thosemodels renamed with the
Modelprefix — but today every one of those specs generates codethat does not compile at all, so this cannot break a working setup.
Deliberately not added, to keep the change scoped:
languageSpecificPrimitives(Date,UUID,Decimal,AnyCodable,OpenAPIDateWithoutTime):toModelNameintentionally maps these onto the primitivetypes, and existing tests pin that behavior;
Session/DataRequest, Vapor'sClientResponse, PromiseKit'sPromise, …): the same shadowing disease exists there,but those names only matter for one library flavor, and
Swift.Resultshows thetemplate-side alternative (qualifying the reference) that would fix them without
renaming anyone's models — happy to do either in a follow-up if there is interest.
The swift6 generator has the identical list with the identical gap; the same additions
apply there and I can extend this PR or follow up, whichever you prefer.
Tests / verification
Swift5ClientCodegenTest#reservedTypeNamesDeclaredByClientTestand#reservedFoundationTypeNamesTestcover both groups; they fail on master and pass withthe fix. Full swift5 test classes pass.
./bin/generate-samples.sh ./bin/configs/swift5-*.yamlproduces no sample diff: nopetstore sample declares a model with any of the reserved names.
./bin/utils/export_docs_generators.shupdates the reserved-words list indocs/generators/swift5.md(committed here).LocaleandValidationErrorschemas:on master the generated client fails with the two errors quoted above; with this fix it
generates
ModelLocale.swift/ModelValidationError.swift, all references follow, andswift buildsucceeds in aswift:6.1container.Existing upstream issues: none found for this shadowing
(searched
Locale swift,Foundation.Locale,OpenISO8601DateFormatter,swift ValidationError). #9903 (closed) was the same class of bug for a query parameternamed
path; #22073 is a different swift6 collision class (property casing).PR checklist
./bin/generate-samples.sh ./bin/configs/swift5-*.yaml— no diff;./bin/utils/export_docs_generators.sh—docs/generators/swift5.mdupdated and committed).Generated with Claude Code
Summary by cubic
Fixes the swift5 generator so schemas named after types the generated client declares or uses from Foundation no longer produce uncompilable code. Models like
LocaleorValidationErrorare now renamedModelLocale/ModelValidationError, the same mechanism already used forResponseandErrorResponse.Naming impact
Configuration,ValidationError) will see them renamed with aModelprefix.Written for commit c1a1280. Summary will update on new commits.