Skip to content

Commit

Permalink
Fix false positive in implicit_getter with Swift 5.2
Browse files Browse the repository at this point in the history
Fixes #3074
  • Loading branch information
marcelofabri committed Feb 10, 2020
1 parent c47db1b commit 6967d95
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 14 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@
* Implicit_return description now reports current config correctly.
[John Buckley](https://github.com/nhojb)

* Fix false positive in `implicit_getter` rule in extensions when using
Swift 5.2.
[Marcelo Fabri](https://github.com/marcelofabri)
[#3074](https://github.com/realm/SwiftLint/issues/3074)

* Do not trigger `optional_enum_case_matching` rule on `_?` as the `?` might
be required in some situations.
[Marcelo Fabri](https://github.com/marcelofabri)
Expand Down
2 changes: 2 additions & 0 deletions Source/SwiftLintFramework/Models/SwiftVersion.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public extension SwiftVersion {
static let five = SwiftVersion(rawValue: "5.0.0")
/// Swift 5.1.x - https://swift.org/download/#swift-51
static let fiveDotOne = SwiftVersion(rawValue: "5.1.0")
/// Swift 5.2.x - https://swift.org/download/#swift-52
static let fiveDotTwo = SwiftVersion(rawValue: "5.2.0")

/// The current detected Swift compiler version, based on the currently accessible SourceKit version.
///
Expand Down
54 changes: 40 additions & 14 deletions Source/SwiftLintFramework/Rules/Style/ImplicitGetterRule.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,7 @@ public struct ImplicitGetterRule: ConfigurationProviderRule, AutomaticTestableRu
)

public func validate(file: SwiftLintFile) -> [StyleViolation] {
let pattern = "\\{[^\\{]*?\\s+get\\b"
let attributesKinds: Set<SyntaxKind> = [.attributeBuiltin, .attributeID]
let getTokens: [SwiftLintSyntaxToken] = file.rangesAndTokens(matching: pattern).compactMap { _, tokens in
let kinds = tokens.kinds
guard let token = tokens.last,
token.kind == .keyword,
attributesKinds.isDisjoint(with: kinds) else {
return nil
}

return token
}
let getTokens = findComputedPropertyToken(keyword: "get", file: file)

let violatingLocations = getTokens.compactMap { token -> (ByteCount, SwiftDeclarationKind?)? in
// the last element is the deepest structure
Expand All @@ -36,8 +25,29 @@ public struct ImplicitGetterRule: ConfigurationProviderRule, AutomaticTestableRu
}

// If there's a setter, `get` is allowed
guard dict.setterAccessibility == nil else {
return nil
if SwiftVersion.current < .fiveDotTwo || dict.accessibility != nil {
guard dict.setterAccessibility == nil else {
return nil
}
} else {
guard let range = dict.bodyByteRange.map(file.stringView.byteRangeToNSRange) else {
return nil
}

let setTokens = findComputedPropertyToken(keyword: "set", file: file, range: range)
let hasSetToken = setTokens.contains { token in
// the last element is the deepest structure
guard let setDict = declarations(forByteOffset: token.offset,
structureDictionary: file.structureDictionary).last else {
return false
}

return setDict.offset == dict.offset
}

guard !hasSetToken else {
return nil
}
}

let kind = dict.declarationKind
Expand All @@ -56,6 +66,22 @@ public struct ImplicitGetterRule: ConfigurationProviderRule, AutomaticTestableRu
reason: reason)
}
}

private func findComputedPropertyToken(keyword: String, file: SwiftLintFile,
range: NSRange? = nil) -> [SwiftLintSyntaxToken] {
let pattern = "\\{[^\\{]*?\\s+\(keyword)\\b"
let attributesKinds: Set<SyntaxKind> = [.attributeBuiltin, .attributeID]
return file.rangesAndTokens(matching: pattern, range: range).compactMap { _, tokens in
let kinds = tokens.kinds
guard let token = tokens.last,
token.kind == .keyword,
attributesKinds.isDisjoint(with: kinds) else {
return nil
}

return token
}
}
}

private extension ImplicitGetterRule {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,22 @@ struct ImplicitGetterRuleExamples {
return self.count
}
}
"""),
Example("""
extension Foo {
var bar: Bool {
get { _bar }
set { self._bar = newValue }
}
}
"""),
Example("""
extension Foo {
var bar: Bool {
get { _bar }
set(newValue) { self._bar = newValue }
}
}
""")
]

Expand Down Expand Up @@ -161,6 +177,13 @@ struct ImplicitGetterRuleExamples {
}
}
}
"""),
Example("""
extension Foo {
var bar: Bool {
↓get { _bar }
}
}
""")
]

Expand Down

0 comments on commit 6967d95

Please sign in to comment.