Fixes#3341
When SwiftLint searches for nested configurations and only one file has been passed in via the `paths` argument, SwiftLint returns early after inadvertently comparing the containing directory of the file-to-be-linted to itself. This happens because `rootDirectory` is calculated from `rootPath`, which is set to the file being linted in this scenario.
We were using this lock to guarantee a new ID for every file, but we can
get that benefit by using values that are guaranteed to be unique
without the need for locks, such as a UUID.
For example, if `CGFloat` is used in a file where only `UIKit` is imported but not `CoreGraphics`, this will be a violation even if the file previously compiled.
This is because Swift allows referencing some declarations that are only transitively imported.
Enabling the `require_explicit_imports` configuration option will require that the module of every declaration referenced in a source file be explicitly imported.
This will add significant noise to the imports list, but has a few advantages:
1. It will be easier to understand all the dependencies explicitly referenced in a source file.
2. Correcting the `unused_import` rule will no longer introduce compilation errors in files that compiled prior to the correction.
If missing imports are added to a file when correcting it, the `sorted_imports` rule will be automatically run on that file.
If you with to allow some imports to be implicitly importable transitively, you may specify the `allowed_transitive_imports` configuration:
```yaml
unused_import:
require_explicit_imports: true
allowed_transitive_imports:
- module: Foundation
allowed_transitive_imports:
- CoreFoundation
- Darwin
- ObjectiveC
```
The new rules introduced in 0.39.0 that depend on SwiftSyntax have been temporarily removed as we work out release packaging issues.
* `prohibited_nan_comparison`
* `return_value_from_void_function`
* `tuple_pattern`
* `void_function_in_ternary`
See https://github.com/realm/SwiftLint/issues/3105 for details.
* Add Example wrapper in order to display test failures inline when running in Xcode.
* Stop using Swift 5.1-only features so we can compile on Xcode 10.2.
* Wrap strings in Example.
* Add Changelog entry.
* Wrap all examples in Example struct.
* Better and more complete capturing of line numbers.
* Fix broken test.
* Better test traceability.
* Address or disable linting warnings.
* Add documentation comments.
* Disable linter for a few cases.
* Limit mutability and add copy-and-mutate utility functions.
* Limit scope of mutability.
This option allows for more fine-grained placement of the location
marker for code violating a custom rule, e.g.:
```swift
print("Hello world.")
^~~~~
```
for this `.swiftlint.yml`:
```yaml
custom_rules:
world_preceded_by_hello:
name: "World Preceded by Hello"
included: ".+\\.swift"
message: "The word World predeced by the word hello should be capitalised."
severity: warning
regex: "(?i:hello)\\s+(world)"
match_kinds: [string]
capture_group: 1
```
When the request is asked which tokens are have in an intersection, the previous solution was searching for first Index (linearly) and then filtered everything that was coming after that index using `intersect function`
The updated solution will search for the first token index using`binary search`
# Speedup
While this is only one function was updated, the next options were considered:
- [**lin+filter**] old solution
- [**lin+prefix**] old solution with `prefix:wihle` instead of filtering
- [**bin+filter**] binary search with filter
- [**bin+prefix**] binary search with `prefix:wihle` instead of filtering
The speedup highly depends on the file sizes. The bigger/longer files the bigger win is
# Benchmark
## Kickstarter
|lin+filter|lin+prefix|bin+filter|bin+prefix|speedup|
|-|-|-|-|-|
|0.494|0.243|0.390|\***0.117\***| ~4x |
## Swift
|lin+filter|lin+prefix|bin+filter|bin+prefix|speedup|
|-|-|-|-|-|
|1.739|0.740|1.273|\***0.103**\*| ~16x |
## WordPress
|lin+filter|lin+prefix|bin+filter|bin+prefix|speedup|
|-|-|-|-|-|
|1.270|0.526|0.918|0.148| ~8x |
# Testing code
This code was tested with these parts of code (in Release build)
```
fileprivate var counter = 0
fileprivate var times: [String: Double] = [:]
fileprivate let timesQueue = DispatchQueue.init(label: "benchmarks")
fileprivate func timeLog<T>(_ name: String, block: () -> T) -> T {
let start = DispatchTime.now()
let result = block()
let end = DispatchTime.now()
timesQueue.async {
let oldValue = times[name, default:0.0]
let diff = TimeInterval(end.uptimeNanoseconds - start.uptimeNanoseconds) / 1_000_000_000
let newValue = oldValue + diff
times[name] = newValue
counter += 1
if counter % 1000 * times.count == 0 {
print("!!!!: \(times)")
}
}
return result
}
internal func tokens(inByteRange byteRange: NSRange) -> [SyntaxToken] {
let new = timeLog("new") { tokensFast(inByteRange: byteRange) }
let new2 = timeLog("old") { tokensOld(inByteRange: byteRange) }
return arc4random() % 2 == 1 ? new : new2
}
```
* Require Swift 5.0 to build
* Update CI
* Stop testing with Swift 4.x & Xcode 10.0/10.1
* Use official Swift docker image instead of norionomura's
* Use Xcode 10.3 as latest stable version
* Update READMEs
* Fixup xcodeproj
* Fixup CI Swift container image tag
* Fixup changelog
This PR adds a new `unused_declaration` analyzer rule to lint for unused declarations.
By default, detects unused `fileprivate`, `private` and `internal` declarations.
Configure the rule with `include_public_and_open: true` to also detect unused `public` and `open` declarations.
Completely remove the `unused_private_declaration` rule.
This is built on the work enabling collecting rule infrastructure in https://github.com/realm/SwiftLint/pull/2714.
* Split cache into one file per configuration
* Only write cache files with changes
* Avoid converting from Data -> String -> Data when saving cache files
* Move empty check to for where
* Split cache changelog entry
* Reword changelog entry to better reflect impact