Skip to content

Latest commit

 

History

History
3036 lines (2303 loc) · 51.8 KB

Rules.md

File metadata and controls

3036 lines (2303 loc) · 51.8 KB

Default Rules (enabled by default)

Opt-in Rules (disabled by default)

Deprecated Rules (do not use)


acronyms

Capitalize acronyms when the first character is capitalized.

Option Description
--acronyms Acronyms to auto-capitalize. Defaults to "ID,URL,UUID"
Examples
- let destinationUrl: URL
- let urlRouter: UrlRouter
- let screenId: String
- let entityUuid: UUID

+ let destinationURL: URL
+ let urlRouter: URLRouter
+ let screenID: String
+ let entityUUID: UUID

andOperator

Prefer comma over && in if, guard or while conditions.

Examples
- if true && true {
+ if true, true {
- guard true && true else {
+ guard true, true else {
- if functionReturnsBool() && true {
+ if functionReturnsBool(), true {
- if functionReturnsBool() && variable {
+ if functionReturnsBool(), variable {

anyObjectProtocol

Prefer AnyObject over class in protocol definitions.

Examples
- protocol Foo: class {}
+ protocol Foo: AnyObject {}

NOTE: The guideline to use AnyObject instead of class was only introduced in Swift 4.1, so the anyObjectProtocol rule is disabled unless the swift version is set to 4.1 or above.


applicationMain

Replace obsolete @UIApplicationMain and @NSApplicationMain attributes with @main for Swift 5.3 and above.

assertionFailures

Changes all instances of assert(false, ...) to assertionFailure(...) and precondition(false, ...) to preconditionFailure(...).

Examples
- assert(false)
+ assertionFailure()
- assert(false, "message", 2, 1)
+ assertionFailure("message", 2, 1)
- precondition(false, "message", 2, 1)
+ preconditionFailure("message", 2, 1)

blankLineAfterImports

Insert blank line after import statements.

Examples
  import A
  import B
  @testable import D
+
  class Foo {
    // foo
  }

blankLineAfterSwitchCase

Insert a blank line after multiline switch cases (excluding the last case, which is followed by a closing brace).

Examples
  func handle(_ action: SpaceshipAction) {
      switch action {
      case .engageWarpDrive:
          navigationComputer.destination = targetedDestination
          await warpDrive.spinUp()
          warpDrive.activate()
+
      case let .scanPlanet(planet):
          scanner.target = planet
          scanner.scanAtmosphere()
          scanner.scanBiosphere()
          scanner.scanForArticialLife()
+
      case .handleIncomingEnergyBlast:
          await energyShields.prepare()
          energyShields.engage()
      }
  }

blankLinesAroundMark

Insert blank line before and after MARK: comments.

Option Description
--lineaftermarks Insert blank line after "MARK:": "true" (default) or "false"
Examples
  func foo() {
    // foo
  }
  // MARK: bar
  func bar() {
    // bar
  }

  func foo() {
    // foo
  }
+
  // MARK: bar
+
  func bar() {
    // bar
  }

blankLinesAtEndOfScope

Remove trailing blank line at the end of a scope.

Examples
  func foo() {
    // foo
-
  }

  func foo() {
    // foo
  }
  array = [
    foo,
    bar,
    baz,
-
  ]

  array = [
    foo,
    bar,
    baz,
  ]

blankLinesAtStartOfScope

Remove leading blank line at the start of a scope.

Option Description
--typeblanklines "remove" (default) or "preserve" blank lines from types
Examples
  func foo() {
-
    // foo
  }

  func foo() {
    // foo
  }
  array = [
-
    foo,
    bar,
    baz,
  ]

  array = [
    foo,
    bar,
    baz,
  ]

blankLinesBetweenChainedFunctions

Remove blank lines between chained functions but keep the linebreaks.

blankLinesBetweenImports

Remove blank lines between import statements.

Examples
  import A
-
  import B
  import C
-
-
  @testable import D
  import E

blankLinesBetweenScopes

Insert blank line before class, struct, enum, extension, protocol or function declarations.

Examples
  func foo() {
    // foo
  }
  func bar() {
    // bar
  }
  var baz: Bool
  var quux: Int

  func foo() {
    // foo
  }
+
  func bar() {
    // bar
  }
+
  var baz: Bool
  var quux: Int

blockComments

Convert block comments to consecutive single line comments.

Examples
- /*
-  * foo
-  * bar
-  */

+ // foo
+ // bar
- /**
-  * foo
-  * bar
-  */

+ /// foo
+ /// bar

braces

Wrap braces in accordance with selected style (K&R or Allman).

Option Description
--allman Use allman indentation style: "true" or "false" (default)
Examples
- if x
- {
    // foo
  }
- else
- {
    // bar
  }

+ if x {
    // foo
  }
+ else {
    // bar
  }

conditionalAssignment

Assign properties using if / switch expressions.

Option Description
--condassignment Use cond. assignment: "after-property" (default) or "always"
Examples
- let foo: String
- if condition {
+ let foo = if condition {
-     foo = "foo"
+     "foo"
  } else {
-     foo = "bar"
+     "bar"
  }

- let foo: String
- switch condition {
+ let foo = switch condition {
  case true:
-     foo = "foo"
+     "foo"
  case false:
-     foo = "bar"
+     "bar"
  }

// With --condassignment always (disabled by default)
- switch condition {
+ foo.bar = switch condition {
  case true:
-     foo.bar = "baaz"
+     "baaz"
  case false:
-     foo.bar = "quux"
+     "quux"
  }

consecutiveBlankLines

Replace consecutive blank lines with a single blank line.

Examples
  func foo() {
    let x = "bar"
-

    print(x)
  }

  func foo() {
    let x = "bar"

    print(x)
  }

consecutiveSpaces

Replace consecutive spaces with a single space.

Examples
- let     foo = 5
+ let foo = 5

consistentSwitchCaseSpacing

Ensures consistent spacing among all of the cases in a switch statement.

Examples
  func handle(_ action: SpaceshipAction) {
      switch action {
      case .engageWarpDrive:
          navigationComputer.destination = targetedDestination
          await warpDrive.spinUp()
          warpDrive.activate()

      case .enableArtificialGravity:
          artificialGravityEngine.enable(strength: .oneG)
+
      case let .scanPlanet(planet):
          scanner.target = planet
          scanner.scanAtmosphere()
          scanner.scanBiosphere()
          scanner.scanForArtificialLife()

      case .handleIncomingEnergyBlast:
          energyShields.engage()
      }
  }
  var name: PlanetType {
  switch self {
  case .mercury:
      "Mercury"
-
  case .venus:
      "Venus"
  case .earth:
      "Earth"
  case .mars:
      "Mars"
-
  case .jupiter:
      "Jupiter"
  case .saturn:
      "Saturn"
  case .uranus:
      "Uranus"
  case .neptune:
      "Neptune"
  }

docComments

Use doc comments for API declarations, otherwise use regular comments.

Option Description
--doccomments Doc comments: "before-declarations" (default) or "preserve"
Examples
- // A placeholder type used to demonstrate syntax rules
+ /// A placeholder type used to demonstrate syntax rules
  class Foo {
-     // This function doesn't really do anything
+     /// This function doesn't really do anything
      func bar() {
-         /// TODO: implement Foo.bar() algorithm
+         // TODO: implement Foo.bar() algorithm
      }
  }

duplicateImports

Remove duplicate import statements.

Examples
  import Foo
  import Bar
- import Foo
  import B
  #if os(iOS)
    import A
-   import B
  #endif

elseOnSameLine

Place else, catch or while keyword in accordance with current style (same or next line).

Option Description
--elseposition Placement of else/catch: "same-line" (default) or "next-line"
--guardelse Guard else: "same-line", "next-line" or "auto" (default)
Examples
  if x {
    // foo
- }
- else {
    // bar
  }

  if x {
    // foo
+ } else {
    // bar
  }
  do {
    // try foo
- }
- catch {
    // bar
  }

  do {
    // try foo
+ } catch {
    // bar
  }
  repeat {
    // foo
- }
- while {
    // bar
  }

  repeat {
    // foo
+ } while {
    // bar
  }

emptyBraces

Remove whitespace inside empty braces.

Option Description
--emptybraces Empty braces: "no-space" (default), "spaced" or "linebreak"
Examples
- func foo() {
-
- }

+ func foo() {}

enumNamespaces

Convert types used for hosting only static members into enums (an empty enum is the canonical way to create a namespace in Swift as it can't be instantiated).

Option Description
--enumnamespaces Change type to enum: "always" (default) or "structs-only"

extensionAccessControl

Configure the placement of an extension's access control keyword.

Option Description
--extensionacl Place ACL "on-extension" (default) or "on-declarations"
Examples

--extensionacl on-extension (default)

- extension Foo {
-     public func bar() {}
-     public func baz() {}
  }

+ public extension Foo {
+     func bar() {}
+     func baz() {}
  }

--extensionacl on-declarations

- public extension Foo {
-     func bar() {}
-     func baz() {}
-     internal func quux() {}
  }

+ extension Foo {
+     public func bar() {}
+     public func baz() {}
+     func quux() {}
  }

fileHeader

Use specified source file header template for all files.

Option Description
--header Header comments: "strip", "ignore", or the text you wish use
--dateformat "system" (default), "iso", "dmy", "mdy" or custom
--timezone "system" (default) or a valid identifier/abbreviation
Examples

You can use the following tokens in the text:

Token Description
{file} File name
{year} Current year
{created} File creation date
{created.year} File creation year
{author} Name and email of the user who first committed the file
{author.name} Name of the user who first committed the file
{author.email} Email of the user who first committed the file

Example:

--header \n {file}\n\n Copyright © {created.year} {author.name}.\n

- // SomeFile.swift

+ //
+ //  SomeFile.swift
+ //  Copyright © 2023 Tim Apple.
+ //

You can use the following built-in formats for --dateformat:

Token Description
system Use the local system locale
iso ISO 8601 (yyyy-MM-dd)
dmy Date/Month/Year (dd/MM/yyyy)
mdy Month/Day/Year (MM/dd/yyyy)

Custom formats are defined using Unicode symbols.

--dateformat iso

- // Created {created}
+ // Created 2023-08-10

--dateformat dmy

- // Created {created}
+ // Created 10/08/2023

--dateformat mdy

- // Created {created}
+ // Created 08/10/2023

--dateformat 'yyyy.MM.dd.HH.mm'

- // Created {created}
+ // Created 2023.08.10.11.00

Setting a time zone enforces consistent date formatting across environments around the world. By default the local system locale is used and for convenience gmt and utc can be used. The time zone can be further customized by setting it to a abbreviation/time zone identifier supported by the Swift standard library.

--dateformat 'yyyy-MM-dd HH:mm ZZZZ' --timezone utc

- // Created {created}
+ // Created 2023-08-10 11:00 GMT

--dateformat 'yyyy-MM-dd HH:mm ZZZZ' --timezone Pacific/Fiji

- // Created 2023-08-10 11:00 GMT
+ // Created 2023-08-10 23:00 GMT+12:00

genericExtensions

Use angle brackets (extension Array<Foo>) for generic type extensions instead of type constraints (extension Array where Element == Foo).

Option Description
--generictypes Semicolon-delimited list of generic types and type parameters
Examples
- extension Array where Element == Foo {}
- extension Optional where Wrapped == Foo {}
- extension Dictionary where Key == Foo, Value == Bar {}
- extension Collection where Element == Foo {}
+ extension Array<Foo> {}
+ extension Optional<Foo> {}
+ extension Dictionary<Key, Value> {}
+ extension Collection<Foo> {}

// With `typeSugar` also enabled:
- extension Array where Element == Foo {}
- extension Optional where Wrapped == Foo {}
- extension Dictionary where Key == Foo, Value == Bar {}
+ extension [Foo] {}
+ extension Foo? {}
+ extension [Key: Value] {}

// Also supports user-defined types!
- extension LinkedList where Element == Foo {}
- extension Reducer where
-     State == FooState,
-     Action == FooAction,
-     Environment == FooEnvironment {}
+ extension LinkedList<Foo> {}
+ extension Reducer<FooState, FooAction, FooEnvironment> {}

headerFileName

Ensure file name in header comment matches the actual file name.

hoistAwait

Move inline await keyword(s) to start of expression.

Option Description
--asynccapturing List of functions with async @autoclosure arguments
Examples
- greet(await forename, await surname)
+ await greet(forename, surname)
- let foo = String(try await getFoo())
+ let foo = await String(try getFoo())

hoistPatternLet

Reposition let or var bindings within pattern.

Option Description
--patternlet let/var placement in patterns: "hoist" (default) or "inline"
Examples
- (let foo, let bar) = baz()
+ let (foo, bar) = baz()
- if case .foo(let bar, let baz) = quux {
    // inner foo
  }

+ if case let .foo(bar, baz) = quux {
    // inner foo
  }

hoistTry

Move inline try keyword(s) to start of expression.

Option Description
--throwcapturing List of functions with throwing @autoclosure arguments
Examples
- foo(try bar(), try baz())
+ try foo(bar(), baz())
- let foo = String(try await getFoo())
+ let foo = try String(await getFoo())

indent

Indent code in accordance with the scope level.

Option Description
--indent Number of spaces to indent, or "tab" to use tabs
--tabwidth The width of a tab character. Defaults to "unspecified"
--smarttabs Align code independently of tab width. defaults to "enabled"
--indentcase Indent cases inside a switch: "true" or "false" (default)
--ifdef #if indenting: "indent" (default), "no-indent" or "outdent"
--xcodeindentation Match Xcode indenting: "enabled" or "disabled" (default)
--indentstrings Indent multiline strings: "false" (default) or "true"
Examples
  if x {
-     // foo
  } else {
-     // bar
-       }

  if x {
+   // foo
  } else {
+   // bar
+ }
  let array = [
    foo,
-     bar,
-       baz
-   ]

  let array = [
    foo,
+   bar,
+   baz
+ ]
  switch foo {
-   case bar: break
-   case baz: break
  }

  switch foo {
+ case bar: break
+ case baz: break
  }

initCoderUnavailable

Add @available(*, unavailable) attribute to required init(coder:) when it hasn't been implemented.

Option Description
--initcodernil Replace fatalError with nil in unavailable init?(coder:)
Examples
+ @available(*, unavailable)
  required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
  }

isEmpty

Prefer isEmpty over comparing count against zero.

Examples
- if foo.count == 0 {
+ if foo.isEmpty {

- if foo.count > 0 {
+ if !foo.isEmpty {

- if foo?.count == 0 {
+ if foo?.isEmpty == true {

NOTE: In rare cases, the isEmpty rule may insert an isEmpty call for a type that doesn't implement that property, breaking the program. For this reason, the rule is disabled by default, and must be manually enabled via the --enable isEmpty option.


leadingDelimiters

Move leading delimiters to the end of the previous line.

Examples
- guard let foo = maybeFoo // first
-     , let bar = maybeBar else { ... }

+ guard let foo = maybeFoo, // first
+      let bar = maybeBar else { ... }

linebreakAtEndOfFile

Add empty blank line at end of file.

linebreaks

Use specified linebreak character for all linebreaks (CR, LF or CRLF).

Option Description
--linebreaks Linebreak character to use: "cr", "crlf" or "lf" (default)

markTypes

Add a MARK comment before top-level types and extensions.

Option Description
--marktypes Mark types "always" (default), "never", "if-not-empty"
--typemark Template for type mark comments. Defaults to "MARK: - %t"
--markextensions Mark extensions "always" (default), "never", "if-not-empty"
--extensionmark Mark for standalone extensions. Defaults to "MARK: - %t + %c"
--groupedextension Mark for extension grouped with extended type. ("MARK: %c")
Examples
+ // MARK: - FooViewController
+
 final class FooViewController: UIViewController { }

+ // MARK: UICollectionViewDelegate
+
 extension FooViewController: UICollectionViewDelegate { }

+ // MARK: - String + FooProtocol
+
 extension String: FooProtocol { }

modifierOrder

Use consistent ordering for member modifiers.

Option Description
--modifierorder Comma-delimited list of modifiers in preferred order
Examples
- lazy public weak private(set) var foo: UIView?
+ public private(set) lazy weak var foo: UIView?
- final public override func foo()
+ override public final func foo()
- convenience private init()
+ private convenience init()

NOTE: If the --modifierorder option isn't set, the default order will be: override, private, fileprivate, internal, package, public, open, private(set), fileprivate(set), internal(set), package(set), public(set), open(set), final, dynamic, optional, required, convenience, indirect, isolated, nonisolated, nonisolated(unsafe), lazy, weak, unowned, static, class, borrowing, consuming, mutating, nonmutating, prefix, infix, postfix


noExplicitOwnership

Don't use explicit ownership modifiers (borrowing / consuming).

Examples
- borrowing func foo(_ bar: consuming Bar) { ... }
+ func foo(_ bar: Bar) { ... }

numberFormatting

Use consistent grouping for numeric literals. Groups will be separated by _ delimiters to improve readability. For each numeric type you can specify a group size (the number of digits in each group) and a threshold (the minimum number of digits in a number before grouping is applied).

Option Description
--decimalgrouping Decimal grouping,threshold (default: 3,6) or "none", "ignore"
--binarygrouping Binary grouping,threshold (default: 4,8) or "none", "ignore"
--octalgrouping Octal grouping,threshold (default: 4,8) or "none", "ignore"
--hexgrouping Hex grouping,threshold (default: 4,8) or "none", "ignore"
--fractiongrouping Group digits after '.': "enabled" or "disabled" (default)
--exponentgrouping Group exponent digits: "enabled" or "disabled" (default)
--hexliteralcase Casing for hex literals: "uppercase" (default) or "lowercase"
--exponentcase Case of 'e' in numbers: "lowercase" or "uppercase" (default)
Examples
- let color = 0xFF77A5
+ let color = 0xff77a5
- let big = 123456.123
+ let big = 123_456.123

opaqueGenericParameters

Use opaque generic parameters (some Protocol) instead of generic parameters with constraints (T where T: Protocol, etc) where equivalent. Also supports primary associated types for common standard library types, so definitions like T where T: Collection, T.Element == Foo are updated to some Collection<Foo>.

Option Description
--someany Use some Any types: "true" (default) or "false"
Examples
- func handle<T: Fooable>(_ value: T) {
+ func handle(_ value: some Fooable) {
      print(value)
  }

- func handle<T>(_ value: T) where T: Fooable, T: Barable {
+ func handle(_ value: some Fooable & Barable) {
      print(value)
  }

- func handle<T: Collection>(_ value: T) where T.Element == Foo {
+ func handle(_ value: some Collection<Foo>) {
      print(value)
  }

// With `--someany enabled` (the default)
- func handle<T>(_ value: T) {
+ func handle(_ value: some Any) {
      print(value)
  }

organizeDeclarations

Organize declarations within class, struct, enum, actor, and extension bodies.

Option Description
--categorymark Template for category mark comments. Defaults to "MARK: %c"
--markcategories Insert MARK comments between categories (true by default)
--beforemarks Declarations placed before first mark (e.g. typealias,struct)
--lifecycle Names of additional Lifecycle methods (e.g. viewDidLoad)
--organizetypes Declarations to organize (default: class,actor,struct,enum)
--structthreshold Minimum line count to organize struct body. Defaults to 0
--classthreshold Minimum line count to organize class body. Defaults to 0
--enumthreshold Minimum line count to organize enum body. Defaults to 0
--extensionlength Minimum line count to organize extension body. Defaults to 0
--organizationmode Organize declarations by "visibility" (default) or "type"
Examples

--organizationmode visibility (default)

  public class Foo {
-     public func c() -> String {}
-
-     public let a: Int = 1
-     private let g: Int = 2
-     let e: Int = 2
-     public let b: Int = 3
-
-     public func d() {}
-     func f() {}
-     init() {}
-     deinit() {}
 }

  public class Foo {
+
+     // MARK: Lifecycle
+
+     init() {}
+     deinit() {}
+
+     // MARK: Public
+
+     public let a: Int = 1
+     public let b: Int = 3
+
+     public func c() -> String {}
+     public func d() {}
+
+     // MARK: Internal
+
+     let e: Int = 2
+
+     func f() {}
+
+     // MARK: Private
+
+     private let g: Int = 2
+
 }

--organizationmode type

  public class Foo {
-     public func c() -> String {}
-
-     public let a: Int = 1
-     private let g: Int = 2
-     let e: Int = 2
-     public let b: Int = 3
-
-     public func d() {}
-     func f() {}
-     init() {}
-     deinit() {}
 }

  public class Foo {
+
+     // MARK: Properties
+
+     public let a: Int = 1
+     public let b: Int = 3
+
+     let e: Int = 2
+
+     private let g: Int = 2
+
+     // MARK: Lifecycle
+
+     init() {}
+     deinit() {}
+
+     // MARK: Functions
+
+     public func c() -> String {}
+     public func d() {}
+
 }

preferForLoop

Convert functional forEach calls to for loops.

Option Description
--anonymousforeach Convert anonymous forEach: "convert" (default) or "ignore"
--onelineforeach Convert one-line forEach: "convert" or "ignore" (default)
Examples
  let strings = ["foo", "bar", "baaz"]
- strings.forEach { placeholder in
+ for placeholder in strings {
      print(placeholder)
  }

  // Supports anonymous closures
- strings.forEach {
+ for string in strings {
-     print($0)
+     print(string)
  }

- foo.item().bar[2].baazValues(option: true).forEach {
+ for baazValue in foo.item().bar[2].baazValues(option: true) {
-     print($0)
+     print(baazValue)
  }

  // Doesn't affect long multiline functional chains
  placeholderStrings
      .filter { $0.style == .fooBar }
      .map { $0.uppercased() }
      .forEach { print($0) }

preferKeyPath

Convert trivial map { $0.foo } closures to keyPath-based syntax.

Examples
- let barArray = fooArray.map { $0.bar }
+ let barArray = fooArray.map(\.bar)

- let barArray = fooArray.compactMap { $0.optionalBar }
+ let barArray = fooArray.compactMap(\.optionalBar)

redundantBackticks

Remove redundant backticks around identifiers.

Examples
- let `infix` = bar
+ let infix = bar
- func foo(with `default`: Int) {}
+ func foo(with default: Int) {}

redundantBreak

Remove redundant break in switch case.

Examples
  switch foo {
    case bar:
        print("bar")
-       break
    default:
        print("default")
-       break
  }

redundantClosure

Removes redundant closures bodies, containing a single statement, which are called immediately.

Examples
- let foo = { Foo() }()
+ let foo = Foo()
- lazy var bar = {
-     Bar(baaz: baaz,
-         quux: quux)
- }()
+ lazy var bar = Bar(baaz: baaz,
+                    quux: quux)

redundantExtensionACL

Remove redundant access control modifiers.

Examples
  public extension URL {
-   public func queryParameter(_ name: String) -> String { ... }
  }

  public extension URL {
+   func queryParameter(_ name: String) -> String { ... }
  }

redundantFileprivate

Prefer private over fileprivate where equivalent.

Examples
-  fileprivate let someConstant = "someConstant"
+  private let someConstant = "someConstant"

In Swift 4 and above, fileprivate can also be replaced with private for members that are only accessed from extensions in the same file:

  class Foo {
-   fileprivate var foo = "foo"
+   private var foo = "foo"
  }

  extension Foo {
    func bar() {
      print(self.foo)
    }
  }

redundantGet

Remove unneeded get clause inside computed properties.

Examples
  var foo: Int {
-   get {
-     return 5
-   }
  }

  var foo: Int {
+   return 5
  }

redundantInit

Remove explicit init if not required.

Examples
- String.init("text")
+ String("text")

redundantInternal

Remove redundant internal access control.

Examples
- internal class Foo {
+ class Foo {
-     internal let bar: String
+     let bar: String

-     internal func baaz() {}
+     func baaz() {}

-     internal init() {
+     init() {
          bar = "bar"
      }
  }

redundantLet

Remove redundant let/var from ignored variables.

Examples
- let _ = foo()
+ _ = foo()

redundantLetError

Remove redundant let error from catch clause.

Examples
- do { ... } catch let error { log(error) }
+ do { ... } catch { log(error) }

redundantNilInit

Remove/insert redundant nil default value (Optional vars are nil by default).

Option Description
--nilinit "remove" (default) redundant nil or "insert" missing nil
Examples

--nilinit remove

- var foo: Int? = nil
+ var foo: Int?
// doesn't apply to `let` properties
let foo: Int? = nil
// doesn't affect non-nil initialization
var foo: Int? = 0

--nilinit insert

- var foo: Int?
+ var foo: Int? = nil

redundantObjc

Remove redundant @objc annotations.

Examples
- @objc @IBOutlet var label: UILabel!
+ @IBOutlet var label: UILabel!
- @IBAction @objc func goBack() {}
+ @IBAction func goBack() {}
- @objc @NSManaged private var foo: String?
+ @NSManaged private var foo: String?

redundantOptionalBinding

Remove redundant identifiers in optional binding conditions.

Examples
- if let foo = foo {
+ if let foo {
      print(foo)
  }

- guard let self = self else {
+ guard let self else {
      return
  }

redundantParens

Remove redundant parentheses.

Examples
- if (foo == true) {}
+ if foo == true {}
- while (i < bar.count) {}
+ while i < bar.count {}
- queue.async() { ... }
+ queue.async { ... }
- let foo: Int = ({ ... })()
+ let foo: Int = { ... }()

redundantPattern

Remove redundant pattern matching parameter syntax.

Examples
- if case .foo(_, _) = bar {}
+ if case .foo = bar {}
- let (_, _) = bar
+ let _ = bar

redundantProperty

Simplifies redundant property definitions that are immediately returned.

Examples
  func foo() -> Foo {
-   let foo = Foo()
-   return foo
+   return Foo()
  }

redundantRawValues

Remove redundant raw string values for enum cases.

Examples
  enum Foo: String {
-   case bar = "bar"
    case baz = "quux"
  }

  enum Foo: String {
+   case bar
    case baz = "quux"
  }

redundantReturn

Remove unneeded return keyword.

Examples
- array.filter { return $0.foo == bar }
+ array.filter { $0.foo == bar }

  // Swift 5.1+ (SE-0255)
  var foo: String {
-     return "foo"
+     "foo"
  }

  // Swift 5.9+ (SE-0380) and with conditionalAssignment rule enabled
  func foo(_ condition: Bool) -> String {
      if condition {
-         return "foo"
+         "foo"
      } else {
-         return "bar"
+         "bar"
      }
  }

redundantSelf

Insert/remove explicit self where applicable.

Option Description
--self Explicit self: "insert", "remove" (default) or "init-only"
--selfrequired Comma-delimited list of functions with @autoclosure arguments
Examples
  func foobar(foo: Int, bar: Int) {
    self.foo = foo
    self.bar = bar
-   self.baz = 42
  }

  func foobar(foo: Int, bar: Int) {
    self.foo = foo
    self.bar = bar
+   baz = 42
  }

In the rare case of functions with @autoclosure arguments, self may be required at the call site, but SwiftFormat is unable to detect this automatically. You can use the --selfrequired command-line option to specify a list of such methods, and the redundantSelf rule will then ignore them.

An example of such a method is the expect() function in the Nimble unit testing framework (https://github.com/Quick/Nimble), which is common enough that SwiftFormat excludes it by default.

There is also an option to always use explicit self but only inside init, by using --self init-only:

  init(foo: Int, bar: Int) {
    self.foo = foo
    self.bar = bar
-   baz = 42
  }

  init(foo: Int, bar: Int) {
    self.foo = foo
    self.bar = bar
+   self.baz = 42
  }

redundantStaticSelf

Remove explicit Self where applicable.

redundantType

Remove redundant type from variable declarations.

Option Description
--redundanttype "inferred", "explicit", or "infer-locals-only" (default)
Examples
// inferred
- let view: UIView = UIView()
+ let view = UIView()

// explicit
- let view: UIView = UIView()
+ let view: UIView = .init()

// infer-locals-only
  class Foo {
-     let view: UIView = UIView()
+     let view: UIView = .init()

      func method() {
-         let view: UIView = UIView()
+         let view = UIView()
      }
  }

// Swift 5.9+, inferred (SE-0380)
- let foo: Foo = if condition {
+ let foo = if condition {
      Foo("foo")
  } else {
      Foo("bar")
  }

// Swift 5.9+, explicit (SE-0380)
  let foo: Foo = if condition {
-     Foo("foo")
+     .init("foo")
  } else {
-     Foo("bar")
+     .init("foo")
  }

redundantTypedThrows

Converts throws(any Error) to throws, and converts throws(Never) to non-throwing.

Examples
- func foo() throws(Never) -> Int {
+ func foo() -> Int {
      return 0
  }

- func foo() throws(any Error) -> Int {
+ func foo() throws -> Int {
      throw MyError.foo
  }

redundantVoidReturnType

Remove explicit Void return type.

Option Description
--closurevoid Closure void returns: "remove" (default) or "preserve"
Examples
- func foo() -> Void {
    // returns nothing
  }

+ func foo() {
    // returns nothing
  }

semicolons

Remove semicolons.

Option Description
--semicolons Allow semicolons: "never" or "inline" (default)
Examples
- let foo = 5;
+ let foo = 5
- let foo = 5; let bar = 6
+ let foo = 5
+ let bar = 6
// semicolon is not removed if it would affect the behavior of the code
return;
goto(fail)

sortDeclarations

Sorts the body of declarations with // swiftformat:sort and declarations between // swiftformat:sort:begin and // swiftformat:sort:end comments.

Examples
  // swiftformat:sort
  enum FeatureFlags {
-     case upsellB
-     case fooFeature
-     case barFeature
-     case upsellA(
-         fooConfiguration: Foo,
-         barConfiguration: Bar)
+     case barFeature
+     case fooFeature
+     case upsellA(
+         fooConfiguration: Foo,
+         barConfiguration: Bar)
+     case upsellB
  }

  enum FeatureFlags {
      // swiftformat:sort:begin
-     case upsellB
-     case fooFeature
-     case barFeature
-     case upsellA(
-         fooConfiguration: Foo,
-         barConfiguration: Bar)
+     case barFeature
+     case fooFeature
+     case upsellA(
+         fooConfiguration: Foo,
+         barConfiguration: Bar)
+     case upsellB
      // swiftformat:sort:end

      var anUnsortedProperty: Foo {
          Foo()
      }
  }

sortImports

Sort import statements alphabetically.

Option Description
--importgrouping "testable-first/last", "alpha" (default) or "length"
Examples
- import Foo
- import Bar
+ import Bar
+ import Foo
- import B
- import A
- #if os(iOS)
-   import Foo-iOS
-   import Bar-iOS
- #endif
+ import A
+ import B
+ #if os(iOS)
+   import Bar-iOS
+   import Foo-iOS
+ #endif

sortSwitchCases

Sort switch cases alphabetically.

sortTypealiases

Sort protocol composition typealiases alphabetically.

Examples
- typealias Placeholders = Foo & Bar & Baaz & Quux
+ typealias Placeholders = Baaz & Bar & Foo & Quux

  typealias Dependencies
-     = FooProviding
+     = BaazProviding
      & BarProviding
-     & BaazProviding
+     & FooProviding
      & QuuxProviding

sortedImports

Sort import statements alphabetically.

Note: sortedImports rule is deprecated. Use sortImports instead.

sortedSwitchCases

Sort switch cases alphabetically.

Note: sortedSwitchCases rule is deprecated. Use sortSwitchCases instead.

spaceAroundBraces

Add or remove space around curly braces.

Examples
- foo.filter{ return true }.map{ $0 }
+ foo.filter { return true }.map { $0 }
- foo( {} )
+ foo({})

spaceAroundBrackets

Add or remove space around square brackets.

Examples
- foo as[String]
+ foo as [String]
- foo = bar [5]
+ foo = bar[5]

spaceAroundComments

Add space before and/or after comments.

Examples
- let a = 5// assignment
+ let a = 5 // assignment
- func foo() {/* ... */}
+ func foo() { /* ... */ }

spaceAroundGenerics

Remove space around angle brackets.

Examples
- Foo <Bar> ()
+ Foo<Bar>()

spaceAroundOperators

Add or remove space around operators or delimiters.

Option Description
--operatorfunc Spacing for operator funcs: "spaced" (default) or "no-space"
--nospaceoperators Comma-delimited list of operators without surrounding space
--ranges Spacing for ranges: "spaced" (default) or "no-space"
--typedelimiter "space-after" (default), "spaced" or "no-space"
Examples
- foo . bar()
+ foo.bar()
- a+b+c
+ a + b + c
- func ==(lhs: Int, rhs: Int) -> Bool
+ func == (lhs: Int, rhs: Int) -> Bool

spaceAroundParens

Add or remove space around parentheses.

Examples
- init (foo)
+ init(foo)
- switch(x){
+ switch (x) {

spaceInsideBraces

Add space inside curly braces.

Examples
- foo.filter {return true}
+ foo.filter { return true }

spaceInsideBrackets

Remove space inside square brackets.

Examples
- [ 1, 2, 3 ]
+ [1, 2, 3]

spaceInsideComments

Add leading and/or trailing space inside comments.

Examples
- let a = 5 //assignment
+ let a = 5 // assignment
- func foo() { /*...*/ }
+ func foo() { /* ... */ }

spaceInsideGenerics

Remove space inside angle brackets.

Examples
- Foo< Bar, Baz >
+ Foo<Bar, Baz>

spaceInsideParens

Remove space inside parentheses.

Examples
- ( a, b)
+ (a, b)

specifiers

Use consistent ordering for member modifiers.

Note: specifiers rule is deprecated. Use modifierOrder instead.

strongOutlets

Remove weak modifier from @IBOutlet properties.

Examples

As per Apple's recommendation (https://developer.apple.com/videos/play/wwdc2015/407/ @ 32:30).

- @IBOutlet weak var label: UILabel!
+ @IBOutlet var label: UILabel!

strongifiedSelf

Remove backticks around self in Optional unwrap expressions.

Examples
- guard let `self` = self else { return }
+ guard let self = self else { return }

NOTE: assignment to un-escaped self is only supported in Swift 4.2 and above, so the strongifiedSelf rule is disabled unless the Swift version is set to 4.2 or above.


todos

Use correct formatting for TODO:, MARK: or FIXME: comments.

Examples
- /* TODO fix this properly */
+ /* TODO: fix this properly */
- // MARK - UIScrollViewDelegate
+ // MARK: - UIScrollViewDelegate

trailingClosures

Use trailing closure syntax where applicable.

Option Description
--trailingclosures Comma-delimited list of functions that use trailing closures
--nevertrailing List of functions that should never use trailing closures
Examples
- DispatchQueue.main.async(execute: { ... })
+ DispatchQueue.main.async {
- let foo = bar.map({ ... }).joined()
+ let foo = bar.map { ... }.joined()

trailingCommas

Add or remove trailing comma from the last item in a collection literal.

Option Description
--commas Commas in collection literals: "always" (default) or "inline"
Examples
  let array = [
    foo,
    bar,
-   baz
  ]

  let array = [
    foo,
    bar,
+   baz,
  ]

trailingSpace

Remove trailing space at end of a line.

Option Description
--trimwhitespace Trim trailing space: "always" (default) or "nonblank-lines"

typeSugar

Prefer shorthand syntax for Arrays, Dictionaries and Optionals.

Option Description
--shortoptionals Use ? for optionals "always" or "except-properties" (default)
Examples
- var foo: Array<String>
+ var foo: [String]
- var foo: Dictionary<String, Int>
+ var foo: [String: Int]
- var foo: Optional<(Int) -> Void>
+ var foo: ((Int) -> Void)?

unusedArguments

Mark unused function arguments with _.

Option Description
--stripunusedargs "closure-only", "unnamed-only" or "always" (default)
Examples
- func foo(bar: Int, baz: String) {
    print("Hello \(baz)")
  }

+ func foo(bar _: Int, baz: String) {
    print("Hello \(baz)")
  }
- func foo(_ bar: Int) {
    ...
  }

+ func foo(_: Int) {
    ...
  }
- request { response, data in
    self.data += data
  }

+ request { _, data in
    self.data += data
  }

void

Use Void for type declarations and () for values.

Option Description
--voidtype How void types are represented: "void" (default) or "tuple"
Examples
- let foo: () -> ()
+ let foo: () -> Void
- let bar: Void -> Void
+ let bar: () -> Void
- let baz: (Void) -> Void
+ let baz: () -> Void
- func quux() -> (Void)
+ func quux() -> Void
- callback = { _ in Void() }
+ callback = { _ in () }

wrap

Wrap lines that exceed the specified maximum width.

Option Description
--maxwidth Maximum length of a line before wrapping. defaults to "none"
--nowrapoperators Comma-delimited list of operators that shouldn't be wrapped
--assetliterals Color/image literal width. "actual-width" or "visual-width"
--wrapternary Wrap ternary operators: "default", "before-operators"

wrapArguments

Align wrapped function arguments or collection elements.

Option Description
--wraparguments Wrap all arguments: "before-first", "after-first", "preserve"
--wrapparameters Wrap func params: "before-first", "after-first", "preserve"
--wrapcollections Wrap array/dict: "before-first", "after-first", "preserve"
--closingparen Closing paren position: "balanced" (default) or "same-line"
--callsiteparen Closing paren at call sites: "balanced" or "same-line"
--wrapreturntype Wrap return type: "if-multiline", "preserve" (default)
--wrapconditions Wrap conditions: "before-first", "after-first", "preserve"
--wraptypealiases Wrap typealiases: "before-first", "after-first", "preserve"
--wrapeffects Wrap effects: "if-multiline", "never", "preserve"
Examples

NOTE: For backwards compatibility with previous versions, if no value is provided for --wrapparameters, the value for --wraparguments will be used.

--wraparguments before-first

- foo(bar: Int,
-     baz: String)

+ foo(
+   bar: Int,
+   baz: String
+ )
- class Foo<Bar,
-           Baz>

+ class Foo<
+   Bar,
+   Baz
+ >

--wrapparameters after-first

- func foo(
-   bar: Int,
-   baz: String
- ) {
    ...
  }

+ func foo(bar: Int,
+          baz: String)
+ {
    ...
  }

--wrapcollections before-first:

- let foo = [bar,
             baz,
-            quuz]

+ let foo = [
+   bar,
    baz,
+   quuz
+ ]

wrapAttributes

Wrap @attributes onto a separate line, or keep them on the same line.

Option Description
--funcattributes Function @attributes: "preserve", "prev-line", or "same-line"
--typeattributes Type @attributes: "preserve", "prev-line", or "same-line"
--storedvarattrs Stored var @attribs: "preserve", "prev-line", or "same-line"
--computedvarattrs Computed var @attribs: "preserve", "prev-line", "same-line"
--complexattrs Complex @attributes: "preserve", "prev-line", or "same-line"
--noncomplexattrs List of @attributes to exclude from complexattrs rule
Examples

--funcattributes prev-line

- @objc func foo() {}

+ @objc
+ func foo() { }

--funcattributes same-line

- @objc
- func foo() { }

+ @objc func foo() {}

--typeattributes prev-line

- @objc class Foo {}

+ @objc
+ class Foo { }

--typeattributes same-line

- @objc
- enum Foo { }

+ @objc enum Foo {}

wrapConditionalBodies

Wrap the bodies of inline conditional statements onto a new line.

Examples
- guard let foo = bar else { return baz }
+ guard let foo = bar else {
+     return baz
+ }
- if foo { return bar }
+ if foo {
+    return bar
+ }

wrapEnumCases

Rewrite comma-delimited enum cases to one case per line.

Option Description
--wrapenumcases Wrap enum cases: "always" (default) or "with-values"
Examples
  enum Foo {
-   case bar, baz
  }

  enum Foo {
+   case bar
+   case baz
  }

wrapLoopBodies

Wrap the bodies of inline loop statements onto a new line.

Examples
- for foo in array { print(foo) }
+ for foo in array {
+     print(foo)
+ }
- while let foo = bar.next() { print(foo) }
+ while let foo = bar.next() {
+     print(foo)
+ }

wrapMultilineConditionalAssignment

Wrap multiline conditional assignment expressions after the assignment operator.

Examples
- let planetLocation = if let star = planet.star {
-     "The \(star.name) system"
- } else {
-     "Rogue planet"
- }
+ let planetLocation =
+     if let star = planet.star {
+         "The \(star.name) system"
+     } else {
+         "Rogue planet"
+     }

wrapMultilineStatementBraces

Wrap the opening brace of multiline statements.

Examples
  if foo,
-   bar {
    // ...
  }

  if foo,
+   bar
+ {
    // ...
  }
  guard foo,
-   bar else {
    // ...
  }

  guard foo,
+   bar else
+ {
    // ...
  }
  func foo(
    bar: Int,
-   baz: Int) {
    // ...
  }

  func foo(
    bar: Int,
+   baz: Int)
+ {
    // ...
  }
  class Foo: NSObject,
-   BarProtocol {
    // ...
  }

  class Foo: NSObject,
+   BarProtocol
+ {
    // ...
  }

wrapSingleLineComments

Wrap single line // comments that exceed the specified --maxwidth.

wrapSwitchCases

Wrap comma-delimited switch cases onto multiple lines.

Examples
  switch foo {
-   case .bar, .baz:
      break
  }

  switch foo {
+   case .foo,
+        .bar:
      break
  }

yodaConditions

Prefer constant values to be on the right-hand-side of expressions.

Option Description
--yodaswap Swap yoda values: "always" (default) or "literals-only"