Baseline: a same-count swap of duplicate-text violations within a rule is invisible
Nobody has claimed this yet.
- Dominant language
- Swift
- Stars
- 19.7k
- Forks
- 2.3k
- Avg merge
- 1d 1h
- Merged PRs (30d)
- 11
Description
Hi, an observation about the baseline filter (Source/SwiftLintCore/Models/Baseline.swift), not a bug report. It comes from a formal result on separation criteria I deposited recently.
A baseline entry is matched first by exact identity (rule, file, line, character, reason, and the source line's text), and any exact match is removed from both sides before anything else happens. What's left is grouped by rule, and within a rule, grouped again by a key that's just the source line's text plus the reason string, with no location in it. For each key, if the current count of violations sharing that key is greater than the baseline's count for that key, all of them get reported; if it's less than or equal, none do.
That second part means two violations of the same rule with the exact same text and the exact same reason, at different locations, are indistinguishable once they're grouped, because the key drops the location. I reimplemented the algorithm from source (a small script, not the real binary) and ran this: a baseline with two identical TODO violations at line 10 and line 20 (same text, same reason). Then I fix line 10 for real, and a genuinely new TODO with the identical text and reason shows up at line 30, unrelated to either original. The current violations, after removing exact matches, are just line 20 (unchanged) and line 30 (new). Grouped by key they're both in the same bucket as the one leftover baseline entry (line 10's, now unmatched), count 1 vs count 1, so nothing gets reported. The new line-30 violation disappears.
This needs duplicate text and duplicate reason to collide, so it won't happen for rules whose reason includes specifics (a value, a name), but it will for rules with a fixed, generic reason and short repeated lines. todo is the obvious one, and I'd guess mark, orphaned_doc_comment, and some of the pattern-matching rules on very short or common expressions have the same shape.
Would it make sense to include location, or at least something coarser like file, when deciding whether two same-key violations are the same reported instance, instead of relying on key count alone once the exact-identity pass has already run? I know that's basically re-adding what the initial exact-match pass already checks, but the count-only fallback for the collision case is what loses it.
Reference, if useful: Closure Trivialization in Typed Separation Systems, https://doi.org/10.5281/zenodo.21908527, section 10.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read Source/SwiftLintCore/Models/Baseline.swift, focusing on the exact-identity removal and the later rule and text/reason grouping. Reproduce the described line 10, line 20, and line 30 TODO scenario to confirm that the new violation disappears. Done means the collision case is distinguished without losing the baseline behavior for exact matches.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- swift
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100