Add auto-correction, indentation config, and multi-violation support to multiline_call_arguments#6745
Conversation
b183a6a to
78a2da1
Compare
|
@SimplyDanny Let's add correctable for The CI failure on oss_scan is not related to this PR — it's a danger bot failing to post a comment due to the repository's interaction limits (422 - Interactions on this repository have been restricted to prior contributors only) |
f16bd4c to
8b5b043
Compare
Generated by 🚫 Danger |
3c09c9b to
c2b5aa8
Compare
9510ef7 to
0cdc2a7
Compare
7b65161 to
9a91acd
Compare
|
@SimplyDanny It would be great if you could review the PR :) |
9a91acd to
0bd454f
Compare
| /// Indentation style for corrected lines. | ||
| /// Can be an integer (number of spaces) or the string "tabs". | ||
| @ConfigurationElement(key: "indentation") | ||
| private(set) var indentationStyle: IndentationStyle = .spaces(count: 4) |
There was a problem hiding this comment.
Can the global option not be reused?
There was a problem hiding this comment.
I looked into this, and unfortunately the global indentation is not currently accessible from rules. Here's what I found:
Linterstores the fullConfiguration(includingindentation), but when invoking rules it only passesSwiftLintFile+ per-rule config tovalidate(file:using:compilerArguments:).- Neither
SwiftLintFile,ViolationsSyntaxVisitor, norRuleStoragehold a reference to the globalConfiguration. - The global
configuration.indentationis consumed only by --format inLintOrAnalyzeCommand.swift— a separate code path that reformats file text directly without invoking any rules.
Is there an existing mechanism for rules to access the global Configuration.indentation that I'm overlooking? If so, could you point me in the right direction?
If not, reusing it would require threading the global indentation through the rule execution path — e.g. by adding it to SwiftLintFile or ViolationsSyntaxVisitor. This is a framework-wide change that affects all rules. I'd suggest doing this as a separate PR (ideally before merging this one) — once the global indentation is available to rules, the per-rule option can be removed in favor of it. For now, the rule reuses the shared IndentationStyle type from SwiftLintCore (the same type the global config uses), so it's ready to switch over when the plumbing is in place
There was a problem hiding this comment.
I looked into this further and found a way to make it work without a separate PR.
The global indentation was indeed not accessible from rules — Linter stores the full Configuration, but validate(file:using:compilerArguments:) only receives SwiftLintFile + per-rule config. However, SwiftLint already has CurrentRule with @TaskLocal properties for exactly this kind of cross-cutting concern (used for identifier and allowSourceKitRequestWithoutRule).
I added @TaskLocal public static var indentation: IndentationStyle? to CurrentRule and set it at the three rule-execution chokepoints in Linter.swift (lint, collect, correct) from Configuration.indentation. The rule reads it via CurrentRule.indentation, falling back to IndentationStyle.default when not set (e.g., in unit tests outside a Linter context).
The per-rule indentation option has been removed — the rule now uses the global indentation setting from .swiftlint.yml. End-to-end tests confirm the full pipeline: Configuration(indentation: .tabs) → Linter → correct → tab-indented output.
ebc98ef to
f694a41
Compare
…to multiline_call_arguments
Thread the global into rules via a new on , set at the three rule-execution chokepoints in (lint, collect, correct). Remove the per-rule option from in favor of the global setting.
8b03add to
1d6eaeb
Compare
SimplyDanny
left a comment
There was a problem hiding this comment.
A few more comments ...
In general, I'm not against using AI to help with coding. However, I expect from contributors that they understand what they are proposing, review the code and clean things up themselves.
I see a lot of redundancy and useless information in comments as well as unused code that I shouldn't not need to take care of as a reviewer. There are many other PRs waiting for my feedback. So please make sure to propose only changes that you have thoroughly reviewed and improved yourself. Otherwise, I might lose my motivation to review anything like this. AI only has a chance to be of help if it makes use faster as a whole. Shifting work from you to someone else doesn't increase throughput at all.
| `.swiftlint.yml`. The per-rule `indentation` option has been removed in | ||
| favor of the global one. The rule detects all violations in a single | ||
| pass (previously required repeated `--fix`); safely handles nested | ||
| calls by suppressing overlapping inner corrections. |
There was a problem hiding this comment.
Only mention what's really important for users to know. Progression of a PR review is not ...
| } | ||
|
|
||
| @Suite | ||
| struct IndentationStyleTests { |
There was a problem hiding this comment.
Should be in this file.
| import Testing | ||
|
|
||
| @Suite(.rulesRegistered) | ||
| struct MultilineCallArgumentsRuleTests { |
There was a problem hiding this comment.
There are still a lot of test cases in here that could just be part of the examples' list.
| guard rule.shouldRun(onFile: file) else { | ||
| return nil | ||
| CurrentRule.$indentation.withValue(configuration.indentation) { | ||
| guard rule.shouldRun(onFile: file) else { |
There was a problem hiding this comment.
Does this need to be part of the withValue block already?
| } | ||
|
|
||
| /// Conformance to ``AcceptableByConfigurationElement`` for use in rule configurations. | ||
| extension IndentationStyle: AcceptableByConfigurationElement { |
|
|
||
| /// The global indentation style from the top-level configuration, made available to rules | ||
| /// without modifying function signatures throughout the codebase. | ||
| @TaskLocal public static var indentation: IndentationStyle? |
There was a problem hiding this comment.
Not sure about the usage of this yet. We should handle that separately anyway. It's not good to mix it into this PR.
There was a problem hiding this comment.
I wasn't entirely sure about separating this change into a separate PR. Thanks for confirming my concerns.
I'll create a separate PR with global values, and after merging, we'll return to the current one.
There was a problem hiding this comment.
@SimplyDanny
I'd be grateful if you could share your ideas about global configurations. Is there anything I should pay attention to? Should I try extracting all configurations or just the indentation?
|
|
||
| /// Configuration for the `multiline_call_arguments` rule. | ||
| /// | ||
| /// This configuration controls how function calls with multiple arguments should be formatted. |
Co-authored-by: Danny Mösch <danny.moesch@icloud.com>
I completely agree with you about speeding up work with AI without shifting. |
I appreciate you running such extensive tests. The implementation and coverage look decent indeed. However, "it works" is not all I have an eye on. Project fit, simplicity and avoidance of redundancy are of similar importance. There is also nothing against letting AI document things. But sometimes no comment is just the right amount, especially in obvious cases. 😉 Thank you for relentlessly fixing all my (nitpicky) comments and the ongoing contributions! |
Summary
Enhances the
multiline_call_argumentsopt-in rule with auto-correction, a newindentationconfiguration option, and multi-violation detection in a single pass.Auto-correction (
--fix))moves to its own line at the call's base indent\n+ indent in the appropriate range--fixpassindentationconfigurationindentation(integer ≥ 1 for spaces, or the string"tab"; default:4)0and negative values are invalid and cause a configuration errorMulti-violation support
duplicateArgumentStartLineViolationandnewlineAfterCommaViolationreturned at the first match, requiring repeated--fixpasses for calls with multiple same-line argument pairsreasonedViolationsreturns[ReasonedRuleViolation])Documentation
RuleDescription.descriptioninto concisedescription(what) + structuredrationale(why/how) with markdown sections