diff --git a/CHANGELOG.md b/CHANGELOG.md index be786e3de4..d4eaeaf466 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,21 @@ ### Enhancements +* Add `excluded_members` configuration to `empty_enum_arguments` to skip members + that require empty parentheses (e.g. HealthKit static functions). + [leno23](https://github.com/leno23) + [#5269](https://github.com/realm/SwiftLint/issues/5269) + +* Fix `unused_enumerated` false positives when offset and element are used in + separate chained trailing closures after `.enumerated()`. + [leno23](https://github.com/leno23) + [#5600](https://github.com/realm/SwiftLint/issues/5600) + +* Treat macro declarations like function declarations for `line_length` when + `ignores_function_declarations` is enabled. + [leno23](https://github.com/leno23) + [#5648](https://github.com/realm/SwiftLint/issues/5648) + * Print fixed code read from stdin to stdout. [SimplyDanny](https://github.com/SimplyDanny) [#6501](https://github.com/realm/SwiftLint/issues/6501) diff --git a/Source/SwiftLintBuiltInRules/Rules/Metrics/LineLengthRule.swift b/Source/SwiftLintBuiltInRules/Rules/Metrics/LineLengthRule.swift index 91765f8e9c..558db97af4 100644 --- a/Source/SwiftLintBuiltInRules/Rules/Metrics/LineLengthRule.swift +++ b/Source/SwiftLintBuiltInRules/Rules/Metrics/LineLengthRule.swift @@ -7,6 +7,11 @@ import SwiftSyntax struct LineLengthRule: Rule { var configuration = LineLengthConfiguration() + private static let longMacroDeclaration = """ + @freestanding(expression) + public macro obfuscate(_ value: String) -> String = #externalMacro(module: "ObfuscatedStringMacros", type: "ObfuscationMacro") + """ + static let description = RuleDescription( identifier: "line_length", name: "Line Length", @@ -16,11 +21,16 @@ struct LineLengthRule: Rule { Example(String(repeating: "/", count: 120) + ""), Example(String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 120) + ""), Example(String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 120) + ""), + Example( + longMacroDeclaration, + configuration: ["ignores_function_declarations": true, "warning": 120] + ), ], triggeringExamples: [ Example(String(repeating: "/", count: 121) + ""), Example(String(repeating: "#colorLiteral(red: 0.9607843161, green: 0.7058823705, blue: 0.200000003, alpha: 1)", count: 121) + ""), Example(String(repeating: "#imageLiteral(resourceName: \"image.jpg\")", count: 121) + ""), + Example(longMacroDeclaration, configuration: ["warning": 120]), ].skipWrappingInCommentTests().skipWrappingInStringTests() ) } @@ -35,7 +45,7 @@ private extension LineLengthRule { private var regexLiteralLines = Set() override func visit(_ node: SourceFileSyntax) -> SyntaxVisitorContinueKind { - // Populate functionDeclarationLines if ignores_function_declarations is true + // Populate declaration lines for functions and macros when ignoring function declarations if configuration.ignoresFunctionDeclarations { let funcVisitor = FunctionLineVisitor(locationConverter: locationConverter) functionDeclarationLines = funcVisitor.walk(tree: node, handler: \.lines) @@ -147,7 +157,7 @@ private extension LineLengthRule { // MARK: - Helper Visitors for Pre-computation -// Visitor to find lines spanned by function declaration signatures +// Visitor to find lines spanned by function and macro declaration signatures private final class FunctionLineVisitor: SyntaxVisitor { let locationConverter: SourceLocationConverter var lines = Set() @@ -181,6 +191,13 @@ private final class FunctionLineVisitor: SyntaxVisitor { ) } + override func visitPost(_ node: MacroDeclSyntax) { + collectLines( + from: node.positionAfterSkippingLeadingTrivia, + to: node.endPositionBeforeTrailingTrivia + ) + } + private func collectLines(from startPosition: AbsolutePosition, to endPosition: AbsolutePosition) { let startLocation = locationConverter.location(for: startPosition) let endLocation = locationConverter.location(for: endPosition)