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

main
Last change on this file since d565449 was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

  • 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");
15const {
16 arrowFunctionExpression,
17 assignmentExpression,
18 binaryExpression,
19 blockStatement,
20 callExpression,
21 conditionalExpression,
22 expressionStatement,
23 identifier,
24 isIdentifier,
25 jsxIdentifier,
26 logicalExpression,
27 LOGICAL_OPERATORS,
28 memberExpression,
29 metaProperty,
30 numericLiteral,
31 objectExpression,
32 restElement,
33 returnStatement,
34 sequenceExpression,
35 spreadElement,
36 stringLiteral,
37 super: _super,
38 thisExpression,
39 toExpression,
40 unaryExpression,
41 toBindingIdentifierName,
42 isFunction,
43 isAssignmentPattern,
44 isRestElement,
45 getFunctionName,
46 cloneNode,
47 variableDeclaration,
48 variableDeclarator,
49 exportNamedDeclaration,
50 exportSpecifier,
51 inherits
52} = _t;
53function toComputedKey() {
54 let key;
55 if (this.isMemberExpression()) {
56 key = this.node.property;
57 } else if (this.isProperty() || this.isMethod()) {
58 key = this.node.key;
59 } else {
60 throw new ReferenceError("todo");
61 }
62 if (!this.node.computed) {
63 if (isIdentifier(key)) key = stringLiteral(key.name);
64 }
65 return key;
66}
67function ensureBlock() {
68 const body = this.get("body");
69 const bodyNode = body.node;
70 if (Array.isArray(body)) {
71 throw new Error("Can't convert array path to a block statement");
72 }
73 if (!bodyNode) {
74 throw new Error("Can't convert node without a body");
75 }
76 if (body.isBlockStatement()) {
77 return bodyNode;
78 }
79 const statements = [];
80 let stringPath = "body";
81 let key;
82 let listKey;
83 if (body.isStatement()) {
84 listKey = "body";
85 key = 0;
86 statements.push(body.node);
87 } else {
88 stringPath += ".body.0";
89 if (this.isFunction()) {
90 key = "argument";
91 statements.push(returnStatement(body.node));
92 } else {
93 key = "expression";
94 statements.push(expressionStatement(body.node));
95 }
96 }
97 this.node.body = blockStatement(statements);
98 const parentPath = this.get(stringPath);
99 body.setup(parentPath, listKey ? parentPath.node[listKey] : parentPath.node, listKey, key);
100 return this.node;
101}
102{
103 exports.arrowFunctionToShadowed = function () {
104 if (!this.isArrowFunctionExpression()) return;
105 this.arrowFunctionToExpression();
106 };
107}
108function unwrapFunctionEnvironment() {
109 if (!this.isArrowFunctionExpression() && !this.isFunctionExpression() && !this.isFunctionDeclaration()) {
110 throw this.buildCodeFrameError("Can only unwrap the environment of a function.");
111 }
112 hoistFunctionEnvironment(this);
113}
114function setType(path, type) {
115 path.node.type = type;
116}
117function arrowFunctionToExpression({
118 allowInsertArrow = true,
119 allowInsertArrowWithRest = allowInsertArrow,
120 noNewArrows = !(_arguments$ => (_arguments$ = arguments[0]) == null ? void 0 : _arguments$.specCompliant)()
121} = {}) {
122 if (!this.isArrowFunctionExpression()) {
123 throw this.buildCodeFrameError("Cannot convert non-arrow function to a function expression.");
124 }
125 let self = this;
126 if (!noNewArrows) {
127 var _self$ensureFunctionN;
128 self = (_self$ensureFunctionN = self.ensureFunctionName(false)) != null ? _self$ensureFunctionN : self;
129 }
130 const {
131 thisBinding,
132 fnPath: fn
133 } = hoistFunctionEnvironment(self, noNewArrows, allowInsertArrow, allowInsertArrowWithRest);
134 fn.ensureBlock();
135 setType(fn, "FunctionExpression");
136 if (!noNewArrows) {
137 const checkBinding = thisBinding ? null : fn.scope.generateUidIdentifier("arrowCheckId");
138 if (checkBinding) {
139 fn.parentPath.scope.push({
140 id: checkBinding,
141 init: objectExpression([])
142 });
143 }
144 fn.get("body").unshiftContainer("body", expressionStatement(callExpression(this.hub.addHelper("newArrowCheck"), [thisExpression(), checkBinding ? identifier(checkBinding.name) : identifier(thisBinding)])));
145 fn.replaceWith(callExpression(memberExpression(fn.node, identifier("bind")), [checkBinding ? identifier(checkBinding.name) : thisExpression()]));
146 return fn.get("callee.object");
147 }
148 return fn;
149}
150const getSuperCallsVisitor = (0, _visitors.environmentVisitor)({
151 CallExpression(child, {
152 allSuperCalls
153 }) {
154 if (!child.get("callee").isSuper()) return;
155 allSuperCalls.push(child);
156 }
157});
158function hoistFunctionEnvironment(fnPath, noNewArrows = true, allowInsertArrow = true, allowInsertArrowWithRest = true) {
159 let arrowParent;
160 let thisEnvFn = fnPath.findParent(p => {
161 if (p.isArrowFunctionExpression()) {
162 var _arrowParent;
163 (_arrowParent = arrowParent) != null ? _arrowParent : arrowParent = p;
164 return false;
165 }
166 return p.isFunction() || p.isProgram() || p.isClassProperty({
167 static: false
168 }) || p.isClassPrivateProperty({
169 static: false
170 });
171 });
172 const inConstructor = thisEnvFn.isClassMethod({
173 kind: "constructor"
174 });
175 if (thisEnvFn.isClassProperty() || thisEnvFn.isClassPrivateProperty()) {
176 if (arrowParent) {
177 thisEnvFn = arrowParent;
178 } else if (allowInsertArrow) {
179 fnPath.replaceWith(callExpression(arrowFunctionExpression([], toExpression(fnPath.node)), []));
180 thisEnvFn = fnPath.get("callee");
181 fnPath = thisEnvFn.get("body");
182 } else {
183 throw fnPath.buildCodeFrameError("Unable to transform arrow inside class property");
184 }
185 }
186 const {
187 thisPaths,
188 argumentsPaths,
189 newTargetPaths,
190 superProps,
191 superCalls
192 } = getScopeInformation(fnPath);
193 if (inConstructor && superCalls.length > 0) {
194 if (!allowInsertArrow) {
195 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.");
196 }
197 if (!allowInsertArrowWithRest) {
198 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.");
199 }
200 const allSuperCalls = [];
201 thisEnvFn.traverse(getSuperCallsVisitor, {
202 allSuperCalls
203 });
204 const superBinding = getSuperBinding(thisEnvFn);
205 allSuperCalls.forEach(superCall => {
206 const callee = identifier(superBinding);
207 callee.loc = superCall.node.callee.loc;
208 superCall.get("callee").replaceWith(callee);
209 });
210 }
211 if (argumentsPaths.length > 0) {
212 const argumentsBinding = getBinding(thisEnvFn, "arguments", () => {
213 const args = () => identifier("arguments");
214 if (thisEnvFn.scope.path.isProgram()) {
215 return conditionalExpression(binaryExpression("===", unaryExpression("typeof", args()), stringLiteral("undefined")), thisEnvFn.scope.buildUndefinedNode(), args());
216 } else {
217 return args();
218 }
219 });
220 argumentsPaths.forEach(argumentsChild => {
221 const argsRef = identifier(argumentsBinding);
222 argsRef.loc = argumentsChild.node.loc;
223 argumentsChild.replaceWith(argsRef);
224 });
225 }
226 if (newTargetPaths.length > 0) {
227 const newTargetBinding = getBinding(thisEnvFn, "newtarget", () => metaProperty(identifier("new"), identifier("target")));
228 newTargetPaths.forEach(targetChild => {
229 const targetRef = identifier(newTargetBinding);
230 targetRef.loc = targetChild.node.loc;
231 targetChild.replaceWith(targetRef);
232 });
233 }
234 if (superProps.length > 0) {
235 if (!allowInsertArrow) {
236 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.");
237 }
238 const flatSuperProps = superProps.reduce((acc, superProp) => acc.concat(standardizeSuperProperty(superProp)), []);
239 flatSuperProps.forEach(superProp => {
240 const key = superProp.node.computed ? "" : superProp.get("property").node.name;
241 const superParentPath = superProp.parentPath;
242 const isAssignment = superParentPath.isAssignmentExpression({
243 left: superProp.node
244 });
245 const isCall = superParentPath.isCallExpression({
246 callee: superProp.node
247 });
248 const isTaggedTemplate = superParentPath.isTaggedTemplateExpression({
249 tag: superProp.node
250 });
251 const superBinding = getSuperPropBinding(thisEnvFn, isAssignment, key);
252 const args = [];
253 if (superProp.node.computed) {
254 args.push(superProp.get("property").node);
255 }
256 if (isAssignment) {
257 const value = superParentPath.node.right;
258 args.push(value);
259 }
260 const call = callExpression(identifier(superBinding), args);
261 if (isCall) {
262 superParentPath.unshiftContainer("arguments", thisExpression());
263 superProp.replaceWith(memberExpression(call, identifier("call")));
264 thisPaths.push(superParentPath.get("arguments.0"));
265 } else if (isAssignment) {
266 superParentPath.replaceWith(call);
267 } else if (isTaggedTemplate) {
268 superProp.replaceWith(callExpression(memberExpression(call, identifier("bind"), false), [thisExpression()]));
269 thisPaths.push(superProp.get("arguments.0"));
270 } else {
271 superProp.replaceWith(call);
272 }
273 });
274 }
275 let thisBinding;
276 if (thisPaths.length > 0 || !noNewArrows) {
277 thisBinding = getThisBinding(thisEnvFn, inConstructor);
278 if (noNewArrows || inConstructor && hasSuperClass(thisEnvFn)) {
279 thisPaths.forEach(thisChild => {
280 const thisRef = thisChild.isJSX() ? jsxIdentifier(thisBinding) : identifier(thisBinding);
281 thisRef.loc = thisChild.node.loc;
282 thisChild.replaceWith(thisRef);
283 });
284 if (!noNewArrows) thisBinding = null;
285 }
286 }
287 return {
288 thisBinding,
289 fnPath
290 };
291}
292function isLogicalOp(op) {
293 return LOGICAL_OPERATORS.includes(op);
294}
295function standardizeSuperProperty(superProp) {
296 if (superProp.parentPath.isAssignmentExpression() && superProp.parentPath.node.operator !== "=") {
297 const assignmentPath = superProp.parentPath;
298 const op = assignmentPath.node.operator.slice(0, -1);
299 const value = assignmentPath.node.right;
300 const isLogicalAssignment = isLogicalOp(op);
301 if (superProp.node.computed) {
302 const tmp = superProp.scope.generateDeclaredUidIdentifier("tmp");
303 const object = superProp.node.object;
304 const property = superProp.node.property;
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.