Skip to content

Commit

Permalink
Add redundantStaticSelf rule.
Browse files Browse the repository at this point in the history
  • Loading branch information
Šimon Javora authored and nicklockwood committed May 29, 2023
1 parent 6c84a11 commit 3a39a33
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Rules.md
Expand Up @@ -89,6 +89,7 @@
* [isEmpty](#isEmpty)
* [markTypes](#markTypes)
* [organizeDeclarations](#organizeDeclarations)
* [redundantStaticSelf](#redundantStaticSelf)
* [sortedSwitchCases](#sortedSwitchCases)
* [wrapConditionalBodies](#wrapConditionalBodies)
* [wrapEnumCases](#wrapEnumCases)
Expand Down Expand Up @@ -1628,6 +1629,10 @@ by using `--self init-only`:
</details>
<br/>

## redundantStaticSelf

Remove explicit `Self` where applicable.

## redundantType

Remove redundant type from variable declarations.
Expand Down
29 changes: 29 additions & 0 deletions Sources/Rules.swift
Expand Up @@ -3233,6 +3233,35 @@ public struct _FormatRules {
}
}

/// Remove redundant Self keyword
public let redundantStaticSelf = FormatRule(
help: "Remove explicit `Self` where applicable.",
disabledByDefault: true
) { formatter in

var endIndex: Int?

formatter.forEachToken { index, token in
if token == .keyword("static") {
if let startOfBodyIndex = formatter.index(of: .startOfScope("{"), after: index) {
endIndex = formatter.endOfScope(at: startOfBodyIndex)
}
} else if endIndex != nil {
if index == endIndex {
endIndex = nil
} else if token == .identifier("Self"),
let nextTokenIndex = formatter.index(of: .nonSpaceOrCommentOrLinebreak, after: index),
formatter.token(at: nextTokenIndex) == .operator(".", .infix),
formatter.token(at: nextTokenIndex + 1) != .identifier("init")
{
let range = index ... nextTokenIndex
formatter.removeTokens(in: range)
endIndex? -= range.count
}
}
}
}

/// Remove redundant self keyword
// TODO: restructure this to use forEachToken to avoid exposing processCommentBody mechanism
public let redundantSelf = FormatRule(
Expand Down
113 changes: 113 additions & 0 deletions Tests/RulesTests+Redundancy.swift
Expand Up @@ -6051,6 +6051,119 @@ class RedundancyTests: RulesTests {
options: FormatOptions(swiftVersion: "5.8"))
}

// MARK: - redundantStaticSelf

func testRedundantStaticSelfInStaticVar() {
let input = "enum E { static var x: Int { Self.y } }"
let output = "enum E { static var x: Int { y } }"
testFormatting(for: input, output, rule: FormatRules.redundantStaticSelf)
}

func testRedundantStaticSelfInStaticMethod() {
let input = "enum E { static func foo() { Self.bar() } }"
let output = "enum E { static func foo() { bar() } }"
testFormatting(for: input, output, rule: FormatRules.redundantStaticSelf)
}

func testRedundantStaticSelfOnNextLine() {
let input = """
enum E {
static func foo() {
Self
.bar()
}
}
"""
let output = """
enum E {
static func foo() {
bar()
}
}
"""
testFormatting(for: input, output, rule: FormatRules.redundantStaticSelf)
}

func testRedundantStaticSelfWithReturn() {
let input = "enum E { static func foo() { return Self.bar() } }"
let output = "enum E { static func foo() { return bar() } }"
testFormatting(for: input, output, rule: FormatRules.redundantStaticSelf)
}

func testRedundantStaticSelfInConditional() {
let input = """
enum E {
static func foo() {
if Bool.random() {
Self.bar()
}
}
}
"""
let output = """
enum E {
static func foo() {
if Bool.random() {
bar()
}
}
}
"""
testFormatting(for: input, output, rule: FormatRules.redundantStaticSelf)
}

func testRedundantStaticSelfInNestedFunction() {
let input = """
enum E {
static func foo() {
func bar() {
Self.foo()
}
}
}
"""
let output = """
enum E {
static func foo() {
func bar() {
foo()
}
}
}
"""
testFormatting(for: input, output, rule: FormatRules.redundantStaticSelf)
}

func testRedundantStaticSelfInNestedType() {
let input = """
enum Outer {
enum Inner {
static func foo() {}
static func bar() { Self.foo() }
}
}
"""
let output = """
enum Outer {
enum Inner {
static func foo() {}
static func bar() { foo() }
}
}
"""
testFormatting(for: input, output, rule: FormatRules.redundantStaticSelf)
}

func testStaticSelfNotRemovedWhenUsedAsImplicitInitializer() {
let input = "enum E { static func foo() { Self().bar() } }"
testFormatting(for: input, rule: FormatRules.redundantStaticSelf)
}

func testStaticSelfNotRemovedWhenUsedAsExplicitInitializer() {
let input = "enum E { static func foo() { Self.init().bar() } }"
testFormatting(for: input, rule: FormatRules.redundantStaticSelf, exclude: ["redundantInit"])
}

// MARK: - semicolons

func testSemicolonRemovedAtEndOfLine() {
Expand Down

0 comments on commit 3a39a33

Please sign in to comment.