Skip to content

Commit edf766a

Browse files
authored
Add the frozen keyword only to enums with the public or package modifiers (#595)
### Motivation As reported in #586, using Xcode 16 Beta 3, the generated Type.swift file now shows multiple warnings due to the `@frozen` attribute being applied to non-public enums. ### Modifications In order to resolve the above issue, I have modified the code to annotate the `@frozen` keyword only on `enum` with the `public` or `package` modifiers. ### Result No warnings are issued when the `@frozen` keyword is annotated on enums with the `public` or `package` modifiers.
1 parent 285ebba commit edf766a

File tree

5 files changed

+146
-3
lines changed

5 files changed

+146
-3
lines changed

Sources/_OpenAPIGeneratorCore/Renderer/TextBasedRenderer.swift

+10-1
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ struct TextBasedRenderer: RendererProtocol {
645645

646646
/// Renders the specified enum declaration.
647647
func renderEnum(_ enumDesc: EnumDescription) {
648-
if enumDesc.isFrozen {
648+
if requiresFrozenAnnotation(enumDesc) {
649649
writer.writeLine("@frozen ")
650650
writer.nextLineAppendsToLastLine()
651651
}
@@ -898,4 +898,13 @@ extension TextBasedRenderer {
898898
renderer.renderExpression(expression)
899899
return renderer.renderedContents()
900900
}
901+
902+
/// Checks if the given enum description requires a @frozen annotation.
903+
/// - Parameter enumDesc: The enum description to check.
904+
/// - Returns: A boolean value indicating whether the enum description requires a @frozen annotation.
905+
func requiresFrozenAnnotation(_ enumDesc: EnumDescription) -> Bool {
906+
guard enumDesc.isFrozen else { return false }
907+
guard let accessModifier = enumDesc.accessModifier else { return false }
908+
return accessModifier == .public || accessModifier == .package
909+
}
901910
}

Tests/OpenAPIGeneratorCoreTests/Renderer/Test_TextBasedRenderer.swift

+22
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,28 @@ final class Test_TextBasedRenderer: XCTestCase {
727727
}
728728
}
729729
730+
extension Test_TextBasedRenderer {
731+
func testRequiresFrozenAnnotation() {
732+
let renderer = TextBasedRenderer.default
733+
let testCases: [(EnumDescription, Bool)] = [
734+
(EnumDescription(isFrozen: true, accessModifier: .`public`, name: ""), true),
735+
(EnumDescription(isFrozen: true, accessModifier: .`package`, name: ""), true),
736+
(EnumDescription(isFrozen: true, accessModifier: .`internal`, name: ""), false),
737+
(EnumDescription(isFrozen: true, accessModifier: .`fileprivate`, name: ""), false),
738+
(EnumDescription(isFrozen: true, accessModifier: .`private`, name: ""), false),
739+
(EnumDescription(isFrozen: false, accessModifier: .`public`, name: ""), false),
740+
(EnumDescription(isFrozen: false, accessModifier: .`package`, name: ""), false),
741+
(EnumDescription(isFrozen: false, accessModifier: .`internal`, name: ""), false),
742+
(EnumDescription(isFrozen: false, accessModifier: .`fileprivate`, name: ""), false),
743+
(EnumDescription(isFrozen: false, accessModifier: .`private`, name: ""), false),
744+
]
745+
746+
for (enumDesc, expectedResult) in testCases {
747+
XCTAssertEqual(renderer.requiresFrozenAnnotation(enumDesc), expectedResult)
748+
}
749+
}
750+
}
751+
730752
extension Test_TextBasedRenderer {
731753
732754
func _test<Input>(

Tests/OpenAPIGeneratorReferenceTests/SnippetBasedReferenceTests.swift

+112
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,116 @@ final class SnippetBasedReferenceTests: XCTestCase {
149149
)
150150
}
151151

152+
func testComponentsSchemasFrozenEnum_accessModifier_public() throws {
153+
try self.assertSchemasTranslation(
154+
"""
155+
schemas:
156+
MyEnum:
157+
type: string
158+
enum:
159+
- one
160+
- two
161+
""",
162+
"""
163+
public enum Schemas {
164+
@frozen public enum MyEnum: String, Codable, Hashable, Sendable, CaseIterable {
165+
case one = "one"
166+
case two = "two"
167+
}
168+
}
169+
""",
170+
accessModifier: .public
171+
)
172+
}
173+
174+
func testComponentsSchemasFrozenEnum_accessModifier_package() throws {
175+
try self.assertSchemasTranslation(
176+
"""
177+
schemas:
178+
MyEnum:
179+
type: string
180+
enum:
181+
- one
182+
- two
183+
""",
184+
"""
185+
package enum Schemas {
186+
@frozen package enum MyEnum: String, Codable, Hashable, Sendable, CaseIterable {
187+
case one = "one"
188+
case two = "two"
189+
}
190+
}
191+
""",
192+
accessModifier: .package
193+
)
194+
}
195+
196+
func testComponentsSchemasFrozenEnum_accessModifier_internal() throws {
197+
try self.assertSchemasTranslation(
198+
"""
199+
schemas:
200+
MyEnum:
201+
type: string
202+
enum:
203+
- one
204+
- two
205+
""",
206+
"""
207+
internal enum Schemas {
208+
internal enum MyEnum: String, Codable, Hashable, Sendable, CaseIterable {
209+
case one = "one"
210+
case two = "two"
211+
}
212+
}
213+
""",
214+
accessModifier: .internal
215+
)
216+
}
217+
218+
func testComponentsSchemasFrozenEnum_accessModifier_fileprivate() throws {
219+
try self.assertSchemasTranslation(
220+
"""
221+
schemas:
222+
MyEnum:
223+
type: string
224+
enum:
225+
- one
226+
- two
227+
""",
228+
"""
229+
fileprivate enum Schemas {
230+
fileprivate enum MyEnum: String, Codable, Hashable, Sendable, CaseIterable {
231+
case one = "one"
232+
case two = "two"
233+
}
234+
}
235+
""",
236+
accessModifier: .fileprivate
237+
)
238+
}
239+
240+
func testComponentsSchemasFrozenEnum_accessModifier_private() throws {
241+
try self.assertSchemasTranslation(
242+
"""
243+
schemas:
244+
MyEnum:
245+
type: string
246+
enum:
247+
- one
248+
- two
249+
""",
250+
"""
251+
private enum Schemas {
252+
private enum MyEnum: String, Codable, Hashable, Sendable, CaseIterable {
253+
case one = "one"
254+
case two = "two"
255+
}
256+
}
257+
""",
258+
accessModifier: .private
259+
)
260+
}
261+
152262
func testComponentsSchemasString() throws {
153263
try self.assertSchemasTranslation(
154264
"""
@@ -5074,10 +5184,12 @@ extension SnippetBasedReferenceTests {
50745184
ignoredDiagnosticMessages: Set<String> = [],
50755185
_ componentsYAML: String,
50765186
_ expectedSwift: String,
5187+
accessModifier: AccessModifier = .public,
50775188
file: StaticString = #filePath,
50785189
line: UInt = #line
50795190
) throws {
50805191
let translator = try makeTypesTranslator(
5192+
accessModifier: accessModifier,
50815193
featureFlags: featureFlags,
50825194
ignoredDiagnosticMessages: ignoredDiagnosticMessages,
50835195
componentsYAML: componentsYAML

docker/docker-compose.2204.59.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ services:
1111
test:
1212
image: *image
1313
environment:
14-
- WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
14+
# - WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
1515
- IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error
1616
- STRICT_CONCURRENCY_ARG=-Xswiftc -strict-concurrency=complete
1717
shell:

docker/docker-compose.2204.590.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ services:
1111
test:
1212
image: *image
1313
environment:
14-
- WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
14+
# - WARN_AS_ERROR_ARG=-Xswiftc -warnings-as-errors
1515
- IMPORT_CHECK_ARG=--explicit-target-dependency-import-check error
1616
- STRICT_CONCURRENCY_ARG=-Xswiftc -strict-concurrency=complete
1717
shell:

0 commit comments

Comments
 (0)