UNPKG

2.69 kBJavaScriptView Raw
1var util = require('util');
2var traverse = require('./lib/traverse');
3var helpers = require('./lib/helpers');
4
5var sourceMap;
6
7exports.compile = function (code, options) {
8 if (!options) {
9 options = {
10 sourceMap: false
11 };
12 }
13
14 var indent = ' ';
15 if (options.indent) {
16 indent = options.indent;
17 }
18
19 if (!options.force && options.explicit && code.indexOf('use continuation') === -1) {
20 //Mark literal not found in code
21 return code;
22 }
23
24 //Reset helper
25 helpers.reset();
26
27 //Parse code
28 var parser = require('./lib/parser');
29 var ast = parser.parse(code);
30
31 if (options.explicit) {
32 //Traverse ast and find explicit compilation mark
33 if (!findExplicitMark(ast)) {
34 return code;
35 }
36 }
37
38 var meta = require('./package.json');
39 var mark = '/* Generated by Continuation.js v' + meta.version + ' */';
40
41 //Tranformation not needed
42 if (!options.force && !transformNeeded(ast)) {
43 return code + '\n' + mark;
44 }
45
46 traverse(ast, function (node) {
47 return node.normalize ? node.normalize() : node;
48 });
49 //console.error(util.inspect(ast, false, null, true)); //debug
50 ast.transform();
51 //console.error(util.inspect(ast, false, null, true)); //debug
52
53 //Generate code
54 var escodegen = require('escodegen');
55 //ast = escodegen.attachComments(ast, ast.comments, ast.tokens); //debug
56 var genOptions = {
57 format: {
58 indent: {
59 style: indent,
60 base: 0
61 }
62 },
63 comment: true
64 };
65 code = escodegen.generate(ast, genOptions);
66
67 //Generate source map
68 if (options.sourceMap) {
69 genOptions.sourceMap = 'continuation.js';
70 sourceMap = JSON.parse(escodegen.generate(ast, genOptions));
71 }
72 return code + '\n' + mark;
73};
74
75exports.getSourceMap = function (file, sources) {
76 sourceMap.file = file;
77 sourceMap.sources = sources;
78 return JSON.stringify(sourceMap);
79};
80
81var findExplicitMark = function (ast) {
82 var found = false;
83 traverse(ast, function (node) {
84 if (node.type === 'ExpressionStatement') {
85 if (node.expression.type === 'Literal' && node.expression.value === 'use continuation') {
86 found = true;
87 }
88 }
89 return node;
90 });
91 return found;
92};
93
94var transformNeeded = function (ast) {
95 var needed = false;
96 traverse(ast, function (node) {
97 if (node.type === 'CallExpression') {
98 node.arguments.forEach(function (argument) {
99 if (argument.type === 'CallExpression' && argument.callee.type === 'Identifier') {
100 if (argument.callee.name === helpers.contName || argument.callee.name === helpers.obtainName) {
101 needed = true;
102 }
103 }
104 });
105 }
106 return node;
107 });
108 return needed;
109};