jpsim/SourceKitten

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.

  1. 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.