Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
80540 views
1
/**
2
* Copyright 2004-present Facebook. All Rights Reserved.
3
*/
4
/*global exports:true*/
5
6
/**
7
* Implements ES6 call spread.
8
*
9
* instance.method(a, b, c, ...d)
10
*
11
* instance.method.apply(instance, [a, b, c].concat(d))
12
*
13
*/
14
15
var Syntax = require('esprima-fb').Syntax;
16
var utils = require('../src/utils');
17
18
function process(traverse, node, path, state) {
19
utils.move(node.range[0], state);
20
traverse(node, path, state);
21
utils.catchup(node.range[1], state);
22
}
23
24
function visitCallSpread(traverse, node, path, state) {
25
utils.catchup(node.range[0], state);
26
27
if (node.type === Syntax.NewExpression) {
28
// Input = new Set(1, 2, ...list)
29
// Output = new (Function.prototype.bind.apply(Set, [null, 1, 2].concat(list)))
30
utils.append('new (Function.prototype.bind.apply(', state);
31
process(traverse, node.callee, path, state);
32
} else if (node.callee.type === Syntax.MemberExpression) {
33
// Input = get().fn(1, 2, ...more)
34
// Output = (_ = get()).fn.apply(_, [1, 2].apply(more))
35
var tempVar = utils.injectTempVar(state);
36
utils.append('(' + tempVar + ' = ', state);
37
process(traverse, node.callee.object, path, state);
38
utils.append(')', state);
39
if (node.callee.property.type === Syntax.Identifier) {
40
utils.append('.', state);
41
process(traverse, node.callee.property, path, state);
42
} else {
43
utils.append('[', state);
44
process(traverse, node.callee.property, path, state);
45
utils.append(']', state);
46
}
47
utils.append('.apply(' + tempVar, state);
48
} else {
49
// Input = max(1, 2, ...list)
50
// Output = max.apply(null, [1, 2].concat(list))
51
var needsToBeWrappedInParenthesis =
52
node.callee.type === Syntax.FunctionDeclaration ||
53
node.callee.type === Syntax.FunctionExpression;
54
if (needsToBeWrappedInParenthesis) {
55
utils.append('(', state);
56
}
57
process(traverse, node.callee, path, state);
58
if (needsToBeWrappedInParenthesis) {
59
utils.append(')', state);
60
}
61
utils.append('.apply(null', state);
62
}
63
utils.append(', ', state);
64
65
var args = node.arguments.slice();
66
var spread = args.pop();
67
if (args.length || node.type === Syntax.NewExpression) {
68
utils.append('[', state);
69
if (node.type === Syntax.NewExpression) {
70
utils.append('null' + (args.length ? ', ' : ''), state);
71
}
72
while (args.length) {
73
var arg = args.shift();
74
utils.move(arg.range[0], state);
75
traverse(arg, path, state);
76
if (args.length) {
77
utils.catchup(args[0].range[0], state);
78
} else {
79
utils.catchup(arg.range[1], state);
80
}
81
}
82
utils.append('].concat(', state);
83
process(traverse, spread.argument, path, state);
84
utils.append(')', state);
85
} else {
86
process(traverse, spread.argument, path, state);
87
}
88
utils.append(node.type === Syntax.NewExpression ? '))' : ')', state);
89
90
utils.move(node.range[1], state);
91
return false;
92
}
93
94
visitCallSpread.test = function(node, path, state) {
95
return (
96
(
97
node.type === Syntax.CallExpression ||
98
node.type === Syntax.NewExpression
99
) &&
100
node.arguments.length > 0 &&
101
node.arguments[node.arguments.length - 1].type === Syntax.SpreadElement
102
);
103
};
104
105
exports.visitorList = [
106
visitCallSpread,
107
];
108
109