Sometimes you really want to cut through a code-base to discover all the functions that can get called in response to a specific function being invoked, with all the other code removed from the picture.
Or you might be coming at it bottom up – when you change a particular function, what is the subset of the code-base that can be affected? Or you might even want to ask the question from both ends – what are all the code items that could get called (or impacted) between 2 specific functions?
Here are the steps to get you that diagram.
- Download and install the free trial of Structure101 Studio.
- Start Structure101 Studio, file/new, and enter the minimal set of information. Mostly you are just pointing the wizard at your byte-code. Just make sure you set the “granularity” option to be “detailed”. When you have created the project you will see something like this (this is a Maven project (actually THE Maven code-base as it happens), the apples are POM’s):
This is an LSM of your code-base, where as far as possible dependencies flow downward.
- Assume you want a call tree starting at a function called getDownstreamProjects in a class called DefaultProjectDependencyGraph in the maven-core project. Drill down to this function by double-clicking on the relevant parent items:
- Right click on the starting function, tag, used by selected, indirectly
- This causes a subset of the model to be tagged with a blue dot. You can now filter the model so that only the tagged items are included by using the “filter in (isolate) tagged items” button on then main toolbar:
Which gives you something like this:
Which is a heavily filtered LSM model – notice there are now just 3 POM’s left, and if you drill into these, each contains just a subset of the packages and classes that are actually in the code.
- Now untag everything (just for tidiness really) using the relevant button on the main toolbar:
- Select the class slice from the LSM window toolbar:
This removes all the POM’s, Jars, and packages from the LSM, leaving just classes. If you expand each class (by double-clicking) you end up with something like this:
Remember that you are only seeing code that is in the dependency closure of getDownstreamProjects, so for instance there are methods and fields inside those classes that are not shown. The 2 interfaces and 1 class are not expanded because they contain no child items – that is they contain no methods or fields that are indirectly used by getDownstreamProjects – and so are not expandable.
- You use the same principle to work upwards, to filter on items that may be impacted by a specific item. For example if you want to show only paths that start at getDownstreamProjects (the current filter) and end at Parent::groupId, then select groupId, tag/uses selected/indirectly, filter in tagged items, which gives this further reduced LSM:
- You can add back some structural context by selecting the “leaf package” slice (same menu as the “outer class slice” earlier on):
Or switch off slicing altogether to show the complete paths of the subset of items: