A couple months have passed since I announced v0.1 and the availability of the source code. I haven’t gotten to work on it as much as I’d like, but such is the way things go. At the end of my last post, I mentioned two key goals as the next steps: 1) Porting the code to NRefactory for distribution and Mono use. 2) Supporting full projects. I’m happy to say that not only have both of these goals have been met, but I now have a handy installable extension available for download.
The first thing you might have noticed is some usability touch ups. There’s no more hovering button off to the side, I’ve integrated into Visual Studio’s smart tags feature to present the feature.
Secondly, I’ve started to generate a test call for you. Now that full namespaces are required in the test code (more later), it seemed only fair that I do the hard work for you. If your method is an instance method, I’ll even go ahead and throw in a new object for you. This feature has a lot of room for improvement, but it’s a start. I’d like to look into actually supplying constructor arguments and better support for arrays/collections next.
Thirdly, although it’s basic, I’ve shunted compiler errors and evaluation exceptions into the status bar. More than once my code has stopped evaluating and figured it was a bug, only to discover there was an issue with my test code.
Full project support
We now have full project support. Previously you were restricted to the confines of a single method, unable to call other methods in the current class or use any other classes from your project. With full project support, you can now use any method or class from your current project as well as any from other, referenced, projects.
This is not optimized in any way and I’d be surprised if it performed remotely acceptably on a large project or even large individual files. I have some ideas on how this can be improved, but for the moment it works. There’s also a distinct possibility that there are some projects that this will not work for; Pre and post-build steps are ignored, for example.
Instant will not recompile other projects for you, as I demonstrate in the example you must do this yourself. Evaluation will silently fail if you haven’t compiled the other libraries at least once. Instant will detect build completions and automatically rerun a current evaluation for you, however.
Having full project support affects the way you use the tool in a number of ways. Now that the context has expanded past a single method, the lax rules of Roslyn’s ScriptEngine are gone. Your project will need to actually compile to get an evaluation, you’ll need to fully qualify any namespaces in your test code and currently your method will need to be publicly accessible. Additionally, portable library projects are not currently supported.
How does this work?
The Visual Studio extension integrates into the project system to obtain a list of the source files for your project and the references it makes. Since the document containing the method you’re evaluating is in an unsaved state most of the time, we pull its source straight from VS.
We create a new AppDomain, pass the source over along with the instrumentation sink (the object that “logs” the changes), compile it and execute it. Why are we doing this in a separate AppDomain? As you may know, you can not unload assemblies individually from an AppDomain, you can only unload whole AppDomains. So, we make a new one for each compilation so that we can unload it and avoid a memory leak, as well as delete the temporary assembly created from the disk.
This version no longer uses Microsoft’s Roslyn, but instead uses NRefactory for a number of reasons. Roslyn is currently in a CTP form and therefore, true to form, its license is unnecessarily restrictive. Not only would it prevent me from moving forward on a MonoDevelop plugin (due to a requirement for it to be on Windows), but it would prevent me from even redistributing a VS/Windows only package. Combine this with the fact that it’s not open source so there’d be no way for me to guarantee that it runs on Mono and the choice was simple.
Porting over from Roslyn was surprisingly easy. I found all same tools I’d been using in Roslyn in only slightly different shapes and was able to quickly get back up to speed. As with all rewrites, I had the chance to make some internal improvements along the way.
Now that a lot of critical plumbing is in place, what’s next? Two areas need some major time investment: Visualization and optimization.
As I’ve mentioned before, there’s lots of visualization improvements that can be made, big and small. This is likely where I will spend the next chunk of time since things generally work now.
For optimization, I will need to grab some large projects and do some profiling tests. I fully expect for the pain points to be AppDomain creation and the actual process of compiling the code to be the main points of delay.
How can I help?
Just trying it out and providing feedback (good, bad, or bugs) would be a huge help. Beyond that, there’s a list of tasks on GitHub to choose from or obviously any enhancements or fixes you come up with on your own. Leave a note you’re working on an item, fork the project and hack away! Be sure to check out the contributing guidelines.
My biggest hope for help is the MonoDevelop addin as I don’t have any immediate plans to accomplish this. If you’re interested in working on it, let’s talk, I’m happy to help.
Where is it?
Visual Studio Extension: Instant-0.2.vsix
Report bugs: https://github.com/ermau/Instant/issues