source: trip-planner-front/node_modules/regenerator-transform/lib/visit.js@ 76712b2

Last change on this file since 76712b2 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 11.1 KB
Line 
1/**
2 * Copyright (c) 2014-present, Facebook, Inc.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7"use strict";
8
9var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
10
11var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
12
13var _assert = _interopRequireDefault(require("assert"));
14
15var _hoist = require("./hoist");
16
17var _emit = require("./emit");
18
19var _replaceShorthandObjectMethod = _interopRequireDefault(require("./replaceShorthandObjectMethod"));
20
21var util = _interopRequireWildcard(require("./util"));
22
23exports.getVisitor = function (_ref) {
24 var t = _ref.types;
25 return {
26 Method: function Method(path, state) {
27 var node = path.node;
28 if (!shouldRegenerate(node, state)) return;
29 var container = t.functionExpression(null, [], t.cloneNode(node.body, false), node.generator, node.async);
30 path.get("body").set("body", [t.returnStatement(t.callExpression(container, []))]); // Regardless of whether or not the wrapped function is a an async method
31 // or generator the outer function should not be
32
33 node.async = false;
34 node.generator = false; // Unwrap the wrapper IIFE's environment so super and this and such still work.
35
36 path.get("body.body.0.argument.callee").unwrapFunctionEnvironment();
37 },
38 Function: {
39 exit: util.wrapWithTypes(t, function (path, state) {
40 var node = path.node;
41 if (!shouldRegenerate(node, state)) return; // if this is an ObjectMethod, we need to convert it to an ObjectProperty
42
43 path = (0, _replaceShorthandObjectMethod["default"])(path);
44 node = path.node;
45 var contextId = path.scope.generateUidIdentifier("context");
46 var argsId = path.scope.generateUidIdentifier("args");
47 path.ensureBlock();
48 var bodyBlockPath = path.get("body");
49
50 if (node.async) {
51 bodyBlockPath.traverse(awaitVisitor);
52 }
53
54 bodyBlockPath.traverse(functionSentVisitor, {
55 context: contextId
56 });
57 var outerBody = [];
58 var innerBody = [];
59 bodyBlockPath.get("body").forEach(function (childPath) {
60 var node = childPath.node;
61
62 if (t.isExpressionStatement(node) && t.isStringLiteral(node.expression)) {
63 // Babylon represents directives like "use strict" as elements
64 // of a bodyBlockPath.node.directives array, but they could just
65 // as easily be represented (by other parsers) as traditional
66 // string-literal-valued expression statements, so we need to
67 // handle that here. (#248)
68 outerBody.push(node);
69 } else if (node && node._blockHoist != null) {
70 outerBody.push(node);
71 } else {
72 innerBody.push(node);
73 }
74 });
75
76 if (outerBody.length > 0) {
77 // Only replace the inner body if we actually hoisted any statements
78 // to the outer body.
79 bodyBlockPath.node.body = innerBody;
80 }
81
82 var outerFnExpr = getOuterFnExpr(path); // Note that getOuterFnExpr has the side-effect of ensuring that the
83 // function has a name (so node.id will always be an Identifier), even
84 // if a temporary name has to be synthesized.
85
86 t.assertIdentifier(node.id);
87 var innerFnId = t.identifier(node.id.name + "$"); // Turn all declarations into vars, and replace the original
88 // declarations with equivalent assignment expressions.
89
90 var vars = (0, _hoist.hoist)(path);
91 var context = {
92 usesThis: false,
93 usesArguments: false,
94 getArgsId: function getArgsId() {
95 return t.clone(argsId);
96 }
97 };
98 path.traverse(argumentsThisVisitor, context);
99
100 if (context.usesArguments) {
101 vars = vars || t.variableDeclaration("var", []);
102 vars.declarations.push(t.variableDeclarator(t.clone(argsId), t.identifier("arguments")));
103 }
104
105 var emitter = new _emit.Emitter(contextId);
106 emitter.explode(path.get("body"));
107
108 if (vars && vars.declarations.length > 0) {
109 outerBody.push(vars);
110 }
111
112 var wrapArgs = [emitter.getContextFunction(innerFnId)];
113 var tryLocsList = emitter.getTryLocsList();
114
115 if (node.generator) {
116 wrapArgs.push(outerFnExpr);
117 } else if (context.usesThis || tryLocsList || node.async) {
118 // Async functions that are not generators don't care about the
119 // outer function because they don't need it to be marked and don't
120 // inherit from its .prototype.
121 wrapArgs.push(t.nullLiteral());
122 }
123
124 if (context.usesThis) {
125 wrapArgs.push(t.thisExpression());
126 } else if (tryLocsList || node.async) {
127 wrapArgs.push(t.nullLiteral());
128 }
129
130 if (tryLocsList) {
131 wrapArgs.push(tryLocsList);
132 } else if (node.async) {
133 wrapArgs.push(t.nullLiteral());
134 }
135
136 if (node.async) {
137 // Rename any locally declared "Promise" variable,
138 // to use the global one.
139 var currentScope = path.scope;
140
141 do {
142 if (currentScope.hasOwnBinding("Promise")) currentScope.rename("Promise");
143 } while (currentScope = currentScope.parent);
144
145 wrapArgs.push(t.identifier("Promise"));
146 }
147
148 var wrapCall = t.callExpression(util.runtimeProperty(node.async ? "async" : "wrap"), wrapArgs);
149 outerBody.push(t.returnStatement(wrapCall));
150 node.body = t.blockStatement(outerBody); // We injected a few new variable declarations (for every hoisted var),
151 // so we need to add them to the scope.
152
153 path.get("body.body").forEach(function (p) {
154 return p.scope.registerDeclaration(p);
155 });
156 var oldDirectives = bodyBlockPath.node.directives;
157
158 if (oldDirectives) {
159 // Babylon represents directives like "use strict" as elements of
160 // a bodyBlockPath.node.directives array. (#248)
161 node.body.directives = oldDirectives;
162 }
163
164 var wasGeneratorFunction = node.generator;
165
166 if (wasGeneratorFunction) {
167 node.generator = false;
168 }
169
170 if (node.async) {
171 node.async = false;
172 }
173
174 if (wasGeneratorFunction && t.isExpression(node)) {
175 util.replaceWithOrRemove(path, t.callExpression(util.runtimeProperty("mark"), [node]));
176 path.addComment("leading", "#__PURE__");
177 }
178
179 var insertedLocs = emitter.getInsertedLocs();
180 path.traverse({
181 NumericLiteral: function NumericLiteral(path) {
182 if (!insertedLocs.has(path.node)) {
183 return;
184 }
185
186 path.replaceWith(t.numericLiteral(path.node.value));
187 }
188 }); // Generators are processed in 'exit' handlers so that regenerator only has to run on
189 // an ES5 AST, but that means traversal will not pick up newly inserted references
190 // to things like 'regeneratorRuntime'. To avoid this, we explicitly requeue.
191
192 path.requeue();
193 })
194 }
195 };
196}; // Check if a node should be transformed by regenerator
197
198
199function shouldRegenerate(node, state) {
200 if (node.generator) {
201 if (node.async) {
202 // Async generator
203 return state.opts.asyncGenerators !== false;
204 } else {
205 // Plain generator
206 return state.opts.generators !== false;
207 }
208 } else if (node.async) {
209 // Async function
210 return state.opts.async !== false;
211 } else {
212 // Not a generator or async function.
213 return false;
214 }
215} // Given a NodePath for a Function, return an Expression node that can be
216// used to refer reliably to the function object from inside the function.
217// This expression is essentially a replacement for arguments.callee, with
218// the key advantage that it works in strict mode.
219
220
221function getOuterFnExpr(funPath) {
222 var t = util.getTypes();
223 var node = funPath.node;
224 t.assertFunction(node);
225
226 if (!node.id) {
227 // Default-exported function declarations, and function expressions may not
228 // have a name to reference, so we explicitly add one.
229 node.id = funPath.scope.parent.generateUidIdentifier("callee");
230 }
231
232 if (node.generator && // Non-generator functions don't need to be marked.
233 t.isFunctionDeclaration(node)) {
234 // Return the identifier returned by runtime.mark(<node.id>).
235 return getMarkedFunctionId(funPath);
236 }
237
238 return t.clone(node.id);
239}
240
241var markInfo = new WeakMap();
242
243function getMarkInfo(node) {
244 if (!markInfo.has(node)) {
245 markInfo.set(node, {});
246 }
247
248 return markInfo.get(node);
249}
250
251function getMarkedFunctionId(funPath) {
252 var t = util.getTypes();
253 var node = funPath.node;
254 t.assertIdentifier(node.id);
255 var blockPath = funPath.findParent(function (path) {
256 return path.isProgram() || path.isBlockStatement();
257 });
258
259 if (!blockPath) {
260 return node.id;
261 }
262
263 var block = blockPath.node;
264
265 _assert["default"].ok(Array.isArray(block.body));
266
267 var info = getMarkInfo(block);
268
269 if (!info.decl) {
270 info.decl = t.variableDeclaration("var", []);
271 blockPath.unshiftContainer("body", info.decl);
272 info.declPath = blockPath.get("body.0");
273 }
274
275 _assert["default"].strictEqual(info.declPath.node, info.decl); // Get a new unique identifier for our marked variable.
276
277
278 var markedId = blockPath.scope.generateUidIdentifier("marked");
279 var markCallExp = t.callExpression(util.runtimeProperty("mark"), [t.clone(node.id)]);
280 var index = info.decl.declarations.push(t.variableDeclarator(markedId, markCallExp)) - 1;
281 var markCallExpPath = info.declPath.get("declarations." + index + ".init");
282
283 _assert["default"].strictEqual(markCallExpPath.node, markCallExp);
284
285 markCallExpPath.addComment("leading", "#__PURE__");
286 return t.clone(markedId);
287}
288
289var argumentsThisVisitor = {
290 "FunctionExpression|FunctionDeclaration|Method": function FunctionExpressionFunctionDeclarationMethod(path) {
291 path.skip();
292 },
293 Identifier: function Identifier(path, state) {
294 if (path.node.name === "arguments" && util.isReference(path)) {
295 util.replaceWithOrRemove(path, state.getArgsId());
296 state.usesArguments = true;
297 }
298 },
299 ThisExpression: function ThisExpression(path, state) {
300 state.usesThis = true;
301 }
302};
303var functionSentVisitor = {
304 MetaProperty: function MetaProperty(path) {
305 var node = path.node;
306
307 if (node.meta.name === "function" && node.property.name === "sent") {
308 var t = util.getTypes();
309 util.replaceWithOrRemove(path, t.memberExpression(t.clone(this.context), t.identifier("_sent")));
310 }
311 }
312};
313var awaitVisitor = {
314 Function: function Function(path) {
315 path.skip(); // Don't descend into nested function scopes.
316 },
317 AwaitExpression: function AwaitExpression(path) {
318 var t = util.getTypes(); // Convert await expressions to yield expressions.
319
320 var argument = path.node.argument; // Transforming `await x` to `yield regeneratorRuntime.awrap(x)`
321 // causes the argument to be wrapped in such a way that the runtime
322 // can distinguish between awaited and merely yielded values.
323
324 util.replaceWithOrRemove(path, t.yieldExpression(t.callExpression(util.runtimeProperty("awrap"), [argument]), false));
325 }
326};
Note: See TracBrowser for help on using the repository browser.