Posts Tagged ‘ReSharper 5’

ReSharper 5.1.3: Visual Studio IntelliSense bug fix release

Tuesday, February 1st, 2011

Do you have ReSharper 5.1.2 installed?

Are you using native Visual Studio IntelliSense?

Are you annoyed by ReSharper turning off Parameter Information and auto-completion when you open new files?

If your answer is “yes, yes and oh yes”, please download ReSharper 5.1.3.

ReSharper 5.1.3 provides exactly one bug fix that prevents disabling Parameter Information and auto-completion when you’re using native Visual Studio IntelliSense (as opposed to ReSharper IntelliSense).

Please note that if you’re been using ReSharper IntelliSense as a workaround in 5.1.2, as soon as you switch back to Visual Studio IntelliSense, you’ll have to initially set Auto-list members and Parameter information check boxes manually, but that is only required once.

If you’re using ReSharper IntelliSense and/or if you haven’t previously upgraded to 5.1.2, you can skip the upgrade to 5.1.3.

ReSharper 5.1.2 is Released

Thursday, January 13th, 2011

ReSharper 5.1.2 bugfix campaign is finally over! Please download ReSharper 5.1.2 release build (5.1.1766.4) from the official ReSharper web site. It should work well with ASP.NET MVC 3 RTM that Microsoft is releasing today.

Here’s a quick overview of fixes and improvements introduced since version 5.1.1:

  • ReSharper 5.1.2 doesn’t interfere with Visual Studio IntelliSense in ASP.NET MVC 3 Razor syntax. Earlier ReSharper 5.x builds had certain issues with Razor IntelliSense that are addressed in 5.1.2. Specifically, ReSharper 5.1.2 doesn’t prevent Visual Studio from automatically providing its own IntelliSense in .cshtml and .vbhtml web pages anymore: both code completion and Parameter Info work as expected. Other than that, ReSharper 5.x doesn’t provide any additional support for Razor: only ReSharper 6 will bring full support for this view engine. Pre-release ReSharper 6 builds are currently available via Early Access Program.
  • Improved IntelliSense in Watch tool windows. The Razor IntelliSense fix has a side effect: ReSharper doesn’t anymore block Visual Studio IntelliSense from automatically popping up after dot in Watch tool windows used during debugging. This fix doesn’t yet apply to the QuickWatch dialog box though.
  • Live templates can now be saved one by one. Prior 5.x releases were able to save all live templates at once but, weirdly, weren’t saving them on Ctrl+S. Now you can save them one by one safely. Besides, saving templates doesn’t deselect them in the Template Explorer anymore (RSRP-90569).
  • Support for Test Projects (MSTest) re-targeted to .NET Framework 3.5. We have already blogged about this particular improvement.
  • A backport from ReSharper 6 allows faster processing of large files (10,000 LOC or more.)
  • ReSharper PowerToys should no longer throw exceptions that they used to throw with 5.1.1.
  • External Sources now reads PDB files in a better way.
  • Bug fixes related to referencing CoreCLR assemblies from Silverlight projects, comments in VB.NET, BizTalk projects, shortcut persistence, and references to SharpSVN.

This is a recommended upgrade, so don’t forget to download ReSharper 5.1.2 and give it a go.

ReSharper 5 Overview: Navigation to and Within External Sources

Monday, October 4th, 2010

While you’re waiting for the first public build of the recently announced ReSharper 6, here’s a follow-up on the “Introducing ReSharper 5″ blog post series that we did earlier this year. One feature that we have not highlighted before but that’s a major presence in ReSharper 5 is navigation to and within external sources.

When you want to know how a certain method is implemented, with ReSharper you expect to be able to quickly navigate to the declaration of an identifier. In most cases you can do this perfectly well. However, things get tricky in the following two scenarios:

  1. The method you’d like to zoom in on is part of the .NET Framework.
  2. Your really huge project is broken down into several subprojects. You’re working in one of them but the class or method that you want to navigate to is declared in another subproject.

ReSharper 5 covers both scenarios with a fresh feature called “External Sources”. External Sources makes all sources available to a developer even if they should be accessed remotely. This is the first step to eliminating differences between your local working copy and actual sources of all components involved in your project.

Let’s take a look at standard use cases when you need access to sources not included in the current project.

.NET Framework Sources

Microsoft provides free access (with certain licensing restrictions) to source code of the entire Microsoft .NET Framework. Within plain Visual Studio, you generally access it during debugging sessions. ReSharper complements this use case with the following extended functionality:

  1. Navigation to.NET Framework sources.
  2. Find Usages over all .NET Framework public symbols.

This enables you to easily and transparently access sources of complex .NET Framework classes such as DataGrid.

Your Company’s Library Sources

When working on a big project, a developer usually either doesn’t have the entire sources on their local machine, or they do have them but not in the current project.

In the latter case, if the sources are available but not included in the current project, ReSharper allows you to specify the path to these sources. So, when you try to navigate to an external symbol, ReSharper will search the local (or network) drive for the appropriate file and open it. The only requirement is having .pdb files available for external components.

In the former case, if the sources are way too numerous (or if it is simply impractical to store them all locally, i.e. if they are used infrequently or if there are just too many versions), you can use the Microsoft Source Server. There’s a good chance that it’s already installed in your place of work. ReSharper provides full support for the Microsoft Source Server and relies on it to implement navigation to the source of the .NET Framework. All you need to do is specify the path to the local server(s) in Visual Studio (Tools | Options | Debugging | Symbols).

Reflector Plugin

Now, what do you do if you don’t have .pdb’s, or even no sources at all? Or if you can’t set up Source Server?

For many developers the answer is Reflector. But as you probably know, it is rather cumbersome to use: first you find the right .dll, then you look inside it for the symbol you need. ReSharper PowerToys include a plugin that lets you to connect Reflector with Visual Studio. On the outside it will look like you’re navigating to the source, only Reflector will be used ‘behind the curtains’ to retrieve them.

You might ask, in what way is Reflector integration with Visual Studio inferior to that of ReSharper? We at ReSharper wanted to make the integration seamless, and that’s exactly what our plugin does. You no longer have to think about where a particular symbol is declared - ReSharper finds it for you, wherever it is. First it looks for it on your local drive, then it polls the Source Server, and if that fails, finally it decompiles the sources you need via Reflector.

About Options

If you open ReSharper Options and select External Sources, you will see a list of configured source providers. Use this dialog window to define the order in which these providers will be polled. For some providers you can define additional options, e.g. set C# or VB as the presentation language, show XML-doc or not, etc.

The first time you try to navigate to an external source, ReSharper will ask you which provider to use by default:

External Sources

If you’re not happy with the current provider or the default provider, you can always click on a symbol to bring up the Navigate To menu (ReSharper | Navigate | Navigate To…) and switch the view:

Navigate To

The Way Forward for External Sources

In Internal mode, you can already see the feature called “Find Usages In Compiled Code”. This works like Find Usages which lets you search for symbols used in builds already compiled. This tool is indispensable for situations such as when you’re developing a system core and you must know exactly where and how your public API methods are used.

Another area JetBrains will focus on in growing this functionality is integration with TeamCity — one of today’s most powerful Continious Integration products. Oftentimes, different development teams work on different parts of a system, and synchronizing all their source versions and compiled libraries becomes a real challenge. Enter TeamCity: it knows at all times which source version corresponds to each local library version. Why maintain a huge codebase locally, when you can rely on TeamCity to be your company’s internal Source Server — with no extra configuration required?

Author: Alexander Zverev, senior ReSharper developer

Sample SSR Pattern Catalog Available for Download

Wednesday, June 2nd, 2010

A while ago we introduced Structural Search and Replace, a new powerful feature in ReSharper 5 that lets you search for custom code patterns and replace them with other patterns, facilitating batch removal (or improvement) of stinky code.

We were hoping to include a set of ready-to-use search and replace patterns into ReSharper 5.0 release but it just didn’t happen. Instead, we’re publishing a sample Pattern Catalog on the web site for you to download.

The sample Pattern Catalog currently contains 17 patterns to search for and replace unreachable code, redundant compound assignments, clumsy method chains, and other pieces of code that you’d better get rid of.

As soon as you’ve downloaded and unzipped the Pattern Catalog, do the following to import it:

  1. In Visual Studio, choose ReSharper | Tools | Pattern Catalog.
  2. Click Import and select the XML file that contains the sample Pattern Catalog.

ReSharper 5.0: Known Issues, Workarounds, and Bugfix Schedule

Tuesday, May 4th, 2010

Hello everyone! Hope you’re having a good time using the new ReSharper 5.0. If you do, just ignore this post :)

If you’re facing issues with ReSharper 5.0, read on. There are certain bugs, usability problems and otherwise weird behavior that users report following the release (surprise!). Some of them you can work around, others you can’t, but both kinds of issues will be addressed in the upcoming ReSharper 5.1. It’s scheduled for release in June but we’ll open the Early Access Program in May, and chances are that the most annoying issues will be fixed in these early builds.

Here are some of the most annoying issues that have known workarounds:

  • RSRP-178681: aspx pages lose references to their code-behind files. A lot of people complained that when saving an aspx page with a code-behind file, the reference to the code behind file gets lost and lots of errors start to pop up.

    Workaround: Go back to the aspx page and save it again (without changing anything): the reference restores and both files display and work correctly.
  • RSRP-178492: Adding Cyrillic comments and creating new custom controls in WPF applications sometimes changes file encoding from UTF-8 to Win-1251.

    Workaround: The only way to change this behavior is to manually roll file encoding back to UTF-8 by choosing File | Advanced Save Options in Visual Studio.
  • Another problem reported in RSRP-178492 is that during refactorings, ReSharper changes the locale of XAML files based on your Windows locale. That only happens if you don’t select the “To enable Undo, open all files with changes for editing” check box in a refactoring dialog box.

    Workaround: Make sure to select the “To enable Undo, open all files with changes for editing” check box.
  • UPDATE! Thanks to Frans Bouma for reminding about the other annoying issue, NP-20: Splitting a Visual Studio text editor tab makes ReSharper marker bar and possibly other features go away in one or both parts of this particular tab.

    Workaround: Rejoin the editor tab, close it, then reopen.
  • UPDATE 2! Visual Studio 2010 crashes during file save and build operations.

    Workaround: ReSharper may cause this problem but there’s a known common cause of this behavior: a certain version of AnkhSvn. If you have both ReSharper and AnkhSvn installed, try following Microsoft guidelines on updating your AnkhSvn build. Builds 2.1.8420 and higher are reported to fix the intermittent Visual Studio crash problem.
  • UPDATE 3a! RSRP-147892: Calling GetTempFileName() in Windows 7 or in Windows Server 2008 R2 causes UnauthorizedAccessException

    Workaround: This is not a ReSharper problem. Microsoft has confirmed that this issue occurs because the GetTempFileName() function in Windows 7 and Windows Server 2008 R2 handles a duplicated file name incorrectly. Download this Microsoft hot fix to remove the issue.
  • UPDATE 3b! Even small cut-and-paste operations raise “insufficient memory” errors in Visual Studio 2010.

    Workaround: Again, this is not a ReSharper issue. Microsoft has released a patch for Visual Studio 2010 that removes this issue. For details on its symptoms and other implications, read this Visual Studio blog post.

We also receive reports about performance issues when renaming and doing Find Usages in large projects that contain aspx files. We are doing performance analysis and aiming to solve these issues in time for the bug fix release.

Just in case you’re interested, here’s the full list of issues currently scheduled for ReSharper 5.1.

On a different note, people report on a regular basis about Visual Studio 2005 or 2008 installations that freeze or crash after opening web forms, or Solution Explorer that hangs up. There are known solutions to this kind of issues (not having anything to do with ReSharper), including:

Before you contact us with such issues suspecting ReSharper, please make sure to try the solutions provided above.

By the way, if you’re using Visual Studio 2010, have you installed Windows Automation API? Rumors say it really boosts Visual Studio performance, particularly with ReSharper.

ReSharper 5.0 Is Out!

Tuesday, April 13th, 2010

ReSharper 5.0 is finally here, and you can download it right now!

We’ve blogged for a while now about the great new stuff in ReSharper 5.0 (and we’ll continue blogging about it), but here’s a short recap:

  • Web Development: You get an extensive toolset for ASP.NET development to work with markup files and web site infrastructure. ASP.NET MVC developers get a bonus with additional syntax highlighting, inspections, navigation, and completion for actions and controllers.
  • Project and Team: Powerful, shareable structural search and replace patterns to remove code smells or comply with team policies; project-level refactorings; localization assistance; and full support for navigation to library sources — all this to help you and your team easily view, change and maintain the structure of complex projects.
  • Code Analysis: Lots of improvements, from viewing all code smells in your solution from a single tool window to upgrading foreach and for loops to LINQ queries, to value tracking and call tracking.
  • Support for Visual Studio 2010: Yes, we did it! ReSharper 5.0 has sim-shipped with the latest Visual Studio! Did you see it coming in your wildest dreams?
  • Other enhancements relating to IntelliSense, bookmarking, native NUnit support, and more.

What’s New has more details we haven’t yet covered in our blogs.

So, what are you waiting for? Grab ReSharper 5.0 while it’s hot!

When you’ve been convinced, buy ReSharper 5.0 or upgrade. The upgrade is free if your 4.5 license is dated October 15, 2009, or later!

Introducing ReSharper 5.0: Structural Search and Replace

Wednesday, April 7th, 2010

Previous posts introducing ReSharper 5.0:

Structural Search and Replace is one of the most powerful yet less explored ReSharper 5.0 features. It allows you to find code that matches a structured template, parts of which may have certain restrictions. For example, you can set the type of the expression you are looking for, or specify the number of arguments. In addition to plainly finding parts of code that match the template, you can instantly replace them using an equally powerful replace template, or even configure ReSharper to inspect your solution for code that matches the search pattern and suggest replacing it using a quick-fix. Simply put, Structural Search and Replace provides you with an opportunity to easily extend built-in ReSharper code inspections with your custom ones.

Smart Search

Let’s look at a specific example. We’ll search for all expressions matching the pattern enumerable.Count() > 0, where enumerable is any expression of type IEnumerable.

If you were to solve this task with Find Usages, you would step through all the calls of the Count() method. This means you would have to go through tens or hundreds of calls, which is tiring and prone to error. Find Text might look slightly more promising, but once you think about it, problems come up too:

  1. The expression may be written with line returns or comments.
  2. The Count() method in your project may be implemented by objects of different types.

Find Text doesn’t cut it either.

Choose ReSharper | Find | Search With Pattern and enter the following pattern in the text box:

   $enumerable$.Count() > 0

The $enumerable$ string will be highlighted red. This is because dollar signs signify placeholders — a placeholder is replaced with any text matching the specified restrictions: the placeholder type and its parameters. In our case, $enumerable$ will match any expression of type IEnumerable. We must define this placeholder by clicking Add Placeholder, selecting Expression and entering “enumerable” in the Name field (the placeholder name without the dollar signs). For Expression Type enter “IEnumerable” (just start typing and ReSharper will suggest suitable options). Make sure to check Or derived type as well.

So, in just a few seconds, without even going near regular expressions we’ve created an effective search pattern. But here’s another feature that’s extra-useful! Note the Match similar constructs check box below the edit field. If you select it, ReSharper will search not only for exact matches but also for constructs that are semantically identical. For example, a > 0 and 0 < a are semantically identical. In our case, you should probably select this check box, because you’re likely to be looking for all the different conditional statements where Count() is compared with zero.

That’s all! Now click Find and see the results.

Smart Replace

A search feature this powerful would not be nearly as useful without a replace feature. You don’t want to just locate all the bad code — you want to replace it with good code! So, go ahead and click Replace in the Search With Pattern dialog. You will get a box to enter the replace pattern. The replace pattern can be any text that is valid for the language you’re using, plus placeholders if you need them. For example, enter the following:

$enumerable$.Any()

And click Replace!

Turn a Pattern into a Highlighting and a Quick-Fix

Now you have a search template and a replace pattern. It makes sense to create a highlighting and a quick-fix based on these patterns. To do so, click Save in the pattern editing dialog, and your pattern will be saved to the Pattern Catalog. This catalog is used to store commonly used patterns, and may turn into a powerful tool for creating your own code inspections.

If you open the catalog (ReSharper | Tools | Pattern Catalog), you can define a tooltip for your pattern, which will pop up in the corresponding quick-fix, as well as the type of highlighting you want to apply:

Once you set these options for your pattern, the highlighting works! Now all code that matches your pattern will be highlighted — on the fly. Also, the appropriate quick-fix will appear as soon as you position the caret on the highlighted expression. Ain’t it cool?!

Search Pattern Examples

This search pattern is designed to simplify expressions:

In this example we used placeholders for the types of the expression and the identifier. We didn’t impose any restrictions on them, but used them in the replace pattern. The only placeholder with restrictions is $seq$ — it’s an IEnumerable.

And here’s a pattern that implements highlighting and a quick-fix for Replace ‘if’ with ‘?:’:

Sharing Patterns

If you have created a useful search and replace pattern that detects and removes a code smell, share your knowledge with colleagues using import/export functionality in the the Pattern Catalog! As an option, leave comments with your patterns, and with your permission, we may include the most interesting patterns in the next version of ReSharper!

UPDATE! A sample Pattern Catalog is now available from the ReSharper web site. Learn details in this blog post.

Author: Alexander Zverev, senior ReSharper developer. Translated from original article (in Russian)

Introducing ReSharper 5.0: Value Tracking

Monday, March 29th, 2010

Previous posts introducing ReSharper 5.0:

Recently we posted about Call Tracking, which is a new feature in ReSharper 5.0.

A logical next step from Call Tracking is Value Tracking. Value Tracking is designed to help you determine how a certain incorrect value might have passed to a given point in your program, and where it might be passed next. This helps you investigate possible NullReferenceExceptions, inappropriate behavior and reasons why you get incorrect values.

You can call Value Tracking by choosing ReSharper | Inspect | Value Origin or ReSharper | Inspect | Value Destination over a local variable, parameter, or another kind of value, and you can also use a new shortcut to Call Tracking, Value Tracking, and Type Hierarchy: Inspect This (Ctrl+Shift+Alt+A).

Without theorizing too much, I will review some use cases and scenarios where Value Tracking is useful.

A Basic Example

In this example, a NullReferenceException is thrown in the VisitData method. Let’s determine where the null comes from. Position the caret at the usage of the dc parameter in VisitData and run the analysis (ReSharper | Inspect | Value Origin):


    public class Main
    {
      void Start()
      {
        Console.WriteLine(Do(new DataClass()));
      }

      void Start2()
      {
        Console.WriteLine(Do(null));
      }

      int Do(DataClass data)
      {
        var v = new Visitor();
        return v.VisitData(data);
      }
    }

    public class DataClass
    {
      public int GetData()
      {
        return 0;
      }
    }

    public class Visitor
    {
      public int VisitData(DataClass dc)
      {
        return dc.GetData();
      }
    }

If you run the analysis in your own code (using the same example) and try to navigate around the results tree, you will see that it contains all the nodes you might be interested in:

  • Our usage of dc (the place the exception is thrown).
  • The data parameter passed to VisitData
  • A call of Do with “good data” (in the graphic above, the values we need are in bold).
  • A call of Do with the null value – the culprit.

Basically, this is a massive Find Usages. However, Value Tracking:

  • Skips the unimportant steps, thus saving time.
  • Displays values in a convenient way, so you can find the source of your problem without looking through all the symbol usages one by one.

Value Tracking is especially useful if variable names are changed often, or if values are placed in collections or passed via closures. Let’s look at these more complex use cases in more detail.

Inheritance

So we have an interface, its implementation, fields, field initializers, and constructors. Our task is to figure out which values Main.Start can display. Highlight dataProvider.Foo and invoke Value Origin on it (ReSharper | Inspect | Value Origin):


    public interface IInterface
    {
      int Foo();
    }

    public class Base1 : IInterface
    {
      public virtual int Foo()
      {
        return 1;
      }
    }

    public class Base2 : IInterface
    {
      private readonly int _foo = 2;

      public Base2()
      {
      }

      public Base2(int foo)
      {
        this._foo = foo;
      }

      public virtual int Foo()
      {
        return _foo;
      }
    }

    public class Main
    {
      public void Start(IInterface dataProvider)
      {
        Console.WriteLine(dataProvider.Foo());
      }

      public void Usage()
      {
        Start(new Base2(3));
      }
    }


The results of this Value Tracking include:

  • Implementation of Foo that returns the constant 1.
  • Implementation of Foo that returns the value of _foo as well as all value sources of that field:
    • The assignment of a value to the field in the constructor.
    • Call of constructor with parameter = 3.
    • Initializer of the field with value = 2.

Note how in just a few seconds we found all the possible values. Imagine how much time you would save on highly-branched hierarchies and complex logic!

Collections

Now let’s look at working with collections. Let’s identify the set of all values that the following code will print to screen. To do this, position the caret on the usage of i inside Console.WriteLine and run the Value Origin analysis (ReSharper | Inspect | Value Origin):


   class Main
   {
     void Foo()
     {
       var list = new List<int>();
       list.AddRange(GetData());
       list.AddRange(GetDataLazy());
       ModifyData(list);

       foreach (var i in list)
       {
         Console.WriteLine(i);
       }
     }

     void ModifyData(List<int> list)
     {
       list.Add(6);
     }

     private IEnumerable<int> GetData()
     {
       return new[] { 1, 2, 3 };
     }

     IEnumerable<int> GetDataLazy()
     {
       yield return 4;
       yield return 5;
     }
   }

We found an explicit creation of the array, the values that come from the lazy enumerator, and even the Add call. Awesome!

Collections backwards, or where values pass to

Now let’s try going the other direction and see where the number 5 passes. Highlight it and run Value Destination (ReSharper | Inspect | Value Destination):


   public class testMy
   {
     void Do()
     {
       int x = 5;
       var list = Foo(x);

       foreach (var item in list)
       {
         Console.WriteLine(item);
        }
     }

     List<int> Foo(int i)
     {
       var list = new List<int>();
       list.Add(i);
       return list;
     }
   }

We find rather quickly that:

  • 5 is passed to Foo
  • 5 is added to the collection.
  • The collection is returned and used.
  • Collection elements are printed to screen.

Note how, in this and earlier examples, tree nodes are marked with a special pink icon whenever Value Tracking switches from tracking a value to tracking a collection.

Lambdas

Lambdas tend to cause problems, especially if there are many of them or they’re nested. Let’s see how ReSharper handles the following situation. We’re going to track the value paths in both directions:


   public class MyClass
   {
     void Main()
     {
       var checkFunction = GetCheckFunction();
       Console.WriteLine(checkFunction(1));
     }

     Func<Func<int, bool>, int, bool> GetCheckFunction()
     {
       Func<Func<int, bool>, int, bool> myLambda = x =>
                  {
                   Console.WriteLine(x);
                   return x > 100; // this is where we start searching from
                  };
       return myLambda;
     }
   }

First, let’s find out where the values of x come from. Highlight its usage in the Console.WriteLine call and invoke Value Origin (ReSharper | Inspect | Value Origin):

  • We found the lambda that contains the parameter.
  • Next, the analysis tracked where this lambda was passed. Note how all the nodes in which we track the lambda are marked with a special icon.
  • On the last step, we see that the lambda is called with the argument of 1. This is the value of x we’re looking for.

Let’s find out where the value that the lambda returned is used. Highlight x>100 and invoke Value Destination (ReSharper | Inspect | Value Destination):

  • The analysis identifies that the expression is returned when the lambda is executed.
  • Next, ReSharper tracks where the lambda was passed.
  • Finally, we see a WriteLine call that uses the value returned by the lambda.

You can come up with a more complex example using nested lambdas, by replacing the Console.WriteLine call with these two lines:


    Func<Func<int, bool>, int, bool> invocator = (func, i) => func(i);
    Console.WriteLine(invocator (checkFunction,1));

The analysis will still work, and you will easily see where the value of x>100 is passed.

Code that uses nested lambdas is difficult to understand for most people, making this kind of analysis even more useful. You can even try to create a collection of nested lambdas — and it will still work! Go ahead and try it… if you’re into hardcore fun!

Author: Alexander Zverev, senior ReSharper developer. Translated from original article (in Russian)

ReSharper 5.0 Goes RC!

Wednesday, March 24th, 2010

Today, we have made available ReSharper 5.0 Release Candidate build that you’re welcome to download and evaluate.

No new features there but instead, a ton of performance improvements (Find Usages anyone?), technology support improvements and Visual Studio 2010 integration fixes.

If you find any critical issues with the RC build, please report them using our bug tracker or our Twitter account or let our know in any other way you’re aware of. Please help us come up with a really successful release next month!

Introducing ReSharper 5.0: Call Tracking

Wednesday, March 17th, 2010

Previous posts introducing ReSharper 5.0:

There’s a cool new feature in ReSharper 5.0 called Call Tracking (or, alternatively, Call Hierarchy). Basically, it’s a convenient way to perform an all-out Find Usages or Go To Declaration. You can access it by choosing ReSharper | Inspect | Outgoing Calls or ReSharper | Inspect | Incoming Calls.

There’s also Inspect This, a new shortcut to Call Tracking, Value Tracking, and Type Hierarchy features: Ctrl+Shift+Alt+A.

At first we thought of comparing our Call Tracking to Call Hierarchy in Visual Studio 2010. However, it turned out that the VS 2010 version is just not up to par: it doesn’t support events, interfaces, closures and a few other things. It offers no help at all with the use cases we present here. So we’re only going to talk about Call Tracking in ReSharper 5.0.

Events

Let’s search for an outgoing call from Foo (ReSharper | Inspect | Outgoing Calls):


   using System;
   public class C2
   {
     public event EventHandler E = (sender, args) => Subscription_In_Initializer();

     static void Subscription_In_Initializer()
     {
     }

     void Foo()
     {
       E(this, EventArgs.Empty);
     }
   }

   class C3
   {
     void Bar()
     {
       new C2().E += Subscription_In_Method;
     }

     void Subscription_In_Method(object sender, EventArgs e)
     {
     }
   }

Outgoing Call From Foo

Pretty self-explanatory. ReSharper easily finds all subscriptions to E and displays them as possible calls. Nothing too special, but handy for sure.

Generics

Consider this code sample:


   public abstract class Base<T>
   {
     public void Do(T value)
     {
       DoImplementation(value);
     }

     protected abstract void DoImplementation(T value);
   }

   public class Concrete1 : Base<int>
   {
     protected override void DoImplementation(int value)
     {
     }
   }

   public class Concrete2 : Base<string>
   {
     protected override void DoImplementation(string value)
     {
     }
   }

Now let’s look at outgoing calls from Base.Foo:

Outgoing Calls From Do

Speaks for itself.

Now, let’s add a Main class and try searching for outgoing calls from Foo:


   class Main
   {
     void Foo()
     {
       Concrete2 c = null; // null so that we don't clutter the call tree
       c.Do("string");
     }
   }

Outgoing Calls From Foo

Concrete1.DoImplementation doesn’t show up anymore! That’s because ReSharper looked at the type parameters and realized that Base.Do will be called with T->string (see the second line of results: Base<string>.Dostring means we’re calling a method that substitutes a specific type). Accordingly, ReSharper filtered out Concrete1 because it uses inheritance with the substitution T->int.

Now let’s look at a slightly more complex, yet very vital example using the Visitor pattern. Let’s search for incoming calls from ConcreteVisitor1.VisitNode1 (ReSharper | Inspect | Incoming Calls). Note how we’re going the other way here, in the direction opposite of method calls:


   public interface IVisitor<T>
   {
     void VisitNode1(T data);
   }

   class Node1
   {
     public void Accept<T>(IVisitor<T> v, T data)
     {
       v.VisitNode1(data);
     }
   }

   public class ConcreteVisitor1 : IVisitor<int>
   {
     public void VisitNode1(int data)
     {
     }
   }

   public class ConcreteVisitor2 : IVisitor<string>
   {
     public void VisitNode1(string data)
     {
     }
   }

   public class C1
   {
     void Foo()
     {
       var v = new ConcreteVisitor1();
       new Node1().Accept(v, 1);
     }

     void Foo2()
     {
       var v = new ConcreteVisitor2();
       new Node1().Accept(v, "string");
     }
   }

The result:

Incoming Calls to VisitNode

While traversing the generic Visitor, ReSharper did not lose any details about the substituted type parameters and successfully filtered out the irrelevant call from Foo2. When you have a highly-branched hierarchy and a large number of generic types, this kind of logic helps to really narrow down your search.

Constructors

Let’s also look at an artificial example using constructors and field initializers. Let’s search for outgoing calls from the Derived class constructor:


   class Base
   {
     public Base()
     {
       Base_Bar();
     }

     void Base_Bar()
     {
     }
   }

   class Derived : Base
   {
     int _i = Foo();

     public Derived()
     {
       Bar();
     }

     void Bar()
     {
     }

     static int Foo()
     {
       return 0;
     }
   }

Outgoing Calls From Derived

Again, nothing out of the ordinary. ReSharper simply displays calls in their the natural order, mindfully listing the implicit call of the base constructor. For a less-experienced developer, this saves a lot of time spent understanding code, and is a nice crutch to lean on for an expert.

Value Tracking

And here’s the final tidbit. If you open the ReSharper | Inspect menu, you’ll see two very interesting items: Value Origin and Value Destination. These functions implement value tracking: they let you track where a particular variable value or parameter value came from, or where it is headed. Naturally, it works with collections and delegates (it determines that an item was taken from a collection and then searches for usages of that particular collection) and is indispensable for identifying the causes of NullReferenceExceptions.

Illustrating this will take a whole batch of screenshots and examples, so please stay tuned for our next post.

Author: Alexander Zverev, senior ReSharper developer. Translated from original article (in Russian)