-
Notifications
You must be signed in to change notification settings - Fork 335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add rules for how to wrap attributes on property declarations #254
Conversation
06b7807
to
9a23e67
Compare
Is there a link/thread to why we chose to inline state, observed, environment where as Viewbuilder/Availability go above? Is it just to match existing usage vs building consistency? Simple vs Complex? This feels like a cognitive load to differentiate |
These rules try to match the most common formatting used by the community for each of these different use cases. I think the formatting in each of these cases is individually well-motivated and reasonable: SwiftUI property wrappersIf you look at Apple's first party SwiftUI sample code, the SwiftUI property wrappers ( Result buildersFor result builders like Within our codebase, placing these on the previous line is by far the most common pattern. With a quick regex search in our codebase, I see 1000+ uses of One reason I think this formatting makes sense is because it means that all uses of // Consistent
@ViewBuilder
var dashboard: some View {
// ...
}
@ViewBuilder
func dashboard(padding: Double) -> some View {
// ...
} // Inconsistent
@ViewBuilder var dashboard: some View {
// ...
}
@ViewBuilder
func dashboard(padding: Double) -> some View {
// ...
}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I am supportive of this direction though I have a bit of feedback around the special case for stored properties.
After some discussion internally, we updated the rule to:
This removes the special case for @State private var warpDriveEnabled: Bool
@ObservedObject private var lifeSupportService: LifeSupportService
@Environment(\.controlPanelStyle) private var controlPanelStyle
@AppStorage("ControlsConfig") private var controlsConfig: ControlConfiguration
@AppStorage("ControlsConfig", store: myCustomUserDefaults)
private var controlsConfig: ControlConfiguration
@Tweak(name: "Aspect ratio")
private var aspectRatio = AspectRatio.stretch
@available(*, unavailable)
var saturn5Builder: Saturn5Builder
@available(*, unavailable, message: "No longer in production")
var saturn5Builder: Saturn5Builder I also added a rationale section to the new rule:
|
Package.swift
Outdated
@@ -42,8 +42,8 @@ let package = Package( | |||
|
|||
.binaryTarget( | |||
name: "SwiftFormat", | |||
url: "https://github.com/calda/SwiftFormat/releases/download/0.53-beta-4/SwiftFormat.artifactbundle.zip", | |||
checksum: "8506e9f6a434127f9eabe62c0a0349ccfd1e12e7cd7a96ba6a0c8f9d4a596099"), | |||
url: "https://github.com/calda/SwiftFormat/releases/download/0.53-beta-7/SwiftFormat.artifactbundle.zip", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will need to update this again after merging nicklockwood/SwiftFormat#1595
0afc42f
to
dbe5737
Compare
dbe5737
to
ad59cbe
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @calda . I love where we landed!
--computedvarattrs prev-line # wrapAttributes | ||
--storedvarattrs same-line # wrapAttributes | ||
--complexattrs prev-line # wrapAttributes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
README.md
Outdated
|
||
@available(*, deprecated, message: "To be retired by 2030") var atlas5Builder: Atlas5Builder | ||
|
||
@available(*, iOS 17.0, tvOS 17.0, macOS 14.0, watchOS 10.0) var newRocketBuilder: NewRocketBuilder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@available(*, iOS 17.0, tvOS 17.0, macOS 14.0, watchOS 10.0) var newRocketBuilder: NewRocketBuilder | |
@available(*, iOS 17.0, tvOS 17.0, macOS 14.0, watchOS 10.0) var newShepardBuilder: NewShepardBuilder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we made this change we should update elsewhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good suggestion! I went with New Glenn (also by Blue Origin) instead, since it's 8-9 years newer than the New Shepard. https://en.wikipedia.org/wiki/New_Glenn
} | ||
``` | ||
|
||
#### Why? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In some other rules we put the "why?" before the examples but I am fine moving it after the examples here.
README.md
Outdated
// WRONG. These complex attached macros should be written on the previous line. | ||
struct SolarSystemView { | ||
|
||
@Query(sort: \.distance) var allPlanets: Planet |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
README.md
Outdated
// Despite being less than 100 characters long, these lines are very complex and feel unnecessarily long: | ||
@available(*, unavailable, message: "No longer in production") var saturn5Builder: Saturn5Builder | ||
@available(*, deprecated, message: "To be retired by 2030") var atlas5Builder: Atlas5Builder | ||
@available(*, iOS 17.0, tvOS 17.0, macOS 14.0, watchOS 10.0) var newRocketBuilder: NewRocketBuilder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With indentation this line is 101 characters. This is in conflict with the comment above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The indentation isn't part of the code block, since the start of the code block is itself indented by two chars. After updating this to newGlennBuilder
it's also two chars shorter than before, so will be under 100 no matter how you count it.
Co-authored-by: Michael Bachand <[email protected]>
Co-authored-by: Michael Bachand <[email protected]>
Co-authored-by: Michael Bachand <[email protected]>
Co-authored-by: Michael Bachand <[email protected]>
Co-authored-by: Michael Bachand <[email protected]>
Co-authored-by: Michael Bachand <[email protected]>
Summary
We currently have a rule for how to wrap attributes on function and type declarations (link), but not property declarations.
This PR adds rules for how to wrap attributes on property declarations. This is split into three groups:
Taken as a whole (including the rules for functions, types, and properties), our rules for wrapping attributes can be summed up as:
Autocorrect is implemented in the SwiftFormat
wrapAttributes
rule, supported by new options added in nicklockwood/SwiftFormat#1588, nicklockwood/SwiftFormat#1591, and nicklockwood/SwiftFormat#1595.Examples
Computed properties
Stored properties
Reasoning
Based on existing usage within our codebase / the iOS community, these are the most common ways to format attributes.
SwiftUI stored property attributes, like
@State
and@Environment
, are almost always written on the same line as the declaration. This applies within our codebase, but also within all first-party example code from Apple.More rationale discussed below in #254 (comment) and #254 (comment).
Please react with 👍/👎 if you agree or disagree with this proposal.