January 26, 2005

JetBrains .NET profiler is out

This Monday we started EAP (Early Access Program) for our new development tool - JetBrains .NET Profiler. As follows from its name the purpose of this tool is to profile performance of your .NET applications. The tool is currently a bit raw as we wanted to atart the EAP as early as possible to collect maximum feedback from our potential customers at early stage of development. As usually we focus on making thing done easier what in this context means that you should be able to find bottlenecks in your code in minutes. Check it out now at http://www.jetbrains.net/confluence/display/NetProf/Download.

Posted by Oleg Stepanov at 06:32 PM | Comments (101) | TrackBack

Decremental Programming

While the whole software development world uses incremental development processes I seem to practive opposite approach which the team calls "Decremental Programming". One of the last refactorings for 1.5 was conversion from interface to abstract class. I started off with a great swiss army knife-like code which could also give new name to the converted class and had option to leave interface and just insert additional level of abstraction between it and its inheritors (I found it useful when a developer wants to share some code between all interface implementations). But after discussion we first cut the option and then the ability to change the name. This resulted in decremental changes in code: I removed the functionality from the actual refactoring code making is clearer. If you find you really need these features I strongly encourage you to post a request to the tracker to we could discuss it. Similar changes I do now for code completion and other subsystems (without reducing functionality, just some clean-up) before starting bugfixing race for 2.0.

Posted by Oleg Stepanov at 06:25 PM | Comments (3) | TrackBack

January 20, 2005

Code Cloverage

Yesterday I finished writing refactorings planned for 1.5 and decided to diverse my activity by investigating possibility to add automated code coverage analysis to our build process. I chose Clover .NET as coverage tool mainly because there are not too many alternatives (NCover seems a bit raw) and that a team next door (Fabrique) successfully uses its big Java brother - Clover.
Integrating it turned out to be a tricky task as our build process is fairy complicated: we use NAnt as general workflow engine, VS.NET for building and multiple custom tools for code generation, etc. So I ended up writing another tool which takes our solution file, goes through its projects and creates copies of the projects which contain instrumented sources. At the end we get copy of our original solution which references instrumented projects.
But unfortunately Clover doesn't seem to handle projects of such size well: when I run unit tests on clovered binaries it starts allocating too much memory and fails with OutOfMemoryException when memory consumption reaches 1.5Gb. First I though we really have so much code and added another gig of RAM to my machine but this didn't help. I even added /3GB switch to the boot.ini file to extend address space for the process. No effect. I only could get results when I instrumented only one of our 40+ projects (medium sized one - about 42000 NCLOC). I got quite reasonable results (however, I have to confess that I wish the coverage was much better).
Then I decided to read through the instrumented sources to learn what the instrumentation process does. It actually creates static array for each instrumented class (of course, it is covered in special reporter class, but details don't matter now). Then at each statement and condition it increments certain elements of array. Indexes are presented as numeric literals in code so it must keep some database which matches these numbers to particular lines in code. First I thought that the problem was with these indexes, but after carefully reading the code through Reflector (it was reallly simple - only three classes in the runtime) I changed my mind. Finally it turned out that the problem was that Clover instrumented a class which was used in COM interop and the changes added static constructor to it which caused TypeLoadException in our code deeps. The exception somehow got uncaught and resulted in maintaining many thousands copies of test data in memory. When I excluded that file from instrumentation everything went ok except one problem with instrumenting boolean expressions containing assignments (I know that Clover has special options for it, but it didn't seem to help).
As a bottomline I don't regret that I spent so much time making it work as the test coverage report seems to be very helpful. We will try to make it run automatically and play with the results for a month or so before deciding whether we're going to use it in our development.

Posted by Oleg Stepanov at 07:52 PM | Comments (18) | TrackBack

January 17, 2005

Build 153

I've just put build 153 to our download storage. Ugh... It includes new refactoring called "Introduce Parameter" and I spent the whole last week implementing it. The idea is simple: you take a variable or an expression, invoke the refactoring and it adds new parameter to your method/constructor/indexer signature and initialises it with the selected expression or variable initializer at all call sites.
But of course there are lot of details: dealing with params modifier, qualified calls, usages of other parameters, etc. Of couse there are quite a few tests on it, but if you find a bug, please report it to our Tracker.
I also added slight modification to the "Extract Interface" refactoring to support so called "quasi supermembers" ;). This is our internal name for the case when an interface member is implemented using base class' public members. So now you can select such members for extraction.

Posted by Oleg Stepanov at 09:15 PM | Comments (40) | TrackBack

January 12, 2005

Raising The Bar

Another thing which excites me in my working experience at JetBrains is that we're always raising the bar whatever we do. This is major difference from what is happening in technology-driven IT giants like Microsoft because their main efforts are put into driving technology forward. If we take, for example, their Visual Studio product, all major efforts are put to implementing that hot technologies which were just developed by peers in Microsoft campus - you know, ASP.NET 2.0, .NET Framework 2.0, SQL Server 2005). Instead of doing this (I'm not talking about Fabrique project) we're working on improving everyday end-user experience by polishing the tools and providing easy ways to do routine work. This might look not as significant (we don't post announcements in every programming magazine sayng that our smart completion now guesses what you're going to type after "case " keyword), but it's important in that we create a solid programming experience for everyone using our products.
In its time Intellij IDEA rose bar in many aspects of Java IDEs and now it's our turn to do the same in .NET world although currently there are now not many players.

Posted by Oleg Stepanov at 06:33 PM | Comments (11) | TrackBack

January 10, 2005

ReSharper 1.5 goes into EAP

Well, it seems like I'm not making any news in the blogsphere announcing start of ReSharper 1.5 Early Access Program. But since it seems like almost all new features of 1.5 are mine I think I'm the one who should write couple words about them.

This version's keyword is “refactorings” (it is even called so in our issue tracking system) which means that current and future ReSharper users will get more quality refactorings this month when 1.5 is released. Next I'll describe each of the new refactorings in a few words.

Extract Interface

A very simple refactoring which can be found in most refactoring add-ins and in VS2005. Our version, however, has interesting enchancement: you can extract not only type members (like methods, events, etc.), but also interface implementations. What I mean can be shown on a simple example:

interface I
{
  void Foo();
}

class C : I
{
  public void Bar() {}

  public void Foo()
  {
    throw new NotImplementedException();
  }
}

If we try to extract interface from class C ReSharper will show the following dialog:

ExtractInterface.png

It gives us option not only to extract members of class C, but also implementation of interface I. If we choose to extract I and Bar, we get the following result:

interface I
{
  void Foo();
}

class C : IC
{
  public void Bar()
  {
  }

  public void Foo()
  {
    throw new NotImplementedException();
  }
}

interface IC : I
{
  void Bar();
}	

Extract Superclass

Extract superclass is like extract interface, but the difference is big enough: since it extracts members with bodies and also can extract constructors the logic is far more complicated than in extract interface. I won't, however, describe these “little details” that should have been taken into account and will only recommend you to try it out.

Copy Type

Copy type is copy type. Take a type declaration, choose Refactor -> Copy Type and you’ll get the same declaration copied under different name.

Introduce Field

Introduce field refactoring replaces usages of an expression or a variable with usages of new field or constant. To use it simply select an expression or place cursor at variable declaration and invoke the refactoring. You will see the following dialog:

IntroduceField.png

The refactoring gives you option to choose where to initialize the new field, which visibility to use (the list misses "protected internal" access modifier since it’s rarely used), whether to introduce constant, declare the field readonly and whether to replace all occurences of the expression. After you decide on each option you can confirm your choice and the field will be created.

Encapsulate Field

This refactoring allows you to create proxy property for a field (like our "Generate Getter/Setter" feature) and replace some or all of its usages with usages of the created property. Simply choose a field and invoke the refactoring. It will give you lots of options including whether to replace reads and writes, external or all usages, new property visibility, etc.

The list is incomplete. This week I'll be working on introduce parameter and maybe some other refactoring(s)...

Posted by Oleg Stepanov at 07:03 PM | Comments (56) | TrackBack

New Year

So, another year passed. Many things were done in 2004 the main of which was, of course, ReSharper 1.0. I developed many different subsystems in in from code completion to refactorings and this gave me a huge development experience boost. In 2005 I plan to finish ReSharper 1.5, improve ReSharper functionality for 2.0 (huge part of such improvement will be .NET 2.0 support) and spend more time designing rather than coding.

Posted by Oleg Stepanov at 06:35 PM | Comments (4) | TrackBack