Skip to content

Add #examples and #examplesDictionary macros to DRY up rule description#6794

Open
ZevEisenberg wants to merge 1 commit into
realm:mainfrom
ZevEisenberg:examples-macro
Open

Add #examples and #examplesDictionary macros to DRY up rule description#6794
ZevEisenberg wants to merge 1 commit into
realm:mainfrom
ZevEisenberg:examples-macro

Conversation

@ZevEisenberg

@ZevEisenberg ZevEisenberg commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

When I wrote the Example type in #3040, it improved the experience of writing and debugging a rule (because test failures would point at precisely the example case that failed the test). But it came at the expense of a lot of repetitive Example("...") call sites.

Now that macros exist, I propose using them to keep the benefits of Example (that is, using file names and line numbers to surface test failures) while cleaning up the call sites. The new macros transform [String] and [String: String] to [Example] and [Example: Example], respectively.

If it's helpful for review, here's a Claude-generated script that confirms that the changes to the rule files are just adding the macro and removing the Example wrapper:
review_mechanical_changes.py

Alternatives/Questions

  1. If you like this format, would you want to add an internal regex lint rule to encourage using the macros in new rules? It's encouraged in the doc comment, but not required.
  2. Instead of individual macros for array and dictionary, I considered a macro that would replace the entire init of RuleDescription. But this seemed like an overreach, and would prevent falling back to passing variables or non-literals, which limits flexibility and experimentation.
  3. How do we feel about naming? I think we could consolidate both macros into a single overloaded one called #examples, but that seemed too cute and not clear enough at the point of use.

@SwiftLintBot

Copy link
Copy Markdown
1 Warning
⚠️ Big PR
19 Messages
📖 Building this branch resulted in the same binary size as when built on main.
📖 Linting Aerial with this PR took 0.64 s vs 0.65 s on main (1% faster).
📖 Linting Alamofire with this PR took 0.92 s vs 0.92 s on main (0% slower).
📖 Linting Brave with this PR took 5.99 s vs 5.94 s on main (0% slower).
📖 Linting DuckDuckGo with this PR took 25.99 s vs 26.01 s on main (0% faster).
📖 Linting Firefox with this PR took 10.28 s vs 10.3 s on main (0% faster).
📖 Linting Kickstarter with this PR took 7.26 s vs 7.33 s on main (0% faster).
📖 Linting Moya with this PR took 0.35 s vs 0.35 s on main (0% slower).
📖 Linting NetNewsWire with this PR took 2.32 s vs 2.32 s on main (0% slower).
📖 Linting Nimble with this PR took 0.53 s vs 0.55 s on main (3% faster).
📖 Linting PocketCasts with this PR took 6.82 s vs 6.83 s on main (0% faster).
📖 Linting Quick with this PR took 0.32 s vs 0.33 s on main (3% faster).
📖 Linting Realm with this PR took 2.39 s vs 2.42 s on main (1% faster).
📖 Linting Sourcery with this PR took 1.46 s vs 1.47 s on main (0% faster).
📖 Linting Swift with this PR took 4.21 s vs 4.21 s on main (0% slower).
📖 Linting SwiftLintPerformanceTests with this PR took 0.16 s vs 0.16 s on main (0% slower).
📖 Linting VLC with this PR took 1.1 s vs 1.07 s on main (2% slower).
📖 Linting Wire with this PR took 15.3 s vs 15.29 s on main (0% slower).
📖 Linting WordPress with this PR took 9.78 s vs 9.83 s on main (0% faster).

Generated by 🚫 Danger

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants