25 Nov 2011

Towards JavaScript Refactoring

Over the past year, we have worked hard to elevate your code editing experience far beyond what a plain text editor gives you. The first step was syntax highlighting. Syntax highlighting visually tells you what is important in your program, it gives you a visual sense of the structure: where are the functions, where are variables declared etc.

The second step we took was to integrate existing tools, for instance JSHint, to mark common JavaScript mistakes, or Narcissus to mark JavaScript parse errors. However, those are very specific tools for specific languages. While our focus is on JavaScript right now, we want to support other languages in the future -- we need a solid foundation to plug in all kinds of fancy code editing features, giving you the feeling the IDE understands your program -- and that a program is more than just a flat text file.

Today, we launch the first version of that language foundation. But before getting into the nitty gritty. Let's look at a few features we built using it.

Variable instance highlighting and renaming

When your cursor is on a variable in your JavaScript code, other instances of that variable are automatically highlighted. This feature gives you a better understanding of your program: this variable -- where else is it used, how is it used, etc. Don't like it? Disable it in the preferences.

Screen_shot_2011-11-24_at_4

In addition, if your cursor is on a variable or function name or function argument declaration, you can now easily rename it through Edit > Refactor > Rename variable (or using Cmd-Option-R on Mac, Ctrl-Alt-R on other operating systems). This will switch the editor into inline refactoring mode. You can now, in the code itself, change the variable name and all places where the variable is used (in the same file) update automatically as you type. To exit this renaming mode, simply move your cursor outside the variable declaration box and you're done. And of course, this feature takes scopes into account -- it understands your code.

Screen_shot_2011-11-24_at_4

Mo' warnings, fewer problems

Adding new analyses that detect commonly made mistakes and other hints are now simple to implement. We added two to begin with: unused variables and assigning to undeclared variables.

Looking for unused modules in your node.js code? They're trivial to find now. Any variable you declare that is not used anywhere will be clearly marked -- ready to be deleted.

Screen_shot_2011-11-24_at_4

The second one is assigning to undeclared variables. JavaScript doesn't complain about it, unless you use strict mode, but when you do it, such variables will be declared in the global namespace -- probably not what you intended. Cloud9 will now clearly mark those for you.

Screen_shot_2011-11-24_at_4

 

Behind the scenes

Powering these features is our new Cloud9 Language Foundation. The framework we built enables Cloud9 IDE extensions to easily plug in:

  • parsers for various languages
  • analyzers that analyze the code and mark warnings and errors
  • code completion engines
  • refactorings

In the future we will also support other features, like code outlines, alternative visualizations etc.

A parser reads in source code, for instance JavaScript code, and turns it into a datastructure called an Abstract Syntax Tree (or AST for short). Analyzers can subsequently traverse this tree-shaped datastructure and perform interesting analyses and emit warnings or errors. All of this heavy lifting happens in a WebWorker so it never slows down your editing experience.

However, as it turns out, nearly all JavaScript analysis tools use a different datastructure to represent ASTs, and they are nearly all specific to JavaScript. This is not what we want to have in Cloud9 IDE.

Therefore, we built treehugger.js, a library that standardizes the format of the AST in a language-independent way, i.e. JavaScript ASTs can be expressed, as well as Ruby or Java ASTs -- using the same data structure. Treehugger.js comes with various utilities to easily traverse ASTs and do analyses using pattern matching. Treehugger.js and the Cloud9 Language Foundation borrow many ideas from Stratego/XT and Spoofax -- two research projects that attempt to simplify the construction of compilers, code analysis tools and IDEs for custom programming language.

Treehugger.js currently comes with a fast and solid JavaScript parser based on UglifyJS. In the future we (or the community!) will build parsers for other languages as well.

Just gettin' started

These new features are just the tip of the iceberg now that we have the new analysis infrastructure. You can look forward to many more analysis-based features in the future! And yes, all of this is open source, ready to be extended by you.

Here's a video demonstrating the features: