Saturday, June 1, 2013

Setting JSHint Options in ACE from Dart (via a postMessage)

‹prev | My Chain | next›

The final round of tech review is starting to flow in for 3D Game Programming for Kids. One of the things noted is that the ICE Code Editor is no longer displaying the same warnings that the book describes. This seems like a good thing to fix in the Dart version of the editor.

The JavaScript linting comes from the ACE code editor, which uses JSHint. I do not recall setting any specific options in the original JavaScript version and it is not working in the JavaScript version that is currently located at http://gamingjs.com/ice (hence the tech review comment). So this is almost certainly a change in the underlying ACE editor.

I am unsure if it is even possible to get the old warning to show, but it seems worth a try. In the following code:
  food;
  eat(food);
ACE used to show the following warning:



The JSHint options in ACE are set in the worker-javascript.js file. I eventually track down the lack of this particular warning to the expr setting in:
        this.options = options || {
            es5: true,
            esnext: true,
            devel: true,
            browser: true,
            node: true,
            laxcomma: true,
            laxbreak: true,
            lastsemic: true,
            onevar: false,
            passfail: false,
            maxerr: 100,
            expr: true,
            multistr: true,
            globalstrict: true
        };
The expr setting disables warnings when code is not setting a variable or calling a function. In other words, by setting expr to true, this setting will not warn for code that serves no purpose.

In fact, looking through those options on the JSHint documentation page, I do not think that I need any of those options. The first five (es5, esnext, devel, browser, and node) define variables that will be ignored when performing global variable checking. That is not even enabled so they currently have no effect. I could set the undef property, but then I would have my work cut out for me defining a bunch of predef options (so that Three.js variables are not flagged as undefined).

The remaining options are useful more for experienced JavaScript developers. Since the primary users of ICE are going to be kids, these options may end up doing more harm than good. So I could hand edit all this code so that the default options are empty:
        this.options = options || {};
I may end up doing just that since I am already hand editing the code to prevent JSHint from choking on HTML.

But first, I would like to see if I can set these options from Dart. It takes a bit of fiddling, but I eventually set up my js-interop proxy to ACE to support setting options with a decent syntax:
_ace.session.workerOptions = {'expr': false, 'undef': true};
For that to work, I add a setter to AceSession:
class AceSession extends jsw.TypedProxy {
  // ...
  set workerOptions(o) {
    $unsafe.$worker.send("setOptions", js.array([o]));
  }
}
The only trick in there is to wrap the setter options in an array. The worker options are eventually apply()-ed in the ACE JavaScript code. Since it is an apply(), the arguments need to be an array. And it cannot be a proxied Dart list—it has to be a real JavaScript array. Hande the js-interop js.array() call.

It works, but I do not have a good use-case for this. I will likely add the setter, but leave it commented out for now. Hand editor of the worker seems a better option at this point.



Day #769

No comments:

Post a Comment