source: frontend/node_modules/@babel/traverse/lib/path/conversion.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 21.0 KB
Line 
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.arrowFunctionToExpression = arrowFunctionToExpression;
7exports.ensureBlock = ensureBlock;
8exports.ensureFunctionName = ensureFunctionName;
9exports.splitExportDeclaration = splitExportDeclaration;
10exports.toComputedKey = toComputedKey;
11exports.unwrapFunctionEnvironment = unwrapFunctionEnvironment;
12var _t = require("@babel/types");
13var _template = require("@babel/template");
14var _visitors = require("../visitors.js");
15var _context = require("./context.js");
16const {
17 arrowFunctionExpression,
18 assignmentExpression,
19 binaryExpression,
20 blockStatement,
21 callExpression,
22 conditionalExpression,
23 expressionStatement,
24 identifier,
25 isIdentifier,
26 jsxIdentifier,
27 logicalExpression,
28 LOGICAL_OPERATORS,
29 memberExpression,
30 metaProperty,
31 numericLiteral,
32 objectExpression,
33 restElement,
34 returnStatement,
35 sequenceExpression,
36 spreadElement,
37 stringLiteral,
38 super: _super,
39 thisExpression,
40 toExpression,
41 unaryExpression,
42 toBindingIdentifierName,
43 isFunction,
44 isAssignmentPattern,
45 isRestElement,
46 getFunctionName,
47 cloneNode,
48 variableDeclaration,
49 variableDeclarator,
50 exportNamedDeclaration,
51 exportSpecifier,
52 inherits
53} = _t;
54function toComputedKey() {
55 let key;
56 if (this.isMemberExpression()) {
57 key = this.node.property;
58 } else if (this.isProperty() || this.isMethod()) {
59 key = this.node.key;
60 } else {
61 throw new ReferenceError("todo");
62 }
63 if (!this.node.computed) {
64 if (isIdentifier(key)) key = stringLiteral(key.name);
65 }
66 return key;
67}
68function ensureBlock() {
69 const body = this.get("body");
70 const bodyNode = body.node;
71 if (Array.isArray(body)) {
72 throw new Error("Can't convert array path to a block statement");
73 }
74 if (!bodyNode) {
75 throw new Error("Can't convert node without a body");
76 }
77 if (body.isBlockStatement()) {
78 return bodyNode;
79 }
80 const statements = [];
81 let stringPath = "body";
82 let key;
83 let listKey;
84 if (body.isStatement()) {
85 listKey = "body";
86 key = 0;
87 statements.push(body.node);
88 } else {
89 stringPath += ".body.0";
90 if (this.isFunction()) {
91 key = "argument";
92 statements.push(returnStatement(body.node));
93 } else {
94 key = "expression";
95 statements.push(expressionStatement(body.node));
96 }
97 }
98 this.node.body = blockStatement(statements);
99 const parentPath = this.get(stringPath);
100 _context.setup.call(body, parentPath, listKey ? parentPath.node[listKey] : parentPath.node, listKey, key);
101 return this.node;
102}
103exports.arrowFunctionToShadowed = function () {
104 if (!this.isArrowFunctionExpression()) return;
105 this.arrowFunctionToExpression();
106};
107function unwrapFunctionEnvironment() {
108 if (!this.isArrowFunctionExpression() && !this.isFunctionExpression() && !this.isFunctionDeclaration()) {
109 throw this.buildCodeFrameError("Can only unwrap the environment of a function.");
110 }
111 hoistFunctionEnvironment(this);
112}
113function setType(path, type) {
114 path.node.type = type;
115}
116function arrowFunctionToExpression({
117 allowInsertArrow = true,
118 allowInsertArrowWithRest = allowInsertArrow,
119 noNewArrows = !(_arguments$ => (_arguments$ = arguments[0]) == null ? void 0 : _arguments$.specCompliant)()
120} = {}) {
121 if (!this.isArrowFunctionExpression()) {
122 throw this.buildCodeFrameError("Cannot convert non-arrow function to a function expression.");
123 }
124 let self = this;
125 if (!noNewArrows) {
126 var _self$ensureFunctionN;
127 self = (_self$ensureFunctionN = self.ensureFunctionName(false)) != null ? _self$ensureFunctionN : self;
128 }
129 const {
130 thisBinding,
131 fnPath: fn
132 } = hoistFunctionEnvironment(self, noNewArrows, allowInsertArrow, allowInsertArrowWithRest);
133 fn.ensureBlock();
134 setType(fn, "FunctionExpression");
135 if (!noNewArrows) {
136 const checkBinding = thisBinding ? null : fn.scope.generateUidIdentifier("arrowCheckId");
137 if (checkBinding) {
138 fn.parentPath.scope.push({
139 id: checkBinding,
140 init: objectExpression([])
141 });
142 }
143 fn.get("body").unshiftContainer("body", expressionStatement(callExpression(this.hub.addHelper("newArrowCheck"), [thisExpression(), checkBinding ? identifier(checkBinding.name) : identifier(thisBinding)])));
144 fn.replaceWith(callExpression(memberExpression(fn.node, identifier("bind")), [checkBinding ? identifier(checkBinding.name) : thisExpression()]));
145 return fn.get("callee.object");
146 }
147 return fn;
148}
149const getSuperCallsVisitor = (0, _visitors.environmentVisitor)({
150 CallExpression(child, {
151 allSuperCalls
152 }) {
153 if (!child.get("callee").isSuper()) return;
154 allSuperCalls.push(child);
155 }
156});
157function hoistFunctionEnvironment(fnPath, noNewArrows = true, allowInsertArrow = true, allowInsertArrowWithRest = true) {
158 let arrowParent;
159 let thisEnvFn = fnPath.findParent(p => {
160 if (p.isArrowFunctionExpression()) {
161 arrowParent != null ? arrowParent : arrowParent = p;
162 return false;
163 }
164 return p.isFunction() || p.isProgram() || p.isClassProperty({
165 static: false
166 }) || p.isClassPrivateProperty({
167 static: false
168 });
169 });
170 const inConstructor = thisEnvFn.isClassMethod({
171 kind: "constructor"
172 });
173 if (thisEnvFn.isClassProperty() || thisEnvFn.isClassPrivateProperty()) {
174 if (arrowParent) {
175 thisEnvFn = arrowParent;
176 } else if (allowInsertArrow) {
177 fnPath.replaceWith(callExpression(arrowFunctionExpression([], toExpression(fnPath.node)), []));
178 thisEnvFn = fnPath.get("callee");
179 fnPath = thisEnvFn.get("body");
180 } else {
181 throw fnPath.buildCodeFrameError("Unable to transform arrow inside class property");
182 }
183 }
184 const {
185 thisPaths,
186 argumentsPaths,
187 newTargetPaths,
188 superProps,
189 superCalls
190 } = getScopeInformation(fnPath);
191 if (inConstructor && superCalls.length > 0) {
192 if (!allowInsertArrow) {
193 throw superCalls[0].buildCodeFrameError("When using '@babel/plugin-transform-arrow-functions', " + "it's not possible to compile `super()` in an arrow function without compiling classes.\n" + "Please add '@babel/plugin-transform-classes' to your Babel configuration.");
194 }
195 if (!allowInsertArrowWithRest) {
196 throw superCalls[0].buildCodeFrameError("When using '@babel/plugin-transform-parameters', " + "it's not possible to compile `super()` in an arrow function with default or rest parameters without compiling classes.\n" + "Please add '@babel/plugin-transform-classes' to your Babel configuration.");
197 }
198 const allSuperCalls = [];
199 thisEnvFn.traverse(getSuperCallsVisitor, {
200 allSuperCalls
201 });
202 const superBinding = getSuperBinding(thisEnvFn);
203 allSuperCalls.forEach(superCall => {
204 const callee = identifier(superBinding);
205 callee.loc = superCall.node.callee.loc;
206 superCall.get("callee").replaceWith(callee);
207 });
208 }
209 if (argumentsPaths.length > 0) {
210 const argumentsBinding = getBinding(thisEnvFn, "arguments", () => {
211 const args = () => identifier("arguments");
212 if (thisEnvFn.scope.path.isProgram()) {
213 return conditionalExpression(binaryExpression("===", unaryExpression("typeof", args()), stringLiteral("undefined")), thisEnvFn.scope.buildUndefinedNode(), args());
214 } else {
215 return args();
216 }
217 });
218 argumentsPaths.forEach(argumentsChild => {
219 const argsRef = identifier(argumentsBinding);
220 argsRef.loc = argumentsChild.node.loc;
221 argumentsChild.replaceWith(argsRef);
222 });
223 }
224 if (newTargetPaths.length > 0) {
225 const newTargetBinding = getBinding(thisEnvFn, "newtarget", () => metaProperty(identifier("new"), identifier("target")));
226 newTargetPaths.forEach(targetChild => {
227 const targetRef = identifier(newTargetBinding);
228 targetRef.loc = targetChild.node.loc;
229 targetChild.replaceWith(targetRef);
230 });
231 }
232 if (superProps.length > 0) {
233 if (!allowInsertArrow) {
234 throw superProps[0].buildCodeFrameError("When using '@babel/plugin-transform-arrow-functions', " + "it's not possible to compile `super.prop` in an arrow function without compiling classes.\n" + "Please add '@babel/plugin-transform-classes' to your Babel configuration.");
235 }
236 const flatSuperProps = superProps.reduce((acc, superProp) => acc.concat(standardizeSuperProperty(superProp)), []);
237 flatSuperProps.forEach(superProp => {
238 const key = superProp.node.computed ? "" : superProp.get("property").node.name;
239 const superParentPath = superProp.parentPath;
240 const isAssignment = superParentPath.isAssignmentExpression({
241 left: superProp.node
242 });
243 const isCall = superParentPath.isCallExpression({
244 callee: superProp.node
245 });
246 const isTaggedTemplate = superParentPath.isTaggedTemplateExpression({
247 tag: superProp.node
248 });
249 const superBinding = getSuperPropBinding(thisEnvFn, isAssignment, key);
250 const args = [];
251 if (superProp.node.computed) {
252 args.push(superProp.get("property").node);
253 }
254 if (isAssignment) {
255 const value = superParentPath.node.right;
256 args.push(value);
257 }
258 const call = callExpression(identifier(superBinding), args);
259 if (isCall) {
260 superParentPath.unshiftContainer("arguments", thisExpression());
261 superProp.replaceWith(memberExpression(call, identifier("call")));
262 thisPaths.push(superParentPath.get("arguments.0"));
263 } else if (isAssignment) {
264 superParentPath.replaceWith(call);
265 } else if (isTaggedTemplate) {
266 superProp.replaceWith(callExpression(memberExpression(call, identifier("bind"), false), [thisExpression()]));
267 thisPaths.push(superProp.get("arguments.0"));
268 } else {
269 superProp.replaceWith(call);
270 }
271 });
272 }
273 let thisBinding;
274 if (thisPaths.length > 0 || !noNewArrows) {
275 thisBinding = getThisBinding(thisEnvFn, inConstructor);
276 if (noNewArrows || inConstructor && hasSuperClass(thisEnvFn)) {
277 thisPaths.forEach(thisChild => {
278 const thisRef = thisChild.isJSX() ? jsxIdentifier(thisBinding) : identifier(thisBinding);
279 thisRef.loc = thisChild.node.loc;
280 thisChild.replaceWith(thisRef);
281 });
282 if (!noNewArrows) thisBinding = null;
283 }
284 }
285 return {
286 thisBinding: thisBinding,
287 fnPath
288 };
289}
290function isLogicalOp(op) {
291 return LOGICAL_OPERATORS.includes(op);
292}
293function standardizeSuperProperty(superProp) {
294 if (superProp.parentPath.isAssignmentExpression() && superProp.parentPath.node.operator !== "=") {
295 const assignmentPath = superProp.parentPath;
296 const op = assignmentPath.node.operator.slice(0, -1);
297 const value = assignmentPath.node.right;
298 const isLogicalAssignment = isLogicalOp(op);
299 if (superProp.node.computed) {
300 const tmp = superProp.scope.generateDeclaredUidIdentifier("tmp");
301 const {
302 object,
303 property
304 } = superProp.node;
305 assignmentPath.get("left").replaceWith(memberExpression(object, assignmentExpression("=", tmp, property), true));
306 assignmentPath.get("right").replaceWith(rightExpression(isLogicalAssignment ? "=" : op, memberExpression(object, identifier(tmp.name), true), value));
307 } else {
308 const object = superProp.node.object;
309 const property = superProp.node.property;
310 assignmentPath.get("left").replaceWith(memberExpression(object, property));
311 assignmentPath.get("right").replaceWith(rightExpression(isLogicalAssignment ? "=" : op, memberExpression(object, identifier(property.name)), value));
312 }
313 if (isLogicalAssignment) {
314 assignmentPath.replaceWith(logicalExpression(op, assignmentPath.node.left, assignmentPath.node.right));
315 } else {
316 assignmentPath.node.operator = "=";
317 }
318 return [assignmentPath.get("left"), assignmentPath.get("right").get("left")];
319 } else if (superProp.parentPath.isUpdateExpression()) {
320 const updateExpr = superProp.parentPath;
321 const tmp = superProp.scope.generateDeclaredUidIdentifier("tmp");
322 const computedKey = superProp.node.computed ? superProp.scope.generateDeclaredUidIdentifier("prop") : null;
323 const parts = [assignmentExpression("=", tmp, memberExpression(superProp.node.object, computedKey ? assignmentExpression("=", computedKey, superProp.node.property) : superProp.node.property, superProp.node.computed)), assignmentExpression("=", memberExpression(superProp.node.object, computedKey ? identifier(computedKey.name) : superProp.node.property, superProp.node.computed), binaryExpression(superProp.parentPath.node.operator[0], identifier(tmp.name), numericLiteral(1)))];
324 if (!superProp.parentPath.node.prefix) {
325 parts.push(identifier(tmp.name));
326 }
327 updateExpr.replaceWith(sequenceExpression(parts));
328 const left = updateExpr.get("expressions.0.right");
329 const right = updateExpr.get("expressions.1.left");
330 return [left, right];
331 }
332 return [superProp];
333 function rightExpression(op, left, right) {
334 if (op === "=") {
335 return assignmentExpression("=", left, right);
336 } else {
337 return binaryExpression(op, left, right);
338 }
339 }
340}
341function hasSuperClass(thisEnvFn) {
342 return thisEnvFn.isClassMethod() && !!thisEnvFn.parentPath.parentPath.node.superClass;
343}
344const assignSuperThisVisitor = (0, _visitors.environmentVisitor)({
345 CallExpression(child, {
346 supers,
347 thisBinding
348 }) {
349 if (!child.get("callee").isSuper()) return;
350 if (supers.has(child.node)) return;
351 supers.add(child.node);
352 child.replaceWithMultiple([child.node, assignmentExpression("=", identifier(thisBinding), identifier("this"))]);
353 }
354});
355function getThisBinding(thisEnvFn, inConstructor) {
356 return getBinding(thisEnvFn, "this", thisBinding => {
357 if (!inConstructor || !hasSuperClass(thisEnvFn)) return thisExpression();
358 thisEnvFn.traverse(assignSuperThisVisitor, {
359 supers: new WeakSet(),
360 thisBinding
361 });
362 });
363}
364function getSuperBinding(thisEnvFn) {
365 return getBinding(thisEnvFn, "supercall", () => {
366 const argsBinding = thisEnvFn.scope.generateUidIdentifier("args");
367 return arrowFunctionExpression([restElement(argsBinding)], callExpression(_super(), [spreadElement(identifier(argsBinding.name))]));
368 });
369}
370function getSuperPropBinding(thisEnvFn, isAssignment, propName) {
371 const op = isAssignment ? "set" : "get";
372 return getBinding(thisEnvFn, `superprop_${op}:${propName || ""}`, () => {
373 const argsList = [];
374 let fnBody;
375 if (propName) {
376 fnBody = memberExpression(_super(), identifier(propName));
377 } else {
378 const method = thisEnvFn.scope.generateUidIdentifier("prop");
379 argsList.unshift(method);
380 fnBody = memberExpression(_super(), identifier(method.name), true);
381 }
382 if (isAssignment) {
383 const valueIdent = thisEnvFn.scope.generateUidIdentifier("value");
384 argsList.push(valueIdent);
385 fnBody = assignmentExpression("=", fnBody, identifier(valueIdent.name));
386 }
387 return arrowFunctionExpression(argsList, fnBody);
388 });
389}
390function getBinding(thisEnvFn, key, init) {
391 const cacheKey = "binding:" + key;
392 let data = thisEnvFn.getData(cacheKey);
393 if (!data) {
394 const id = thisEnvFn.scope.generateUidIdentifier(key);
395 data = id.name;
396 thisEnvFn.setData(cacheKey, data);
397 thisEnvFn.scope.push({
398 id: id,
399 init: init(data)
400 });
401 }
402 return data;
403}
404const getScopeInformationVisitor = (0, _visitors.environmentVisitor)({
405 ThisExpression(child, {
406 thisPaths
407 }) {
408 thisPaths.push(child);
409 },
410 JSXIdentifier(child, {
411 thisPaths
412 }) {
413 if (child.node.name !== "this") return;
414 if (!child.parentPath.isJSXMemberExpression({
415 object: child.node
416 }) && !child.parentPath.isJSXOpeningElement({
417 name: child.node
418 })) {
419 return;
420 }
421 thisPaths.push(child);
422 },
423 CallExpression(child, {
424 superCalls
425 }) {
426 if (child.get("callee").isSuper()) superCalls.push(child);
427 },
428 MemberExpression(child, {
429 superProps
430 }) {
431 if (child.get("object").isSuper()) superProps.push(child);
432 },
433 Identifier(child, {
434 argumentsPaths
435 }) {
436 if (!child.isReferencedIdentifier({
437 name: "arguments"
438 })) return;
439 let curr = child.scope;
440 do {
441 if (curr.hasOwnBinding("arguments")) {
442 curr.rename("arguments");
443 return;
444 }
445 if (curr.path.isFunction() && !curr.path.isArrowFunctionExpression()) {
446 break;
447 }
448 } while (curr = curr.parent);
449 argumentsPaths.push(child);
450 },
451 MetaProperty(child, {
452 newTargetPaths
453 }) {
454 if (!child.get("meta").isIdentifier({
455 name: "new"
456 })) return;
457 if (!child.get("property").isIdentifier({
458 name: "target"
459 })) return;
460 newTargetPaths.push(child);
461 }
462});
463function getScopeInformation(fnPath) {
464 const thisPaths = [];
465 const argumentsPaths = [];
466 const newTargetPaths = [];
467 const superProps = [];
468 const superCalls = [];
469 fnPath.traverse(getScopeInformationVisitor, {
470 thisPaths,
471 argumentsPaths,
472 newTargetPaths,
473 superProps,
474 superCalls
475 });
476 return {
477 thisPaths,
478 argumentsPaths,
479 newTargetPaths,
480 superProps,
481 superCalls
482 };
483}
484function splitExportDeclaration() {
485 if (!this.isExportDeclaration() || this.isExportAllDeclaration()) {
486 throw new Error("Only default and named export declarations can be split.");
487 }
488 if (this.isExportNamedDeclaration() && this.get("specifiers").length > 0) {
489 throw new Error("It doesn't make sense to split exported specifiers.");
490 }
491 const declaration = this.get("declaration");
492 if (this.isExportDefaultDeclaration()) {
493 const standaloneDeclaration = declaration.isFunctionDeclaration() || declaration.isClassDeclaration();
494 const exportExpr = declaration.isFunctionExpression() || declaration.isClassExpression();
495 const scope = declaration.isScope() ? declaration.scope.parent : declaration.scope;
496 let id = declaration.node.id;
497 let needBindingRegistration = false;
498 if (!id) {
499 needBindingRegistration = true;
500 id = scope.generateUidIdentifier("default");
501 if (standaloneDeclaration || exportExpr) {
502 declaration.node.id = cloneNode(id);
503 }
504 } else if (exportExpr && scope.hasBinding(id.name)) {
505 needBindingRegistration = true;
506 id = scope.generateUidIdentifier(id.name);
507 }
508 const updatedDeclaration = standaloneDeclaration ? declaration.node : variableDeclaration("var", [variableDeclarator(cloneNode(id), declaration.node)]);
509 const updatedExportDeclaration = exportNamedDeclaration(null, [exportSpecifier(cloneNode(id), identifier("default"))]);
510 this.insertAfter(updatedExportDeclaration);
511 this.replaceWith(updatedDeclaration);
512 if (needBindingRegistration) {
513 scope.registerDeclaration(this);
514 }
515 return this;
516 } else if (this.get("specifiers").length > 0) {
517 throw new Error("It doesn't make sense to split exported specifiers.");
518 }
519 const bindingIdentifiers = declaration.getOuterBindingIdentifiers();
520 const specifiers = Object.keys(bindingIdentifiers).map(name => {
521 return exportSpecifier(identifier(name), identifier(name));
522 });
523 const aliasDeclar = exportNamedDeclaration(null, specifiers);
524 this.insertAfter(aliasDeclar);
525 this.replaceWith(declaration.node);
526 return this;
527}
528const refersOuterBindingVisitor = {
529 "ReferencedIdentifier|BindingIdentifier"(path, state) {
530 if (path.node.name !== state.name) return;
531 state.needsRename = true;
532 path.stop();
533 },
534 Scope(path, state) {
535 if (path.scope.hasOwnBinding(state.name)) {
536 path.skip();
537 }
538 }
539};
540function ensureFunctionName(supportUnicodeId) {
541 if (this.node.id) return this;
542 const res = getFunctionName(this.node, this.parent);
543 if (res == null) return this;
544 let {
545 name
546 } = res;
547 if (!supportUnicodeId && /[\uD800-\uDFFF]/.test(name)) {
548 return null;
549 }
550 if (name.startsWith("get ") || name.startsWith("set ")) {
551 return null;
552 }
553 name = toBindingIdentifierName(name.replace(/[/ ]/g, "_"));
554 const id = identifier(name);
555 inherits(id, res.originalNode);
556 const state = {
557 needsRename: false,
558 name
559 };
560 const {
561 scope
562 } = this;
563 const binding = scope.getOwnBinding(name);
564 if (binding) {
565 if (binding.kind === "param") {
566 state.needsRename = true;
567 } else {}
568 } else if (scope.parent.hasBinding(name) || scope.hasGlobal(name)) {
569 this.traverse(refersOuterBindingVisitor, state);
570 }
571 if (!state.needsRename) {
572 this.node.id = id;
573 scope.getProgramParent().references[id.name] = true;
574 return this;
575 }
576 if (scope.hasBinding(id.name) && !scope.hasGlobal(id.name)) {
577 scope.rename(id.name);
578 this.node.id = id;
579 scope.getProgramParent().references[id.name] = true;
580 return this;
581 }
582 if (!isFunction(this.node)) return null;
583 const key = scope.generateUidIdentifier(id.name);
584 const params = [];
585 for (let i = 0, len = getFunctionArity(this.node); i < len; i++) {
586 params.push(scope.generateUidIdentifier("x"));
587 }
588 const call = _template.default.expression.ast`
589 (function (${key}) {
590 function ${id}(${params}) {
591 return ${cloneNode(key)}.apply(this, arguments);
592 }
593
594 ${cloneNode(id)}.toString = function () {
595 return ${cloneNode(key)}.toString();
596 }
597
598 return ${cloneNode(id)};
599 })(${toExpression(this.node)})
600 `;
601 return this.replaceWith(call)[0].get("arguments.0");
602}
603function getFunctionArity(node) {
604 const count = node.params.findIndex(param => isAssignmentPattern(param) || isRestElement(param));
605 return count === -1 ? node.params.length : count;
606}
607
608//# sourceMappingURL=conversion.js.map
Note: See TracBrowser for help on using the repository browser.