Get the type name from USR
alex-swiftify opened this issue · 4 comments
I'm parsing the Xcode documentation database to obtain some information, e.g. Objective-C to Swift method mappings.
I know the approach looks weird but we couldn't get all the needed information using SourceKit.
Each documentation entry, i.e. for a method declaration, contains an USR stored in the "externalId" field (example).
Is it possible to obtain the type name (i.e. UITableViewDataSource
) from the USR ("c:objc(pl)UITableViewDataSource(im)tableView:cellForRowAtIndexPath:"
), without having the source file (since we don't have the source files for built-in Apple frameworks)?
I tried parsing the USR string manually, but sometimes the USR string looks too cryptic, i.e. s:9CareKitUI16OCKLogItemButtonC5coderACSgSo7NSCoderC_tcfc
where the type name is "OCKLogItemButton".
Is there a way to get the type name using SourceKitten?
I've already tried the cursorInfoUSR
request, but it returns "Lookup for C/C++/ObjC USRs not implemented." in the JSON output.
For ObjC usrs (c:objc(pl) prefix) I've parsed them manually, the format seems very simple.
For Swift USRs I've found the easiest way is to use swift demangle
:
; swift demangle -simplified -compact s9CareKitUI16OCKLogItemButtonC5coderACSgSo7NSCoderC_tcfc
OCKLogItemButton.init(coder:)
;
Note the /^s:/s/
. Lots of options under swift demangle -h
to destructure the output.
SourceKit does have a source.request.demangle
(source) but it's a lot less flexible than the CLI.
@johnfairh Thanks, that seems really useful!
Although I am still missing a bit of the information I need.
1) For cases like this one (a global function definition):
swift demangle -simplified -compact s6XCTest24XCTAssertLessThanOrEqual___4file4lineyxyKXK_xyKXKSSyXKs12StaticStringVSutSLRzlF
Is there any way to retrieve the framework name (XCTest
) without manually parsing the string?
Update: Figured it out - removing "--simplified" allows to include the framework name.
- Some Obj-C (or plain C?) USR's still look quite cryptic:
- "c:@sa@NSMapTableKeyCallBacks@FI@notAKeyMarker"
- "c:@s@ATSUCaret@FI@fX"
- "c:@f@GLKQuaternionSlerp"
- "c:@ea@kCTRunDelegateVersion1"
- "c:@NSURLUbiquitousItemDownloadingStatusKey"
I've tried manually parsing these but that looks way too hacky. Any other suggestions?
Swift - see --expand
too if you haven't already, may be easier to parse.
C - (plain C ObjC subset I think) - nothing more to suggest beyond finding the code that generates them and reverse engineering or an existing utility that does that. I think it's clang:lib/Index/USRGeneration.cpp
.
@johnfairh Many thanks!
Really useful, and I was a bit stuck with this.
Will dig further in the sources.