Files
JP Simard ea311bab23 [UnusedDeclarationRule] Speed up and detect more dead code (#3340)
By using SourceKit's `index` request to index the entire source file,
we can avoid having to make `cursor-info` requests for every candidate
token in the file, which scales linearly with the number of candiate
tokens.

For the Yams project, this approach improved the total SwiftLint run
time by 4.6x: 7.9 down from 36.8s.

The SourceKit index response doesn't have everything we need to identify
declarations, so we still need to make some `cursor-info` requests,
mostly to detect overrides: protocol conformances and parent class
overrides.

This approach ends up finding more unused declarations because the index
contains more declared USRs than can be found by calling `cursor-info`
on candidate tokens in a file.

---

Remove unused declaration in ArrayInitRule

---

Update package versions
2020-09-15 10:33:27 -07:00

40 lines
1.5 KiB
Swift

import Dispatch
/// A storage mechanism for aggregating the results of `CollectingRule`s.
public class RuleStorage: CustomStringConvertible {
private var storage: [ObjectIdentifier: [SwiftLintFile: Any]]
private let access = DispatchQueue(label: "io.realm.swiftlint.ruleStorageAccess", attributes: .concurrent)
public var description: String {
storage.description
}
/// Creates a `RuleStorage` with no initial stored data.
public init() {
storage = [:]
}
/// Collects file info for a given rule into the storage.s
///
/// - parameter info: The file information to store.
/// - parameter file: The file for which this information pertains to.
/// - parameter rule: The SwiftLint rule that generated this info.
func collect<R: CollectingRule>(info: R.FileInfo, for file: SwiftLintFile, in rule: R) {
let key = ObjectIdentifier(R.self)
access.sync(flags: .barrier) {
storage[key, default: [:]][file] = info
}
}
/// Retrieves all file information for a given rule that was collected via `collect(...)`.
///
/// - parameter rule: The rule whose collected information should be retrieved.
///
/// - returns: All file information for a given rule that was collected via `collect(...)`.
func collectedInfo<R: CollectingRule>(for rule: R) -> [SwiftLintFile: R.FileInfo]? {
return access.sync {
storage[ObjectIdentifier(R.self)] as? [SwiftLintFile: R.FileInfo]
}
}
}