Skip to content

Commit 01914f8

Browse files
authored
Merge pull request swiftlang#138 from dylansturg/use_enums_must_go_deeper
Transform nested structs in UseEnumForNamespacing.
2 parents 7d45ac2 + 0e3e9d8 commit 01914f8

File tree

3 files changed

+77
-5
lines changed

3 files changed

+77
-5
lines changed

Sources/SwiftFormatRules/UseEnumForNamespacing.swift

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,18 @@ import SwiftSyntax
2828
public final class UseEnumForNamespacing: SyntaxFormatRule {
2929

3030
public override func visit(_ node: StructDeclSyntax) -> DeclSyntax {
31+
let rewrittenMembers = node.members.members.compactMap {
32+
super.visit($0).as(MemberDeclListItemSyntax.self)
33+
}
34+
guard rewrittenMembers.count == node.members.members.count else {
35+
// No members should be deleted - exit early instead of breaking the source.
36+
return DeclSyntax(node)
37+
}
38+
let rewrittenMemberDeclList = SyntaxFactory.makeMemberDeclList(rewrittenMembers)
3139
guard node.genericParameterClause == nil, node.inheritanceClause == nil,
32-
let memberDecls = membersToKeepIfUsedAsNamespace(node.members.members)
40+
let memberDecls = membersToKeepIfUsedAsNamespace(rewrittenMemberDeclList)
3341
else {
34-
return DeclSyntax(node)
42+
return DeclSyntax(node.withMembers(node.members.withMembers(rewrittenMemberDeclList)))
3543
}
3644

3745
diagnose(.convertToEnum(kind: "struct", name: node.identifier), on: node)
@@ -77,9 +85,11 @@ public final class UseEnumForNamespacing: SyntaxFormatRule {
7785
// Do not append private initializer.
7886

7987
case .ifConfigDecl(let decl):
80-
let membersToKeep: [MemberDeclListSyntax] = decl.clauses
81-
.compactMap { clause in
82-
(clause.elements.as(MemberDeclListSyntax.self)).flatMap(membersToKeepIfUsedAsNamespace(_:))
88+
// Note that the child nodes have already been rewritten, so any nested structs that should
89+
// become enums have already been transformed.
90+
let membersToKeep: [MemberDeclListSyntax] =
91+
decl.clauses.compactMap {
92+
($0.elements.as(MemberDeclListSyntax.self)).flatMap(membersToKeepIfUsedAsNamespace(_:))
8393
}
8494

8595
if membersToKeep.count < decl.clauses.count {

Tests/SwiftFormatRulesTests/UseEnumForNamespacingTests.swift

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,65 @@ final class UseEnumForNamespacingTests: DiagnosingTestCase {
160160
}
161161
""")
162162
}
163+
164+
public func testNestedEnumsForNameSpaces() {
165+
XCTAssertFormatting(
166+
UseEnumForNamespacing.self,
167+
input: """
168+
struct A {
169+
static func fooA() {}
170+
struct B {
171+
static func fooB() {}
172+
}
173+
}
174+
struct C {
175+
func fooC() {}
176+
struct D {
177+
static func fooB() {}
178+
}
179+
}
180+
struct E {
181+
static func fooE() {}
182+
struct F {
183+
func fooF() {}
184+
}
185+
}
186+
struct G {
187+
func fooG() {}
188+
#if useH
189+
struct H {
190+
static func fooH() {}
191+
}
192+
#endif
193+
}
194+
""",
195+
expected: """
196+
enum A {
197+
static func fooA() {}
198+
enum B {
199+
static func fooB() {}
200+
}
201+
}
202+
struct C {
203+
func fooC() {}
204+
enum D {
205+
static func fooB() {}
206+
}
207+
}
208+
enum E {
209+
static func fooE() {}
210+
struct F {
211+
func fooF() {}
212+
}
213+
}
214+
struct G {
215+
func fooG() {}
216+
#if useH
217+
enum H {
218+
static func fooH() {}
219+
}
220+
#endif
221+
}
222+
""")
223+
}
163224
}

Tests/SwiftFormatRulesTests/XCTestManifests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,7 @@ extension UseEnumForNamespacingTests {
302302
// `swift test --generate-linuxmain`
303303
// to regenerate.
304304
static let __allTests__UseEnumForNamespacingTests = [
305+
("testNestedEnumsForNameSpaces", testNestedEnumsForNameSpaces),
305306
("testNonEnumsUsedAsNamespaces", testNonEnumsUsedAsNamespaces),
306307
]
307308
}

0 commit comments

Comments
 (0)