EclipseCon: Next-generation JavaScript Language Tooling

EclipseCon: Next-generation JavaScript Language Tooling

Presented at EclipseCon NA 2014 (March 19, 2014):
https://www.eclipsecon.org/na2014/session/next-generation-javascript-language-tooling

Web applications written in JavaScript rapidly grow in size and complexity. Ensuring and tracking the quality of such large-scale complex applications are daunting, especially with the lack of proper language tooling. In this presentation, a new trend in emerging composeable JavaScript language tools will be discussed. Armed with those tools, a wide range of end-to-end quality workflow can be established, from simple static analysis, syntax augmentation/transformation, dynamic code analysis, as well as run-time complexity profiling.

0284b8950e0f4a57bcc092d4dbb98d97?s=128

Ariya Hidayat

March 19, 2014
Tweet

Transcript

  1. 3.

    MyView = Backbone.View.extend({ events: { 'click .toggle': 'toggleCompletd', 'click .destroy':

    'clear', 'blur .edit': 'close', }, toggleCompleted: function () { this.model.toggle() }, // and so on }); Unexpected comma Missing semicolon
  2. 6.

    Every tool is open-source Tweak/customize/run with it! There are links

    (everywhere) to detailed articles/blog posts speakerdeck.com/ariya
  3. 7.

    Composeable Tools Write programs that do one thing and do

    it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.
  4. 8.

    { type: "Program", body: [ { type: "VariableDeclaration", declarations: [

    { type: "VariableDeclarator", id: { type: "Identifier", name: "answer" }, init: { type: "Literal", value: 42, raw: "42" } } ], kind: "var" } ] } Syntax Tree var answer = 42;
  5. 12.

    Stray Logging function detect_console(code) { function check(node) { if (node.type

    === 'CallExpression') { if (node.callee.type === 'MemberExpression') { if (node.callee.object.name === 'console') { alert('console call at line', node.loc.start.line); } } } } var tree = esprima.parse(code, { loc: true }); estraverse.traverse(tree, { enter:check }); } http://ariya.ofilabs.com/2013/04/automagic-removal-of-javascript-logging.html
  6. 13.

    Boolean Traps reload(x, y, false) function checkLastArgument(node) { var args

    = node['arguments']; if (args.length < 2) { return; } if (typeof args[args.length - 1].value === 'boolean') { report(node, 'Dangerous Boolean literal'); } } http://ariya.ofilabs.com/2012/06/detecting-boolean-traps-with-esprima.html
  7. 22.

    ES6 Lexical Block Scope http://ariya.ofilabs.com/2013/05/es6-and-block-scope.html function f() { let j

    = data.length; console.log(j, 'items'); for (let i = 0; i < j; ++i) { let j = data[i] * data[i]; console.log(j); // squares } } function f() { var j = data.length; console.log(j, 'items'); for (var i = 0; i < j; ++i) { var j$0 = data[i] * data[i]; console.log(j$0); // squares } }
  8. 23.

    ES6 “Class” at class Derived extends Base { constructor(value) {

    super(value + 1); } getValue() { return super.getValue() - 1; } static getName() { return "Derived"; } } http://benjamn.github.io/fluent2014-talk/#/26 function Derived(value) { Base.call(this, value + 1); } Derived.prototype = Object.create(Base. prototype); Derived.prototype.constructor = Derived; Derived.prototype.getValue = function() { return Base.prototype.getValue.call (this) - 1; }; Derived.getName = function() { return "Derived"; };
  9. 25.

    Fast = Enough? Alice Bob Chuck Dan ... Bob Alice

    Dan Chuck ... Sort How’s the speed? 2 ms to sort 10 contacts
  10. 26.

    Array.prototype.swap = function (i, j) { var k = this[i];

    this[i] = this[j]; this[j] = k; } function sort(list) { var items = list.slice(0), swapped = false, p, q; for (p = 1; p < items.length; ++p) { for (q = 0; q < items.length - p; ++q) { if (items[q + 1] < items[q]) { items.swap(q, q + 1); swapped =true; } } if (!swapped) break; } return items; } Bubble Sort ???
  11. 27.

    Run-time Complexity http://ariya.ofilabs.com/2012/01/scalable-web-apps-the-complexity-issue.html Array.prototype.swap = function (i, j) { var

    k = this[i]; this[i] = this[j]; this[j] = k; } Array.prototype.swap = function (i, j) { Log({ name: 'Array.prototype.swap', lineNumber: 1, range: [23, 94] }); var k = this[i]; this[i] = this[j]; this[j] = k; } http://esprima.org/demo/functiontrace.html
  12. 28.
  13. 30.

    Code Coverage with Istanbul function inc(p, q) { if (q

    == undefined) q = 1; return p + q/q; } assert("inc(4) must give 5", inc(4) == 5); E = Else is not taken http://ariya.ofilabs.com/2012/12/javascript-code-coverage-with-istanbul.html