How it works
Like content assist in Java editors in Eclipse, the Esprima content assist plugin is based off of a semantically rich abstract syntax tree (AST) and so content assist proposals are more likely to be relevant than if we were using a lexical approach to content assist. Here is what happens:
- On a content assist invocation, the contents of the buffer are parsed by Esprima.
- The resulting AST is walked by the content assist plugin.
- While walking the AST, the target type of any AST node is recorded as well as assignments and declarations. This information helps us keep track of what properties are available on each known type at any given point in the AST.
- After walking a sufficient amount of the AST (we don't need to walk the entire tree since parts of it are not going to be relevant for a given content assist invocation), all available proposals are calculated based on the target type of the invocation offset and the prefix.
The best way to understand how this works is through examples.
What it can do
Recognizing function scopes
As you can see in this screenshot, scoping is respected and identifiers that are not accessible in the current scope (vInnerInner, v3, v4,…) are not shown in content assist.
The key/values of object literals are appropriately proposed:
Even nested object literals are recognized:
Simple control flow
Simple control flow is recorded by the plugin, so that assignments are remembered:
Some (but not all) predefined types are available in content assist.
Currently, the plugin recognizes
Date, but I will probably add more as it makes sense.
Functions that start with capital letters are considered constructors
As you can see in the screenshot, despite all of the funky dots, the plugin is able to realize that myVar is of type Number and is providing appropriate proposals.
What it can't do (yet)
This is still early for the content assist plugin and there is quite a bit of work to do. For example:
- There is no pre-defined window object, which probably should be there, along with possibly other predefined objects, like dojo, dijit, and $ (jquery).
- There is no analysis of function return types
- No inter-file type inferencing, which will be crucial for getting anything really smart working
- The plugin should recognize /*global */ comments
- The Esprima-based proposals are currently intermingled with proposals from the default JS content assist plugin and so duplicates appear. (Esprima proposals are always prefixed with a handle (Esprima) so you know where they come from, but they are always on the bottom).
I hope to deal with each of these issues eventually, but I also need to make sure that performance remains reasonable, which it currently seems to be, but is something I need to watch.
How to get it
Mark Macdonald has already added the pluign to the Orion plugin page, so after you log into Orion, click to the "Get Plugins" link and select the Install link for the Esprima content assist plugin:
The github page is located here: https://github.com/aeisenberg/esprimaContentAssist so try it out, have a look at the code and let me know what you think!