Tuesday, April 29, 2008

JavaScript Type Inference in NetBeans

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.

Roman Strobl has just
published a screencast of the new JavaScript editor in NetBeans 6.1. The demo is around 5 minutes and highlights many of the editing features.

I'd like to dwell on the type inference part a bit. Around four minutes into the demo, Roman shows that NetBeans figures out the types of expressions, including those involving function calls. In his example, all the types happened to be Strings so it may look like a lucky coincidence. It's not! Here's some code fragments showing in more detail what's going on. Let's start with a jQuery expression in an HTML file - in my
last entry
I showed how code completion already
helps you fill in the strings inside the jQuery dollar function. NetBeans knows the return type of the dollar function so we're only presented with jQuery methods here:

jQuery methods return the jQuery object itself as the return value, so we can chain calls into jQuery. We'll do that here by calling a function on the return value from addClass:

As you can see, when NetBeans knows the return type of a function, it's shown in code completion item separated by a colon. Here I want to call the queue() method which returns an array of functions. Let's see what happens if we just call functions on the result object:

As you can see - we're getting methods on the Array class, since we're getting an array back. Let's pick a specific element in the array instead, and see what code completion gets us:

As you can see it knows that this must be a Function, so we get for example the apply method suggested. (Put another way, we're tracking internally the type of the elements within the array.)

At this point you may wonder where these types come from. JavaScript is not a statically typed language, so what gives? It turns out that while JavaScript isn't typed, a lot of code is written with specific types in mind, and in fact there are a lot of documentation conventions for declaring the intended types not just of function return values, but of parameters and properties as well. NetBeans understands many of these - such as @param {Type}, @return {Type}, and @type. Here's a new function we've added in the editor which declares a return type:

As you can see, when we try to invoke code completion on the return value of this function, it's using the return type we specified - the Date class.

However, it doesn't end there. In many cases, NetBeans can also figure out the type without it needing to be explicitly specified. Here's a function without a type declaration, yet NetBeans knows what to do with the return value:

This is an area where the type handling in NetBeans is currently better for JavaScript than for Ruby. Ruby doesn't have the same convention of documenting types for libraries. In fact, many Rubyists feel that this would be counter to what Ruby is all about: Methods shouldn't know what the types of the parameters are - all that matters is what the objects respond to the required method names used by the function. However, for people who -want- IDE help, improved type documentation could certainly help. And NetBeans understands some Ruby type assertions for parameters:

There are several efforts to allow type hints for Ruby. For example, Charlie Nutter's Duby project uses type hints to generate more efficient bytecode for Ruby execution - and the same hints could be interpreted by the IDE to assist with code completion, go to declaration, etc.

Finally, as the last JavaScript screenshot shows, there are many cases where it's easy to figure out what the return type will actually be for the current implementation of the method. That's an area I want to look into next, such that I can apply the principles I've applied for JavaScript to Ruby as well. Fun times ahead!

Let me finally apologize for my tardiness in responding to e-mail, blog comments, newsgroup posts etc. We're just a week away from JavaOne, so work is extremely hectic at the moment. But it's going to be a blast as always! I hope to see many of you there - please say hi!

P.S. I've been fixing quite a few bugs in the JavaScript support since the 6.1. code freeze. I'm hoping to get it all rolled into an AutoUpdate patch. If you're running into problems with 6.1, please give the daily builds a try! By the way, Martin Krauskopf just integrated (into the daily build) a new Rake Runner for Ruby!

No comments:

Post a Comment