Better late than never: CodeRush and Refactor! Pro 2.2.2 Revealed

24 May 2007
There was a knock on the door late at night a week or so ago, but when I opened it I saw nothing but flurries of snow whisking into the porch light and away into the darkness and an envelope propped up against the door jamb. No one was around. I ripped open the envelope and there it was: the new features in CodeRush and Refactor! Pro. No longer were they a Stealth Release, the envelope was proof I could talk about them. And then I went to Montréal and forgot all about it...

Until Mark and Dustin sent the boys round and they wouldn't leave until this got posted. Sorry guys.

 

DXCore

So with no further ado, let's start with DXCore:

  • Support for Visual Studio Orcas beta 1 has been added. This support is considered experimental until Orcas is formally released and of course we'll be providing updates in step with further Orcas beta releases. Note though we are aware that the plug-in wizards are broken in Orcas and we are working on fixing this issue.
  • The performance of the C# parser has been improved by approximately 30% and it now has support for C# 3.0. We'll see how this affects Refactor! Pro in particular in a moment.
  • The About Box dialog has changed slightly: we've added buttons to open the plug-in and user settings directories on the current machine. If one of these buttons is clicked while the Shift key is held down, the About Box dialog will be automatically closed.
  • A few changes to the Linked Identifiers support: Visual Studio Intellisense can now be used within linked identifiers; we've corrected the painting of linked identifiers when word wrapping is enabled; and we've corrected the painting of text fields when word wrapping is enabled.
  • For those people keen on writing DXCore plug-ins, there are two new contexts, Project\IsWPF and File\IsWPF, and there's a new CodeRush.Synchronization service for synchronizing code on Visual Studio's UI thread.

 

CodeRush

Moving on to CodeRush itself now:

  • We've added Camel Case Filtering. This is Mark's, er, "celebrated" Camel Humping support, that is, we added a new filter to QuickNav and Recent Files dialogs that matches against uppercase letters in identifiers.
  • The 'f' templates for declaring a field have been deprecated due to conflicts with the for-loop templates. You should use the 'v' templates to declare fields.
  • After some discussions on the forums and internally, we did a lot of work in improving the context-checking for many single-letter templates to ensure that they don't expand unexpectedly.
  • Most graphics templates are now WPF-aware.
  • There's a new template set for declaring constants using the 'q' mnemonic (for example 'qi' declares an Int32 constant).
  • There's a new template set for declaring readonly fields using the 'o' mnemonic (for example 'oi' declares an Int32 readonly int field).
  • There are new WPF templates for dependency properties, attached properties, routed commands and routed events. For more information on these, see the Graphics\WPF folder in the Editor\Templates options page. Slowly but surely our WPF work leaks out...
  • To support our eXpress Persistent Objects product (XPO), there are some new templates and type mnemonics specifically for XPO.


Refactor! Pro

And now let's see what's happened to Refactor! Pro and our aim to hit 100, er, sorry, 125 refactorings by the end of the year. First of all, we'll look at the fully supported features, and then the Early Experience ones.

  • Change Tag: changes a <sometag></sometag> pair in an aspx file to a user-specified tag. This is most useful I find for changing a div to a span or vice versa, or maybe an em to/from a strong.
  • Collapse Getter: collapses simple getter code onto a single line. By "simple" here we mean that the getter code consists of a single line return statement, such as returning the value of the backing store. The final outcome is a single line like this:
    get { return fooField; }
  • Collapse Setter: collapses simple setter code onto a single line. By "simple" here we mean that the setter code consists of a single line, such as setting the value of the backing store. The final outcome is a single line like this:
    set { fooField = value; }
  • Compress to Null Coalescing Operation: converts a ternary expression to an equivalent null coalescing operation. (C# 2.0+ only)
In other words, something like this:
    int? someValue = null;
    int realValue = someValue.HasValue ? someValue.Value : -1;
    string someText;
    // code setting someText, or not
    MessageBox(someText != null ? someText : "<NULL>");

is refactored in two steps to this:  
    int? someValue = null;
    int realValue = someValue ?? -1;
    string someText;
    // code setting someText, or not
    MessageBox(someText ?? "<NULL>");

  • Convert to HEX: converts a color to the equivalent hexadecimal representation. (ASP.NET only)
  • Convert to Named Color: converts a color to the equivalent named color representation. (ASP.NET only)
  • Convert to RGB: converts a color to the equivalent RGB representation. (ASP.NET only)
  • Decompose Parameter: replaces a single parameter with one or more new parameters, each standing in for a property access on the original parameter. This can help a method have a wider audience in that the original parameter no longer has to be constructed in order to call the method.
  • Expand Getter: expands single-line getter code onto multiple lines. The reverse of Collapse Getter.
  • Expand Null Coalescing Operation: converts a null coalescing operation to an equivalent ternary expression. (C# 2.0+ only) The reverse of Compress to Null Coalescing Operation.
  • Expand Setter: expands single-line setter code onto multiple lines. The reverse of Collapse Setter.
  • Extract to UserControl: creates a UserControl for the selected block including content and dependent code. (ASP.NET only)
  • Collapse Getter: collapses simple getter code onto a single line. By "simple" here we mean that the getter code consists of a single line return statement, such as returning the value of the backing store. The final outcome is a single line like this:

     get { return fooField; }

  • Introduce ForEach Action: replaces the contents of the List-iterating loop with an anonymous method, which is passed as the Action delegate to the List<T>.ForEach method. (C# 2.0+ only) This can seem a little bizarre at first. In essence it changes code like this:

      private static void GetCountStringsWithZ(string[] text) {
         char[] Zeds = new char[] {'z', 'Z'};
         int zCount = 0;
         foreach (string s in text) {
            if (s.IndexOfAny(Zeds) < 0)
               zCount++;
         }
         return zCount;
      }

into this:
      private static void GetCountStringsWithZ(string[] text) {
         char[] Zeds = new char[] {'z', 'Z'};
         int zCount = 0;
         Array.ForEach(text, delegate(string s) {
            if (s.IndexOfAny(Zeds) < 0)
               zCount++;
         });
         return zCount;
      }
which seems a little weird (unless you prefer this declarative form) until you see the Compress to Lambda Expression refactoring.
  • Introduce Setter Guard Clause: introduces a value changed check at the start of a property setter, exiting early if the value matches the backing store. In other words produces this kind of code:
   private string text;
   public string Text {
      get {...}
      set {
         if (value == text)
            return;
         DoSomethingLongWindedWith(value);
         text = value;
      }
   }
  • Line-up Arguments: moves arguments of a method call that are broken onto multiple lines up so they all exist on the same line.
  • Line-up Parameters: moves parameter declarations that are broken onto multiple lines up so they all exist on the same line.
  • Remove Private Setter: removes a private property setter that simply assigns a value to a field without any side-effects.
  • Remove Setter Guard Clause: removes the value changed check at the start of a property setter. The reverse of Introduce Setter Guard Clause.
  • Remove Tag: removes a tag pair while preserving the inner content. (ASP.NET only)


And now the Early Experience refactorings. These can be enabled through the "Editor\Refactoring\Early Experience" options page.

  • Compress to Lambda Expression: converts an anonymous method to an equivalent lambda expression. (C# 3.0 only) Taking the above example for Introduce ForEach Action to the next step, we'll get:
      private static void GetCountStringsWithZ(string[] text) {
         char[] Zeds = new char[] {'z', 'Z'};
         int zCount = 0;
         Array.ForEach(text,
            s => if (s.IndexOfAny(Zeds) < 0) zCount++
         );
         return zCount;
      }

  • Convert to Auto-Implemented Property: removes the backing store and converts a property to an auto-implemented property. (C# 3.0 only) For those who haven't come across these before, auto-implemented properties are a bit of sugar candy from C# 3.0. The C# team noticed that declaring properties was too long-winded, even with a cool tool like CodeRush, so they added auto-implemented properties. Instead of writing
   private Fooness foo;
   public Fooness Foo {
      get { return foo; }
      set { foo = value; }
   }
with C# 3.0 you can write the abbvreviated form and the compiler will produce the same code as you would have written in earlier version of C# (albeit with a weird automatically generated backing store name):
   public Fooness Foo { get; set; }
  • Create Backing Store: converts an auto-implemented property to a conventional property with a backing store. (C# 3.0 only) The reverse of Convert to Auto-Implemented Property, but we'll do a better job of naming the backing store...
  • Encapsulate Downcast: changes the return type of a method to the type that all callers downcast to, removing all typecasting at the calling sites.
  • Extract String to Resource: extracts a string and puts it into a resource file. (Yesssss!)
  • Introduce Parameter Object: consolidates selected parameters into single object. The reverse of Decompose Parameter.
  • Promote to Parameter: removes all references to a field or local declaration from a method, replacing it with a parameter. Calling code is adjusted to pass in the field or expression of the local declaration as the argument for the new parameter.
  • Reduce Visibility: reduces the visibility of a method or property to match the highest calling visibility. Although you should always program to reduce the visible interface of your classes (making the class more of a black box), sometimes you are given code in which this principle was violated. This refactoring can help in shrinking the visible interface of a class.
no comments
No Comments

Please login or register to post comments.