Seeking help from someone who knows rustc internals well.
I'm trying to analyze my codebase to build a (huge!) directed graph of references between all Items in all crates. Any time a type or function references another type or function in any way, I want to see an arrow between the two in my graph. For instance, if a
struct A contains a
Box<Fn(B) -> C>, then I want to see arrows in my graph from A to B and C. If a function calls another function in its body, then I want to see an arrow between those two functions, and if a function F contains some type D in its signature, then I want to see an arrow between F and D. You get the idea.
And I want this to happen across all crates, so that whether I have all my code in one crate, or have it split up into 10 or 100 crates, I would get the same graph.
The reason I want this is to assist in reorganizing a huge project into crates. I figure I can do queries and modifications on this graph to understand the implications of moving a particular item from one crate to another, and to get a sense of which items belong together and where the natural lines of separation are.
I've gotten pretty close to a promising solution, using
rustc_interface to run a compiler and walk the HIR, visiting every item in the codebase. The thing I'm not clear on is what identifier I should be using to ensure that items are registered the same way across different crates. I think what I want is
DefId. I'm not sure how to get my hands on
DefId for items though. I am able to get the
HirId of every item, but I don't know how to get to a
DefId from there. I know I can get the
DefId of the owner of any item via
item.hir_id().owner.def_id, but not the DefId of the item itself...
So, first of all I'm wondering if my approach seems good for the problem I'm solving. If not, please suggest something else! If so, I'm wondering if DefId is indeed what I want, and if so, how I can get at it.