mirror of
https://github.com/realm/SwiftLint.git
synced 2026-05-07 20:12:49 +00:00
Improve detection of comment-only lines in file_length rule (#6231)
This commit is contained in:
@@ -59,6 +59,10 @@
|
||||
[#6220](https://github.com/realm/SwiftLint/issues/6220)
|
||||
[#6219](https://github.com/realm/SwiftLint/issues/6219)
|
||||
|
||||
* Improve detection of comment-only lines in `file_length` rule.
|
||||
[SimplyDanny](https://github.com/SimplyDanny)
|
||||
[#6219](https://github.com/realm/SwiftLint/issues/6219)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fix `closure_end_indentation` rule reporting violations when the called base
|
||||
|
||||
@@ -23,7 +23,10 @@ struct FileLengthRule: Rule {
|
||||
private extension FileLengthRule {
|
||||
final class Visitor: ViolationsSyntaxVisitor<ConfigurationType> {
|
||||
override func visitPost(_ node: SourceFileSyntax) {
|
||||
let lineCount = configuration.ignoreCommentOnlyLines ? countNonCommentLines(in: node) : file.lines.count
|
||||
let lineCount = configuration.ignoreCommentOnlyLines
|
||||
? CommentLinesVisitor(locationConverter: locationConverter)
|
||||
.walk(tree: node, handler: \.linesWithCode).count
|
||||
: file.lines.count
|
||||
|
||||
let severity: ViolationSeverity, upperBound: Int
|
||||
if let error = configuration.severityConfiguration.error, lineCount > error {
|
||||
@@ -52,51 +55,5 @@ private extension FileLengthRule {
|
||||
)
|
||||
violations.append(violation)
|
||||
}
|
||||
|
||||
private func countNonCommentLines(in node: SourceFileSyntax) -> Int {
|
||||
var linesWithActualContent = Set<Int>()
|
||||
|
||||
for token in node.tokens(viewMode: .sourceAccurate) {
|
||||
addTokenContentLines(token, to: &linesWithActualContent)
|
||||
|
||||
// Process leading trivia
|
||||
addTriviaLines(token.leadingTrivia, startingAt: token.position, to: &linesWithActualContent)
|
||||
}
|
||||
return linesWithActualContent.count
|
||||
}
|
||||
|
||||
private func addTokenContentLines(_ token: TokenSyntax, to lines: inout Set<Int>) {
|
||||
// Skip tokens whose text is empty or only whitespace
|
||||
// (e.g., EOF token, or an unlikely malformed token).
|
||||
guard !token.text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return }
|
||||
|
||||
let startLocation = locationConverter.location(for: token.positionAfterSkippingLeadingTrivia)
|
||||
let endLocation = locationConverter.location(for: token.endPositionBeforeTrailingTrivia)
|
||||
|
||||
addLinesInRange(from: startLocation.line, to: endLocation.line, to: &lines)
|
||||
}
|
||||
|
||||
private func addTriviaLines(
|
||||
_ trivia: Trivia,
|
||||
startingAt startPosition: AbsolutePosition,
|
||||
to lines: inout Set<Int>
|
||||
) {
|
||||
var currentPosition = startPosition
|
||||
for piece in trivia {
|
||||
if !piece.isComment, !piece.isWhitespace {
|
||||
let startLocation = locationConverter.location(for: currentPosition)
|
||||
let endLocation = locationConverter.location(for: currentPosition + piece.sourceLength)
|
||||
addLinesInRange(from: startLocation.line, to: endLocation.line, to: &lines)
|
||||
}
|
||||
currentPosition += piece.sourceLength
|
||||
}
|
||||
}
|
||||
|
||||
private func addLinesInRange(from startLine: Int, to endLine: Int, to lines: inout Set<Int>) {
|
||||
guard startLine > 0, startLine <= endLine else { return }
|
||||
for line in startLine...endLine {
|
||||
lines.insert(line)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ public final class CommentLinesVisitor: SyntaxVisitor {
|
||||
private let locationConverter: SourceLocationConverter
|
||||
|
||||
private var linesWithComments = Set<Int>()
|
||||
private var linesWithCode = Set<Int>()
|
||||
|
||||
/// Lines that contain actual code (not comments).
|
||||
public private(set) var linesWithCode = Set<Int>()
|
||||
|
||||
/// Lines that contain only comments (and whitespace).
|
||||
public var commentOnlyLines: Set<Int> {
|
||||
|
||||
Reference in New Issue
Block a user