07 November 2008
Microsoft Tech·Ed EMEA 2008 / Developers
We'll be there, at Microsoft Tech·Ed EMEA 2008 Developers, Barcelona, booth E3. If you are going to be there come visit us and let's talk! Whether you like to learn about ReSharper or TeamCity or dotTrace, grab some tips and tricks, learn what we are going to do in future versions, or just talk about how wonderful the world is - you're welcome at our booth. See you!
01 November 2008
Wild World of Visual Studio -- Proxies confront Hooks
How can Internet Explorer settings interfere with productivity add-in to Visual Studio, such as ReSharper? And even lead to Visual Studio crash when doing some seemingly unrelated operations, like checking out source code from Team Foundation Server?
Story 3 -- Proxies confront Hooks
We've got a number of reports about Visual Studio crash when doing repository operations using TFS. Of course, when ReSharper is disabled, no crashes occurs, which make users think ReSharper is guilty. We couldn't reproduce the problem in the labs, and we again tried to assert/log/verify everything we can think about. We even got some dumps with the crash, but could not find anything really useful there, besides evidence that there are numerous SecurityExceptions instances in the managed heap waiting to be collected. We needed reproducible case with WinDbg attached. Thanks to Vasily, we got one.
It is funny how we were debugging this crash. Since we were not able to reproduce the problem in the labs, we needed access to the faulty computer. However, due to corporate rules on the user's side, we were not able to arrange real remote session. But we had WinDbg with command line interface, and we had instant messaging. So I was sending WinDbg commands, he copied them into WinDbg, executed, and then copied back the result. We laughed about it and were kidding about extension to WinDbg which would be Jabber client :)
After several days being in this copy-paste process, we finally found the problem. Three components playing together made it explosive:
Remove one, and all is fine again. So, what is happening in our case? Now, watch my hands.
Well, actually, this one was our fault. I added SecurityPermissionAttribute asserting UnmanagedCode permission to the hook procedure and ReSharper is shining like a diamond again.
Case closed, lessons learned.
Story 3 -- Proxies confront Hooks
We've got a number of reports about Visual Studio crash when doing repository operations using TFS. Of course, when ReSharper is disabled, no crashes occurs, which make users think ReSharper is guilty. We couldn't reproduce the problem in the labs, and we again tried to assert/log/verify everything we can think about. We even got some dumps with the crash, but could not find anything really useful there, besides evidence that there are numerous SecurityExceptions instances in the managed heap waiting to be collected. We needed reproducible case with WinDbg attached. Thanks to Vasily, we got one.
It is funny how we were debugging this crash. Since we were not able to reproduce the problem in the labs, we needed access to the faulty computer. However, due to corporate rules on the user's side, we were not able to arrange real remote session. But we had WinDbg with command line interface, and we had instant messaging. So I was sending WinDbg commands, he copied them into WinDbg, executed, and then copied back the result. We laughed about it and were kidding about extension to WinDbg which would be Jabber client :)
After several days being in this copy-paste process, we finally found the problem. Three components playing together made it explosive:
- Connecting to web site with HTTP when automatic proxy configuration script is enabled (It is basically JScript function which gives proxy address for given host)
- Managed hooks installed (here is ReSharper's role in the problem, but could be any other plugin)
- Pumping messages during JScript code execution
Remove one, and all is fine again. So, what is happening in our case? Now, watch my hands.
- TeamFoundation client is going to communicate to server.
- It initiates connection to web service.
- HttpWebRequest is asking for proxy information.
- WebProxy detects that automatic proxy configuration script is enabled.
- AutoWebProxyScriptEngine downloads script and uses JScript engine to execute it
- JScript engine restricts code permissions to execute only.
- Exception happens while executing JScript and dialog is going to be shown with error information. This is who pumps messages.
- Our managed hook is executed and attempts to use CallNextHookEx to pass data to other hooks.
- Code Access Security system demands UnmanagedCode permission.
- Due to restricted mode in which JScript executes, demand fails and SecurityException is rised.
- Exception causes corruption of some internal Visual Studio COM objects, which instantly leads to Access Violation.
Well, actually, this one was our fault. I added SecurityPermissionAttribute asserting UnmanagedCode permission to the hook procedure and ReSharper is shining like a diamond again.
Case closed, lessons learned.
31 October 2008
Wild World of Visual Studio -- Mysterious Component
This one was bugging us for a long time, until we got message from Jay (thanks!) who had similar problem and was willing to help.
Story 2 -- Mysterious Component
The problem itself is mysterious. From time to time it happens that Visual Studio stops loading any add-ins. ReSharper is installed, but its menus are suddenly all gray and it is not listed in the "Tools \ Add-in manager" dialog. It happens after installing various products, it could be service pack, SQL server tools, Visual Studio components - anything! Some users install them and all works fine. Some users loose their favorite productivity tool.
Logging, debugging, trying to reproduce for may be several years(!) led to no result. ReSharper was simply not loaded into the process, though all registration information appears to be in the right place. We checked encodings, verified files are not corrupted, verified registry access rights - all we can think of. As you can guess now, the reason was not anywhere near.
After lots of email exchanges with Jay, including mini-dumps, Process Monitor traces, registry excerpts, configuration files and such we suddenly found ourselves staring at the right thing. It was msxml6.dll. Actually, it was the fact that there were no msxml6.dll in the call stack. Instead, there was msxml3.dll.
We use .addin files to register our add-in in Visual Studio. It is XML file describing add-in, containing information about primary assembly, descriptions, load options and Visual Studio version compatibility information. The latter was that msxml3 was not able to process and thus Visual Studio refused add-in as non-compatible. In fact, msxml6 was there in System32, but it somehow happened to be not registered as COM object. Using regsvr32 on msxml6.dll repaired the system, resurrected ReSharper and enabled customers to enjoy our productivity add-in again.
Case closed.
Story 2 -- Mysterious Component
The problem itself is mysterious. From time to time it happens that Visual Studio stops loading any add-ins. ReSharper is installed, but its menus are suddenly all gray and it is not listed in the "Tools \ Add-in manager" dialog. It happens after installing various products, it could be service pack, SQL server tools, Visual Studio components - anything! Some users install them and all works fine. Some users loose their favorite productivity tool.
Logging, debugging, trying to reproduce for may be several years(!) led to no result. ReSharper was simply not loaded into the process, though all registration information appears to be in the right place. We checked encodings, verified files are not corrupted, verified registry access rights - all we can think of. As you can guess now, the reason was not anywhere near.
After lots of email exchanges with Jay, including mini-dumps, Process Monitor traces, registry excerpts, configuration files and such we suddenly found ourselves staring at the right thing. It was msxml6.dll. Actually, it was the fact that there were no msxml6.dll in the call stack. Instead, there was msxml3.dll.
We use .addin files to register our add-in in Visual Studio. It is XML file describing add-in, containing information about primary assembly, descriptions, load options and Visual Studio version compatibility information. The latter was that msxml3 was not able to process and thus Visual Studio refused add-in as non-compatible. In fact, msxml6 was there in System32, but it somehow happened to be not registered as COM object. Using regsvr32 on msxml6.dll repaired the system, resurrected ReSharper and enabled customers to enjoy our productivity add-in again.
Case closed.
30 October 2008
Wild World of Visual Studio -- Unfriendly Package
While developing "The Most Intelligent Add-In To Visual Studio" we often face issues that originates from the outside of our code. Being that Visual Studio itself, other packages and add-ins installed, OS components or other things added to the mix - it is always extremely hard to reproduce, debug and understand. Usually we have to perform post-mortem debugging, when all we have is mini-dump from the user experiencing the crash. And we are very happy when we have mini-dump! Often we have to resort to psychic debugging, speculating about what could have happened, trying this and that until we find the cause and issue the fix.
I though I could share some stories of pure insanity we happened to participate in recently. May be another add-in developer is scratching his head in an attempt to understand the source of strange sounds from beneath the ground, and these stories will help. Or it may be just interesting reading for you. Or not :)
The first one is the most recent one and is pretty simple.
Story 1 -- Unfriendly Package
Our customers were complaining about Visual Studio crashing on start with ReSharper installed when running non-admin. Disabling ReSharper allows Visual Studio to load normally. When you see such behavior, you are absolutely sure ReSharper is guilty, aren't you?
We've learned to be cautious in such cases. So I asked user (thanks Jon!) to capture mini-dump and send it to me for investigation. While downloading it, I was preparing myself to long hours of WinDbg magic, but !ClrStack revealed it in a second. SnippetDesigner was not able to access its files, since it placed it in privileged folder. It did so in the background thread and didn't catch exceptions. The result is CLR termination, which get Visual Studio to nowhere with itself.
But wait! Why disabling ReSharper helped to avoid crash? Well, actually crash happens during SnippetDesigner package loading. Normally, it occurs when its window is opened (and it indeed crashes VS at this point without ReSharper). However, ReSharper uses Visual Studio API to get some configuration information, which can be extended with packages. So, by calling this API ReSharper caused those packages to load, essentially triggering the bug in SnippetDesigner on startup.
Case closed, opened another one.
I though I could share some stories of pure insanity we happened to participate in recently. May be another add-in developer is scratching his head in an attempt to understand the source of strange sounds from beneath the ground, and these stories will help. Or it may be just interesting reading for you. Or not :)
The first one is the most recent one and is pretty simple.
Story 1 -- Unfriendly Package
Our customers were complaining about Visual Studio crashing on start with ReSharper installed when running non-admin. Disabling ReSharper allows Visual Studio to load normally. When you see such behavior, you are absolutely sure ReSharper is guilty, aren't you?
We've learned to be cautious in such cases. So I asked user (thanks Jon!) to capture mini-dump and send it to me for investigation. While downloading it, I was preparing myself to long hours of WinDbg magic, but !ClrStack revealed it in a second. SnippetDesigner was not able to access its files, since it placed it in privileged folder. It did so in the background thread and didn't catch exceptions. The result is CLR termination, which get Visual Studio to nowhere with itself.
But wait! Why disabling ReSharper helped to avoid crash? Well, actually crash happens during SnippetDesigner package loading. Normally, it occurs when its window is opened (and it indeed crashes VS at this point without ReSharper). However, ReSharper uses Visual Studio API to get some configuration information, which can be extended with packages. So, by calling this API ReSharper caused those packages to load, essentially triggering the bug in SnippetDesigner on startup.
Case closed, opened another one.
06 October 2008
ReSharper Combos - Hiding Details
Today my day started with the question from Oleg Stepanov, Project Manager of ReSharper. He asked about avoiding huge amount of manual code changes, and after short discussion we got it done with ReSharper. I was very excited! We were able to solve refactoring task in seconds, invent new refactoring combo, and ReSharper was so smart to handle it absolutely right. No manual code changes outside of the type being refactored. Here is simplified version of what we had, what we were to accomplish and how we did it.
Consider PersonInformation class above. We wanted to decouple it from Person class and make it store Name and Age itself. However, we had a lot of usages like in Processor.Process, where Person property was being used to access Name and Age. How would we do it?
First, we use Generate (Alt-Ins) and select Delegating Members to generate Name and Age properties in PersonInformation class:
Then we change Person Property to return PersonInformation instead. Since there are all required properties already, usages are not broken. They are now routed through delegating members and use Name and Age properties of PersonInformation:
And here magic happens, we use Inline Property refactoring to get rid of the property!
Look how Processor now uses Name and Age directly on PersonInformation class and has no idea about Person class used inside! Now the fact that PersonInformation uses Person is implementation detail and we can change it any way we like.
Refactor With Pleasure!
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class PersonInformation
{
private readonly Person myPerson;
public PersonInformation(Person person)
{
myPerson = person;
}
public Person Person
{
get { return myPerson; }
}
}
internal class Processor
{
private readonly PersonInformation myPersonInformation;
public Processor(PersonInformation personInformation)
{
myPersonInformation = personInformation;
}
public int Process()
{
switch (myPersonInformation.Person.Name)
{
case "Mike":
return 1;
case "Sally":
return myPersonInformation.Person.Age > 30 ? 2 : 3;
}
return myPersonInformation.Person.Age < 20 ? 0 : 1;
}
}
Consider PersonInformation class above. We wanted to decouple it from Person class and make it store Name and Age itself. However, we had a lot of usages like in Processor.Process, where Person property was being used to access Name and Age. How would we do it?
First, we use Generate (Alt-Ins) and select Delegating Members to generate Name and Age properties in PersonInformation class:
public string Name
{
get { return myPerson.Name; }
set { myPerson.Name = value; }
}
public int Age
{
get { return myPerson.Age; }
set { myPerson.Age = value; }
}
Then we change Person Property to return PersonInformation instead. Since there are all required properties already, usages are not broken. They are now routed through delegating members and use Name and Age properties of PersonInformation:
public PersonInformation Person
{
get { return this; }
}
And here magic happens, we use Inline Property refactoring to get rid of the property!
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public class PersonInformation
{
private readonly Person myPerson;
public PersonInformation(Person person)
{
myPerson = person;
}
public string Name
{
get { return myPerson.Name; }
set { myPerson.Name = value; }
}
public int Age
{
get { return myPerson.Age; }
set { myPerson.Age = value; }
}
}
internal class Processor
{
private readonly PersonInformation myPersonInformation;
public Processor(PersonInformation personInformation)
{
myPersonInformation = personInformation;
}
public int Process()
{
switch (myPersonInformation.Name)
{
case "Mike":
return 1;
case "Sally":
return myPersonInformation.Age > 30 ? 2 : 3;
}
return myPersonInformation.Age < 20 ? 0 : 1;
}
}
Look how Processor now uses Name and Age directly on PersonInformation class and has no idea about Person class used inside! Now the fact that PersonInformation uses Person is implementation detail and we can change it any way we like.
Refactor With Pleasure!
03 October 2008
ReSharper Guidelines -- First Time Users
Harry L. wrote in review of ReSharper on Visual Studio Gallery:
Indeed, most important ReSharper features can be instantly learned right from the code editor without reading any documentation. However, I thought that having some guidelines about where to look and how to improve own productivity would be nice anyway. So I'm going to write several posts about how to use ReSharper in a form of guidelines.
Shortcuts are given for Visual Studio keyboard scheme, but you can easily find shortcuts for your configuration in ReSharper menu.
First Time Users guidelines:
After you familiarize yourself with these basic actions, download and print key map and start exploring other commands.
... I have found that I used the features of Resharper almost without knowing it. What amazed me was how many features I use without going up a long learning curve...
Indeed, most important ReSharper features can be instantly learned right from the code editor without reading any documentation. However, I thought that having some guidelines about where to look and how to improve own productivity would be nice anyway. So I'm going to write several posts about how to use ReSharper in a form of guidelines.
Shortcuts are given for Visual Studio keyboard scheme, but you can easily find shortcuts for your configuration in ReSharper menu.
First Time Users guidelines:
- DO open your real project in Visual Studio with ReSharper enabled. Playing with the productivity tool in a sandbox doesn't really give you understanding about its effect. It can take some time for ReSharper to analyze your solution for the first time, but it will be much faster during subsequent runs.
- DO NOT run away from your Visual Studio when you first open your source code with ReSharper :) You will see colored identifiers, a lot of squiggles indicating warnings and suggestions, redundant code painted in gray -- your code most likely will be overhighlighted. You will clean it up pretty fast with ReSharper. You can switch Color Identifiers off if you wish (ReSharper / Options / Code Inspection / Settings).
- DO configure your naming (ReSharper / Options / Languages / Common / Naming Style) and formatting preferences (ReSharper / Options / Languages / C# / Formatting Style). ReSharper uses these settings when guessing on identifiers, while updating the code and doing other automatic code generation and transformation for you.
- DO learn 4 keyboard shortcuts to use in code editor:
- Alt-Enter - opens code transformation menu with Quick Fixes and Context Actions. Try it whenever you see light bulb to the left of your code, and see what you can do with it.
- Alt-` (Navigate from Here) to open menu with actions to navigate from currently selected symbol, like "Go to base", "Go to derived" and "Go to usages"
- Alt-Ins (Generate) -- generates type members, like properties, constructors, overrides and implementations, Equals, GetHashCode and ToString methods.
- Ctrl-Shift-R (Refactor This) -- opens menu with all refactorings available at current caret position (or current selection in any ReSharper tool window).
- Alt-Enter - opens code transformation menu with Quick Fixes and Context Actions. Try it whenever you see light bulb to the left of your code, and see what you can do with it.
- DO NOT use Solution Explorer to find code, use "Go to Type" (Ctrl-T), "Go to File" (Ctrl-Shift-T), "Recent Files" (Ctrl-,) and other commands from ReSharper / Go To menu. This will help you navigate much faster.
After you familiarize yourself with these basic actions, download and print key map and start exploring other commands.
13 August 2008
ReSharper Combos -- Refactoring To Components
ReSharper has a number of features which are powerful by themselves, but reveal even more coolness when combined with other features. It's like Kung-Fu, when master can outperform enemies by wisely combining basic movements and strikes.
Let's take for example a task of converting existing system, where all types are instantiated explicitly, to some component container system. Without ReSharper, this task is SCARY! Just imagine, going through hundreds or even thousands of files, checking where particular component is used, where instance is created and how passed to clients and manually updating all that code. Days or weeks to complete? No, we aren't going to do this...
With ReSharper the task is still not simple one, but it can be achieved in a reasonable amount of time. Here is simple example:
Now let's make it utilize some fictional ComponentContainer:
1. Create temporary static class ComponentFactory to put factory methods in
2. Execute Replace constructor with factory method refactoring against component constructor, specify ComponentFactory as containing type.
3. Use Extract Interface refactoring from the component implementation.
4. Utilize Use base type where possible refactoring, select extracted interface. This should update all usages from specific class to interface.
5. Find Usages of component and verify you don't have any references to the class except instantiation inside ComponentFactory. Having other references mean interface was not complete, or there are dependencies on component implementation. Refactor as needed.
Now you should have something like this:
Note, how TheProcessor now uses ITheManager interface instead of specific implementation.
What you do next depends on what framework for components you are going to use. If you plan to use one of the Dependency Injection frameworks out there, you will continue with other components (TheProcessor in our example) and let framework inject ITheManager dependency into constructor. If you are going to use component querying system, you will update component constructor to use factory method instead of parameters, and use Safe Delete on parameters to remove them and update usages.
After you finish with refactoring all component access to ComponentFactory static class, you can change the implementation of factory methods to query your component framework of choice.
Finally, you are ready for the last strike to finish it off: use Inline Method refactoring to get rid of temporary factory methods and finish conversion of your code.
Let's take for example a task of converting existing system, where all types are instantiated explicitly, to some component container system. Without ReSharper, this task is SCARY! Just imagine, going through hundreds or even thousands of files, checking where particular component is used, where instance is created and how passed to clients and manually updating all that code. Days or weeks to complete? No, we aren't going to do this...
With ReSharper the task is still not simple one, but it can be achieved in a reasonable amount of time. Here is simple example:
public class TheManager
{
public void Manage(string text) { }
}
public class TheProcessor
{
private readonly TheManager myManager;
public TheProcessor(TheManager manager)
{
myManager = manager;
}
public void Process(IEnumerable<string> texts)
{
foreach (var text in texts)
myManager.Manage(text);
}
}
internal class Program
{
public static void Main(string[] args)
{
var processor = new TheProcessor(new TheManager());
processor.Process(args);
}
}
Now let's make it utilize some fictional ComponentContainer:
1. Create temporary static class ComponentFactory to put factory methods in
2. Execute Replace constructor with factory method refactoring against component constructor, specify ComponentFactory as containing type.
3. Use Extract Interface refactoring from the component implementation.
4. Utilize Use base type where possible refactoring, select extracted interface. This should update all usages from specific class to interface.
5. Find Usages of component and verify you don't have any references to the class except instantiation inside ComponentFactory. Having other references mean interface was not complete, or there are dependencies on component implementation. Refactor as needed.
Now you should have something like this:
public static class ComponentFactory
{
public static ITheManager CreateTheManager()
{
return new TheManager();
}
}
public interface ITheManager
{
void Manage(string text);
}
public class TheManager : ITheManager
{
public void Manage(string text) { }
}
public class TheProcessor
{
private readonly ITheManager myManager;
public TheProcessor(ITheManager manager)
{
myManager = manager;
}
public void Process(IEnumerable<string> texts)
{
foreach (var text in texts)
myManager.Manage(text);
}
}
internal class Program
{
public static void Main(string[] args)
{
var processor = new TheProcessor(ComponentFactory.CreateTheManager());
processor.Process(args);
}
}
Note, how TheProcessor now uses ITheManager interface instead of specific implementation.
What you do next depends on what framework for components you are going to use. If you plan to use one of the Dependency Injection frameworks out there, you will continue with other components (TheProcessor in our example) and let framework inject ITheManager dependency into constructor. If you are going to use component querying system, you will update component constructor to use factory method instead of parameters, and use Safe Delete on parameters to remove them and update usages.
After you finish with refactoring all component access to ComponentFactory static class, you can change the implementation of factory methods to query your component framework of choice.
Finally, you are ready for the last strike to finish it off: use Inline Method refactoring to get rid of temporary factory methods and finish conversion of your code.
29 July 2008
What's Next? -- Life After Release
We released ReSharper 4 in June and I didn't post since then. First, I was on vacation and it was great. Then, our team left the city to spend 4 full days discussing ReSharper future, inventing new features, building plans and coordinating efforts. Awesome experience, I must say. After that, we focused on preparing maintenance release 4.0.1 which will be out as soon as we verify it against recently released Visual Studio 2008 SP1. Now we are starting to work towards 4.5 release, which is tentatively planned to be released by the end of the year, or may be at the beginning of year 2009. So, what are we going to do?
Please note, that it is preliminary plan only and is subject to change at any time.
1. More performance
2. Less memory usage
Yes, we are going to spend about four months tackling performance and memory issues, optimizing various parts of our product and improving architecture to prepare for the next major step forward.
In addition to the overall product quality improvement, we are going to improve some existing features, based on your feedback, and add some new.
3. New refactorings are being developed, which will allow you to perform more intelligent solution-wide code transformation. We didn't finalize the list yet, but most likely they will be from "Inline" family.
4. Enhanced setup for naming conventions which will be supported by all ReSharper features. We are not going to implement all functionality of the AgentSmith plugin, but we want to stop naming issues experienced by some of ReSharper users once and for all.
5. Visual Build - new feature to display build process inside Visual Studio in a better way. Think "Unit Test Session" style, but for building your solution. This feature will also lay the foundation for future features, like optimizing build procedure.
6. Visual Basic 9 support. Our cross-language refactorings and editing experience enhancements will fully support VB9 constructs, like anonymous functions and XML literals.
As usual, once we perform all potentially dangerous changes to our code base and stabilize the build, we will start publishing nightly builds for your Early Access Pleasure.
PS: If you didn't express your opinion about ReSharper 4 on Visual Studio Gallery, you can let other people know what do you think via rating and review functionality recently added to this site.
Please note, that it is preliminary plan only and is subject to change at any time.
1. More performance
2. Less memory usage
Yes, we are going to spend about four months tackling performance and memory issues, optimizing various parts of our product and improving architecture to prepare for the next major step forward.
In addition to the overall product quality improvement, we are going to improve some existing features, based on your feedback, and add some new.
3. New refactorings are being developed, which will allow you to perform more intelligent solution-wide code transformation. We didn't finalize the list yet, but most likely they will be from "Inline" family.
4. Enhanced setup for naming conventions which will be supported by all ReSharper features. We are not going to implement all functionality of the AgentSmith plugin, but we want to stop naming issues experienced by some of ReSharper users once and for all.
5. Visual Build - new feature to display build process inside Visual Studio in a better way. Think "Unit Test Session" style, but for building your solution. This feature will also lay the foundation for future features, like optimizing build procedure.
6. Visual Basic 9 support. Our cross-language refactorings and editing experience enhancements will fully support VB9 constructs, like anonymous functions and XML literals.
As usual, once we perform all potentially dangerous changes to our code base and stabilize the build, we will start publishing nightly builds for your Early Access Pleasure.
PS: If you didn't express your opinion about ReSharper 4 on Visual Studio Gallery, you can let other people know what do you think via rating and review functionality recently added to this site.
09 June 2008
ReSharper 4.0 Gone Diamond
Here it is, ReSharper 4.0. After faceting our diamond, we are finally ready to release it!
In this new release, C# 3.0 is supported in all its power -- lambdas, extension methods, language integrated queries (aka LINQ), object and collection initializers, anonymous types, automatic properties and partial methods. Ah, of course implicitly typed locals ("vars") are there to argue for or against using them. I already wrote about some of the features, and you can find more information on the New Features page. Here is small final touch about how deeeeep we dived into the language: try introducing parameter from expression which uses local variables and play with checkboxes for local variables.
Except for new language support, we also improved our product in many other ways:
I can't really enumerate all the improvements in ReSharper 4.0 made during last year. It would take too much space on this blog. Try it yourself! Feel the difference!
develop.With(pleasure => pleasure * 4.0);
In this new release, C# 3.0 is supported in all its power -- lambdas, extension methods, language integrated queries (aka LINQ), object and collection initializers, anonymous types, automatic properties and partial methods. Ah, of course implicitly typed locals ("vars") are there to argue for or against using them. I already wrote about some of the features, and you can find more information on the New Features page. Here is small final touch about how deeeeep we dived into the language: try introducing parameter from expression which uses local variables and play with checkboxes for local variables.
Except for new language support, we also improved our product in many other ways:
- We added new powerful refactorings and greatly improved existing.
- We extended typing helpers with CamelCase completion and Complete Statement. Now you can achieve more in less time.
- We analysed many .NET Framework assemblies for you, and maked them up for you with CanBeNull/NotNull attributes. And ReSharper's value analysis raised to the next level.
- We tested it with numerious other addons, plugins, SDKs and packages. And improved ReSharper's integration into Visual Studio ecosystem by a wonderful degree.
- Of course we fixed a lot of problems and eliminated many performance bottlenecks.
I can't really enumerate all the improvements in ReSharper 4.0 made during last year. It would take too much space on this blog. Try it yourself! Feel the difference!
develop.With(pleasure => pleasure * 4.0);
03 June 2008
ReSharper 4.0 Release Candidate
After extensive testing and fixing problems in Beta we are ready to publish Release Candidate build. Some critical fixes can still happen in this branch, but otherwise we are almost ready to release.
If you are using any nightly build or beta, please upgrade to Release Candidate. If by chance you find a problem that prevents ReSharper 4 from being used on a regular basis, please tell us! You can submit request into our issue tracking system, and we will try hard to fix any critical problem, if we can reproduce it. So please, please, please, include as much information about your environment, projects and source files as you can.
Thank you very much for participating in our Early Access Program!
If you are using any nightly build or beta, please upgrade to Release Candidate. If by chance you find a problem that prevents ReSharper 4 from being used on a regular basis, please tell us! You can submit request into our issue tracking system, and we will try hard to fix any critical problem, if we can reproduce it. So please, please, please, include as much information about your environment, projects and source files as you can.
Thank you very much for participating in our Early Access Program!
26 May 2008
Functional Style -- Highlight Mutable Variables
Once you go for lambdas, lazy computations and other functional techniques in programming, you may want your code to be mostly immutable. With ReSharper 4 we didn't do much about data analysis, like do not detect immutable objects or methods. However, one analysis is already available to you: highlight mutable local variables. Open Tools menu, select Options, browse for Fonts and Colors under Environment group. In the Display items find ReSharper Mutable Local Variable and change the appearance as you like. I use Bold font. ReSharper will now highlight every variable that changes its value after the value has been already used.
Try it, and tell us what do you think!
Try it, and tell us what do you think!
21 May 2008
ReSharper 4 Beta
Did you use one of the nightly builds we publish for several months already? If you thought it is dangerous for you to run early development bits, today we present you ReSharper 4 Beta, which we optimized, stabilized and verified to be of better quality than ordinary nightlies. It is not complete product yet, we have some more work to do in various areas of product, but otherwise this build is pretty stable and usable.
C# 3.0
This major language update was not an easy thing to support. It was tough to make it right, when tool knows the code inside out and understands every detail of what is written. There are many little things that you probably will not even notice, but which were well thought out and implemented to provide flawless code editing, navigating and refactoring experience.
I'd like to highlight some features: global completion for extension methods, which inserts required namespace imports; optional parameter info in form of lambda, like "IEnumerable<string> => string" instead of Func<IEnumerable<string>,string>; refactorings specific to new language features, like creating named type from anonymous one or converting static method to extension method and updating usages.
.NET Framework Annotations
Since version 2.5 we have "Null Reference Analysis", which is capable to warn developer about potential NullReferenceException in the code. To aid this analysis, developers can annotate methods with NotNull or CanBeNull attributes, which ReSharper then uses to initialize variable states. That's cool enough by itself, but there are thousands of methods you can't annotate in source: the .NET Framework assemblies. We took up a challenge and implemented the way to annotate libraries with external annotations. And we made second step, too. We annotated most of .NET Framework (56 assemblies!), so that you can get potential NullReferenceException warning on the code like (SomeStruct)Marshal.PtrToStructure(...);
Completion-on-steroids
That's something I like most. No, wait, I love new refactorings, recent edits window, to-do browser understanding of NotImplementedException, and all other features mentioned on the official site.
Two things: "CamelHumps Completion" and "Complete Statement" bring my coding speed to a new level. I don't know what it would be called in Jedi hierarchy, but it seems to me that I can create code withlightning teleportation speed.
ASP.NET speed-up
The last, but not least thing I'd like to mention is our raid against ASP.NET problems. It is something that had speed and memory problems through all versions of ReSharper, and we finally managed to identify them, and fix. Now, if you develop ASP.NET web sites, go try ReSharper 4 Beta.
Download
In this release we bring you the single installer for both Visual Studio 2005 and 2008, as well as all editions we have. Download, install, select "Free Evaluation", choose edition - and you are ready to be productive.
C# 3.0
This major language update was not an easy thing to support. It was tough to make it right, when tool knows the code inside out and understands every detail of what is written. There are many little things that you probably will not even notice, but which were well thought out and implemented to provide flawless code editing, navigating and refactoring experience.
I'd like to highlight some features: global completion for extension methods, which inserts required namespace imports; optional parameter info in form of lambda, like "IEnumerable<string> => string" instead of Func<IEnumerable<string>,string>; refactorings specific to new language features, like creating named type from anonymous one or converting static method to extension method and updating usages.
.NET Framework Annotations
Since version 2.5 we have "Null Reference Analysis", which is capable to warn developer about potential NullReferenceException in the code. To aid this analysis, developers can annotate methods with NotNull or CanBeNull attributes, which ReSharper then uses to initialize variable states. That's cool enough by itself, but there are thousands of methods you can't annotate in source: the .NET Framework assemblies. We took up a challenge and implemented the way to annotate libraries with external annotations. And we made second step, too. We annotated most of .NET Framework (56 assemblies!), so that you can get potential NullReferenceException warning on the code like (SomeStruct)Marshal.PtrToStructure(...);
Completion-on-steroids
That's something I like most. No, wait, I love new refactorings, recent edits window, to-do browser understanding of NotImplementedException, and all other features mentioned on the official site.
Two things: "CamelHumps Completion" and "Complete Statement" bring my coding speed to a new level. I don't know what it would be called in Jedi hierarchy, but it seems to me that I can create code with
if(CVM.I.SV(SCV.FU <Ctrl-Shift-Enter>When I hit keys like above, it is completed into:
if (CodeViewManager.Instance.SupportsView(StandardCodeViews.FindUsages))And caret is inside braces for me to type in the body of the "if" statement.
{
}
ASP.NET speed-up
The last, but not least thing I'd like to mention is our raid against ASP.NET problems. It is something that had speed and memory problems through all versions of ReSharper, and we finally managed to identify them, and fix. Now, if you develop ASP.NET web sites, go try ReSharper 4 Beta.
Download
In this release we bring you the single installer for both Visual Studio 2005 and 2008, as well as all editions we have. Download, install, select "Free Evaluation", choose edition - and you are ready to be productive.
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!
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!
02 April 2008
We Read You, Anonymous
9 minutes ago I've received the following from anonymous user of our uninstall feedback form:
Thank you, Anonymous, I will pass this to our administrators so they can decide which server to route information to :)
I am uninstalling ReSharper because my licencse is only for C# :)
Reinstall is waiting for me, so i can't lose my time typing some unuseful text that won't be read anyway.
Have a good time, JetBrains Server!
Thank you, Anonymous, I will pass this to our administrators so they can decide which server to route information to :)
24 March 2008
MbUnit for ReSharper 4
Albert Weinert ported MbUnit plugin to ReSharper 4 API, so you can try it with latest ReSharper 4 nightly builds. Read more and download Beta 7.
04 March 2008
Varification -- Using Implicitly Typed Locals
With the ReSharper 4 nightly builds available, some people are complaining about numerious suggestions to convert explicit type to "var" keyword. Of course, you can hide this suggestion by using Options / Code Inspection / Inspection Severity, or by using Alt-Enter and selecting "Change severity" option. But what's the deal with implicitly typed locals, anyway? Using var keyword can significantly improve your code, not just save you some typing. However, it may require discipline to apply good practices when using implicitly typed variables. Here is my list:
To summarize the list above, by actively using var keyword and refactoring your code as needed you improve the way your code speaks for itself.
PS: Visit ReSharper at Visual Studio Gallery!
- It is required to express variables of anonymous type. This is pretty obvious - you cannot declare local variable of anonymous type without using var.
- It induces better naming for local variables. When you read local variable declaration with explicit type, you have more information at that moment and something like "IUnitTestElement current" makes sense. However, when this local variable is used later, you read "current" which takes some time to figure out the meaning. Using "var currentElement" makes it easier to read at any place.
- It induces better API. When you let compiler deduce type from method return type or property type, you have to have good types in the first place. When you don't have explicit type in the initialization expression, you have to have best names for members.
- It induces variable initialization. It is generally a good practice to initialize variable in the declaration, and compiler needs initializer to infer type for local variable declared with "var" keyword.
- It removes code noise. There are a lot of cases, when implicitly typed local will reduce amount of text developer needs to read, or rather skip. Declaring local variable from new object expression or cast expression requires specifying type twice, if we don't use "var". With generics it can lead to a lot of otherwise redundant code. Another example would be iteration variable in foreach over Dictionary<TKey,TValue>.
- It doesn't require using directive. With var, you don't have explicit reference to type, as compiler infers type for you, so you don't need to import namespace when you need a temporary variable.
To summarize the list above, by actively using var keyword and refactoring your code as needed you improve the way your code speaks for itself.
PS: Visit ReSharper at Visual Studio Gallery!
20 February 2008
Visual Studio 2005 and ReSharper 4 Nightly Builds
ReSharper 4 should work with Visual Studio 2005, and it will support C# 2.0 language features. If you happen to participate in our early access program, and you are using Visual Studio 2005, please note that you have to have .NET Framework 3.5 installed.
Also, we would be happy if you were reporting any features that belong to C# 3.0 but appear in Visual Studio 2005, like suggestions for lambdas or var. Please read information about our issue tracker beforehand.
Thank you.
Also, we would be happy if you were reporting any features that belong to C# 3.0 but appear in Visual Studio 2005, like suggestions for lambdas or var. Please read information about our issue tracker beforehand.
Thank you.
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.
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.
14 February 2008
ReSharper 4 Nightly Builds - Are You Geek Enough?
-- When ReSharper 4 will be ready?
-- It is ready when it is ready!
We in ReSharper team want to make sure that C# 3.0 language is fully supported by the product. We spend a lot of time on features and look deep into details of every language quirk. You know, compilers and language standards may have very strange relationships, sometimes very weird. Still, we want to ensure maximum pleasure developing in C# 3.0 when ReSharper is ready. And it is not ready yet.
However, due to the popular demand amongst professional developers using ReSharper and C# 3.0, we are going to open nightly builds to the public. That is, not fully fledged tool, but rather our current development bits. Which could be very well broken, buggy, hanging, slow and useless at times. We will not take any responsibility if the tool wipes out all your source code! But you have a version control system in place, don't you?
So, are you geek enough to take the pill and try ReSharper 4 early builds? Read the ReSharper 4 EAP notes before you decide!
If you feel you can survive pre-release build, you can go to ReSharper 4 Nightly Builds and download your copy of ReSharper development bits.
Good luck!
04 February 2008
Compiler Optimizations May Be Dangerous
Consider the following code:
This code doesn't use System.Linq extensions methods to do LINQ, and instead declares own Select and Where methods, which are rather crazy. This code compiles, but what is the type of "lengths" variable? It should be IEnumerable<int>, because that is what Select method returns. But if you look at actual compilation output, it turns out that compiler decided "select hashCode" to be very simple (actually, transforms into identity lambda hashCode => hashCode). And it removes the call to Select() method. And breaks my code. One can have some hard time understanding why their code doesn't work, or even doesn't compile.
I can force compiler to call my Select() method by surrounding hashCode in select clause with parenthesis:
It is not trivial to compiler anymore, and thus it emits correct code.
UPDATE: This behaviour is by design. See 7.15.2.5 Select clauses:
I still find this very error prone...
static class Test
{
public static IEnumerable<int> Select<T>(this IEnumerable<T> list, Func<int, int> f)
{
foreach (var item in list)
yield return f(item.GetHashCode());
}
public static IEnumerable<bool> Where<T>(this IEnumerable<T> list, Func<int, bool> f)
{
foreach (var item in list)
yield return f(item.GetHashCode());
}
static void Foo(IList<string> list, IList<string> list2)
{
var lengths = from hashCode in list
where hashCode * 2 > 10
select hashCode;
}
}
This code doesn't use System.Linq extensions methods to do LINQ, and instead declares own Select and Where methods, which are rather crazy. This code compiles, but what is the type of "lengths" variable? It should be IEnumerable<int>, because that is what Select method returns. But if you look at actual compilation output, it turns out that compiler decided "select hashCode" to be very simple (actually, transforms into identity lambda hashCode => hashCode). And it removes the call to Select() method. And breaks my code. One can have some hard time understanding why their code doesn't work, or even doesn't compile.
I can force compiler to call my Select() method by surrounding hashCode in select clause with parenthesis:
var lengths = from hashCode in list
where hashCode * 2 > 10
select (hashCode);
It is not trivial to compiler anymore, and thus it emits correct code.
UPDATE: This behaviour is by design. See 7.15.2.5 Select clauses:
A query expression of the form
from x in e select v
is translated into
( e ) . Select ( x => v )
except when v is the identifier x, the translation is simply
( e )
I still find this very error prone...
31 January 2008
ReSharper 4 EAP Will Start in Two Weeks
ReSharper 4 Early Access Program will start within next two weeks, before Feb 15.
The delay is caused mostly by the complexity of lambda implementation, which we really want to do right so that the power of C# 3.0 and ReSharper can be utilized at a full rate. Now, when we have lambdas working, we will finish with LINQ processing, polish the code a bit and start nightly builds.
I'm going to post some feature highlights here during that period. This will cover C# 3.0 new features support, new features like Complete Statement and Recent Edits, improvements in intellisense like CamelHumps completion and other.
Stay tuned.
The delay is caused mostly by the complexity of lambda implementation, which we really want to do right so that the power of C# 3.0 and ReSharper can be utilized at a full rate. Now, when we have lambdas working, we will finish with LINQ processing, polish the code a bit and start nightly builds.
I'm going to post some feature highlights here during that period. This will cover C# 3.0 new features support, new features like Complete Statement and Recent Edits, improvements in intellisense like CamelHumps completion and other.
Stay tuned.
25 January 2008
One Line - Navigation in Parameter Information
When ReSharper's parameter information is displayed for a method, TAB and SHIFT-TAB will navigate caret through arguments you are passing.
14 January 2008
One Line - Find Usages Advanced
When you want to search for all overloads of a method, or search for type and its members usages, or search in referenced libaries in addition to source code - use Find Usages Advanced command (ReSharper | Search | Find Usages Advanced...).
Subscribe to:
Posts (Atom)