Files
SwiftLint/Source/SwiftLintFramework/Extensions/SwiftLintFile+BodyLineCount.swift
T
JP SimardandGitHub 2f0e537f9b Update SwiftSyntax to latest development snapshot (#4759)
* Merge `spacedBinaryOperator` and `unspacedBinaryOperator`

* New contextual keyword enums

* Update for removed `UnavailabilityConditionSyntax`

* Handle how attributes are now defined

This partially reverts commit 325d0ee1e4.

* Handle removal of `TokenListSyntax`

* Update `Package.swift`

* Extract some SwiftSyntax helpers

* Update to `0.50900.0-swift-DEVELOPMENT-SNAPSHOT-2023-02-06-a`

* Skip attributes with keypath arguments in `attributes` rule

To preserve the rule's existing behavior.

* Limit unowned_variable_capture violations to capture lists

* Add changelog entries
2023-02-20 10:51:31 -05:00

59 lines
2.3 KiB
Swift

import SwiftSyntax
extension SwiftLintFile {
/// This function determines if given a scope with a left/right brace, such as a function, closure, type, etc, how
/// many lines the "body" spans when you ignore lines only containing comments and/or whitespace.
///
/// - parameter leftBraceLine: The line where the scope's left opening brace is located.
/// - parameter rightBraceLine: The line where the scope's right closing brace is located.
///
/// - returns: The number of effective lines of the body ignoring lines only containing comments and/or whitespace.
func bodyLineCountIgnoringCommentsAndWhitespace(
leftBraceLine: Int, rightBraceLine: Int
) -> Int {
// Ignore left/right brace lines
let startLine = min(leftBraceLine + 1, rightBraceLine - 1)
let endLine = max(rightBraceLine - 1, leftBraceLine + 1)
// Add one because if `endLine == startLine` it's still a one-line "body". Here are some examples:
//
// # 1 line
// {}
//
// # 1 line
// {
// }
//
// # 1 line
// {
// print("foo")
// }
//
// # 2 lines
// {
// let sum = 1 + 2
// print(sum)
// }
let totalNumberOfLines = 1 + endLine - startLine
let numberOfCommentAndWhitespaceOnlyLines = Set(startLine...endLine).subtracting(linesWithTokens).count
return totalNumberOfLines - numberOfCommentAndWhitespaceOnlyLines
}
func computeLinesWithTokens() -> Set<Int> {
let locationConverter = locationConverter
return syntaxTree
.tokens(viewMode: .sourceAccurate)
.reduce(into: []) { linesWithTokens, token in
if case .stringSegment = token.tokenKind {
let sourceRange = token
.trimmed
.sourceRange(converter: locationConverter)
let startLine = sourceRange.start.line!
let endLine = sourceRange.end.line!
linesWithTokens.formUnion(startLine...endLine)
} else if let line = locationConverter.location(for: token.positionAfterSkippingLeadingTrivia).line {
linesWithTokens.insert(line)
}
}
}
}