diff --git a/CHANGELOG.md b/CHANGELOG.md index e09c32ab7..fcc61ee0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,9 +23,7 @@ [SimplyDanny](https://github.com/SimplyDanny) [#3726](https://github.com/realm/SwiftLint/issues/3726) -* Trigger `prefer_self_in_static_references` rule on more type references like: - * Types (e.g. `let a: MyType? { nil }` -> `let a: Self? { nil }`) - +* Trigger `prefer_self_in_static_references` rule on more type references. [SimplyDanny](https://github.com/SimplyDanny) #### Bug Fixes diff --git a/Source/SwiftLintFramework/Rules/Style/PreferSelfInStaticReferencesRule.swift b/Source/SwiftLintFramework/Rules/Style/PreferSelfInStaticReferencesRule.swift index 32feba124..36f6c8175 100644 --- a/Source/SwiftLintFramework/Rules/Style/PreferSelfInStaticReferencesRule.swift +++ b/Source/SwiftLintFramework/Rules/Style/PreferSelfInStaticReferencesRule.swift @@ -10,221 +10,9 @@ struct PreferSelfInStaticReferencesRule: SwiftSyntaxRule, CorrectableRule, Confi name: "Prefer Self in Static References", description: "Use `Self` to refer to the surrounding type name", kind: .style, - nonTriggeringExamples: [ - Example(""" - class C { - static let primes = [2, 3, 5, 7] - func isPrime(i: Int) -> Bool { Self.primes.contains(i) } - """), - Example(""" - struct T { - static let i = 0 - } - struct S { - static let i = 0 - } - extension T { - static let j = S.i + T.i - static let k = { T.j }() - } - """), - Example(""" - class `Self` { - static let i = 0 - func f() -> Int { Self.i } - } - """), - Example(""" - class C { - static private(set) var i = 0, j = C.i - static let k = { C.i }() - let h = C.i - @GreaterThan(C.j) var k: Int - func f() { - _ = [Int: C]() - _ = [C]() - } - } - """, excludeFromDocumentation: true), - Example(""" - struct S { - struct T { - struct R { - static let i = 3 - } - } - struct R { - static let j = S.T.R.i - } - static let j = Self.T.R.i + Self.R.j - let h = Self.T.R.i + Self.R.j - } - """, excludeFromDocumentation: true), - Example(""" - class C { - static let s = 2 - func f(i: Int = C.s) -> Int { - func g(@GreaterEqualThan(C.s) j: Int = C.s) -> Int { j } - return i + Self.s - } - func g() -> Any { C.self } - } - """, excludeFromDocumentation: true), - Example(""" - struct Record { - static func get() -> Record { Record() } - } - """, excludeFromDocumentation: true), - Example(""" - @objc class C: NSObject { - @objc var s = "" - @objc func f() { _ = #keyPath(C.s) } - } - """, excludeFromDocumentation: true), - Example(""" - class C { - let i = 1 - let c: C = C() - func f(c: C) -> KeyPath { \\Self.i } - } - """, excludeFromDocumentation: true) - ], - triggeringExamples: [ - Example(""" - final class CheckCellView: NSTableCellView { - @IBOutlet var checkButton: NSButton! - - override func awakeFromNib() { - checkButton.action = #selector(↓CheckCellView.check(_:)) - } - - @objc func check(_ button: AnyObject?) {} - } - """), - Example(""" - class C { - struct S { - static let i = 2 - let h = ↓S.i - } - static let i = 1 - let h = C.i - var j: Int { ↓C.i } - func f() -> Int { ↓C.i + h } - } - """), - Example(""" - struct S { - let j: Int - static let i = 1 - static func f() -> Int { ↓S.i } - func g() -> Any { ↓S.self } - func h() -> ↓S { ↓S(j: 2) } - func i() -> KeyPath<↓S, Int> { \\↓S.j } - func j(@Wrap(-↓S.i, ↓S.i) n: Int = ↓S.i) {} - } - """), - Example(""" - struct S { - struct T { - static let i = 3 - } - struct R { - static let j = S.T.i - } - static let h = ↓S.T.i + ↓S.R.j - } - """), - Example(""" - enum E { - case A - static func f() -> ↓E { ↓E.A } - static func g() -> ↓E { ↓E.f() } - } - """), - Example(""" - extension E { - class C { - static var i = 2 - var j: Int { ↓C.i } - var k: Int { - get { ↓C.i } - set { ↓C.i = newValue } - } - } - } - """, excludeFromDocumentation: true), - Example(""" - class C { - let d: C? = nil - var c: C { C() } - init() {} - func f(e: C) -> C { - let f: C = C() - return f - } - } - final class D { - let c: D? = nil - var d: D { D() } - init() {} - func f(e: D) -> D { - let f: D = D() - return f - } - } - struct S { - // let s: S? = nil // Struct cannot contain itself - var t: ↓S { ↓S() } - init() {} - func f(e: ↓S) -> ↓S { - let f: ↓S = ↓S() - return f - } - } - """, excludeFromDocumentation: true) - ], - corrections: [ - Example(""" - final class CheckCellView: NSTableCellView { - @IBOutlet var checkButton: NSButton! - - override func awakeFromNib() { - checkButton.action = #selector(↓CheckCellView.check(_:)) - } - - @objc func check(_ button: AnyObject?) {} - } - """): - Example(""" - final class CheckCellView: NSTableCellView { - @IBOutlet var checkButton: NSButton! - - override func awakeFromNib() { - checkButton.action = #selector(Self.check(_:)) - } - - @objc func check(_ button: AnyObject?) {} - } - """), - Example(""" - struct S { - static let i = 1 - static let j = ↓S.i - let k = ↓S . j - static func f(_ l: Int = ↓S.i) -> Int { l*↓S.j } - func g() { ↓S.i + ↓S.f() + k } - } - """): Example(""" - struct S { - static let i = 1 - static let j = Self.i - let k = Self . j - static func f(_ l: Int = Self.i) -> Int { l*Self.j } - func g() { Self.i + Self.f() + k } - } - """) - ] + nonTriggeringExamples: PreferSelfInStaticReferencesRuleExamples.nonTriggeringExamples, + triggeringExamples: PreferSelfInStaticReferencesRuleExamples.triggeringExamples, + corrections: PreferSelfInStaticReferencesRuleExamples.corrections ) func makeVisitor(file: SwiftLintFile) -> ViolationsSyntaxVisitor { diff --git a/Source/SwiftLintFramework/Rules/Style/PreferSelfInStaticReferencesRuleExamples.swift b/Source/SwiftLintFramework/Rules/Style/PreferSelfInStaticReferencesRuleExamples.swift new file mode 100644 index 000000000..fc9f3afa1 --- /dev/null +++ b/Source/SwiftLintFramework/Rules/Style/PreferSelfInStaticReferencesRuleExamples.swift @@ -0,0 +1,219 @@ +enum PreferSelfInStaticReferencesRuleExamples { + static let nonTriggeringExamples = [ + Example(""" + class C { + static let primes = [2, 3, 5, 7] + func isPrime(i: Int) -> Bool { Self.primes.contains(i) } + """), + Example(""" + struct T { + static let i = 0 + } + struct S { + static let i = 0 + } + extension T { + static let j = S.i + T.i + static let k = { T.j }() + } + """), + Example(""" + class `Self` { + static let i = 0 + func f() -> Int { Self.i } + } + """), + Example(""" + class C { + static private(set) var i = 0, j = C.i + static let k = { C.i }() + let h = C.i + @GreaterThan(C.j) var k: Int + func f() { + _ = [Int: C]() + _ = [C]() + } + } + """, excludeFromDocumentation: true), + Example(""" + struct S { + struct T { + struct R { + static let i = 3 + } + } + struct R { + static let j = S.T.R.i + } + static let j = Self.T.R.i + Self.R.j + let h = Self.T.R.i + Self.R.j + } + """, excludeFromDocumentation: true), + Example(""" + class C { + static let s = 2 + func f(i: Int = C.s) -> Int { + func g(@GreaterEqualThan(C.s) j: Int = C.s) -> Int { j } + return i + Self.s + } + func g() -> Any { C.self } + } + """, excludeFromDocumentation: true), + Example(""" + struct Record { + static func get() -> Record { Record() } + } + """, excludeFromDocumentation: true), + Example(""" + @objc class C: NSObject { + @objc var s = "" + @objc func f() { _ = #keyPath(C.s) } + } + """, excludeFromDocumentation: true), + Example(""" + class C { + let i = 1 + let c: C = C() + func f(c: C) -> KeyPath { \\Self.i } + } + """, excludeFromDocumentation: true) + ] + + static let triggeringExamples = [ + Example(""" + final class CheckCellView: NSTableCellView { + @IBOutlet var checkButton: NSButton! + + override func awakeFromNib() { + checkButton.action = #selector(↓CheckCellView.check(_:)) + } + + @objc func check(_ button: AnyObject?) {} + } + """), + Example(""" + class C { + struct S { + static let i = 2 + let h = ↓S.i + } + static let i = 1 + let h = C.i + var j: Int { ↓C.i } + func f() -> Int { ↓C.i + h } + } + """), + Example(""" + struct S { + let j: Int + static let i = 1 + static func f() -> Int { ↓S.i } + func g() -> Any { ↓S.self } + func h() -> ↓S { ↓S(j: 2) } + func i() -> KeyPath<↓S, Int> { \\↓S.j } + func j(@Wrap(-↓S.i, ↓S.i) n: Int = ↓S.i) {} + } + """), + Example(""" + struct S { + struct T { + static let i = 3 + } + struct R { + static let j = S.T.i + } + static let h = ↓S.T.i + ↓S.R.j + } + """), + Example(""" + enum E { + case A + static func f() -> ↓E { ↓E.A } + static func g() -> ↓E { ↓E.f() } + } + """), + Example(""" + extension E { + class C { + static var i = 2 + var j: Int { ↓C.i } + var k: Int { + get { ↓C.i } + set { ↓C.i = newValue } + } + } + } + """, excludeFromDocumentation: true), + Example(""" + class C { + let d: C? = nil + var c: C { C() } + init() {} + func f(e: C) -> C { + let f: C = C() + return f + } + } + final class D { + let c: D? = nil + var d: D { D() } + init() {} + func f(e: D) -> D { + let f: D = D() + return f + } + } + struct S { + // let s: S? = nil // Struct cannot contain itself + var t: ↓S { ↓S() } + init() {} + func f(e: ↓S) -> ↓S { + let f: ↓S = ↓S() + return f + } + } + """, excludeFromDocumentation: true) + ] + + static let corrections = [ + Example(""" + final class CheckCellView: NSTableCellView { + @IBOutlet var checkButton: NSButton! + + override func awakeFromNib() { + checkButton.action = #selector(↓CheckCellView.check(_:)) + } + + @objc func check(_ button: AnyObject?) {} + } + """): + Example(""" + final class CheckCellView: NSTableCellView { + @IBOutlet var checkButton: NSButton! + + override func awakeFromNib() { + checkButton.action = #selector(Self.check(_:)) + } + + @objc func check(_ button: AnyObject?) {} + } + """), + Example(""" + struct S { + static let i = 1 + static let j = ↓S.i + let k = ↓S . j + static func f(_ l: Int = ↓S.i) -> Int { l*↓S.j } + func g() { ↓S.i + ↓S.f() + k } + } + """): Example(""" + struct S { + static let i = 1 + static let j = Self.i + let k = Self . j + static func f(_ l: Int = Self.i) -> Int { l*Self.j } + func g() { Self.i + Self.f() + k } + } + """) + ] +}