Showing posts with label tools. Show all posts
Showing posts with label tools. Show all posts

06 April 2009

Mortal Kode -- Quite Simple Generics

It is very important for a tool to understand correctly what is written in the code. You just can't underestimate the importance of this ability. If the code is not correctly parsed, resolved, analyzed and understood by the tool's core, any other feature of the tool can easily fail. Nobody wants Rename refactoring to miss changes, code completion to insert unavailable symbols and code navigation to put the caret in a wrong position. Actually, the most annoying thing would be wrong code analysis, when code is incorrectly flagged with error, when in fact it compiles just fine. This all can easily happen if underlying code model is wrong.

That's why here at JetBrains, we put a lot of effort into our code model, language understanding and work hard to handle even most complex cases -- after all, they can easily be found in real applications.

Today we will look at complexity of code involving generics in C#. Consider the following example (thanks to Vladimir for this one):

  abstract class A<T>
  {
    public abstract void Foo(T x);
    public abstract class B<S> : A<B<S>>
    {
      public class C<U> : B<C<U>> 
      {
 
      }
    }
  }

I think not too many people out there can easily say what would be the correct signature for the implementation of method Foo in the nested class C<U>. As for me, I can't. Doing it manually is simply too much.

First, we try Visual Studio "override" helper and we get the following:

  public override void Foo(A<B<S>>.B<C<U>> x)
  {
    throw new NotImplementedException();
  }

Complex enough, and not quite correct:
error CS0115: 'A<T>.B<S>.C<U>.Foo(A<A<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>>.B<S>>.B<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>.C<U>>)': no suitable method found to override 
error CS0534: 'A<T>.B<S>.C<U>' does not implement inherited abstract member 'A<A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>>.Foo(A<A<T>.B<S>>.B<A<T>.B<S>.C<U>>)'

Let's see what ReSharper 4.5 inserts when developer uses "Implement missing members" action from the "Generate" menu:

  public override void Foo(A<A<T>.B<S>>.B<A<T>.B<S>.C<U>> x)
  {
  }

You can see that parameter type is exactly the same as expected by compiler. Needless to say the signature is correct, and you don't have to compile it first.

Does your tool understand non-trivial code?

Next time, we'll take a look at some lambda fun.

08 April 2008

Extending the Extension -- ReSharper Plug-Ins

ReSharper, the ultimate productivity tool for Visual Studio, is not just pre-packaged set of features. ReSharper provides rich platform for intelligent extensions, which can read and modify code and provide even more productivity features to you. I thought I would compile list of known public plugins.

ReSharper PowerToys - cyclomatic complexity analysis, explore type interface, find text, generate ToString, csUnit support. Open Source.

RGreatEx - resource refactoring and string manipulation. Commercial.

MbUnit - support for MbUnit tests in ReSharper Unit Testing subsystem. Open Source

xUnit - support for xUnit tests in ReSharper Unit Testing subsystem. Open Source

NSpecify - support for NSpecify in ReSharper Unit Testing subsystem. Open Source

Agent Smith - naming convention validation, spell checking, xml-comments validation, smart paste. Open Source

Agent Johnson - documents exceptions, batch-annotate with NotNull/CanBeNull, favorite files. Open Source

ARP - log4net and NHibernate support. Open Source

Stefan Lieser’s NHibernate plugin - NHibernate support. Free

Scout - navigate to .NET Framework Reference Source. Open Source


If you know any other public plugins to ReSharper, let us know!

18 February 2008

Better Development Tools -- Building Together

Dear early adopters!

We thank you kindly for your participation in ReSharper 4 early access program. It is going to be wonderful release for everyone, because of you. This time we receive the best response ever, and we are so excited about it!

Many brave developers, who are trying ReSharper 4 early builds with Visual Studio 2008, registered in our issue tracker and provided us with detailed, specific and very important information. This is really great, because we were able to reproduce many issues that were lurking around our code base for some time now. It is very important that you registered and provide us with non-anonymous feedback: bidirectional communication is at least 16 times more effective than one way exception submitting. One sample solution which manifests the problem is 256 times better than 1024 exceptions without a comment. And it is invaluable when you submit instructions to reproduce the problem (well, at least var value = int.MaxValue).

Thank you very much, we really appreciate your effort! With that kind of feedback we receive today, I believe we can build the best release of ReSharper, ever. Everybody wants better tools, right? ;)

Sincerely Yours, Ilya.

02 July 2007

Of Tools and Languages

People often discuss tools for languages, often discuss languages, but rarely discuss languages for tools. If you haven't checked the NBL - The Next Big Language - go read it. Until, of course, you don't care about new languages. Here is small quotation:

Most programmers don't realize how often they need to deal with code that processes code. It's an important case that comes up in many, many everyday situations, but we don't have particularly good tools for dealing with it, because the syntax itself prevents it from being easy.


Being tool developer myself, I must say that it is often extremely hard to make desired feature. Not that it is hard to implement the feature, but rather understand how it should work in a particular language and how to "fix" the language. Few examples to illustrate the problem:

Braces in C#
C# block delimiters are braces, symbols "{" and "}", and they are used everywhere, and thus has context-dependent semantics. For a class body they surround methods and properties; for a method they designate start and end of implementation code; inside method they are used for conditional and loop blocks. The problem is that they can easily become unmatched, and thus closing braces change their meaning. The one which was at the method end suddenly becomes closing brace for the loop, method borrows its closing brace from class and all the code looks broken. ReSharper's code analysis goes crazy and highlights the rest of the file in red.

Note, that we don't have such problem in Visual Basic .NET, because we have different "braces" for different constructs and we can detect unmatched "brace" early. However, VB.NET has own problems...

Name suggesting in VB.NET
ReSharper always had name suggesting feature for C# - when you have name of the type in the editor plus space and hit Control+Space you're presented with generated names for local variable or field:



Those names are generated from type name to the left. Note the order - type name first, than declaring symbol name. In VB.NET the order is the opposite. You first give name to the declaring symbol and then specify what type is it.

ReSharper can't help you find the type for the specified name, it would be too slow. We have to invert the order, and we do so by providing "dim" Live Template:



We have similar problem in C# with interface implementation, actually.

So what?
No modern software development process can exist without tools. Continous integration and version control, refactoring and code editing, error detection and code analysis - all these require tools. If the language doesn't support tools, tools cannot support language very well. It requires significant effort to develop tools for unfriendly language and thus less tools appear on the market. At times tool vendors attempt to "fix" language editing expirience with techniques that are not natural to the language itself, because at some moment they need information not typed in yet. In order to get maximum information about developer's intention, we create special features for each intention (like "surround with") instead of understanding what is being typed; just because language forces us to do so.

That said, if you are creating your own language, or even the Next Big Language, be sure to consider tools as a major thing influencing language design.

10 November 2006

Code Metrics

Many people ask, if we are going to implement code metrics in ReSharper. Most people talk here about cyclomatic complexity, some mention maintainability index or even Halstead complexity measures. In fact, there are two major cases when people need code metrics.

One case is part of global measurement process in software development company. That is, when company measures and tracks requirements, design and architecture, implementation, tests, deployment, support and operations, etc. Obviously, this is out of ReSharper scope. It won't track history of measurements (as it doesn't track history of errors found in source code), it doesn't integrate with corporate database, it doesn't provide any help in fixing these measures. Someday this case will be covered by TeamCity, I think.

Another case is helping developer spot "code smells". This would suit ReSharper's nature perfectly, but why then just talk about code metrics? Why people want just "have a warning about too complex method", and not about "method belongs to different class"? Many of such "code smells" can be automated, and can aid developer in building Good Code. The problem with such warnings is that they often can give false positive. False positives are very frustrating, people will think something like this: "Well, I know, this code is complex. It should be. It was optimized for speed, implements complex algorithm and maintained by experienced Senior Developer. I DON"T want this warning here!". Thus, system that issues such warnings should have "ignore specific warning in specific place" mechanism, otherwise these warnings will be switched off globally most of the time.

I believe ReSharper team most likely will introduce suggestion system sooner or later, and then implement "code smells", including code metrics, and other useful suggestions that will help you write better code.