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. Next-Generation JavaScript Language Tooling @ariyahidayat March 19, 2014

  2. http://todomvc.com/architecture-examples/backbone/

  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
  4. Tools separate us

  5. Static analysis Dynamic analysis Transformation

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

    (everywhere) to detailed articles/blog posts speakerdeck.com/ariya
  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.
  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;
  9. Building Blocks → Tools Parser Code Generator Obvious examples: minifier,

    obfuscator, ...
  10. Execution Visualization http://int3.github.io/metajs/

  11. Static Analysis

  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
  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
  14. Nested Ternary Conditionals http://ariya.ofilabs.com/2012/10/detecting-nested-ternary-conditionals.html var str = (age < 1)

    ? "baby" : (age < 5) ? "toddler" : (age < 18) ? "child": "adult";
  15. Cyclomatic Complexity http://ariya.ofilabs.com/2012/12/complexity-analysis-of-javascript-code.html if (true) "foo"; else "bar"; Control Flow

    Graph 6 edges 6 nodes 1 exit Cyclomatic Complexity = 2
  16. Monitoring of Complexity http://ariya.ofilabs.com/2013/05/continuous-monitoring-of-javascript-code-complexity.html

  17. “YOU SHALL NOT PASS!” — Darth Vader

  18. Complexity Visualization http://ariya.ofilabs.com/2013/01/javascript-code-complexity-visualization.html

  19. Transformation

  20. Source Transformation Parser Code Generator In-place Modification Non-Destructive Regenerative http://ariya.ofilabs.com/2013/06/javascript-source-transformation-non-destructive-vs-regenerative.html

  21. String Literal Quotes http://ariya.ofilabs.com/2012/02/from-double-quotes-to-single-quotes.html console.log('Hello') console.log("Hello")

  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 } }
  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"; };
  24. Dynamic Analysis

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

    Dan Chuck ... Sort How’s the speed? 2 ms to sort 10 contacts
  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 ???
  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
  28. None
  29. T D D B D D P D D

  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
  31. http://ariya.ofilabs.com/2012/09/the-hidden-trap-of-code-coverage.html Does not catch the missing code sequence

  32. Coverage Thresholds http://ariya.ofilabs.com/2013/05/hard-thresholds-on-javascript-code-coverage.html istanbul check-coverage --statement -5 --branch -3 --function

    100
  33. “If you think JSLint hurts your feelings, wait until you

    use Istanbul.”
  34. ...I gave you my heart But the very next day

    you gave it away...
  35. Final Words

  36. http://ariya.ofilabs.com/2012/12/quality-code-via-multiple-layers-of-defense.html Being Defensive

  37. Being Objective Mr. Reviewer Your code sucks! Your code sucks!

  38. Tools: The Final Frontier To boldly analyze what no man

    has analyzed before...
  39. Thank You shapesecurity.com @ariyahidayat

  40. Evaluate This Session Sign-in: www.eclipsecon.org Select session from schedule Evaluate:

    1 2 3