Ben Newman
(Meteor)
Facebook New York
10 November 2014
{ github, twitter, instagram, facebook }.com/benjamn
var Answer = Component.extend({ onLoad: function() { var params = { uid: this.viewer, aid: this.answer }; this.$("#upvote").click(this.bind(function() { this.serverCall("upvote", params).send(); })); this.$("#downvote").click(this.bind(function() { this.serverCall("downvote", params).send(); })); this.$("body").bind("scroll", this.bind(function() { // Every time the viewport scrolls, check visibility. if (this.$("#container").inViewport()) { this.serverCall("viewed_answer", params).send(); } })); } });
gofmt
?jsfmt
.
var recast = require("recast"); var ast = recast.parse(source); transform(ast); // Anything goes. console.log(recast.print(ast).code);
recast.parse
var foo = recast.parse("foo;").program.body[0]; assert.deepEqual(foo, { "type": "ExpressionStatement", "expression": { "type": "Identifier", "name": "foo", "original": { // Identical to foo.original.expression. "type": "Identifier", "name": "foo", "loc": { "start": { "line": 1, "column": 0 }, "end": { "line": 1, "column": 3 } } }, }, "original": { "type": "ExpressionStatement", "expression": { // Identical to foo.expression.original. "type": "Identifier", "name": "foo", "loc": { "start": { "line": 1, "column": 0 }, "end": { "line": 1, "column": 4 } } } } });
recast.visit
recast.visit
is
only a suggestion!)
=>
function syntax[3, 1, 10, 28].sort((a, b) => a - b)
var recast = require("recast"); var n = recast.types.namedTypes; var b = recast.types.builders; var ast = recast.parse( "[3, 1, 10, 28].sort((a, b) => a - b)" );
recast.visit(ast, { });
recast.visit(ast, { visitArrowFunctionExpression: function(path) { } });
recast.visit(ast, { visitArrowFunctionExpression: function(path) { var node = path.node; } });
recast.visit(ast, { visitArrowFunctionExpression: function(path) { var node = path.node; if (!n.BlockStatement.check(node.body)) { } } });
recast.visit(ast, { visitArrowFunctionExpression: function(path) { var node = path.node; if (!n.BlockStatement.check(node.body)) { n.Expression.assert(node.body); } } });
recast.visit(ast, { visitArrowFunctionExpression: function(path) { var node = path.node; if (!n.BlockStatement.check(node.body)) { n.Expression.assert(node.body); node.body = b.blockStatement([b.returnStatement(node.body)]); } } });
recast.visit(ast, { visitArrowFunctionExpression: function(path) { var node = path.node; if (!n.BlockStatement.check(node.body)) { n.Expression.assert(node.body); node.body = b.blockStatement([b.returnStatement(node.body)]); node.expression = false; } } });
recast.visit(ast, { visitArrowFunctionExpression: function(path) { var node = path.node; if (!n.BlockStatement.check(node.body)) { n.Expression.assert(node.body); node.body = b.blockStatement([b.returnStatement(node.body)]); node.expression = false; } var funExp = b.functionExpression( node.id, node.params, node.body, node.generator, node.expression ); } });
recast.visit(ast, { visitArrowFunctionExpression: function(path) { var node = path.node; if (!n.BlockStatement.check(node.body)) { n.Expression.assert(node.body); node.body = b.blockStatement([b.returnStatement(node.body)]); node.expression = false; } var funExp = b.functionExpression( node.id, node.params, node.body, node.generator, node.expression ); return b.callExpression( b.memberExpression(funExp, b.identifier("bind"), false), [b.thisExpression()] ); } });
recast.print
Lines
instead of strings
(lib/lines.js)
recast.print
tries to recyle the original
source code wherever possible.
find ~/www/html/js/lib | \ grep "\.js$" | \ time parallel ~/www/scripts/bin/classify --update 228.03s user 12.25s system 1229% cpu 19.548 total
recast.visit
github.com/{ benjamn/jsconf-2014, facebook/jstransform, benjamn/recast, benjamn/ast-types, facebook/regenerator, square/esnext } code.facebook.com/projects What about Traceur?