swiftlang/swift-format

Special case macros?

Opened this issue · 4 comments

struct SettingsView: View {

  @Environment(\.modelContext) private var modelContext

  @Query(sort: \BlockedUserModel.createdAt) private var blockedUsers: [BlockedUserModel]

  // --snip--
}

becomes:

struct SettingsView: View {

  @Environment(\.modelContext) private var modelContext

  @Query(sort: \BlockedUserModel.createdAt, order: .reverse) private var blockedUsers:
    [BlockedUserModel]

  // --snip--
}

which seems non-ideal, I feel like something similar to:

struct SettingsView: View {

  @Environment(\.modelContext) private var modelContext

  @Query(sort: \BlockedUserModel.createdAt, order: .reverse)
  private var blockedUsers: [BlockedUserModel]

  // --snip--
}

would be more readable

Synced to Apple’s issue tracker as rdar://133811486

Syntactically, there's nothing that distinguishes attached macros from other attributes, so we can't special case them.

I think the example you're showing is one where attributes/macros in general can be improved, though. The same thing happens with long availability macros:

struct SettingsView: View {
  @available(iOS 16.0, tvOS 16.0, watchOS 10.0, macOS 15.0) private var blockedUsers:
    [BlockedUserModel]
}

I think we could make the change that if any of a declaration's attributes has parenthesized content, then we force the declaration to start on its own line after the attributes. That would solve this case but avoid putting unnecessary line breaks before simple things like @objc.

j-f1 commented

There’s also the case of @objc(selector). Maybe the attributes should only be split onto multiple lines if the declaration as a whole (excluding the body) needs to be broken up?

That's another option, if folks prefer

@objc
func reallyLongFunctionName(
  arg: Arg
) {

over

@objc func reallyLongFunctionName(
  arg: Arg
) {

I don't really have a strong opinion as long as it's consistent. But I'm not swayed too much by @objc(selector) because the selector is typically going to be long enough that the likelihood is high that it'll force whatever is after it to wrap anyway, so I don't think carving out a way to keep @objc(selector) on the same line makes sense.