1 | var util = require('util');
|
2 | var helpers = require('../helpers');
|
3 | var AssignmentExpression = require('./AssignmentExpression');
|
4 | var BlockStatement = require('./BlockStatement');
|
5 | var ExpressionStatement = require('./ExpressionStatement');
|
6 | var FunctionExpression = require('./FunctionExpression');
|
7 | var Identifier = require('./Identifier');
|
8 | var IfStatement = require('./IfStatement');
|
9 | var Literal = require('./Literal');
|
10 | var MemberExpression = require('./MemberExpression');
|
11 | var ThrowStatement = require('./ThrowStatement');
|
12 | var VariableDeclaration = require('./VariableDeclaration');
|
13 | var VariableDeclarator = require('./VariableDeclarator');
|
14 |
|
15 | var CallExpression = module.exports = function(callee, args) {
|
16 | this.type = 'CallExpression';
|
17 | this.callee = callee;
|
18 | this.arguments = args;
|
19 | if (!this.arguments) {
|
20 | this.arguments = [];
|
21 | }
|
22 | if (!util.isArray(this.arguments)) {
|
23 | this.arguments = [this.arguments];
|
24 | }
|
25 | };
|
26 |
|
27 | CallExpression.prototype.normalize = function (place) {
|
28 | var self = this;
|
29 | this.callee.normalize();
|
30 | for (var i = 0; i < this.arguments.length; i++) {
|
31 | this.arguments[i].normalize();
|
32 | }
|
33 |
|
34 | findContinuation(this.arguments, function (contExpr, contPos, options) {
|
35 | if (options.obtain) {
|
36 |
|
37 | contExpr.arguments.unshift(new Identifier(helpers.errName));
|
38 | }
|
39 |
|
40 | contExpr.arguments.forEach(function (argument, index) {
|
41 |
|
42 | if (argument.type === 'MemberExpression') {
|
43 | argument = argument.object;
|
44 | }
|
45 | place.push(new VariableDeclaration(
|
46 | new VariableDeclarator(
|
47 | argument
|
48 | )
|
49 | ));
|
50 | });
|
51 | });
|
52 | };
|
53 |
|
54 | CallExpression.prototype.transform = function (place) {
|
55 | var self = this;
|
56 |
|
57 | this.callee.transform();
|
58 | if (this.callee.async) {
|
59 | this.async = true;
|
60 | }
|
61 |
|
62 | this.arguments.forEach(function (expression) {
|
63 | expression.transform();
|
64 | if (expression.async) {
|
65 | this.async = true;
|
66 | }
|
67 | });
|
68 |
|
69 | var newPlace;
|
70 | findContinuation(this.arguments, function (contExpr, contPos, options) {
|
71 |
|
72 | var callbackPlace = [];
|
73 | contExpr.arguments.forEach(function (argument, index) {
|
74 | callbackPlace.push(new ExpressionStatement(
|
75 | new AssignmentExpression(
|
76 | '=',
|
77 | argument,
|
78 | new MemberExpression(new Identifier('arguments'), new Literal(index))
|
79 | )
|
80 | ));
|
81 | });
|
82 |
|
83 | if (options.obtain) {
|
84 |
|
85 | var errIdentifier = new Identifier(helpers.errName);
|
86 | callbackPlace.push(new IfStatement(
|
87 | errIdentifier,
|
88 | new ThrowStatement(errIdentifier)
|
89 | ));
|
90 | }
|
91 |
|
92 |
|
93 | self.arguments[contPos] = new FunctionExpression(
|
94 | null,
|
95 | [],
|
96 | new BlockStatement(callbackPlace)
|
97 | );
|
98 | self.async = true;
|
99 | newPlace = callbackPlace;
|
100 | });
|
101 | if (newPlace) {
|
102 | return newPlace;
|
103 | }
|
104 |
|
105 | return place;
|
106 | };
|
107 |
|
108 | var findContinuation = function (args, callback) {
|
109 |
|
110 | for (var i = 0; i < args.length; i++) {
|
111 | var arg = args[i];
|
112 | if (arg.type === 'CallExpression') {
|
113 | if (arg.callee.name === helpers.contName) {
|
114 | return callback(arg, i, {});
|
115 | } else if (arg.callee.name === helpers.obtainName) {
|
116 | return callback(arg, i, {obtain: true});
|
117 | }
|
118 | }
|
119 | }
|
120 | return -1;
|
121 | };
|