Skip to content

Commit 2aeedb2

Browse files
authored
Merge pull request swiftlang#3 from allevato/sr-11110
Make members of a private extension fileprivate.
2 parents fd0626f + 0fbc618 commit 2aeedb2

File tree

3 files changed

+31
-1
lines changed

3 files changed

+31
-1
lines changed

Sources/SwiftFormatRules/NoAccessLevelOnExtensionDeclaration.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,20 @@ public final class NoAccessLevelOnExtensionDeclaration: SyntaxFormatRule {
3636
// Public, private, or fileprivate keywords need to be moved to members
3737
case .publicKeyword, .privateKeyword, .fileprivateKeyword:
3838
diagnose(.moveAccessKeyword(keyword: accessKeyword.name.text), on: accessKeyword)
39+
40+
// The effective access level of the members of a `private` extension is `fileprivate`, so
41+
// we have to update the keyword to ensure that the result is correct.
42+
let accessKeywordToAdd: DeclModifierSyntax
43+
if keywordKind == .privateKeyword {
44+
accessKeywordToAdd
45+
= accessKeyword.withName(accessKeyword.name.withKind(.fileprivateKeyword))
46+
} else {
47+
accessKeywordToAdd = accessKeyword
48+
}
49+
3950
let newMembers = SyntaxFactory.makeMemberDeclBlock(
4051
leftBrace: node.members.leftBrace,
41-
members: addMemberAccessKeywords(memDeclBlock: node.members, keyword: accessKeyword),
52+
members: addMemberAccessKeywords(memDeclBlock: node.members, keyword: accessKeywordToAdd),
4253
rightBrace: node.members.rightBrace)
4354
let newKeyword = replaceTrivia(
4455
on: node.extensionKeyword,
@@ -47,6 +58,7 @@ public final class NoAccessLevelOnExtensionDeclaration: SyntaxFormatRule {
4758
return node.withMembers(newMembers)
4859
.withModifiers(modifiers.remove(name: accessKeyword.name.text))
4960
.withExtensionKeyword(newKeyword)
61+
5062
// Internal keyword redundant, delete
5163
case .internalKeyword:
5264
diagnose(
@@ -58,6 +70,7 @@ public final class NoAccessLevelOnExtensionDeclaration: SyntaxFormatRule {
5870
leadingTrivia: accessKeyword.leadingTrivia) as! TokenSyntax
5971
return node.withModifiers(modifiers.remove(name: accessKeyword.name.text))
6072
.withExtensionKeyword(newKeyword)
73+
6174
default:
6275
break
6376
}

Tests/SwiftFormatRulesTests/NoAccessLevelOnExtensionDeclarationTests.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,20 @@ public class NoAccessLevelOnExtensionDeclarationTests: DiagnosingTestCase {
8484
"""
8585
)
8686
}
87+
88+
public func testPrivateIsEffectivelyFileprivate() {
89+
XCTAssertFormatting(
90+
NoAccessLevelOnExtensionDeclaration.self,
91+
input: """
92+
private extension Foo {
93+
func f() {}
94+
}
95+
""",
96+
expected: """
97+
extension Foo {
98+
fileprivate func f() {}
99+
}
100+
"""
101+
)
102+
}
87103
}

Tests/SwiftFormatRulesTests/XCTestManifests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ extension NoAccessLevelOnExtensionDeclarationTests {
157157
static let __allTests__NoAccessLevelOnExtensionDeclarationTests = [
158158
("testExtensionDeclarationAccessLevel", testExtensionDeclarationAccessLevel),
159159
("testPreservesCommentOnRemovedModifier", testPreservesCommentOnRemovedModifier),
160+
("testPrivateIsEffectivelyFileprivate", testPrivateIsEffectivelyFileprivate),
160161
]
161162
}
162163

0 commit comments

Comments
 (0)