Skip to content

Commit 49456c2

Browse files
committed
- rule added for avoiding redundant extensions resolve realm#5359
1 parent fefc4ce commit 49456c2

File tree

5 files changed

+74
-0
lines changed

5 files changed

+74
-0
lines changed

.swiftlint.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ disabled_rules:
4242
- prefer_nimble
4343
- prefer_self_in_static_references
4444
- prefixed_toplevel_constant
45+
- redundant_extension
4546
- redundant_self_in_closure
4647
- required_deinit
4748
- self_binding

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
#### Enhancements
1212

13+
* Add new `redundant_extension` rule that detect redundant extensions.
14+
[Muhammad Zeeshan](https://github.com/mzeeshanid)
15+
[#5359](https://github.com/realm/SwiftLint/issues/5359)
16+
1317
* Add new `one_declaration_per_file` rule that allows only a
1418
single class/struct/enum/protocol declaration per file.
1519
Extensions are an exception; more than one is allowed.

Source/SwiftLintBuiltInRules/Models/BuiltInRules.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ public let builtInRules: [any Rule.Type] = [
166166
ReduceBooleanRule.self,
167167
ReduceIntoRule.self,
168168
RedundantDiscardableLetRule.self,
169+
RedundantExtensionRule.self,
169170
RedundantNilCoalescingRule.self,
170171
RedundantObjcAttributeRule.self,
171172
RedundantOptionalInitializationRule.self,
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import SwiftSyntax
2+
3+
@SwiftSyntaxRule
4+
struct RedundantExtensionRule: OptInRule {
5+
var configuration = SeverityConfiguration<Self>(.warning)
6+
7+
static let description = RuleDescription(
8+
identifier: "redundant_extension",
9+
name: "Redundant Extension",
10+
description: "Avoid redundant extensions",
11+
kind: .idiomatic,
12+
nonTriggeringExamples: [
13+
Example("""
14+
extension Foo {
15+
func something() {}
16+
}
17+
"""),
18+
Example("""
19+
extension Foo {
20+
var a: Int { 1 }
21+
}
22+
""")
23+
],
24+
triggeringExamples: [
25+
Example("""
26+
↓extension Bar {}
27+
""")
28+
]
29+
)
30+
}
31+
32+
private extension RedundantExtensionRule {
33+
final class Visitor: ViolationsSyntaxVisitor<ConfigurationType> {
34+
private var isRedundantExtension = false
35+
override var skippableDeclarations: [any DeclSyntaxProtocol.Type] {
36+
return .allExcept(VariableDeclSyntax.self, FunctionDeclSyntax.self)
37+
}
38+
39+
override func visitPost(_ node: VariableDeclSyntax) {
40+
isRedundantExtension = false
41+
}
42+
43+
override func visitPost(_ node: FunctionDeclSyntax) {
44+
isRedundantExtension = false
45+
}
46+
47+
override func visit(_ node: ExtensionDeclSyntax) -> SyntaxVisitorContinueKind {
48+
isRedundantExtension = true
49+
return .visitChildren
50+
}
51+
52+
override func visitPost(_ node: ExtensionDeclSyntax) {
53+
appendViolationIfNeeded(node: node.extensionKeyword)
54+
}
55+
56+
func appendViolationIfNeeded(node: TokenSyntax) {
57+
if isRedundantExtension {
58+
violations.append(node.positionAfterSkippingLeadingTrivia)
59+
}
60+
}
61+
}
62+
}

Tests/GeneratedTests/GeneratedTests.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,12 @@ class RedundantDiscardableLetRuleGeneratedTests: SwiftLintTestCase {
986986
}
987987
}
988988

989+
class RedundantExtensionRuleGeneratedTests: SwiftLintTestCase {
990+
func testWithDefaultConfiguration() {
991+
verifyRule(RedundantExtensionRule.description)
992+
}
993+
}
994+
989995
class RedundantNilCoalescingRuleGeneratedTests: SwiftLintTestCase {
990996
func testWithDefaultConfiguration() {
991997
verifyRule(RedundantNilCoalescingRule.description)

0 commit comments

Comments
 (0)