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

Don't trigger explicit_type_interface on if case statements #2853

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -37,7 +37,9 @@

#### Bug Fixes

* None.

* Don't trigger `explicit_type_interface` on `if case let` statements.
[Carlos Millani](https://github.com/cmillani)

## 0.35.0: Secondary Lint Trap

Expand Down
2 changes: 1 addition & 1 deletion Source/SwiftLintFramework/Models/MasterRuleList.swift
@@ -1,4 +1,4 @@
// Generated using Sourcery 0.17.0 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 0.16.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT

public let masterRuleList = RuleList(rules: [
Expand Down
Expand Up @@ -96,6 +96,7 @@ public struct ExplicitTypeInterfaceRule: OptInRule, ConfigurationProviderRule {
(!dictionary.isInitCall(file: file) && !dictionary.isTypeReferenceAssignment(file: file))
),
!parentStructure.contains([.forEach, .guard]),
!parentStructure.isIfCaseCall(),
!parentStructure.caseStatementPatternRanges.contains(offset),
!parentStructure.caseExpressionRanges.contains(offset),
!file.captureGroupByteRanges.contains(offset) else {
Expand All @@ -115,6 +116,12 @@ private extension Dictionary where Key == String, Value == SourceKitRepresentabl
return typeName != nil
}

func isIfCaseCall() -> Bool {
let isOnlyArgumentInCall = self.kind == SwiftExpressionKind.call.rawValue
let isOneOfManyArguments = self.kind == SwiftExpressionKind.argument.rawValue
return isOnlyArgumentInCall || isOneOfManyArguments
}

func isInitCall(file: File) -> Bool {
guard
let nameOffset = nameOffset,
Expand Down
3 changes: 2 additions & 1 deletion Tests/LinuxMain.swift
@@ -1,4 +1,4 @@
// Generated using Sourcery 0.17.0 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 0.16.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT

@testable import SwiftLintFrameworkTests
Expand Down Expand Up @@ -443,6 +443,7 @@ extension ExplicitTypeInterfaceRuleTests {
("testAllowRedundancy", testAllowRedundancy),
("testEmbededInStatements", testEmbededInStatements),
("testCaptureGroup", testCaptureGroup),
("testTryCatchDeclarations", testTryCatchDeclarations),
("testFastEnumerationDeclaration", testFastEnumerationDeclaration),
("testSwitchCaseDeclarations", testSwitchCaseDeclarations)
]
Expand Down
@@ -1,4 +1,4 @@
// Generated using Sourcery 0.17.0 — https://github.com/krzysztofzablocki/Sourcery
// Generated using Sourcery 0.16.2 — https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT

import SwiftLintFramework
Expand Down
44 changes: 44 additions & 0 deletions Tests/SwiftLintFrameworkTests/ExplicitTypeInterfaceRuleTests.swift
@@ -1,6 +1,7 @@
import SwiftLintFramework
import XCTest

//swiftlint:disable type_body_length
class ExplicitTypeInterfaceRuleTests: XCTestCase {
func testExplicitTypeInterface() {
verifyRule(ExplicitTypeInterfaceRule.description)
Expand Down Expand Up @@ -126,6 +127,27 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase {
verifyRule(description)
}

func testTryCatchDeclarations() {
let nonTriggeringExaples = [
"""
enum FooError: Error {
case errorWithValue(value: Int)
}
do {
throw FooError.errorWithValue(value: 2)
} catch FooError.errorWithValue(let value) {
print(value)
}
"""
]

let triggeringExamples = ExplicitTypeInterfaceRule.description.triggeringExamples
let description = ExplicitTypeInterfaceRule.description
.with(triggeringExamples: triggeringExamples)
.with(nonTriggeringExamples: nonTriggeringExaples)
verifyRule(description)
}

func testFastEnumerationDeclaration() {
let nonTriggeringExaples = [
"""
Expand Down Expand Up @@ -178,6 +200,28 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase {
case var (x, y): break
}
}
""",
"""
enum Foo {
case caseOne(propOne: Int)
}

enum Bar: Error {
case testError
case multiVariable(foo: Int, bar: String)
}

let testA: Foo = .caseOne(propOne: 2)

if case let Foo.caseOne(propOne) = testA { }

if case Foo.caseOne(let propOne) = testA { }

if 5 > 2, case Foo.caseOne(let propOne) = testA { }

let multiVariable: Error = Bar.multiVariable(foo: 10, bar: "")

if case Bar.multiVariable(let foo, _) = multiVariable { }
"""
]

Expand Down