Skip to content

feat(swift): add final classes option#2947

Merged
schani merged 2 commits into
glideapps:masterfrom
coyaSONG:agent/swift-final-classes
Jul 15, 2026
Merged

feat(swift): add final classes option#2947
schani merged 2 commits into
glideapps:masterfrom
coyaSONG:agent/swift-final-classes

Conversation

@coyaSONG

@coyaSONG coyaSONG commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Description

Add an opt-in --final-classes Swift renderer option. When enabled, it emits every generated Swift reference type as a final class:

  • models explicitly emitted as classes via --struct-or-class class
  • models promoted to classes to break recursive value-type cycles
  • the generated JSONNull, JSONCodingKey, and JSONAny Codable helpers

The option defaults to false, so existing Swift output remains unchanged. Struct output is unchanged in either mode.

Related Issue

Closes #1241

Motivation and Context

Final classes communicate that generated models are not intended as subclassing surfaces and can avoid dynamic subclass dispatch. Making the behavior opt-in provides that benefit without introducing a breaking change for users who currently subclass generated types.

The renderer previously had no option for this behavior: it selected only class or struct for model declarations and hard-coded bare class declarations for helper types.

Previous Behaviour / Output

class Person: Codable {
    // ...
}

class JSONAny: Codable {
    // ...
}

New Behaviour / Output

With --final-classes:

final class Person: Codable {
    // ...
}

final class JSONAny: Codable {
    // ...
}

How Has This Been Tested?

  • focused final-class tests: 3/3 passed, including default-off compatibility
  • npm run test:unit: 17 files and 130 tests passed with no type errors
  • FIXTURE=swift npm run test:fixtures: all 241 Swift fixture runs passed with Swift 6.2.3, including the explicit struct-or-class: class, final-classes: true variant
  • npm run build
  • Biome on all four changed files
  • git diff --check
  • manual CLI generation confirmed bare class by default and final class with --final-classes

The repository's requested Node 24.6.0 was not installed in this environment; validation used Node 25.6.1. Implementation and validation were assisted by OpenAI Codex and reviewed against the repository guidance.

Screenshots (if appropriate):

Not applicable; this changes generated source output.

@coyaSONG coyaSONG marked this pull request as ready for review July 14, 2026 21:21
@schani

schani commented Jul 14, 2026

Copy link
Copy Markdown
Member

Could you put this behind an option that's default off please? It's a breaking change otherwise.

@coyaSONG coyaSONG changed the title fix(swift): generate final classes feat(swift): add final classes option Jul 14, 2026
@schani schani merged commit 3fd1dcd into glideapps:master Jul 15, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Please generate "final" Swift classes

2 participants