UNPKG

3.22 kBJavaScriptView Raw
1"use strict";
2
3/*
4 * 'fast-async' plugin for Babel v6.x. It uses nodent to transform the entire program before passing it off
5 * to the next transformer.
6 */
7
8var parserExtensionName = 'asyncFunctions';
9
10module.exports = function (types) {
11 var logger = console.log.bind(console) ;
12 var nodent = require('nodent') ;
13
14 return {
15 // Lifted from https://github.com/babel/babel/blob/master/packages/babel-plugin-syntax-async-functions/src/index.js#L3,
16 // which is not nice, but avoids installation complexity with plugins (which I must try to work out sometime)
17 manipulateOptions: function manipulateOptions(opts, parserOpts) {
18 parserOpts.plugins.push(parserExtensionName);
19 },
20 visitor: {
21 Program:function Program(path,state) {
22 var envOpts = state.opts.env || {} ;
23 if (!('log' in envOpts)) envOpts.log = logger ;
24 if (!('dontInstallRequireHook' in envOpts)) envOpts.dontInstallRequireHook = true ;
25 var compiler = nodent(envOpts) ;
26
27 var opts = compiler.parseCompilerOptions('"use nodent-promises";',compiler.log) ;
28 opts.babelTree = true ;
29
30 for (var k in opts) {
31 if (state.opts && state.opts.compiler && (k in state.opts.compiler))
32 opts[k] = state.opts.compiler[k] ;
33 }
34
35 var pr = { origCode:state.file.code, filename:"", ast:path.node } ;
36 compiler.asynchronize(pr,undefined,opts,compiler.log) ;
37
38 function getRuntime(symbol,fn) {
39 var runtime = symbol+"="+fn.toString().replace(/[\s]+/g," ")+";\n" ;
40 opts.parser.ranges = false ;
41 opts.parser.locations = false ;
42 var ast = compiler.parse(runtime,null,opts).ast.body[0] ;
43 // Remove location information from the runtime as Babel >=6.5.0 does a search by
44 // location and barfs if multiple nodes appearantly occupy the same source locations
45 ast = JSON.parse(JSON.stringify(ast,function replacer(key, value) {
46 if (key==="start" || key==="end")
47 return undefined;
48 return value;
49 })) ;
50
51 return ast ;
52 }
53
54 if (!state.opts.runtimePattern) {
55 pr.ast.body.unshift(getRuntime('Function.prototype.$asyncbind',Function.prototype.$asyncbind)) ;
56 } else {
57 if (state.opts.runtimePattern==='directive') {
58 if (path.node.directives) {
59 for (var i=0; i<path.node.directives.length; i++) {
60 if (path.node.directives[i].value.type==="DirectiveLiteral" && path.node.directives[i].value.value==="use runtime-nodent") {
61 pr.ast.body.unshift(getRuntime('Function.prototype.$asyncbind',Function.prototype.$asyncbind)) ;
62 path.node.directives.splice(i,1) ;
63 break ;
64 }
65 }
66 }
67 } else {
68 var pattern = new RegExp(state.opts.runtimePattern) ;
69 if (state.file.parserOpts.filename.match(pattern)) {
70 pr.ast.body.unshift(getRuntime('Function.prototype.$asyncbind',Function.prototype.$asyncbind)) ;
71 }
72 }
73 }
74 }
75 }
76 };
77};