Skip to content

Commit b9b815f

Browse files
Add redundantViewBuilder rule (#353)
Co-authored-by: Cal Stephens <[email protected]>
1 parent 7d0d58c commit b9b815f

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

Package.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ let package = Package(
4747

4848
.binaryTarget(
4949
name: "swiftformat",
50-
url: "https://github.com/calda/SwiftFormat-nightly/releases/download/2025-12-10-b/SwiftFormat.artifactbundle.zip",
51-
checksum: "9f00a9adb66794f253b58f68b4f1687c58804b056ed93e8570a63aff953f98f6"
50+
url: "https://github.com/calda/SwiftFormat-nightly/releases/download/2025-12-20/SwiftFormat.artifactbundle.zip",
51+
checksum: "0902054e8904dbe233dbcd3c43e5bc0a644cceff1fa599ce950d1295cd146fc0"
5252
),
5353

5454
.binaryTarget(

README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4903,6 +4903,62 @@ _You can enable the following settings in Xcode by running [this script](resourc
49034903

49044904
</details>
49054905

4906+
- <a id='redundant-viewbuilder'></a>(<a href='#redundant-viewbuilder'>link</a>) **Omit `@ViewBuilder` when it is not required.** `@ViewBuilder` is implicit on `View.body` properties and `ViewModifier.body(content:)` functions, and is unnecessary on single-expression properties or functions.
4907+
4908+
<details>
4909+
4910+
[![SwiftFormat: redundantViewBuilder](https://img.shields.io/badge/SwiftFormat-redundantViewBuilder-7B0051.svg)](https://github.com/nicklockwood/SwiftFormat/blob/main/Rules.md#redundantViewBuilder)
4911+
4912+
#### Why?
4913+
4914+
`@ViewBuilder` is automatically applied by the compiler to `View.body` and `ViewModifier.body(content:)`, so adding it explicitly is redundant. Similarly, single-expression properties and functions don't need `@ViewBuilder` since there's only one view being returned.
4915+
4916+
```swift
4917+
// WRONG
4918+
struct PlanetView: View {
4919+
@ViewBuilder
4920+
var body: some View {
4921+
Text("Hello, World!")
4922+
}
4923+
4924+
@ViewBuilder
4925+
var subtitle: some View {
4926+
Text("Subtitle")
4927+
}
4928+
}
4929+
4930+
// RIGHT
4931+
struct PlanetView: View {
4932+
var body: some View {
4933+
Text("Hello, World!")
4934+
}
4935+
4936+
var subtitle: some View {
4937+
Text("Subtitle")
4938+
}
4939+
}
4940+
4941+
// ALSO RIGHT: @ViewBuilder is necessary for conditionals
4942+
struct ConditionalView: View {
4943+
var showDetails: Bool
4944+
4945+
var body: some View {
4946+
title
4947+
}
4948+
4949+
@ViewBuilder
4950+
var title: some View {
4951+
if showDetails {
4952+
Text("Details")
4953+
} else {
4954+
Text("Summary")
4955+
}
4956+
}
4957+
}
4958+
```
4959+
4960+
</details>
4961+
49064962
**[⬆ back to top](#table-of-contents)**
49074963

49084964
## Testing

Sources/AirbnbSwiftFormatTool/airbnb.swiftformat

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,3 +146,4 @@
146146
--rules redundantTypedThrows
147147
--rules preferFinalClasses
148148
--rules simplifyGenericConstraints
149+
--rules redundantViewBuilder

0 commit comments

Comments
 (0)