29

In Visual Studio, with or without an extension, is there a way to automatically sort private methods inside a class based on the order of their usage (their location in the call stack)?

For example consider the following class:

public class MyClass
{
    public void MyMethod()
    {
        TestC();
    }

    private void TestA()
    {
        TestB();
    }

    private void TestB()
    {
        Console.WriteLine("Hello");
    }

    private void TestC()
    {
        TestA();
    }
}

The public method in this class is MyMethod, it calls TestC which calls TestA which calls TestB. I would like to (automatically) order these methods by this order so that the class looks like this:

public class MyClass
{
    public void MyMethod()
    {
        TestC();
    }

    private void TestC()
    {
        TestA();
    }

    private void TestA()
    {
        TestB();
    }

    private void TestB()
    {
        Console.WriteLine("Hello");
    }
}

I need to be able to select a class, request such method sorting, and have the methods sorted automatically. I.e., I don't want to manually sort these methods.

I understand that there are some nuances. For example, there could be a private method that is called from two methods which are at two different levels in the call stack. I guess in this case it makes sense to consider the smallest (call stack) distance from the public method.

UPDATE:

This idea of sorting the methods in this way comes from the Clean Code book by Robert C. Martin. In chapter 3, the Stepdown rule is defined which talks about having the higher level functions appear before the low level functions.

Doing a quick search for stepdown rule on google, I found a netbeans plugin at: http://plugins.netbeans.org/plugin/58863/stepdownruleplugin

I would guess that it does something similar to what I need, but for netbeans.

Yacoub Massad
  • 27,509
  • 2
  • 36
  • 62
  • Resharper claims to be able to sort methods in various ways. –  Oct 29 '16 at 21:21
  • @RawN, I tried to find a way to do this via Resharper but I couldn't find any. – Yacoub Massad Oct 29 '16 at 21:22
  • I doubt you'll find this out-of-the-box. You can certainly code it using roslyn (https://github.com/dotnet/roslyn) which can parse the code, determine calling hierarchy, etc. – Simon Mourier Nov 02 '16 at 12:24
  • @SimonMourier, I am hoping that someone has done that already. – Yacoub Massad Nov 02 '16 at 12:34
  • @YacoubMassad May I ask why you want to do this? Just curious – CodingYoshi Nov 05 '16 at 19:29
  • @CodingYoshi, see the update on the question. Mainly, I would like to see higher level methods first, and then lower level methods. This makes it easy to read a class from top to bottom. – Yacoub Massad Nov 05 '16 at 21:48
  • @CodingYoshi, mainly I want to use this feature for [Composition Roots](http://blog.ploeh.dk/2011/07/28/CompositionRoot/) that are created using [Pure DI](http://blog.ploeh.dk/2014/06/10/pure-di/). See [this article](http://www.dotnetcurry.com/patterns-practices/1285/clean-composition-roots-dependency-injection) for more details. Such classes would contain a lot of methods that create the application components. – Yacoub Massad Nov 05 '16 at 21:57
  • I think most people use the naming convention, if the hierarchy is simple enough. Automating what you want would need info about context that isn't in the code, how would you want sibling methods/methods with multiple parents ranked? The reason it's not there is it's not simple. – Beth Nov 07 '16 at 13:51
  • @Beth, if for example you can get to a method via 2 or 4 steps from the root public methods, you can consider this method to be at level two (the shortest). Note that this way of sorting methods is not new, take a look at the Stepdown rule. – Yacoub Massad Nov 07 '16 at 15:34

5 Answers5

11

The ReSharper Plugin "Greenkeeper" does the job:

https://bitbucket.org/denniskniep/greenkeeper

The plugin can sort the methods in "newspapermode": Important code first and details at the bottom. The newspapermode has the same behaviour as the "Stepdown rule".

https://bitbucket.org/denniskniep/greenkeeper/wiki/SortingDeclarations

Dennis K
  • 477
  • 1
  • 3
  • 12
  • 1
    This is exactly what I was looking for. Thanks. This plugin works with Resharper 8.2, I have tested it. I am going to try to make it work with later versions of Resharper. – Yacoub Massad Nov 08 '16 at 11:42
  • Doesn't appear in the list for Resharper 2017 :( – willem Aug 31 '17 at 10:19
  • Shouldn't be necessary with a plug-in for R#2017. It is built into R#. Check the accepted answer here: https://stackoverflow.com/questions/1509244/resharper-clean-up-code-how-to-affect-sorting-of-methods (haven't tried it myself though...) – Thomas Sep 01 '17 at 10:37
9

I don't know whether it's possible to do this natively within Visual Studio. However, I think that the best method would be to use ReSharper (a Visual Studio extension) to do this.

It provides at least two options that comes to mind:

1) Using the File and Type Layout preferences with patterns,

2) Using the File Structure window (this might be the quickest way if the class you want to reorder doesn't have too many methods). You can check it out here.

Hope that helps.

Brian
  • 109
  • 4
  • 2
    I really can't understand your answer. You say that you don't know of an extension that does this but then you provide some options. What are these options for? – Yacoub Massad Oct 29 '16 at 21:34
  • Sorry about the confusion. The options I'm referring to are provided by ReSharper, a Visual Studio extension. I've provided the links for each different option that would allow you to easily change the order of the methods within your file. One of those options, which uses the File Structure window, shows you the structure of your file by member variables, properties and methods. From there, you can use your mouse to drag and drop them in any order you want, and you'll see the methods in the new order within the file. – Brian Oct 30 '16 at 01:55
  • I would like to have these methods sorted automatically as a refactoring option (on demand of course), not manually. – Yacoub Massad Oct 31 '16 at 14:11
9

Here are the other products that no one has referenced that could add the functionality with a friendly request:

Its not that hard to write this yourself. The new Visual Studio VSIX Project templates are available in the VS2015 setup, if you cant find them under (File > New > Project.. Visual C# > Extensibility) just Modify the Install (cmd > appwiz.cpl > VS2015 Change/Modify).

The great news is that the CodeMaid project is open source and contains most of the code & logic you will need to reorder chunks of code.

The other thing you will need is the Call Stack and one of our helpful fellow Stackoverflow'rs has provided the code for that here: How to get stack trace of a running process from within a Visual Studio add-in?

Given this is a bounty you were probably expecting a full solution, sorry I dont have time to code it up for you right now but am happy to give you a hand if you run into any issues. Let me know in the comments.

To get up and running quickly I'd personally just copy the code in this Visual Studio extension and replace the guts with Re-Ordering by Call Stack: Debug Single Thread.

Community
  • 1
  • 1
Jeremy Thompson
  • 61,933
  • 36
  • 195
  • 321
  • Thanks. So it seems that there is no existing solution, and that I have to create one my self, or build on similar tools. – Yacoub Massad Nov 07 '16 at 15:36
  • Yes, or you could put in a feature request to one of the authors of the tools I mentioned. You know what do though when I want to see the code in call order, I just use Debug/Code Canvas or Bubble Debugging, here's a comparison https://blogs.msdn.microsoft.com/kaelr/2012/03/10/code-canvas-vs-code-bubbles-vs-debugger-canvas/ try it out, it could be even better for you than having to reorder code because often there are many different branches/paths/reuse that one order won't be always right. – Jeremy Thompson Nov 08 '16 at 01:34
3

if you want to trigger that logic manually and you use vs 2015, you can create a visual studio CodeFix that will use Roslyn. see: Build CodeFix ex

The steps that you should do are:

  1. Create CodeFix project
  2. The logic of the CodeFix, using Roslyn, will analyze all the methods in the document and create a dependency graph between the methods. Than it will change the order and rewrite the code to the document
  3. Install the CodeFix, as an analyzer, and use it for every visual studio document you want
Eli Dagan
  • 808
  • 8
  • 14
  • Although this would work, the question asks for an existing solution (if any). I was hoping that one of the productivity tools for visual studio has this feature already. – Yacoub Massad Nov 03 '16 at 19:47
1

Short answer is NO See the reason is simply because majority of developers try to write code that is easily readable. If I need to make an update to TestB and looking at the code I would expect TestB to be defined after TestA and before TestC. Then you also take into account defined fields for the class and the use of get/set methods for setting and getting the value of a defined field.

The code below shows 2 classes. The first class is in the layout that I personally use for readability should another developer need to update the code they aren't wasting time hunting down through the code. The second class follows the way you are wanting them to be re-arranged.

            public class MyClass
            {
                private string _HelloWorld;
                public string HelloWorld
                {
                    get {return _HelloWorld;}
                    set {_HelloWorld = value;}
                }

                public void MyMethod
                {
                    TestC();
                }

                public void TestA()
                {
                    TestB();
                }

                public void TestB()
                {
                    Console.WriteLine(HelloWorld);
                }

                public void TestC()
                {
                    TestA();
                }

            }

            public class MyClass2
            {
                private string _HelloWorld;

                public void MyMethod
                {
                    TestC();
                }

                public void TestC()
                {
                    TestA();
                }

                public void TestA()
                {
                    TestB();
                }

                public void TestB()
                {
                    Console.WriteLine(HelloWorld);
                }

                public string HelloWorld
                {
                    get {return _HelloWorld;}
                    set {_HelloWorld = value;}
                }
            }
  • 1
    There are some readability benefits from having the methods sorted the way I want. Mainly, you first understand the high level methods, and then you move down to see the lower level methods, etc.. – Yacoub Massad Nov 05 '16 at 21:47
  • That's a valid point. It all depends on the team you are working with. – Chase Woofer Nov 06 '16 at 03:30