Creating (Eclipse) Aptana JavaScript Content Assist Files (sdocml)

I have a been a long time user of Aptana (I use the Eclipse plugin; there is also a self-contained Aptana IDE which wraps eclipse), and find it to be a very good (free) IDE for web development (JavaScript, CSS, HTML). JavaScript editors today don’t seem to be as good or advanced as other languages like Java, C# or just about any strongly-typed language and thus good content assist is hard to get.  Content assist for me is a big feature specially when working with a large code bases or many libraries or frameworks. Yes, you can have a second page open with the API documentation visible, but having as you type your code is a big productivity tool.

Aptana, for the most part, seems to do (IMO) a good job at it by picking up methods and variables available in the scope/context as well as suggestion for browser globals and the JavaScript language. One the more powerful features, however, is the ability to drop in documentation files that can help with content assist if the source is not available. Kind of an extension point, so that we are not limited to only having suggestion come from source files.  A good example is jQuery which Aptana provides support out of the box. The files, written in XML using ScriptDoc 2.0 Specification, allow library writers to provide these along with their work and thus automatically enable content assist in this popular editor. Here is a sample file:

<?xml version="1.0"?>
<javascript>
    <class type="Widget">
        <description>Widget base class. Provides a foundation for other more specific widgets.</description>
        <constructors>
            <constructor scope="instance">
                <parameters></parameters>
                <return-types>
                    <return-type type="Widget"/>
                </return-types>
            </constructor>
        </constructors>
        <methods>
            <method name="init" scope="instance">
                <description>Initializes the widget.</description>
                <parameters>
                    <parameter name="options" type="Object" usage="optional"></parameter>
                </parameters>
            </method>
            <method name="onReady" scope="instance">
                <description>Callback function called when widget is ready.</description>
                <parameters></parameters>
            </method>
            <method name="extend" scope="instance">
                <description>Extends this class and returns a new class constructor</description>
                <parameters></parameters>
                <return-types>
                    <return-type type="Widget"/>
                </return-types>
            </method>
        </methods>
    </class>
</javascript>

For a long time I have been generating these SDOCML files and they work just fine for global and static members, but I was not able to trigger content assist for class instances. With the increasingly popular use of classes and modules using the AMD patterns in JavaScript projects, having this work as expected in these cases would be a huge plus.
The need to make these work became even more important to me professionally in the last month or so as a took on a new role as a GUI Web Developer and started working with a large internal framework.  If I am going to make a different quickly in this project, I needed my tools (editor) to cooperate.

So what is the problem? Here is a code sample

var wdg;

/** @type {Widget} */
wdg = new Widget();

Typing wdg. should suggest the three methods you see above in the SDOCML file (init, onReady and extend).  Instead I get the following:

aptana-no-content-assist

In the last few days I got a break through after interacting with a developer named Jocki on github (thread here). He has a patched version of Aptana that adds a few improvements to jQuery’s content assist. In that discussion, he was kind enough to suggested that I add the <type-maps> declaration to my file and map the Class Names to the internal way Aptana handles the looks ups (which they are looking to fix, according to this – I think).

With that tip, I changed my SDOCML file to this:


<?xml version="1.0"?>
<javascript>
    <class type="Widget">
        <description>Widget base class. Provides a foundation for other more specific widgets.</description>
        <constructors>
            <constructor scope="instance">
                <parameters></parameters>
                <return-types>
                    <return-type type="Widget"/>
                </return-types>
            </constructor>
        </constructors>
        <methods>
            <method name="init" scope="instance">
                <description>Initializes the widget.</description>
                <parameters>
                    <parameter name="options" type="Object" usage="optional"></parameter>
                </parameters>
            </method>
            <method name="onReady" scope="instance">
                <description>Callback function called when widget is ready.</description>
                <parameters></parameters>
            </method>
            <method name="extend" scope="instance">
                <description>Extends this class and returns a new class constructor</description>
                <parameters></parameters>
                <return-types>
                    <return-type type="Widget"/>
                </return-types>
            </method>
        </methods>
    </class>
    <type-maps>
          <type-map source-type="Widget" destination-type="Function&lt;Widget&gt;"/>
    </type-maps>
</javascript>

And voila! Content assist in the editor.

aptana-content-assist

I found that the type-maps needed to be added to the end of the file or after the class definitions. Placing it at the top of the file did not seem to work for me.

In my use of the @type declaration I have found only 1 issue: if you use it together on the same line as the ‘var’ declaration, content assist does not seem to display. Example:


var /** @type {Widget} */ wdg = new Widget();

Aside from that, which is a small tweak to how you code, the use of these help files along with @type declarations work pretty well, including placing these next to Function input parameters:


function doSomething ( /** @type {Widget} */ wdg) {

}

aptana-content-assist-function-param

 

Generating SDOCML files

These files can be created manually but for large projects, that’s just not feasible. The ideal would be to run a tool against the code and generate such file. I have always annotated my code with jsdoc tags, which makes it a fairly easy task to now just generate the content assist file by using template. And that’s what I created: a jsdoc3 template that outputs a SDOCML file from source files annotated with jsdoc tags. I’ll save this topic and the introduction/availability of that template for a subsequent post.

 

 

Advertisements

One thought on “Creating (Eclipse) Aptana JavaScript Content Assist Files (sdocml)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s