Skip to content

Commit

Permalink
Refactor if case detection to use AST only
Browse files Browse the repository at this point in the history
  • Loading branch information
cmillani committed Sep 6, 2019
1 parent 2336a5d commit 4e09cad
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 13 deletions.
Expand Up @@ -95,8 +95,8 @@ public struct ExplicitTypeInterfaceRule: OptInRule, ConfigurationProviderRule {
(!configuration.allowRedundancy ||
(!dictionary.isInitCall(file: file) && !dictionary.isTypeReferenceAssignment(file: file))
),
!dictionary.isIfCaseCall(file: file, parentStructure: parentStructure),
!parentStructure.contains([.forEach, .guard]),
!parentStructure.isIfCaseCall(),
!parentStructure.caseStatementPatternRanges.contains(offset),
!parentStructure.caseExpressionRanges.contains(offset),
!file.captureGroupByteRanges.contains(offset) else {
Expand All @@ -116,18 +116,10 @@ private extension Dictionary where Key == String, Value == SourceKitRepresentabl
return typeName != nil
}

func isIfCaseCall(file: File, parentStructure: [String: SourceKitRepresentable]) -> Bool {
guard parentStructure.kind == SwiftExpressionKind.call.rawValue,
let parentOffset = parentStructure.offset,
case let contents = file.contents.bridge(),
let beforeParentRange = contents.byteRangeToNSRange(start: parentOffset, length: 0) else {
return false
}

let fileUpToParent = contents.substring(to: beforeParentRange.location)
let isCaseRegex = regex("if\\s+case\\s+(let|var)?\\s*$")

return isCaseRegex.firstMatch(in: fileUpToParent, options: [], range: fileUpToParent.fullNSRange) != 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 {
Expand Down
11 changes: 11 additions & 0 deletions Tests/SwiftLintFrameworkTests/ExplicitTypeInterfaceRuleTests.swift
Expand Up @@ -184,11 +184,22 @@ class ExplicitTypeInterfaceRuleTests: XCTestCase {
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

0 comments on commit 4e09cad

Please sign in to comment.