Skip to content

Commit

Permalink
Make nsobject_prefer_isequal rule work for nested classes (realm#4329)
Browse files Browse the repository at this point in the history
  • Loading branch information
SimplyDanny authored Oct 7, 2022
1 parent fe6a930 commit 957208c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@
* Add column for SourceKit usage to `rules` command.
[JP Simard](https://github.com/jpsim)

* Make `nsobject_prefer_isequal` rule work for nested `@objc` classes. Also consider
the `@objcMembers` annotation.
[SimplyDanny](https://github.com/SimplyDanny)

## 0.49.1: Buanderie Principale

_Note: The default branch for the SwiftLint git repository was renamed from
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,24 +23,18 @@ private extension NSObjectPreferIsEqualRule {
final class Visitor: SyntaxVisitor, ViolationsSyntaxVisitor {
private(set) var violationPositions: [AbsolutePosition] = []

override func visit(_ node: ClassDeclSyntax) -> SyntaxVisitorContinueKind {
node.isObjC ? .visitChildren : .skipChildren
}

// Extensions do not allow nested classes.
override func visit(_ node: ExtensionDeclSyntax) -> SyntaxVisitorContinueKind {
.skipChildren
}

override func visit(_ node: StructDeclSyntax) -> SyntaxVisitorContinueKind {
.skipChildren
}

override func visit(_ node: EnumDeclSyntax) -> SyntaxVisitorContinueKind {
// Protocols do not allow nested classes.
override func visit(_ node: ProtocolDeclSyntax) -> SyntaxVisitorContinueKind {
.skipChildren
}

override func visitPost(_ node: FunctionDeclSyntax) {
if node.isSelfEqualFunction {
if node.isSelfEqualFunction, Syntax(node).isInObjcClass {
violationPositions.append(node.positionAfterSkippingLeadingTrivia)
}
}
Expand Down Expand Up @@ -89,6 +83,14 @@ private extension FunctionDeclSyntax {
}
}

private extension Syntax {
var isInObjcClass: Bool {
if let parentClass = parent?.as(ClassDeclSyntax.self) {
return parentClass.isObjC
}
return parent?.isInObjcClass ?? false
}
}
private extension ModifierListSyntax? {
var isStatic: Bool {
guard let modifiers = self else {
Expand All @@ -101,6 +103,6 @@ private extension ModifierListSyntax? {

private extension AttributeListSyntax {
var isObjc: Bool {
contains { $0.as(AttributeSyntax.self)?.attributeName.text == "objc" }
contains { ["objc", "objcMembers"].contains($0.as(AttributeSyntax.self)?.attributeName.text) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,17 @@ internal struct NSObjectPreferIsEqualRuleExamples {
return true
}
}
""")
"""),
// Nested class is not itself inheriting from NSObject
Example("""
class C: NSObject {
class NestedClass {
static func ==(lhs: NestedClass, rhs: NestedClass) -> Bool {
return false
}
}
}
""", excludeFromDocumentation: true)
]

static let triggeringExamples: [Example] = [
Expand Down Expand Up @@ -98,6 +108,32 @@ internal struct NSObjectPreferIsEqualRuleExamples {
return false
}
}
""")
"""),
// Nested @objc class implementing ==
Example("""
class C {
@objc class NestedClass {
↓static func ==(lhs: NestedClass, rhs: NestedClass) -> Bool {
return false
}
}
}
struct S {
@objcMembers class NestedClass {
↓static func ==(lhs: NestedClass, rhs: NestedClass) -> Bool {
return false
}
}
}
enum E {
struct S {
@objc class NestedClass {
↓static func ==(lhs: NestedClass, rhs: NestedClass) -> Bool {
return false
}
}
}
}
""", excludeFromDocumentation: true)
]
}

0 comments on commit 957208c

Please sign in to comment.