Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@

### Enhancements

* Add `excluded_members` configuration to `empty_enum_arguments` to skip members
that require empty parentheses (e.g. HealthKit static functions).
[leno23](https://github.com/leno23)
[#5269](https://github.com/realm/SwiftLint/issues/5269)

* Print fixed code read from stdin to stdout.
[SimplyDanny](https://github.com/SimplyDanny)
[#6501](https://github.com/realm/SwiftLint/issues/6501)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import SwiftLintCore

@AutoConfigParser
struct EmptyEnumArgumentsConfiguration: SeverityBasedRuleConfiguration {
@ConfigurationElement(key: "severity")
private(set) var severityConfiguration = SeverityConfiguration<Parent>(.warning)
@ConfigurationElement(key: "excluded_members")
private(set) var excludedMembers = Set<String>()
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ private func wrapInFunc(_ str: String, file: StaticString = #filePath, line: UIn

@SwiftSyntaxRule(explicitRewriter: true)
struct EmptyEnumArgumentsRule: Rule {
var configuration = SeverityConfiguration<Self>(.warning)
var configuration = EmptyEnumArgumentsConfiguration()

static let description = RuleDescription(
identifier: "empty_enum_arguments",
Expand Down Expand Up @@ -61,6 +61,7 @@ struct EmptyEnumArgumentsRule: Rule {
return true
}
"""),
Example("if case .gram() = foo {}", configuration: ["excluded_members": ["gram"]]),
],
triggeringExamples: [
wrapInSwitch("case .bar↓(_)"),
Expand Down Expand Up @@ -117,29 +118,41 @@ struct EmptyEnumArgumentsRule: Rule {
private extension EmptyEnumArgumentsRule {
final class Visitor: ViolationsSyntaxVisitor<ConfigurationType> {
override func visitPost(_ node: SwitchCaseItemSyntax) {
if let violationPosition = node.pattern.emptyEnumArgumentsViolation(rewrite: false)?.position {
if let violationPosition = node.pattern.emptyEnumArgumentsViolation(
rewrite: false,
excludedMembers: configuration.excludedMembers
)?.position {
violations.append(violationPosition)
}
}

override func visitPost(_ node: MatchingPatternConditionSyntax) {
if let violationPosition = node.pattern.emptyEnumArgumentsViolation(rewrite: false)?.position {
if let violationPosition = node.pattern.emptyEnumArgumentsViolation(
rewrite: false,
excludedMembers: configuration.excludedMembers
)?.position {
violations.append(violationPosition)
}
}
}

final class Rewriter: ViolationsSyntaxRewriter<ConfigurationType> {
override func visit(_ node: SwitchCaseItemSyntax) -> SwitchCaseItemSyntax {
guard let (_, newPattern) = node.pattern.emptyEnumArgumentsViolation(rewrite: true) else {
guard let (_, newPattern) = node.pattern.emptyEnumArgumentsViolation(
rewrite: true,
excludedMembers: configuration.excludedMembers
) else {
return super.visit(node)
}
numberOfCorrections += 1
return super.visit(node.with(\.pattern, newPattern))
}

override func visit(_ node: MatchingPatternConditionSyntax) -> MatchingPatternConditionSyntax {
guard let (_, newPattern) = node.pattern.emptyEnumArgumentsViolation(rewrite: true) else {
guard let (_, newPattern) = node.pattern.emptyEnumArgumentsViolation(
rewrite: true,
excludedMembers: configuration.excludedMembers
) else {
return super.visit(node)
}
numberOfCorrections += 1
Expand All @@ -149,7 +162,10 @@ private extension EmptyEnumArgumentsRule {
}

private extension PatternSyntax {
func emptyEnumArgumentsViolation(rewrite: Bool) -> (position: AbsolutePosition, pattern: PatternSyntax)? {
func emptyEnumArgumentsViolation(
rewrite: Bool,
excludedMembers: Set<String>
) -> (position: AbsolutePosition, pattern: PatternSyntax)? {
guard
var pattern = `as`(ExpressionPatternSyntax.self),
let expression = pattern.expression.as(FunctionCallExprSyntax.self),
Expand All @@ -161,6 +177,15 @@ private extension PatternSyntax {
return nil
}

let memberName = expression.innermostFunctionCall.calledExpression
.as(MemberAccessExprSyntax.self)?
.declName
.baseName
.text
if let memberName, excludedMembers.contains(memberName) {
return nil
}

if rewrite {
pattern.expression = expression.removingInnermostDiscardArguments
}
Expand Down