Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend ImplicitReturnRule to apply to switch statements #5665

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct ImplicitReturnConfiguration: SeverityBasedRuleConfiguration {
case getter
case `subscript`
case initializer
case `switch`

static func < (lhs: Self, rhs: Self) -> Bool {
lhs.rawValue < rhs.rawValue
Expand Down
30 changes: 30 additions & 0 deletions Source/SwiftLintBuiltInRules/Rules/Style/ImplicitReturnRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,36 @@ private extension ImplicitReturnRule {
}
}

override func visitPost(_ node: SwitchExprSyntax) {
if configuration.isKindIncluded(.switch) {
dump(file.syntaxTree)
var violations: [CodeBlockItemListSyntax] = []
let switchCases: SwitchCaseListSyntax = node.cases
for switchCase in switchCases {
dump("🏴‍☠️ \(switchCase)")
var childViolations: [CodeBlockItemListSyntax] = []
if let item = switchCase.as(SwitchCaseSyntax.self) {
if item.statements.count > 1 {
return
} else {
childViolations.append(item.statements)
}
}
for violation in childViolations {
violations.append(violation)
}
}
// if node.statements.syntaxNodeType != NilLiteralExprSyntax.self {
// if item != "return" && item != "return nil" {
// collectViolation(in: node.statements)
// }
// }
for violation in violations {
collectViolation(in: violation)
}
}
}

private func collectViolation(in itemList: CodeBlockItemListSyntax) {
guard let returnStmt = itemList.onlyElement?.item.as(ReturnStmtSyntax.self) else {
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,88 @@ struct ImplicitReturnRuleExamples {
]
}

struct SwitchExamples {
static let nonTriggeringExamples = [
Example("""
switch someBool {
case true: true
case false: nil
}
"""),
Example("""
switch someBool {
case true:
true
case false:
nil
}
"""),
Example("""
return switch someBool {
case true:
true
case false:
nil
}
"""),
Example("""
switch someBool {
case true:
return true
case false:
let someVar = 0
return nil
}
"""),
]

static let triggeringExamples = [
Example("""
switch someBool {
case true: ↓return true
case false: ↓return nil
}
"""),
Example("""
switch someBool {
case true:
↓return true
case false:
↓return nil
}
"""),
]

static let corrections = [
Example("""
switch someBool {
case true: ↓return true
case false: ↓return nil
}
"""): Example("""
switch someBool {
case true: true
case false: nil
}
"""),
Example("""
switch someBool {
case true:
↓return true
case false:
↓return nil
}
"""): Example("""
switch someBool {
case true:
true
case false:
nil
}
"""),
]
}

struct MixedExamples {
static let corrections = [
Example("""
Expand All @@ -356,14 +438,16 @@ struct ImplicitReturnRuleExamples {
FunctionExamples.nonTriggeringExamples +
GetterExamples.nonTriggeringExamples +
InitializerExamples.nonTriggeringExamples +
SubscriptExamples.nonTriggeringExamples
SubscriptExamples.nonTriggeringExamples +
SwitchExamples.nonTriggeringExamples

static let triggeringExamples =
ClosureExamples.triggeringExamples +
FunctionExamples.triggeringExamples +
GetterExamples.triggeringExamples +
InitializerExamples.triggeringExamples +
SubscriptExamples.triggeringExamples
SubscriptExamples.triggeringExamples +
SwitchExamples.triggeringExamples

static var corrections: [Example: Example] {
[
Expand All @@ -372,6 +456,7 @@ struct ImplicitReturnRuleExamples {
GetterExamples.corrections,
InitializerExamples.corrections,
SubscriptExamples.corrections,
SwitchExamples.corrections,
MixedExamples.corrections,
]
.reduce(into: [:]) { result, element in
Expand Down
2 changes: 1 addition & 1 deletion Tests/IntegrationTests/default_rule_configurations.yml
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ implicit_getter:
severity: warning
implicit_return:
severity: warning
included: [closure, function, getter, initializer, subscript]
included: [closure, function, getter, initializer, subscript, switch]
implicitly_unwrapped_optional:
severity: warning
mode: all_except_iboutlets
Expand Down
15 changes: 15 additions & 0 deletions Tests/SwiftLintFrameworkTests/ImplicitReturnRuleTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,21 @@ final class ImplicitReturnRuleTests: SwiftLintTestCase {
)
}

func testOnlySwitchKindIncluded() {
var nonTriggeringExamples = ImplicitReturnRuleExamples.nonTriggeringExamples +
ImplicitReturnRuleExamples.triggeringExamples
nonTriggeringExamples.removeAll(
where: ImplicitReturnRuleExamples.SwitchExamples.triggeringExamples.contains
)

verifySubset(
nonTriggeringExamples: nonTriggeringExamples,
triggeringExamples: ImplicitReturnRuleExamples.SwitchExamples.triggeringExamples,
corrections: ImplicitReturnRuleExamples.SwitchExamples.corrections,
kind: .switch
)
}

private func verifySubset(
nonTriggeringExamples: [Example],
triggeringExamples: [Example],
Expand Down
Loading