UNPKG

2.45 kBJavaScriptView Raw
1var util = require('util');
2var escodegen = require('escodegen');
3
4var meta = require('./package.json');
5var parser = require('./lib/parser');
6var traverse = require('./lib/traverse');
7var helpers = require('./lib/helpers');
8var Program = require('./lib/syntax/Program');
9
10var header = '/* Generated by Continuation.js v' + meta.version + ' */\n';
11
12exports.compile = function (origCode, options) {
13 if (!options) {
14 options = {};
15 }
16
17 var indent = ' ';
18 if (options.tabIndent) {
19 indent = '\t';
20 } else if (options.indentSpaces) {
21 indent = Array(options.indentSpaces + 1).join(c);
22 }
23
24 //Wrap whole file into a function
25 var code = '(function () {' + origCode + '\n}).call(this);\n';
26
27 if (options.compileMark && code.indexOf('use continuation') === -1) {
28 //Mark literal not found in code
29 return origCode;
30 }
31
32 helpers.reset();
33 var ast = parser.parse(code);
34
35 if (options.compileMark) {
36 //Traverse ast and find compile mark
37 if (!findCompileMark(ast)) {
38 return origCode;
39 }
40 }
41
42 if (!options.force && !transformNeeded(ast)) {
43 return header + origCode;
44 }
45
46 ast.normalize();
47 //console.error(util.inspect(ast, false, null, true));
48 ast.transform();
49 //console.error(util.inspect(ast, false, null, true));
50
51 ast = new Program(ast.body[0].expression.callee.object.body.body);
52
53 //ast = escodegen.attachComments(ast, ast.comments, ast.tokens);
54 code = escodegen.generate(ast, {
55 format: {
56 indent: {
57 style: indent,
58 base: 0
59 },
60 },
61 comment: true,
62 });
63
64 return header + code;
65};
66
67//Alias
68exports.transform = exports.compile;
69
70var findCompileMark = function (ast) {
71 var found = false;
72 traverse(ast, function (node) {
73 if (node.type === 'ExpressionStatement') {
74 if (node.expression.type === 'Literal' && node.expression.value === 'use continuation') {
75 found = true;
76 }
77 }
78 return node;
79 });
80 return found;
81};
82
83var transformNeeded = function (ast) {
84 var needed = false;
85 traverse(ast, function (node) {
86 if (node.type === 'CallExpression') {
87 node.arguments.forEach(function (argument) {
88 if (argument.type === 'CallExpression' && argument.callee.type === 'Identifier') {
89 if (argument.callee.name === helpers.contName || argument.callee.name === helpers.obtainName) {
90 needed = true;
91 }
92 }
93 });
94 }
95 return node;
96 });
97 return needed;
98};