Open ghost opened 7 years ago
It looks like vertical_whitespace
is the one to blame. Could please post the result of swiftlint autocorrect
to confirm?
(PS: it'd also be weird if it was, because you're disabling that rule in your configuration file)
I can't post any code that is actually reproducing the problem. It's company code. The problem immediately went away when I changed the file encoding from CRLF to LF.
I'm trying to make a sample file to reproduce the issue, but I can't get it to create the extra empty lines any more. Atom seems to have trouble with CRLF line endings, though. See image below.
We have SwiftLint run in a Build Phase in our iOS project using the script below. I never see the issue then. It only happens when I open terminal and run using the autocorrect command. Which brings up another point, running swiftlint autocorrect
in the Xcode Build Phase corrects very little, whereas, running autocorrect via Terminal corrects a ton, but also produces this bug. That's a little frustrating.
Xcode Build Phase script
if which swiftlint >/dev/null; then
swiftlint autocorrect
else
echo "Warning: SwiftLint not installed, install using 'brew install swiftlint' or download from https://github.com/realm/SwiftLint"
fi
Here is another screenshot of Atom with an even better bug. The red indicator for the error isn't even near where the error occurs. Similar issues occur in terminal where the line number given for the warning or error is not even close to where the error occurs.
And here I have only changed the file encoding from CRLF to LF. All the warnings have gone away and the error correctly shows where the error is. You'll notice I haven't even saved the file yet after changing the encoding.
Sorry, I am unable to reproduce the original issue. I even tried converting the original file where I found this problem back to CRLF. Now I only see the issues mentioned above about the line numbers being wrong, but no extra empty lines.
Sorry to flood you with screenshots. I hope they are helpful. Here's one that shows all the Linter packages I have installed in Atom
Hi @chadcummings, these are the steps I've used to reproduce it without plugins and/or IDE extensions:
$ cat quick.swift
internal struct Toto {
func foo() -> Bool {
return false
}
func bar(_ variable: Bool) -> Bool {
return !variable
}
}
$ file quick.swift
quick.swift: ASCII text, with CRLF line terminators
$ swiftlint autocorrect --path quick.swift
$ cat quick.swift
internal struct Toto {
func foo() -> Bool {
return false
}
func bar(_ variable: Bool) -> Bool {
return !variable
}
}
After running autocorrect once, the file won't have CRLF line terminators anymore.
$ file quick.swift
quick.swift: ASCII text
For this example (w/ CRLF line terminators):
internal struct Toto {
func foo() -> Bool {
return false
}
func bar(_ variable: Bool) -> Bool {
return !variable
}
}
SourceKittenFramework's File.init(path:)
returns 18 lines:
(lldb) po contents.bridge().lines().count
18
po contents.bridge().lines()
▿ 18 elements
▿ 0 : Line
- index : 1
- content : "internal struct Toto {"
▿ range : {0, 23}
- location : 0
- length : 23
▿ byteRange : {0, 23}
- location : 0
- length : 23
▿ 1 : Line
- index : 2
- content : ""
▿ range : {23, 1}
- location : 23
- length : 1
▿ byteRange : {23, 1}
- location : 23
- length : 1
▿ 2 : Line
- index : 3
- content : " func foo() -> Bool {"
▿ range : {24, 25}
- location : 24
- length : 25
▿ byteRange : {24, 25}
- location : 24
- length : 25
▿ 3 : Line
- index : 4
- content : ""
▿ range : {49, 1}
- location : 49
- length : 1
▿ byteRange : {49, 1}
- location : 49
- length : 1
▿ 4 : Line
- index : 5
- content : " return false"
▿ range : {50, 21}
- location : 50
- length : 21
▿ byteRange : {50, 21}
- location : 50
- length : 21
▿ 5 : Line
- index : 6
- content : ""
▿ range : {71, 1}
- location : 71
- length : 1
▿ byteRange : {71, 1}
- location : 71
- length : 1
▿ 6 : Line
- index : 7
- content : " }"
▿ range : {72, 6}
- location : 72
- length : 6
▿ byteRange : {72, 6}
- location : 72
- length : 6
▿ 7 : Line
- index : 8
- content : ""
▿ range : {78, 1}
- location : 78
- length : 1
▿ byteRange : {78, 1}
- location : 78
- length : 1
▿ 8 : Line
- index : 9
- content : ""
▿ range : {79, 1}
- location : 79
- length : 1
▿ byteRange : {79, 1}
- location : 79
- length : 1
▿ 9 : Line
- index : 10
- content : ""
▿ range : {80, 1}
- location : 80
- length : 1
▿ byteRange : {80, 1}
- location : 80
- length : 1
▿ 10 : Line
- index : 11
- content : " func bar(_ variable: Bool) -> Bool {"
▿ range : {81, 41}
- location : 81
- length : 41
▿ byteRange : {81, 41}
- location : 81
- length : 41
▿ 11 : Line
- index : 12
- content : ""
▿ range : {122, 1}
- location : 122
- length : 1
▿ byteRange : {122, 1}
- location : 122
- length : 1
▿ 12 : Line
- index : 13
- content : " return !variable"
▿ range : {123, 25}
- location : 123
- length : 25
▿ byteRange : {123, 25}
- location : 123
- length : 25
▿ 13 : Line
- index : 14
- content : ""
▿ range : {148, 1}
- location : 148
- length : 1
▿ byteRange : {148, 1}
- location : 148
- length : 1
▿ 14 : Line
- index : 15
- content : " }"
▿ range : {149, 6}
- location : 149
- length : 6
▿ byteRange : {149, 6}
- location : 149
- length : 6
▿ 15 : Line
- index : 16
- content : ""
▿ range : {155, 1}
- location : 155
- length : 1
▿ byteRange : {155, 1}
- location : 155
- length : 1
▿ 16 : Line
- index : 17
- content : "}"
▿ range : {156, 2}
- location : 156
- length : 2
▿ byteRange : {156, 2}
- location : 156
- length : 2
▿ 17 : Line
- index : 18
- content : ""
▿ range : {158, 1}
- location : 158
- length : 1
▿ byteRange : {158, 1}
- location : 158
- length : 1
Nice investigation work, @ornithocoder 🕵️
Maybe this is the problem?
Apparently .components(separatedBy: .newlines)
returns the empty lines when the file has CRLF line terminators. So enumerator
is already looping thru twice the number of lines.
Sounds like you all have it all under control! I'll let you take it from here. Just ping me if you need anything else from me. Happy Coding!
I've come up with a fix for that in SourceKitten: https://github.com/marcelofabri/SourceKitten/commit/01195936a6251b269038e3276cfb097f6d7cdfcc
However, that API is not implemented on Linux yet 🙃
fatal error: enumerateSubstrings(in:options:using:) is not yet implemented: file Foundation/NSString.swift, line 770
I just encountered this too. @marcelofabri any update on the status of Linux and SourceKitten? Thanks
No updates yet.
I just verified this is still an issue as of 0.57.0
New Issue Checklist
Issue Description
Linting CRLF encoded files causes an empty line to be inserted between each line of code
Complete output when running SwiftLint, including the stack trace and command used
Environment
xcode-select -p
)? 8.3.3