I usually write a blog post once every week, but this time I have two features thay may already interest some people :-) . Now that the QML support in KDevelop is nearly complete and quite usable (several things are still missing though, for instance the support for directory imports), I wanted to work on Javascript-related things that I had to put aside for the past month or so.
The first feature is function call-tips, that display the signature of the current function (or functions, if they are nested) as you type. This way, you can see the name and the type of the arguments, which can be very useful. This feature is available in Javascript and QML, and my example is, in fact, a QML code snippet.
The second feature concerns only Javascript and is the automatic declaration of object members to which a value is assigned. Objects (or arrays) can be declared by two means in Javascript: using object literals (var o = {key: value, key2: value2};
) and using an empty object literal, just to say that the variable is an object, and then each key is assigned its value separately:
1 2 3 4 | var o = {};
o.key = value;
o.key2 = value2;
|
The two types of object declarations are widely used, the second one maybe even more than the first one. For instance, Javascript developers are encouraged to declare their functions in "namespaces", that are simply objects in the global scope :
1 2 3 4 | var APP = {};
APP.say_hello = function() { alert("Hello"); };
APP.say_world = function() { alert("World !"); };
|
The QML/JS plugin supports this by allowing the declaration of object members after the object itself has been created. This is fairly simple: when object.member
is encountered in the source code, the plugin checks whether member
already exists in object
. If it is not the case, the member is declared on the fly and added to the object.
Here are some technical details. The fact that the declaration of the member happens after the object has been completely created obliged me to cheat: KDevelop doesn't allow declarations to live outside their context (so I cannot declare the "say_hello" member of my example in the context that exists between the brackets of APP), but a context can import another one, even if the other one lives in a different file or anywhere else (this is what is used to implement import statements or C/C++ includes). The solution is therefore to declare say_hello
in a new context that spans the "say_hello" identifier, and to import this context in APP. This way, "say_hello" becomes visible to APP, and code-completion works as expected:
I'm now working on function prototypes and Javascript object-oriented programming. This is a bit more complicated than what I've thought, but I think I have found a possible solution. I will implement it tomorrow and I hope that it will make things like jQuery a bit more usable in KDevelop.