Skip to content

Commit 318a4f0

Browse files
committed
improve type safety, performance, and code sharing from swift review (#172)
1 parent 1665ea4 commit 318a4f0

12 files changed

Lines changed: 265 additions & 239 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
# oc9-otl
3+
title: 'Swift review: modernization, shared code, performance'
4+
status: completed
5+
type: task
6+
priority: normal
7+
created_at: 2026-04-11T02:42:35Z
8+
updated_at: 2026-04-11T02:42:35Z
9+
sync:
10+
github:
11+
issue_number: "172"
12+
synced_at: "2026-04-11T02:45:17Z"
13+
---
14+
15+
## Changes
16+
17+
- [x] Cache `CachedRegex.numberOfCaptureGroups` at init — avoids repeated `NSRegularExpression` allocation on every access
18+
- [x] Replace `SwiftLintConfigParser.ruleConfigs` from `nonisolated(unsafe) var [String: Any]` to `var [String: ConfigValue]` — removes `nonisolated(unsafe)` and `Any`
19+
- [x] Extract `DeclModifierListSyntax.accessibility` from fileprivate in MissingDocsRule to shared `SwiftSyntax+Declarations.swift`
20+
- [x] Extract OptionsTab inline Binding allocations to computed properties — avoids per-render closure re-creation
21+
- [x] Simplify `Array+Parallel.parallelMap` — replaced two `@unchecked Sendable` wrapper classes and `UnsafeMutableBufferPointer` manipulation with `Array(unsafeUninitializedCapacity:)` + `nonisolated(unsafe) let` bindings
22+
23+
## Summary of Changes
24+
25+
Five targeted improvements from swift review: one performance fix (cached regex capture groups), one type-safety fix (ConfigValue replacing Any), one shared code extraction (accessibility extension), one SwiftUI best practice (OptionsTab bindings), and one code simplification (parallel map). All 445 tests pass.

.jig.yaml

Lines changed: 70 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,75 @@
11
nope:
22
rules:
3-
- name: git-no-verify
4-
pattern: 'git\s+.*--no-verify'
5-
message: "--no-verify is never allowed - fix the issue that's failing the hook instead"
6-
# - name: git-checkout-switch
7-
# pattern: 'git\s+(checkout|switch|stash)'
8-
# message: "git checkout/switch not allowed - branch changes require user approval"
9-
- name: altering-jig
10-
pattern: 'jig.yaml'
11-
tools: ["Write", "Edit"]
12-
message: "cannot reconfigure jig directly - print desired config and user will edit"
13-
- name: bypassing-mcp
14-
pattern: 'swift (build|test)'
15-
message: "Use xc-mcp to build and test"
16-
- name: altering-project
17-
pattern: '\.(xcode|pbx)proj'
18-
tools: ["Write", "Edit"]
19-
message: "Project may only be modified using xc-mcp"
3+
- name: git-no-verify
4+
pattern: 'git\s+.*--no-verify'
5+
message: "--no-verify is never allowed - fix the issue that's failing the hook instead"
6+
# - name: git-checkout-switch
7+
# pattern: 'git\s+(checkout|switch|stash)'
8+
# message: "git checkout/switch not allowed - branch changes require user approval"
9+
- name: altering-jig
10+
pattern: 'jig.yaml'
11+
tools: [ "Write", "Edit" ]
12+
message: "cannot reconfigure jig directly - print desired config and user will edit"
13+
- name: bypassing-mcp
14+
pattern: 'swift (build|test)'
15+
message: "Use xc-mcp to build and test"
16+
- name: altering-project
17+
pattern: '\.(xcode|pbx)proj'
18+
tools: [ "Write", "Edit" ]
19+
message: "Project may only be modified using xc-mcp"
2020
companions:
21-
brew: toba/homebrew-tap
21+
brew: toba/homebrew-tap
2222
todo:
23-
path: .issues
24-
default_status: ready
25-
default_type: task
26-
sync:
27-
github:
28-
repo: toba/swiftiomatic
23+
path: .issues
24+
default_status: ready
25+
default_type: task
26+
sync:
27+
github:
28+
repo: toba/swiftiomatic
2929
citations:
30-
- repo: swiftlang/swift-syntax
31-
branch: main
32-
notes: A set of Swift libraries for parsing, inspecting, generating, and transforming Swift source code.
33-
paths:
34-
high: [Sources/**/*.swift]
35-
medium: [Package.swift]
36-
low: [.github/**, README.md, LICENSE]
37-
- repo: nicklockwood/SwiftFormat
38-
branch: main
39-
notes: A command-line tool and Xcode Extension for formatting Swift code
40-
paths:
41-
high: [Sources/**/*.swift]
42-
medium: [Package.swift]
43-
low: [.github/**, README.md, LICENSE]
44-
- repo: realm/SwiftLint
45-
branch: main
46-
notes: A tool to enforce Swift style and conventions.
47-
paths:
48-
high: ['**/*.swift']
49-
medium: [Package.swift]
50-
low: [.github/**, README.md, LICENSE]
51-
- repo: jpsim/SourceKitten
52-
branch: main
53-
notes: An adorable little framework and command line tool for interacting with SourceKit.
54-
paths:
55-
high: ['**/*.swift']
56-
medium: [Package.swift]
57-
low: [.github/**, README.md, LICENSE]
58-
- repo: swiftlang/swift-format
59-
branch: main
60-
notes: Formatting technology for Swift source code
61-
paths:
62-
high: [Sources/**/*.swift]
63-
medium: [Package.swift]
64-
low: [.github/**, README.md, LICENSE]
30+
- repo: swiftlang/swift-syntax
31+
branch: main
32+
notes: A set of Swift libraries for parsing, inspecting, generating, and transforming Swift source code.
33+
last_checked_sha: aacb56bc763b70e27d4f66d901365b45531f76bd
34+
last_checked_date: "2026-04-11T02:38:51Z"
35+
paths:
36+
high: [ Sources/**/*.swift ]
37+
medium: [ Package.swift ]
38+
low: [ .github/**, README.md, LICENSE ]
39+
- repo: nicklockwood/SwiftFormat
40+
branch: main
41+
notes: A command-line tool and Xcode Extension for formatting Swift code
42+
last_checked_sha: c8e50ff2cfc2eab46246c072a9ae25ab656c6ec3
43+
last_checked_date: "2026-04-11T02:38:51Z"
44+
paths:
45+
high: [ Sources/**/*.swift ]
46+
medium: [ Package.swift ]
47+
low: [ .github/**, README.md, LICENSE ]
48+
- repo: realm/SwiftLint
49+
branch: main
50+
notes: A tool to enforce Swift style and conventions.
51+
last_checked_sha: bd662b7009942bfa163c349c7e8a31e8aee33a70
52+
last_checked_date: "2026-04-11T02:38:51Z"
53+
paths:
54+
high: [ '**/*.swift' ]
55+
medium: [ Package.swift ]
56+
low: [ .github/**, README.md, LICENSE ]
57+
- repo: jpsim/SourceKitten
58+
branch: main
59+
notes: An adorable little framework and command line tool for interacting with SourceKit.
60+
last_checked_sha: 02d1db1084dde306a4f7fd7a85480d6a0f4831c4
61+
last_checked_date: "2026-04-11T02:38:51Z"
62+
paths:
63+
high: [ '**/*.swift' ]
64+
medium: [ Package.swift ]
65+
low: [ .github/**, README.md, LICENSE ]
66+
- repo: swiftlang/swift-format
67+
branch: main
68+
notes: Formatting technology for Swift source code
69+
last_checked_sha: 6ddbafa85bff26c7a99c9c86295bbb44ed1a5bfb
70+
last_checked_date: "2026-04-11T02:38:51Z"
71+
paths:
72+
high: [ Sources/**/*.swift ]
73+
medium: [ Package.swift ]
74+
low: [ .github/**, README.md, LICENSE ]
75+
changelog: weekly

.swiftiomatic.yaml

Lines changed: 78 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,82 +3,82 @@ rules:
33
unhandled_throwing_task:
44
severity: warning
55
disabled:
6-
- blanket_disable_command
7-
- closure_parameter_position
8-
- cyclomatic_complexity
9-
- file_length
10-
- function_body_length
11-
- function_parameter_count
12-
- identifier_name
13-
- inclusive_language
14-
- function_parameter_count
15-
- line_length
16-
- mark
17-
- multiple_closures_with_trailing_closure
18-
- nesting
19-
- opening_brace
20-
- shorthand_argument
21-
- opening_brace
22-
- switch_case_alignment
23-
- trailing_comma
24-
- trailing_whitespace
25-
- type_body_length
26-
- type_name
27-
- conditional_assignment
28-
- doc_comments
29-
- doc_comments_before_modifiers
30-
- extension_access_control
31-
- file_macro
32-
- header_file_name
6+
- blanket_disable_command
7+
- closure_parameter_position
8+
- cyclomatic_complexity
9+
- file_length
10+
- function_body_length
11+
- function_parameter_count
12+
- identifier_name
13+
- inclusive_language
14+
- function_parameter_count
15+
- line_length
16+
- mark
17+
- multiple_closures_with_trailing_closure
18+
- nesting
19+
- opening_brace
20+
- shorthand_argument
21+
- opening_brace
22+
- switch_case_alignment
23+
- trailing_comma
24+
- trailing_whitespace
25+
- type_body_length
26+
- type_name
27+
- conditional_assignment
28+
- doc_comments
29+
- doc_comments_before_modifiers
30+
- extension_access_control
31+
- file_macro
32+
- header_file_name
3333
enabled:
34-
- async_without_await
35-
- comma_inheritance
36-
- convenience_type
37-
- contains_over_filter_count
38-
- contains_over_filter_is_empty
39-
- first_where
40-
- contains_over_range_nil_comparison
41-
- discouraged_assert
42-
- direct_return
43-
- empty_collection_literal
44-
- empty_collection_literal
45-
- empty_string
46-
- empty_xctest_method
47-
- expiring_todo
48-
- fatal_error_message
49-
- file_name_no_space
50-
- first_where
51-
- flatmap_over_map_reduce
52-
- identical_operands
53-
- joined_default_parameter
54-
- last_where
55-
- legacy_multiple
56-
- legacy_objc_type
57-
- multiline_parameters
58-
- operator_usage_whitespace
59-
- optional_enum_case_matching
60-
- pattern_matching_keywords
61-
- period_spacing
62-
- prefer_key_path
63-
- prefer_self_type_over_type_of_self
64-
- prefer_zero_over_explicit_init
65-
- reduce_into
66-
- redundant_nil_coalescing
67-
- redundant_self
68-
- redundant_sendable
69-
- redundant_type_annotation
70-
- return_value_from_void_function
71-
- shorthand_optional_binding
72-
- sorted_first_last
73-
- toggle_bool
74-
- unavailable_function
75-
- unhandled_throwing_task
76-
- unneeded_escaping
77-
- unneeded_parentheses_in_closure_argument
78-
- unneeded_throws_rethrows
79-
- unused_declaration
80-
- unused_import
81-
- block_comments
82-
- prefer_final_classes
83-
- prefer_swift_testing
84-
- url_macro
34+
- async_without_await
35+
- comma_inheritance
36+
- convenience_type
37+
- contains_over_filter_count
38+
- contains_over_filter_is_empty
39+
- first_where
40+
- contains_over_range_nil_comparison
41+
- discouraged_assert
42+
- direct_return
43+
- empty_collection_literal
44+
- empty_collection_literal
45+
- empty_string
46+
- empty_xctest_method
47+
- expiring_todo
48+
- fatal_error_message
49+
- file_name_no_space
50+
- first_where
51+
- flatmap_over_map_reduce
52+
- identical_operands
53+
- joined_default_parameter
54+
- last_where
55+
- legacy_multiple
56+
- legacy_objc_type
57+
- multiline_parameters
58+
- operator_usage_whitespace
59+
- optional_enum_case_matching
60+
- pattern_matching_keywords
61+
- period_spacing
62+
- prefer_key_path
63+
- prefer_self_type_over_type_of_self
64+
- prefer_zero_over_explicit_init
65+
- reduce_into
66+
- redundant_nil_coalescing
67+
- redundant_self
68+
- redundant_sendable
69+
- redundant_type_annotation
70+
- return_value_from_void_function
71+
- shorthand_optional_binding
72+
- sorted_first_last
73+
- toggle_bool
74+
- unavailable_function
75+
- unhandled_throwing_task
76+
- unneeded_escaping
77+
- unneeded_parentheses_in_closure_argument
78+
- unneeded_throws_rethrows
79+
- unused_declaration
80+
- unused_import
81+
- block_comments
82+
- prefer_final_classes
83+
- prefer_swift_testing
84+
- url_macro

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Changelog
2+
3+
## Week of Apr 6 – Apr 12, 2026
4+
5+
### ✨ Features
6+
7+
- Inline suppression comments ([#166](https://github.com/toba/swiftiomatic/issues/166))
8+
- Config and inline comment migration tool ([#165](https://github.com/toba/swiftiomatic/issues/165))
9+
- Nested per-directory configuration ([#169](https://github.com/toba/swiftiomatic/issues/169))
10+
11+
### 🐛 Fixes
12+
13+
- Fix 7 test failures in Swiftiomatic test suite ([#126](https://github.com/toba/swiftiomatic/issues/126))
14+
15+
### 🗜️ Tweaks
16+
17+
- Setup brew installation within existing toba tap ([#171](https://github.com/toba/swiftiomatic/issues/171))
18+
- Build `assertLint`/`assertFormatting` test infrastructure ([#168](https://github.com/toba/swiftiomatic/issues/168))
19+
- Adopt Apple `swift-format` test patterns for comprehensive rule coverage ([#162](https://github.com/toba/swiftiomatic/issues/162))

0 commit comments

Comments
 (0)