UNPKG

4.72 kBJavaScriptView Raw
1"use strict";
2
3exports.__esModule = true;
4exports.visitor = undefined;
5
6var _getIterator2 = require("babel-runtime/core-js/get-iterator");
7
8var _getIterator3 = _interopRequireDefault(_getIterator2);
9
10var _babelHelperGetFunctionArity = require("babel-helper-get-function-arity");
11
12var _babelHelperGetFunctionArity2 = _interopRequireDefault(_babelHelperGetFunctionArity);
13
14var _babelHelperCallDelegate = require("babel-helper-call-delegate");
15
16var _babelHelperCallDelegate2 = _interopRequireDefault(_babelHelperCallDelegate);
17
18var _babelTemplate = require("babel-template");
19
20var _babelTemplate2 = _interopRequireDefault(_babelTemplate);
21
22var _babelTypes = require("babel-types");
23
24var t = _interopRequireWildcard(_babelTypes);
25
26function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
27
28function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
29
30var buildDefaultParam = (0, _babelTemplate2.default)("\n let VARIABLE_NAME =\n ARGUMENTS.length > ARGUMENT_KEY && ARGUMENTS[ARGUMENT_KEY] !== undefined ?\n ARGUMENTS[ARGUMENT_KEY]\n :\n DEFAULT_VALUE;\n");
31
32var buildCutOff = (0, _babelTemplate2.default)("\n let $0 = $1[$2];\n");
33
34function hasDefaults(node) {
35 for (var _iterator = node.params, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : (0, _getIterator3.default)(_iterator);;) {
36 var _ref;
37
38 if (_isArray) {
39 if (_i >= _iterator.length) break;
40 _ref = _iterator[_i++];
41 } else {
42 _i = _iterator.next();
43 if (_i.done) break;
44 _ref = _i.value;
45 }
46
47 var param = _ref;
48
49 if (!t.isIdentifier(param)) return true;
50 }
51 return false;
52}
53
54function isSafeBinding(scope, node) {
55 if (!scope.hasOwnBinding(node.name)) return true;
56
57 var _scope$getOwnBinding = scope.getOwnBinding(node.name),
58 kind = _scope$getOwnBinding.kind;
59
60 return kind === "param" || kind === "local";
61}
62
63var iifeVisitor = {
64 ReferencedIdentifier: function ReferencedIdentifier(path, state) {
65 var scope = path.scope,
66 node = path.node;
67
68 if (node.name === "eval" || !isSafeBinding(scope, node)) {
69 state.iife = true;
70 path.stop();
71 }
72 },
73 Scope: function Scope(path) {
74 path.skip();
75 }
76};
77
78var visitor = exports.visitor = {
79 Function: function Function(path) {
80 var node = path.node,
81 scope = path.scope;
82
83 if (!hasDefaults(node)) return;
84
85 path.ensureBlock();
86
87 var state = {
88 iife: false,
89 scope: scope
90 };
91
92 var body = [];
93
94 var argsIdentifier = t.identifier("arguments");
95 argsIdentifier._shadowedFunctionLiteral = path;
96
97 function pushDefNode(left, right, i) {
98 var defNode = buildDefaultParam({
99 VARIABLE_NAME: left,
100 DEFAULT_VALUE: right,
101 ARGUMENT_KEY: t.numericLiteral(i),
102 ARGUMENTS: argsIdentifier
103 });
104 defNode._blockHoist = node.params.length - i;
105 body.push(defNode);
106 }
107
108 var lastNonDefaultParam = (0, _babelHelperGetFunctionArity2.default)(node);
109
110 var params = path.get("params");
111 for (var i = 0; i < params.length; i++) {
112 var param = params[i];
113
114 if (!param.isAssignmentPattern()) {
115 if (!state.iife && !param.isIdentifier()) {
116 param.traverse(iifeVisitor, state);
117 }
118
119 continue;
120 }
121
122 var left = param.get("left");
123 var right = param.get("right");
124
125 if (i >= lastNonDefaultParam || left.isPattern()) {
126 var placeholder = scope.generateUidIdentifier("x");
127 placeholder._isDefaultPlaceholder = true;
128 node.params[i] = placeholder;
129 } else {
130 node.params[i] = left.node;
131 }
132
133 if (!state.iife) {
134 if (right.isIdentifier() && !isSafeBinding(scope, right.node)) {
135 state.iife = true;
136 } else {
137 right.traverse(iifeVisitor, state);
138 }
139 }
140
141 pushDefNode(left.node, right.node, i);
142 }
143
144 for (var _i2 = lastNonDefaultParam + 1; _i2 < node.params.length; _i2++) {
145 var _param = node.params[_i2];
146 if (_param._isDefaultPlaceholder) continue;
147
148 var declar = buildCutOff(_param, argsIdentifier, t.numericLiteral(_i2));
149 declar._blockHoist = node.params.length - _i2;
150 body.push(declar);
151 }
152
153 node.params = node.params.slice(0, lastNonDefaultParam);
154
155 if (state.iife) {
156 body.push((0, _babelHelperCallDelegate2.default)(path, scope));
157 path.set("body", t.blockStatement(body));
158 } else {
159 path.get("body").unshiftContainer("body", body);
160 }
161 }
162};
\No newline at end of file