Plugin Development with ReSharper SDK

Dear all

I’m an informatics student at the University of Zurich in Switzerland and I’m currently writing my bachelor’s thesis. The topic of my work is to write a Visual Studio 2010 plugin which should somehow do the following:

-          Aggregate all available methods of a project into a separate view/window (such that the developer can select some of these methods)

-          The selected methods then should be shown in a further tool window/view in a graphical representation

-          In addition to the selected methods, the tool window should also show the caller-methods and the callee-methods of these selected methods

-          (later on I will try to analyze different comit version of the method code bodies to show the differences)

-          (furthermore I will try to make those two views touch-based on a huge touchscreen, such that developers can analyze their project with their fingers)

As you can see this is a pretty complex task for a student like me. I read about the creation of normal VSPackages to extend Visual Studio 2010, but it seems that the API and the functionality is very limitted. I also found the ReSharper SDK which should make plugin development « enjoyable ». I invested several days trying to create a start with the aid of the SDK’s samples and the very limitted confluence guide (http://confluence.jetbrains.net/display/ReSharper/ReSharper+6+Plugin+Development).

As I’m kind of used to WPF I thought about writing the views with this. I didn’t understand the creation of the SDKs ToolWindows.

As I am no expert, do you have any tips for me how I could get started? Or at least what kind of extension or what features of the SDK I should use ? I see that the SDK is very mighty and cool, but I have difficulties handling all the undocumented APIs etc.

It would be very great if you could help me out anyhow :)

Best Regards and thank you very much in advance!

Christian

3 comments
Comment actions Permalink

Hi Christian. Sounds like an interesting project. ReSharper's PSI (Program Structure Index) is a form of Abstract Syntax Tree that should be able to provide all the information you need to get at all of the methods in the solution. As a plugin, you can get access to the PSI and walk the tree and collect whatever data you need.

If you want to display it in a ToolWindow, you need to follow the steps in the dev guide which explain what classes should be created.

While it might be a little overwhelming (it's doing quite a lot, including caching and lifetime management, that makes it a little less straightforward), it's worth taking a look at CodeStructureBrowser in dotPeek (open all dlls in the ReSharper\bin folder) and browsing around there. It's an example of something that owns a tool window (the file structure window), and listens to changes in the PSI to update a tree view of the structure of the current file. It uses the CodeStructureBrowserPanel as the UI control to display in the tool window.

Let me know what you've tried and where you've got stuck, and I'll see what I can do to help.

Thanks
Matt

0
Comment actions Permalink

Hi Matt

Thank you for your input, I really needed and appreciate your fast help! Decompiling and investigating the DLLs was actually a brilliant idea ;-) But know I have some follow up questions:

I explored the CodeStructureBrowser and some dependent files but I didnt get exactly, where the hierarchy is built up by Resharper. If I take a look at the "File Structure" view of R# which is the view of CodeStructureBrowser etc., I see pretty much everything I need: class name, fields, properties and most importantly its methods. The only problem I have now is that it shows those members only of a single class. I thought about implementing an own class that gets the Solution and then checks for its projects, the projects classes and finally the projects methods. But I don't know how to achieve that! I guess the Solution should be retrieved like the following:

public void Execute(IDataContext context, DelegateExecute nextExecute)     {       // Get solution from context in which action is executed       ISolution solution = context.GetData(ProjectModel.DataContext.DataConstants.SOLUTION);       if (solution == null)         return;

     // Here I want to investigate the Solution among its projects, classes, methods -> own nested model to create an own WPF UI

     }



I did the above code within Execute() of an action handler because I didn't knew how to get a DataContext otherwise ?:|

The questions that arise are the following:
- Is this the right way to start and is it possible to get projects, classes, methods from here (i.e. having the ISolution object)
- Is is possible, when finally having the methods that have been found by this way, to retrieve the relations between them? (i.e. to find the callers and the callees methods of a method)

I should further mention, that:
- I do not need any UI component, I guess. Since handling all the descriptors and tree representations etc. seems complicated to me and I later on should do something touch-based, I will just build an own model and then databind the filtered data in an own WPF window that can be docked within Visual Studio.

Thanks again for your support! I already got a better insight so far!
0
Comment actions Permalink

Hi Christian. If you are doing this in an action handler, then yes, retrieving the ISolution from the context like this is the right way. Various other components, such as the CodeStructureBrowser (which has the [SolutionComponent] attribute) are created by ReSharper's dependency injection container, and can have the ISolution injected into the constructor. You could also get the ISolution from a call to Shell.Instance.GetComponent<ISolution>(). See the page on the Component Model in the dev guide for more information.

Once you've got the ISolution, you can walk the whole solution structure by creating a class that inherits from RecursiveProjectVisitor, and passing it to ISolution.Accept(). This will walk the solution and all projects and files.

Getting the callers and callees is more complex, and more time-consuming. You will need to query for incoming and outgoing calls for each method and property you encounter (although presumably, if you're looking at the whole solution, then you could just get outgoing calls for everything, and work out the inverse relationships yourself).

I'm not entirely sure how to do this, but the best place to stat looking is with ReSharper's Analyse This -> Outgoing Calls and Incoming Calls action implementations - ShowOutgoingCallsAction and ShowIncomingCallsAction. These actions will find incoming and outgoing calls for the current method, and display them in a tool window, so they're doing too much, but if you follow the code down, you see that they're using CallTreeIncomingStrategy and CallTreeOutgoingStrategy, and in turn, those classes use the CallHierarchyFinder, and these classes might be the place to start looking.

Hope this helps
Matt

0

Please sign in to leave a comment.