A long-standing limitation with SourceKit's "editor open" request is
that we weren't able to get certain tokens, such as braces, brackets and
parentheses.
This meant that this code block would be counted as two lines:
```swift
print(
"hi"
)
```
because the trailing `)` would be treated as a whitespace line.
This meant that our "body length" family of rules that measure the
effective line count of declarations like functions, types or closures
would often significantly under-count the number of content lines in a
body.
Now with SwiftSyntax, we can get all tokens, including the ones
SourceKit was previously ignoring, so we can get much more accurate line
counts when ignoring whitespace and comments.
In addition, we weren't very thorough in how we measured body length.
As an exercise, how many lines long would you say the body of this
function is?
```swift
func hello() {
print("hello")
}
```
Does the body span one line or three lines?
I propose that we consistently ignore the left and right brace lines
when calculating the body line count of these scopes so that we measure
body line counts like this:
```swift
// 1 line
{ print("foo") }
// 1 line
{
}
// 1 line
{
print("foo")
}
// 2 lines
{
let sum = 1 + 2
print(sum)
}
```
Now with those changes in place, in order to keep the default
configuration thresholds to similar levels as before, we need to adjust
them slightly. Here's what I'm suggesting:
|Rule|Before|After|
|-|-|-|
|closure_body_length|20/100|30/100|
|function_body_length|40/100|50/100|
|type_body_length|200/350|250/350|
This is a pretty significant breaking change and I suspect we'll hear
from users who are surprised that some of their declarations now exceed
the rule limits, but I believe this new approach to calculating body
lines is more correct and intuitive compared to what we've had until
now.
OSSCheck is also going to report a bazillion changes with this, which is
expected given the scope of this change.
When linting SwiftLint, this brings memory usage down by around 20%,
going from 372MB to 297MB.
This is achieved by removing the unused `RebuildQueue` and by clearing
cached data associated with files after processing them.
Depends on https://github.com/jpsim/SourceKitten/pull/749.
By using SwiftSyntax instead, we avoid the overhead of a SourceKit
request, which has a significant impact if none of the rules being
corrected use SourceKit.
* Improve docstrings for `StringView+SwiftSyntax.swift`
* Move changelog entry to correct section & reword
* Change parameter type from `Int` to `ByteCount`
* Move AbsolutePosition / ByteCount conversion to internal API
* Only warn once if syntax tree cannot be parsed
* Move Syntactic Sugar examples to a dedicated file
* Change SyntacticSugarRuleVisitor from SyntaxAnyVisitor to SyntaxVisitor
* Add `SugaredType` enum to help with the implement `SyntacticSugarRule`
Uses SwiftSyntax 5.5 on Linux when building with Swift 5.5. We use the 5.6 version of
SwiftSyntax when building with Swift 5.5 and 5.6 on macOS because we statically link
`lib_InternalSwiftSyntaxParser` thanks to
https://github.com/keith/StaticInternalSwiftSyntaxParser/releases/tag/5.6.
This keeps SwiftLint binaries portable across machines on macOS, regardless of
_where_ or even _if_ `lib_InternalSwiftSyntaxParser` is installed.
* Run TSan CI job with `--configuration release` to avoid stack overflows
* Add Swift 5.6 CI job
* Fix linker settings
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.
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.