Several weeks ago, KDevelop became able to display the list of all the QML components shipped with Qt, along with their properties, signals and methods. This week, the same happened for Javascript: all the standard ECMAScript 6 classes and objects are now recognized by the KDevelop QML/JS language plugin.
Adding this support was easy but not the funniest part of the project :-) . I had to read the ECMAScript specification (more specifically the sections about the built-in objects) and to write a big Javascript files that describes the built-in classes and objects. This file declares all the classes and all their methods and attributes. Assignations and calls are also performed so that the QML/JS plugin can infer the type of the attributes and the arguments of the methods. The file is 1133 lines long and looks like this:
1 2 3 4 5 6 7 | Number.prototype.isNaN = function (number) { return true; };
Number.prototype.isNaN(1.0);
Number.prototype.isSafeInteger = function (number) { return true; };
Number.prototype.isSafeInteger(1);
Number.prototype.MAX_SAFE_INTEGER = 1;
|
Here, an isNaN
method is declared. It contains a return statement so that the plugin knows that this method returns a boolean. There is also a call that allows the plugin to infer that the argument is of type float
. The second methods is declared the same way. It also returns a boolean but it takes an int
as argument. Finally, an attribute is declared.
Note that the ECMAScript specification makes the distinction between the methods/attributes of the Number class (that should be declared using Number.MAX_SAGE_INTEGER=1;
I think) and the methods/attributes of Number instances (declared using the prototype). As the QML/JS plugin currently does not differentiates class members and prototype members, all the declarations are currently visible both in Number and in Number instances.
The screenshots
Now that the QML/JS has a big list of declarations, they can be used. The simplest use of the declarations is simply to show them to the user:
Math and JSON are interesting objects because they are also widely used in QML files. In fact, I decided to add declarations for built-in ECMAScript types because I discovered that they were so heavily used in QML.
The second (and most interesting) feature is to provide code-completion items for variables and members having a built-in Javascript type like int
, float
, string
or array
:
Support for RegExp literals
Finally, adding support for built-in ECMAScript classes allowed me to support RegExp literals. They were not supported before because KDevelop does not have a "regexp" type, so the language plugin has to provide one itself. This is now done, and regular expressions are now fully supported:
The last screenshot might be quite pleasing to RegExp users: the return value of RegExp.match
is known to the plugin, which can therefore display useful code-completion items. How this special return value is supported is a bit dirty and involves code like this (and a good type inference engine):
1 2 | RegExp.prototype.match = function (string) { return {index: 1, input: "", length: 1}; };
RegExp.prototype.match("");
|
The match
function returns an object having three special keys, that become available to any code calling RegExp.match
.
Now I have to add support for the DOM, and I think that this task may be even bigger than ECMAScript. The DOM is so huge, but supporting all of it is a prerequisite to supporting big Javascript libraries like jQuery. I'll also look at Node.js, which seems to be used by several early users of the plugin. Maybe having basic support for Node.js (and its require
function) may be possible without having to describe the whole DOM.