-
Notifications
You must be signed in to change notification settings - Fork 246
[codex] Fix generated asset catalog symbol detection #98
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -136,6 +136,49 @@ struct SearchRuleTests { | |
| #expect(result.isEmpty) | ||
| } | ||
|
|
||
| @Test("Swift member access rule applies to nested asset catalog symbols") | ||
| func swiftMemberAccessRuleAppliesToNestedAssetCatalogSymbols() { | ||
| let searcher = SwiftMemberAccessSearchRule() | ||
| let content = """ | ||
| let image = Image(.Icons.Settings.logo) | ||
| let resource = ImageResource.Symbols.plug | ||
| let direct = Image(ImageResource.emptyIcon) | ||
| """ | ||
| let result = searcher.search(in: content) | ||
| let expected: Set<String> = [ | ||
| ".Icons.Settings.logo", | ||
| ".Symbols.plug", | ||
| ".emptyIcon", | ||
| ] | ||
| #expect(result == expected) | ||
| } | ||
|
Comment on lines
+139
to
+154
|
||
|
|
||
| @Test("Swift member access rule applies to nested symbols via type inference") | ||
| func swiftMemberAccessRuleAppliesToNestedSymbolsViaTypeInference() { | ||
| let searcher = SwiftMemberAccessSearchRule() | ||
| let content = """ | ||
| let r: ImageResource = .Icons.Settings.logo | ||
| let img = UIImage(resource: .Symbols.plug) | ||
| let view = ContentView(image: .Icons.Settings.logo, fallback: .emptyIcon) | ||
| """ | ||
| let result = searcher.search(in: content) | ||
| #expect(result.contains(".Icons.Settings.logo")) | ||
| #expect(result.contains(".Symbols.plug")) | ||
| #expect(result.contains(".emptyIcon")) | ||
| } | ||
|
|
||
| @Test("Swift member access rule ignores custom type prefixes that only end with asset type names") | ||
| func swiftMemberAccessRuleIgnoresCustomTypePrefixesThatOnlyEndWithAssetTypeNames() { | ||
| let searcher = SwiftMemberAccessSearchRule() | ||
| let content = """ | ||
| let a = SomeImageResource.icon | ||
| let b = FooImage.value | ||
| let c = CustomNSImage.tintColor | ||
| """ | ||
| let result = searcher.search(in: content) | ||
| #expect(result.isEmpty) | ||
| } | ||
|
|
||
| @Test("Objective-C member access rule applies to generated symbols") | ||
| func objcMemberAccessRuleAppliesToGeneratedSymbols() { | ||
| let searcher = ObjCMemberAccessSearchRule() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| { | ||
| "info" : { | ||
| "author" : "xcode", | ||
| "version" : 1 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "images" : [ | ||
| { | ||
| "filename" : "logo.png", | ||
| "idiom" : "universal" | ||
| } | ||
| ], | ||
| "info" : { | ||
| "author" : "xcode", | ||
| "version" : 1 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "images" : [ | ||
| { | ||
| "filename" : "plug.png", | ||
| "idiom" : "universal" | ||
| } | ||
| ], | ||
| "info" : { | ||
| "author" : "xcode", | ||
| "version" : 1 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "images" : [ | ||
| { | ||
| "filename" : "empty.icon.png", | ||
| "idiom" : "universal" | ||
| } | ||
| ], | ||
| "info" : { | ||
| "author" : "xcode", | ||
| "version" : 1 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| { | ||
| "images" : [ | ||
| { | ||
| "filename" : "unused.png", | ||
| "idiom" : "universal" | ||
| } | ||
| ], | ||
| "info" : { | ||
| "author" : "xcode", | ||
| "version" : 1 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| import SwiftUI | ||
|
|
||
| struct SampleView: View { | ||
| var body: some View { | ||
| VStack { | ||
| Image(.Icons.Settings.logo) | ||
| Image(ImageResource.emptyIcon) | ||
| Image(ImageResource.Symbols.plug) | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SwiftMemberAccessSearchRule currently extracts full nested symbols only for
Type( .a.b.c )andImageResource.a.b.c. If nested symbols are used directly via type inference (e.g.let r: ImageResource = .Icons.Settings.logoor passed asresource: .Icons.Settings.logo), the fallback regex will only capture the first component (.Icons) and miss the full chain, which can cause used assets to be reported as unused. Consider adding a dedicated pattern that captures dot-prefixed chains (e.g..A.B.c) regardless of surrounding call syntax, while keeping the negative-lookbehind to avoid regular property access.