Add new one_declaration_per_file rule (#5377)

This commit is contained in:
Muhammad Zeeshan
2023-12-09 15:11:25 +05:00
committed by GitHub
parent f369caae44
commit 7d6f6cfa17
5 changed files with 89 additions and 0 deletions
+1
View File
@@ -38,6 +38,7 @@ disabled_rules:
- no_fallthrough_only
- no_grouping_extension
- no_magic_numbers
- one_declaration_per_file
- prefer_nimble
- prefer_self_in_static_references
- prefixed_toplevel_constant
+6
View File
@@ -10,6 +10,12 @@
#### Enhancements
* Add new `one_declaration_per_file` rule that allows only a
single class/struct/enum/protocol declaration per file.
Extensions are an exception; more than one is allowed.
[Muhammad Zeeshan](https://github.com/mzeeshanid)
[#2802](https://github.com/realm/SwiftLint/issues/2802)
* Rewrite the following rules with SwiftSyntax:
* `identifier_name`
* `let_var_whitespace`
@@ -135,6 +135,7 @@ public let builtInRules: [any Rule.Type] = [
NotificationCenterDetachmentRule.self,
NumberSeparatorRule.self,
ObjectLiteralRule.self,
OneDelarationPerFileRule.self,
OpeningBraceRule.self,
OperatorFunctionWhitespaceRule.self,
OperatorUsageWhitespaceRule.self,
@@ -0,0 +1,75 @@
import SwiftSyntax
@SwiftSyntaxRule
struct OneDelarationPerFileRule: OptInRule {
var configuration = SeverityConfiguration<Self>(.warning)
static let description = RuleDescription(
identifier: "one_declaration_per_file",
name: "One Declaration per File",
description: "Only a single declaration is allowed in a file",
kind: .idiomatic,
nonTriggeringExamples: [
Example("""
class Foo {}
"""),
Example("""
class Foo {}
extension Foo {}
"""),
Example("""
struct S {
struct N {}
}
""")
],
triggeringExamples: [
Example("""
class Foo {}
↓class Bar {}
"""),
Example("""
protocol Foo {}
↓enum Bar {}
"""),
Example("""
struct Foo {}
↓struct Bar {}
""")
]
)
}
private extension OneDelarationPerFileRule {
final class Visitor: ViolationsSyntaxVisitor<ConfigurationType> {
private var declarationVisited = false
override var skippableDeclarations: [any DeclSyntaxProtocol.Type] { .all }
override func visitPost(_ node: ActorDeclSyntax) {
appendViolationIfNeeded(node: node.actorKeyword)
}
override func visitPost(_ node: ClassDeclSyntax) {
appendViolationIfNeeded(node: node.classKeyword)
}
override func visitPost(_ node: StructDeclSyntax) {
appendViolationIfNeeded(node: node.structKeyword)
}
override func visitPost(_ node: EnumDeclSyntax) {
appendViolationIfNeeded(node: node.enumKeyword)
}
override func visitPost(_ node: ProtocolDeclSyntax) {
appendViolationIfNeeded(node: node.protocolKeyword)
}
func appendViolationIfNeeded(node: TokenSyntax) {
if declarationVisited {
violations.append(node.positionAfterSkippingLeadingTrivia)
}
declarationVisited = true
}
}
}
@@ -800,6 +800,12 @@ class ObjectLiteralRuleGeneratedTests: SwiftLintTestCase {
}
}
class OneDelarationPerFileRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(OneDelarationPerFileRule.description)
}
}
class OpeningBraceRuleGeneratedTests: SwiftLintTestCase {
func testWithDefaultConfiguration() {
verifyRule(OpeningBraceRule.description)