Sunday, September 28, 2008

New Features

I had a lot of fun this weekend.

Added a context action to negate the condition of an 'if' statement. This does not keep the semantics of the statement, but just applies a 'not' operation to the expression.

Added a context action and a live template macro to pull the parameters of the containing method to the caret position. This is useful when you have to pass a set of parameters on to another method.

Added a Implement ICloneable refactoring.

Added a Implement proxy class refactoring.

Added using() statements to the scope analysis in Smart Generate.

Considered adding a Implement IEnumerable refactoring, but as far as I can see, it wouldn't be very helpful, as most of the code could not be auto generated.

Considered how Document Exceptions could be extended to allow more than one description per exception. In the MSDN documentation, descriptions are separated by and "-- or --" text. But I'll have to think some more about this.

An usual amount of work for a weekend.

Tip

To convert from an IClassDeclaration to an IClass, do this:


IClass cls = classDeclaration.DeclaredElement as IClass;


And as always remember to null check afterwards.

Saturday, September 27, 2008

Tip

To get the IElement at the current caret position, do this:


IElement element = TextControlToPsi.GetElementFromCaretPosition(solution, textControl);


The TextControlToPsi class is located in the JetBrains.Resharper.IDECore assembly.

Thursday, September 25, 2008

StyleCop Plugin for Resharper

I do not really like StyleCop, but I like that there is a plugin for Resharper to use it.

StyleCop Plugin for Resharper

ReSharper Plugins

Here is a nice overview by Rob Smyth for those who want to learn the arcane art of ReSharper plugin development:

ReSharper Plugin

Using Smart Generate

I am just amazed at how well Smart Generate works.

Here is an example:

Whenever I write use a string, that is visible to the user, I need to run it through a Translate.Text method, e.g:


output.Write(Translate.Text("Visible output"));


However writing the call the Translate.Text is tedious, so I want to put that in Smart Generate.

First I write the statement with out the Translate.Text call.


output.Write("Visible output");


I place the caret on top of the string literal, and press Shift+Enter, which brings up the Smart Generate menu.

From the menu I select "Create Live Template" and then "Surround String Expression".

ReSharpers Live Template Editor opens and I name the Live Template "Translate string". The code of the Live template is:


Translate.Text($SELECTION$)


Save the Live Template and return to original code.

Press Shift+Enter to show the Smart Generate menu and select "Translate string".

And bingo, I have:


output.Write(Translate.Text("Visible output"));


Never have to write another call to Translate.Text manually again.

Big smile!

Saturday, September 20, 2008

Tip

Here is how to create an IDeclaredType instance from a string:

string typeName = "System.ISerializable";

IDeclarationsCache cache = PsiManager.GetInstance(solution).
GetDeclarationsCache(DeclarationsCacheScope.SolutionScope(solution, true), true);

ITypeElement typeElement = cache.GetTypeElementByCLRName(typeName);

IDeclaredType declaredType = TypeFactory.CreateType(typeElement);

New Features

Implemented "Implement IDisposable" refactoring.

Implemented "Implement ISerializable" refactoring.
It does not handle superclasses that already implement ISerializable, which it probably should.

Not sure if these are refactorings or generators.

Anyway this will bump the next version number to 1.5.

New Installer, a Fix and an Idea

Changed the installer from the Visual Studio Installer to WiX. Shamelessly ripped it from Agent Smith.

Added a Value Analysis check to Assignment Check Smart Generate. Pretty difficult as I needed to temporarily insert an if statement at the caret to get an IReferenceExpression, run Value Analysis, and then cancel insertion. Worried about performance.

Considered how to detect code similarites to highlight common code blocks. Common code blocks could be extracted into methods which would increase maintainablility.

Each important element of a code block; statement, invocation, assignment etc. could be represented as an integer. A code block would then be a list of integers. I could then use Levenshtein distance to compute the difference between two code blocks. If the distance is small, the code blocks are similar.

It is a nice idea, but probably not workable in real life.