Skip to content

Commit

Permalink
Improve attribute handling in opaqueGenericParameters rule (#1713)
Browse files Browse the repository at this point in the history
  • Loading branch information
calda authored and nicklockwood committed Jun 11, 2024
1 parent d45da28 commit 8cffd92
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 3 deletions.
12 changes: 9 additions & 3 deletions Sources/Rules.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6626,9 +6626,7 @@ public struct _FormatRules {
genericSignatureStartIndex < paramListStartIndex,
genericSignatureEndIndex < paramListStartIndex,
let openBraceIndex = formatter.index(of: .startOfScope("{"), after: paramListEndIndex),
let closeBraceIndex = formatter.endOfScope(at: openBraceIndex),
// Ignore anything with attributes
!formatter.modifiersForDeclaration(at: keywordIndex, contains: { $1.hasPrefix("@") })
let closeBraceIndex = formatter.endOfScope(at: openBraceIndex)
else { return }

var genericTypes = [Formatter.GenericType]()
Expand Down Expand Up @@ -6700,6 +6698,14 @@ public struct _FormatRules {
continue
}

// If the generic type is referenced in any attributes, then it can't be removed
let startOfModifiers = formatter.startOfModifiers(at: keywordIndex, includingAttributes: true)
let modifierTokens = formatter.tokens[startOfModifiers ..< keywordIndex]
if modifierTokens.contains(where: { $0.string == genericType.name }) {
genericType.eligibleToRemove = false
continue
}

// If the generic type is used in a constraint of any other generic type, then the type
// can't be removed without breaking that other type
let otherGenericTypes = genericTypes.filter { $0.name != genericType.name }
Expand Down
31 changes: 31 additions & 0 deletions Tests/RulesTests+Syntax.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2867,6 +2867,37 @@ class SyntaxTests: RulesTests {
testFormatting(for: input, rule: FormatRules.opaqueGenericParameters, options: options)
}

func testGenericSimplifiedInMethodWithAttributeOrMacro() {
let input = """
@MyResultBuilder
func foo<T: Foo, U: Bar>(foo: T, bar: U) -> MyResult {
foo
bar
}
@MyFunctionBodyMacro(withArgument: true)
func foo<T: Foo, U: Bar>(foo: T, bar: U) {
print(foo, bar)
}
"""

let output = """
@MyResultBuilder
func foo(foo: some Foo, bar: some Bar) -> MyResult {
foo
bar
}
@MyFunctionBodyMacro(withArgument: true)
func foo(foo: some Foo, bar: some Bar) {
print(foo, bar)
}
"""

let options = FormatOptions(swiftVersion: "5.7")
testFormatting(for: input, output, rule: FormatRules.opaqueGenericParameters, options: options)
}

// MARK: - genericExtensions

func testGenericExtensionNotModifiedBeforeSwift5_7() {
Expand Down

0 comments on commit 8cffd92

Please sign in to comment.