source: frontend/node_modules/@babel/traverse/lib/scope/index.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: 30.7 KB
Line 
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7var _renamer = require("./lib/renamer.js");
8var _index = require("../index.js");
9var _traverseForScope = require("./traverseForScope.js");
10var _binding = require("./binding.js");
11var _t = require("@babel/types");
12var t = _t;
13var _cache = require("../cache.js");
14const globalsBuiltinLower = require("@babel/helper-globals/data/builtin-lower.json"),
15 globalsBuiltinUpper = require("@babel/helper-globals/data/builtin-upper.json");
16const {
17 assignmentExpression,
18 callExpression,
19 cloneNode,
20 getBindingIdentifiers,
21 identifier,
22 isArrayExpression,
23 isBinary,
24 isCallExpression,
25 isClass,
26 isClassBody,
27 isClassDeclaration,
28 isExportAllDeclaration,
29 isExportDefaultDeclaration,
30 isExportNamedDeclaration,
31 isFunctionDeclaration,
32 isIdentifier,
33 isImportDeclaration,
34 isLiteral,
35 isMemberExpression,
36 isMethod,
37 isModuleSpecifier,
38 isNullLiteral,
39 isObjectExpression,
40 isProperty,
41 isPureish,
42 isRegExpLiteral,
43 isSuper,
44 isTaggedTemplateExpression,
45 isTemplateLiteral,
46 isThisExpression,
47 isUnaryExpression,
48 isVariableDeclaration,
49 expressionStatement,
50 matchesPattern,
51 memberExpression,
52 numericLiteral,
53 toIdentifier,
54 variableDeclaration,
55 variableDeclarator,
56 isObjectProperty,
57 isTopicReference,
58 isMetaProperty,
59 isPrivateName,
60 isExportDeclaration,
61 buildUndefinedNode,
62 sequenceExpression
63} = _t;
64function gatherNodeParts(node, parts) {
65 switch (node == null ? void 0 : node.type) {
66 default:
67 if (isImportDeclaration(node) || isExportDeclaration(node)) {
68 var _node$specifiers;
69 if ((isExportAllDeclaration(node) || isExportNamedDeclaration(node) || isImportDeclaration(node)) && node.source) {
70 gatherNodeParts(node.source, parts);
71 } else if ((isExportNamedDeclaration(node) || isImportDeclaration(node)) && (_node$specifiers = node.specifiers) != null && _node$specifiers.length) {
72 for (const e of node.specifiers) gatherNodeParts(e, parts);
73 } else if ((isExportDefaultDeclaration(node) || isExportNamedDeclaration(node)) && node.declaration) {
74 gatherNodeParts(node.declaration, parts);
75 }
76 } else if (isModuleSpecifier(node)) {
77 gatherNodeParts(node.local, parts);
78 } else if (isLiteral(node) && !isNullLiteral(node) && !isRegExpLiteral(node) && !isTemplateLiteral(node)) {
79 parts.push(node.value);
80 }
81 break;
82 case "MemberExpression":
83 case "OptionalMemberExpression":
84 case "JSXMemberExpression":
85 gatherNodeParts(node.object, parts);
86 gatherNodeParts(node.property, parts);
87 break;
88 case "Identifier":
89 case "JSXIdentifier":
90 parts.push(node.name);
91 break;
92 case "CallExpression":
93 case "OptionalCallExpression":
94 case "NewExpression":
95 gatherNodeParts(node.callee, parts);
96 break;
97 case "ObjectExpression":
98 case "ObjectPattern":
99 for (const e of node.properties) {
100 gatherNodeParts(e, parts);
101 }
102 break;
103 case "SpreadElement":
104 case "RestElement":
105 gatherNodeParts(node.argument, parts);
106 break;
107 case "ObjectProperty":
108 case "ObjectMethod":
109 case "ClassProperty":
110 case "ClassMethod":
111 case "ClassPrivateProperty":
112 case "ClassPrivateMethod":
113 gatherNodeParts(node.key, parts);
114 break;
115 case "ThisExpression":
116 parts.push("this");
117 break;
118 case "Super":
119 parts.push("super");
120 break;
121 case "Import":
122 case "ImportExpression":
123 parts.push("import");
124 break;
125 case "DoExpression":
126 parts.push("do");
127 break;
128 case "YieldExpression":
129 parts.push("yield");
130 gatherNodeParts(node.argument, parts);
131 break;
132 case "AwaitExpression":
133 parts.push("await");
134 gatherNodeParts(node.argument, parts);
135 break;
136 case "AssignmentExpression":
137 gatherNodeParts(node.left, parts);
138 break;
139 case "VariableDeclarator":
140 gatherNodeParts(node.id, parts);
141 break;
142 case "FunctionExpression":
143 case "FunctionDeclaration":
144 case "ClassExpression":
145 case "ClassDeclaration":
146 gatherNodeParts(node.id, parts);
147 break;
148 case "PrivateName":
149 gatherNodeParts(node.id, parts);
150 break;
151 case "ParenthesizedExpression":
152 gatherNodeParts(node.expression, parts);
153 break;
154 case "UnaryExpression":
155 case "UpdateExpression":
156 gatherNodeParts(node.argument, parts);
157 break;
158 case "MetaProperty":
159 gatherNodeParts(node.meta, parts);
160 gatherNodeParts(node.property, parts);
161 break;
162 case "JSXElement":
163 gatherNodeParts(node.openingElement, parts);
164 break;
165 case "JSXOpeningElement":
166 gatherNodeParts(node.name, parts);
167 break;
168 case "JSXFragment":
169 gatherNodeParts(node.openingFragment, parts);
170 break;
171 case "JSXOpeningFragment":
172 parts.push("Fragment");
173 break;
174 case "JSXNamespacedName":
175 gatherNodeParts(node.namespace, parts);
176 gatherNodeParts(node.name, parts);
177 break;
178 }
179}
180function resetScope(scope) {
181 scope.references = Object.create(null);
182 scope.uids = Object.create(null);
183 scope.bindings = Object.create(null);
184 scope.globals = Object.create(null);
185}
186function isAnonymousFunctionExpression(path) {
187 return path.isFunctionExpression() && !path.node.id || path.isArrowFunctionExpression();
188}
189var NOT_LOCAL_BINDING = Symbol.for("should not be considered a local binding");
190const collectorVisitor = {
191 ForStatement(path) {
192 const declar = path.get("init");
193 if (declar.isVar()) {
194 const {
195 scope
196 } = path;
197 const parentScope = scope.getFunctionParent() || scope.getProgramParent();
198 parentScope.registerBinding("var", declar);
199 }
200 },
201 Declaration(path) {
202 if (path.isBlockScoped()) return;
203 if (path.isImportDeclaration()) return;
204 if (path.isExportDeclaration()) return;
205 const parent = path.scope.getFunctionParent() || path.scope.getProgramParent();
206 parent.registerDeclaration(path);
207 },
208 ImportDeclaration(path) {
209 const parent = path.scope.getBlockParent();
210 parent.registerDeclaration(path);
211 },
212 TSImportEqualsDeclaration(path) {
213 const parent = path.scope.getBlockParent();
214 parent.registerDeclaration(path);
215 },
216 ReferencedIdentifier(path, state) {
217 if (t.isTSQualifiedName(path.parent) && path.parent.right === path.node) {
218 return;
219 }
220 if (path.parentPath.isTSImportEqualsDeclaration()) return;
221 state.references.push(path);
222 },
223 ForXStatement(path, state) {
224 const left = path.get("left");
225 if (left.isPattern() || left.isIdentifier()) {
226 state.constantViolations.push(path);
227 } else if (left.isVar()) {
228 const {
229 scope
230 } = path;
231 const parentScope = scope.getFunctionParent() || scope.getProgramParent();
232 parentScope.registerBinding("var", left);
233 }
234 },
235 ExportDeclaration: {
236 exit(path) {
237 const {
238 node,
239 scope
240 } = path;
241 if (isExportAllDeclaration(node)) return;
242 const declar = node.declaration;
243 if (isClassDeclaration(declar) || isFunctionDeclaration(declar)) {
244 const id = declar.id;
245 if (!id) return;
246 const binding = scope.getBinding(id.name);
247 binding == null || binding.reference(path);
248 } else if (isVariableDeclaration(declar)) {
249 for (const decl of declar.declarations) {
250 for (const name of Object.keys(getBindingIdentifiers(decl))) {
251 const binding = scope.getBinding(name);
252 binding == null || binding.reference(path);
253 }
254 }
255 }
256 }
257 },
258 LabeledStatement(path) {
259 path.scope.getBlockParent().registerDeclaration(path);
260 },
261 AssignmentExpression(path, state) {
262 state.assignments.push(path);
263 },
264 UpdateExpression(path, state) {
265 state.constantViolations.push(path);
266 },
267 UnaryExpression(path, state) {
268 if (path.node.operator === "delete") {
269 state.constantViolations.push(path);
270 }
271 },
272 BlockScoped(path) {
273 let scope = path.scope;
274 if (scope.path === path) scope = scope.parent;
275 const parent = scope.getBlockParent();
276 parent.registerDeclaration(path);
277 if (path.isClassDeclaration() && path.node.id) {
278 const id = path.node.id;
279 const name = id.name;
280 path.scope.bindings[name] = path.scope.parent.getBinding(name);
281 }
282 },
283 CatchClause(path) {
284 path.scope.registerBinding("let", path);
285 },
286 Function(path) {
287 const params = path.get("params");
288 for (const param of params) {
289 path.scope.registerBinding("param", param);
290 }
291 if (path.isFunctionExpression() && path.node.id && !path.node.id[NOT_LOCAL_BINDING]) {
292 path.scope.registerBinding("local", path.get("id"), path);
293 }
294 },
295 ClassExpression(path) {
296 if (path.node.id && !path.node.id[NOT_LOCAL_BINDING]) {
297 path.scope.registerBinding("local", path.get("id"), path);
298 }
299 },
300 TSTypeAnnotation(path) {
301 path.skip();
302 }
303};
304let scopeVisitor;
305let uid = 0;
306class Scope {
307 constructor(path) {
308 this.uid = void 0;
309 this.path = void 0;
310 this.block = void 0;
311 this.inited = void 0;
312 this.labels = void 0;
313 this.bindings = void 0;
314 this.referencesSet = void 0;
315 this.globals = void 0;
316 this.uidsSet = void 0;
317 this.data = void 0;
318 this.crawling = void 0;
319 const {
320 node
321 } = path;
322 const cached = _cache.scope.get(node);
323 if ((cached == null ? void 0 : cached.path) === path) {
324 return cached;
325 }
326 _cache.scope.set(node, this);
327 this.uid = uid++;
328 this.block = node;
329 this.path = path;
330 this.labels = new Map();
331 this.inited = false;
332 Object.defineProperties(this, {
333 references: {
334 enumerable: true,
335 configurable: true,
336 writable: true,
337 value: Object.create(null)
338 },
339 uids: {
340 enumerable: true,
341 configurable: true,
342 writable: true,
343 value: Object.create(null)
344 }
345 });
346 }
347 get parent() {
348 var _parent;
349 let parent,
350 path = this.path;
351 do {
352 var _path;
353 const shouldSkip = path.key === "key" || path.listKey === "decorators";
354 path = path.parentPath;
355 if (shouldSkip && path.isMethod()) path = path.parentPath;
356 if ((_path = path) != null && _path.isScope()) parent = path;
357 } while (path && !parent);
358 return (_parent = parent) == null ? void 0 : _parent.scope;
359 }
360 get references() {
361 throw new Error("Scope#references is not available in Babel 8. Use Scope#referencesSet instead.");
362 }
363 get uids() {
364 throw new Error("Scope#uids is not available in Babel 8. Use Scope#uidsSet instead.");
365 }
366 generateDeclaredUidIdentifier(name) {
367 const id = this.generateUidIdentifier(name);
368 this.push({
369 id
370 });
371 return cloneNode(id);
372 }
373 generateUidIdentifier(name) {
374 return identifier(this.generateUid(name));
375 }
376 generateUid(name = "temp") {
377 name = toIdentifier(name).replace(/^_+/, "").replace(/\d+$/g, "");
378 let uid;
379 let i = 0;
380 do {
381 uid = `_${name}`;
382 if (i >= 11) uid += i - 1;else if (i >= 9) uid += i - 9;else if (i >= 1) uid += i + 1;
383 i++;
384 } while (this.hasLabel(uid) || this.hasBinding(uid) || this.hasGlobal(uid) || this.hasReference(uid));
385 const program = this.getProgramParent();
386 program.references[uid] = true;
387 program.uids[uid] = true;
388 return uid;
389 }
390 generateUidBasedOnNode(node, defaultName) {
391 const parts = [];
392 gatherNodeParts(node, parts);
393 let id = parts.join("$");
394 id = id.replace(/^_/, "") || defaultName || "ref";
395 return this.generateUid(id.slice(0, 20));
396 }
397 generateUidIdentifierBasedOnNode(node, defaultName) {
398 return identifier(this.generateUidBasedOnNode(node, defaultName));
399 }
400 isStatic(node) {
401 if (isThisExpression(node) || isSuper(node) || isTopicReference(node)) {
402 return true;
403 }
404 if (isIdentifier(node)) {
405 const binding = this.getBinding(node.name);
406 if (binding) {
407 return binding.constant;
408 } else {
409 return this.hasBinding(node.name);
410 }
411 }
412 return false;
413 }
414 maybeGenerateMemoised(node, dontPush) {
415 if (this.isStatic(node)) {
416 return null;
417 } else {
418 const id = this.generateUidIdentifierBasedOnNode(node);
419 if (!dontPush) {
420 this.push({
421 id
422 });
423 return cloneNode(id);
424 }
425 return id;
426 }
427 }
428 checkBlockScopedCollisions(local, kind, name, id) {
429 if (kind === "param") return;
430 if (local.kind === "local") return;
431 const duplicate = kind === "let" || local.kind === "let" || local.kind === "const" || local.kind === "module" || local.kind === "param" && kind === "const";
432 if (duplicate) {
433 throw this.path.hub.buildError(id, `Duplicate declaration "${name}"`, TypeError);
434 }
435 }
436 rename(oldName, newName) {
437 const binding = this.getBinding(oldName);
438 if (binding) {
439 newName || (newName = this.generateUidIdentifier(oldName).name);
440 const renamer = new _renamer.default(binding, oldName, newName);
441 renamer.rename(arguments[2]);
442 }
443 }
444 dump() {
445 const sep = "-".repeat(60);
446 console.log(sep);
447 let scope = this;
448 do {
449 console.log("#", scope.block.type);
450 for (const name of Object.keys(scope.bindings)) {
451 const binding = scope.bindings[name];
452 console.log(" -", name, {
453 constant: binding.constant,
454 references: binding.references,
455 violations: binding.constantViolations.length,
456 kind: binding.kind
457 });
458 }
459 } while (scope = scope.parent);
460 console.log(sep);
461 }
462 hasLabel(name) {
463 return !!this.getLabel(name);
464 }
465 getLabel(name) {
466 return this.labels.get(name);
467 }
468 registerLabel(path) {
469 this.labels.set(path.node.label.name, path);
470 }
471 registerDeclaration(path) {
472 if (path.isLabeledStatement()) {
473 this.registerLabel(path);
474 } else if (path.isFunctionDeclaration()) {
475 this.registerBinding("hoisted", path.get("id"), path);
476 } else if (path.isVariableDeclaration()) {
477 const declarations = path.get("declarations");
478 const {
479 kind
480 } = path.node;
481 for (const declar of declarations) {
482 this.registerBinding(kind === "using" || kind === "await using" ? "const" : kind, declar);
483 }
484 } else if (path.isClassDeclaration()) {
485 if (path.node.declare) return;
486 this.registerBinding("let", path);
487 } else if (path.isImportDeclaration()) {
488 const isTypeDeclaration = path.node.importKind === "type" || path.node.importKind === "typeof";
489 const specifiers = path.get("specifiers");
490 for (const specifier of specifiers) {
491 const isTypeSpecifier = isTypeDeclaration || specifier.isImportSpecifier() && (specifier.node.importKind === "type" || specifier.node.importKind === "typeof");
492 this.registerBinding(isTypeSpecifier ? "unknown" : "module", specifier);
493 }
494 } else if (path.isExportDeclaration()) {
495 const declar = path.get("declaration");
496 if (declar.isClassDeclaration() || declar.isFunctionDeclaration() || declar.isVariableDeclaration()) {
497 this.registerDeclaration(declar);
498 }
499 } else {
500 this.registerBinding("unknown", path);
501 }
502 }
503 buildUndefinedNode() {
504 return buildUndefinedNode();
505 }
506 registerConstantViolation(path) {
507 const ids = path.getAssignmentIdentifiers();
508 for (const name of Object.keys(ids)) {
509 var _this$getBinding;
510 (_this$getBinding = this.getBinding(name)) == null || _this$getBinding.reassign(path);
511 }
512 }
513 registerBinding(kind, path, bindingPath = path) {
514 if (!kind) throw new ReferenceError("no `kind`");
515 if (path.isVariableDeclaration()) {
516 const declarators = path.get("declarations");
517 for (const declar of declarators) {
518 this.registerBinding(kind, declar);
519 }
520 return;
521 }
522 const parent = this.getProgramParent();
523 const ids = path.getOuterBindingIdentifiers(true);
524 for (const name of Object.keys(ids)) {
525 parent.references[name] = true;
526 for (const id of ids[name]) {
527 const local = this.getOwnBinding(name);
528 if (local) {
529 if (local.identifier === id) continue;
530 this.checkBlockScopedCollisions(local, kind, name, id);
531 }
532 if (local) {
533 local.reassign(bindingPath);
534 } else {
535 this.bindings[name] = new _binding.default({
536 identifier: id,
537 scope: this,
538 path: bindingPath,
539 kind: kind
540 });
541 }
542 }
543 }
544 }
545 addGlobal(node) {
546 this.globals[node.name] = node;
547 }
548 hasUid(name) {
549 let scope = this;
550 do {
551 if (scope.uids[name]) return true;
552 } while (scope = scope.parent);
553 return false;
554 }
555 hasGlobal(name) {
556 let scope = this;
557 do {
558 if (scope.globals[name]) return true;
559 } while (scope = scope.parent);
560 return false;
561 }
562 hasReference(name) {
563 return !!this.getProgramParent().references[name];
564 }
565 isPure(node, constantsOnly) {
566 if (isIdentifier(node)) {
567 const binding = this.getBinding(node.name);
568 if (!binding) return false;
569 if (constantsOnly) return binding.constant;
570 return true;
571 } else if (isThisExpression(node) || isMetaProperty(node) || isTopicReference(node) || isPrivateName(node)) {
572 return true;
573 } else if (isClass(node)) {
574 var _node$decorators;
575 if (node.superClass && !this.isPure(node.superClass, constantsOnly)) {
576 return false;
577 }
578 if (((_node$decorators = node.decorators) == null ? void 0 : _node$decorators.length) > 0) {
579 return false;
580 }
581 return this.isPure(node.body, constantsOnly);
582 } else if (isClassBody(node)) {
583 for (const method of node.body) {
584 if (!this.isPure(method, constantsOnly)) return false;
585 }
586 return true;
587 } else if (isBinary(node)) {
588 return this.isPure(node.left, constantsOnly) && this.isPure(node.right, constantsOnly);
589 } else if (isArrayExpression(node) || (node == null ? void 0 : node.type) === "TupleExpression") {
590 for (const elem of node.elements) {
591 if (elem !== null && !this.isPure(elem, constantsOnly)) return false;
592 }
593 return true;
594 } else if (isObjectExpression(node) || (node == null ? void 0 : node.type) === "RecordExpression") {
595 for (const prop of node.properties) {
596 if (!this.isPure(prop, constantsOnly)) return false;
597 }
598 return true;
599 } else if (isMethod(node)) {
600 var _node$decorators2;
601 if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
602 if (((_node$decorators2 = node.decorators) == null ? void 0 : _node$decorators2.length) > 0) {
603 return false;
604 }
605 return true;
606 } else if (isProperty(node)) {
607 var _node$decorators3;
608 if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
609 if (((_node$decorators3 = node.decorators) == null ? void 0 : _node$decorators3.length) > 0) {
610 return false;
611 }
612 if (isObjectProperty(node) || node.static) {
613 if (node.value !== null && !this.isPure(node.value, constantsOnly)) {
614 return false;
615 }
616 }
617 return true;
618 } else if (isUnaryExpression(node)) {
619 return this.isPure(node.argument, constantsOnly);
620 } else if (isTemplateLiteral(node)) {
621 for (const expression of node.expressions) {
622 if (!this.isPure(expression, constantsOnly)) return false;
623 }
624 return true;
625 } else if (isTaggedTemplateExpression(node)) {
626 return matchesPattern(node.tag, "String.raw") && !this.hasBinding("String", {
627 noGlobals: true
628 }) && this.isPure(node.quasi, constantsOnly);
629 } else if (isMemberExpression(node)) {
630 return !node.computed && isIdentifier(node.object) && node.object.name === "Symbol" && isIdentifier(node.property) && node.property.name !== "for" && !this.hasBinding("Symbol", {
631 noGlobals: true
632 });
633 } else if (isCallExpression(node)) {
634 return matchesPattern(node.callee, "Symbol.for") && !this.hasBinding("Symbol", {
635 noGlobals: true
636 }) && node.arguments.length === 1 && t.isStringLiteral(node.arguments[0]);
637 } else {
638 return isPureish(node);
639 }
640 }
641 setData(key, val) {
642 return this.data[key] = val;
643 }
644 getData(key) {
645 let scope = this;
646 do {
647 const data = scope.data[key];
648 if (data != null) return data;
649 } while (scope = scope.parent);
650 }
651 removeData(key) {
652 let scope = this;
653 do {
654 const data = scope.data[key];
655 if (data != null) scope.data[key] = null;
656 } while (scope = scope.parent);
657 }
658 init() {
659 if (!this.inited) {
660 this.inited = true;
661 this.crawl();
662 }
663 }
664 crawl() {
665 const path = this.path;
666 resetScope(this);
667 this.data = Object.create(null);
668 let scope = this;
669 do {
670 if (scope.crawling) return;
671 if (scope.path.isProgram()) {
672 break;
673 }
674 } while (scope = scope.parent);
675 const programParent = scope;
676 const state = {
677 references: [],
678 constantViolations: [],
679 assignments: []
680 };
681 this.crawling = true;
682 scopeVisitor || (scopeVisitor = _index.default.visitors.merge([{
683 Scope(path) {
684 resetScope(path.scope);
685 }
686 }, collectorVisitor]));
687 if (path.type !== "Program") {
688 const typeVisitors = scopeVisitor[path.type];
689 if (typeVisitors) {
690 for (const visit of typeVisitors.enter) {
691 visit.call(state, path, state);
692 }
693 }
694 }
695 path.traverse(scopeVisitor, state);
696 this.crawling = false;
697 for (const path of state.assignments) {
698 const ids = path.getAssignmentIdentifiers();
699 for (const name of Object.keys(ids)) {
700 if (path.scope.getBinding(name)) continue;
701 programParent.addGlobal(ids[name]);
702 }
703 path.scope.registerConstantViolation(path);
704 }
705 for (const ref of state.references) {
706 const binding = ref.scope.getBinding(ref.node.name);
707 if (binding) {
708 binding.reference(ref);
709 } else {
710 programParent.addGlobal(ref.node);
711 }
712 }
713 for (const path of state.constantViolations) {
714 path.scope.registerConstantViolation(path);
715 }
716 }
717 push(opts) {
718 let path = this.path;
719 if (path.isPattern()) {
720 path = this.getPatternParent().path;
721 } else if (!path.isBlockStatement() && !path.isProgram()) {
722 path = this.getBlockParent().path;
723 }
724 if (path.isSwitchStatement()) {
725 path = (this.getFunctionParent() || this.getProgramParent()).path;
726 }
727 const {
728 init,
729 unique,
730 kind = "var",
731 id
732 } = opts;
733 if (!init && !unique && (kind === "var" || kind === "let") && isAnonymousFunctionExpression(path) && isCallExpression(path.parent, {
734 callee: path.node
735 }) && path.parent.arguments.length <= path.node.params.length && isIdentifier(id)) {
736 path.pushContainer("params", id);
737 path.scope.registerBinding("param", path.get("params")[path.node.params.length - 1]);
738 return;
739 }
740 if (path.isLoop() || path.isCatchClause() || path.isFunction()) {
741 path.ensureBlock();
742 path = path.get("body");
743 }
744 const blockHoist = opts._blockHoist == null ? 2 : opts._blockHoist;
745 const dataKey = `declaration:${kind}:${blockHoist}`;
746 let declarPath = !unique && path.getData(dataKey);
747 if (!declarPath) {
748 const declar = variableDeclaration(kind, []);
749 declar._blockHoist = blockHoist;
750 [declarPath] = path.unshiftContainer("body", [declar]);
751 if (!unique) path.setData(dataKey, declarPath);
752 }
753 const declarator = variableDeclarator(id, init);
754 const len = declarPath.node.declarations.push(declarator);
755 path.scope.registerBinding(kind, declarPath.get("declarations")[len - 1]);
756 }
757 getProgramParent() {
758 let scope = this;
759 do {
760 if (scope.path.isProgram()) {
761 return scope;
762 }
763 } while (scope = scope.parent);
764 throw new Error("Couldn't find a Program");
765 }
766 getFunctionParent() {
767 let scope = this;
768 do {
769 if (scope.path.isFunctionParent()) {
770 return scope;
771 }
772 } while (scope = scope.parent);
773 return null;
774 }
775 getBlockParent() {
776 let scope = this;
777 do {
778 if (scope.path.isBlockParent()) {
779 return scope;
780 }
781 } while (scope = scope.parent);
782 throw new Error("We couldn't find a BlockStatement, For, Switch, Function, Loop or Program...");
783 }
784 getPatternParent() {
785 let scope = this;
786 do {
787 if (!scope.path.isPattern()) {
788 return scope.getBlockParent();
789 }
790 } while (scope = scope.parent.parent);
791 throw new Error("We couldn't find a BlockStatement, For, Switch, Function, Loop or Program...");
792 }
793 getAllBindings() {
794 const ids = Object.create(null);
795 let scope = this;
796 do {
797 for (const key of Object.keys(scope.bindings)) {
798 if (key in ids === false) {
799 ids[key] = scope.bindings[key];
800 }
801 }
802 scope = scope.parent;
803 } while (scope);
804 return ids;
805 }
806 bindingIdentifierEquals(name, node) {
807 return this.getBindingIdentifier(name) === node;
808 }
809 getBinding(name) {
810 let scope = this;
811 let previousPath;
812 do {
813 const binding = scope.getOwnBinding(name);
814 if (binding) {
815 var _previousPath;
816 if ((_previousPath = previousPath) != null && _previousPath.isPattern() && binding.kind !== "param" && binding.kind !== "local") {} else {
817 return binding;
818 }
819 } else if (!binding && name === "arguments" && scope.path.isFunction() && !scope.path.isArrowFunctionExpression()) {
820 break;
821 }
822 previousPath = scope.path;
823 } while (scope = scope.parent);
824 }
825 getOwnBinding(name) {
826 return this.bindings[name];
827 }
828 getBindingIdentifier(name) {
829 var _this$getBinding2;
830 return (_this$getBinding2 = this.getBinding(name)) == null ? void 0 : _this$getBinding2.identifier;
831 }
832 getOwnBindingIdentifier(name) {
833 const binding = this.bindings[name];
834 return binding == null ? void 0 : binding.identifier;
835 }
836 hasOwnBinding(name) {
837 return !!this.getOwnBinding(name);
838 }
839 hasBinding(name, opts) {
840 if (!name) return false;
841 let noGlobals;
842 let noUids;
843 let upToScope;
844 if (typeof opts === "object") {
845 noGlobals = opts.noGlobals;
846 noUids = opts.noUids;
847 upToScope = opts.upToScope;
848 } else if (typeof opts === "boolean") {
849 noGlobals = opts;
850 }
851 let scope = this;
852 do {
853 if (upToScope === scope) {
854 break;
855 }
856 if (scope.hasOwnBinding(name)) {
857 return true;
858 }
859 } while (scope = scope.parent);
860 if (!noUids && this.hasUid(name)) return true;
861 if (!noGlobals && Scope.globals.includes(name)) return true;
862 if (!noGlobals && Scope.contextVariables.includes(name)) return true;
863 return false;
864 }
865 parentHasBinding(name, opts) {
866 var _this$parent;
867 return (_this$parent = this.parent) == null ? void 0 : _this$parent.hasBinding(name, opts);
868 }
869 moveBindingTo(name, scope) {
870 const info = this.getBinding(name);
871 if (info) {
872 info.scope.removeOwnBinding(name);
873 info.scope = scope;
874 scope.bindings[name] = info;
875 }
876 }
877 removeOwnBinding(name) {
878 delete this.bindings[name];
879 }
880 removeBinding(name) {
881 var _this$getBinding3;
882 (_this$getBinding3 = this.getBinding(name)) == null || _this$getBinding3.scope.removeOwnBinding(name);
883 let scope = this;
884 do {
885 if (scope.uids[name]) {
886 scope.uids[name] = false;
887 }
888 } while (scope = scope.parent);
889 }
890 hoistVariables(emit = id => this.push({
891 id
892 })) {
893 this.crawl();
894 const seen = new Set();
895 for (const name of Object.keys(this.bindings)) {
896 const binding = this.bindings[name];
897 if (!binding) continue;
898 const {
899 path
900 } = binding;
901 if (!path.isVariableDeclarator()) continue;
902 const {
903 parent,
904 parentPath
905 } = path;
906 if (parent.kind !== "var" || seen.has(parent)) continue;
907 seen.add(path.parent);
908 let firstId;
909 const init = [];
910 for (const decl of parent.declarations) {
911 firstId != null ? firstId : firstId = decl.id;
912 if (decl.init) {
913 init.push(assignmentExpression("=", decl.id, decl.init));
914 }
915 const ids = Object.keys(getBindingIdentifiers(decl, false, true, true));
916 for (const name of ids) {
917 emit(identifier(name), decl.init != null);
918 }
919 }
920 if (parentPath.parentPath.isForXStatement({
921 left: parent
922 })) {
923 parentPath.replaceWith(firstId);
924 } else if (init.length === 0) {
925 parentPath.remove();
926 } else {
927 const expr = init.length === 1 ? init[0] : sequenceExpression(init);
928 if (parentPath.parentPath.isForStatement({
929 init: parent
930 })) {
931 parentPath.replaceWith(expr);
932 } else {
933 parentPath.replaceWith(expressionStatement(expr));
934 }
935 }
936 }
937 }
938}
939exports.default = Scope;
940Scope.globals = [...globalsBuiltinLower, ...globalsBuiltinUpper];
941Scope.contextVariables = ["arguments", "undefined", "Infinity", "NaN"];
942Scope.prototype._renameFromMap = function _renameFromMap(map, oldName, newName, value) {
943 if (map[oldName]) {
944 map[newName] = value;
945 map[oldName] = null;
946 }
947};
948Scope.prototype.traverse = function (node, opts, state) {
949 (0, _index.default)(node, opts, this, state, this.path);
950};
951Scope.prototype._generateUid = function _generateUid(name, i) {
952 let id = name;
953 if (i > 1) id += i;
954 return `_${id}`;
955};
956Scope.prototype.toArray = function toArray(node, i, arrayLikeIsIterable) {
957 if (isIdentifier(node)) {
958 const binding = this.getBinding(node.name);
959 if (binding != null && binding.constant && binding.path.isGenericType("Array")) {
960 return node;
961 }
962 }
963 if (isArrayExpression(node)) {
964 return node;
965 }
966 if (isIdentifier(node, {
967 name: "arguments"
968 })) {
969 return callExpression(memberExpression(memberExpression(memberExpression(identifier("Array"), identifier("prototype")), identifier("slice")), identifier("call")), [node]);
970 }
971 let helperName;
972 const args = [node];
973 if (i === true) {
974 helperName = "toConsumableArray";
975 } else if (typeof i === "number") {
976 args.push(numericLiteral(i));
977 helperName = "slicedToArray";
978 } else {
979 helperName = "toArray";
980 }
981 if (arrayLikeIsIterable) {
982 args.unshift(this.path.hub.addHelper(helperName));
983 helperName = "maybeArrayLike";
984 }
985 return callExpression(this.path.hub.addHelper(helperName), args);
986};
987Scope.prototype.getAllBindingsOfKind = function getAllBindingsOfKind(...kinds) {
988 const ids = Object.create(null);
989 for (const kind of kinds) {
990 let scope = this;
991 do {
992 for (const name of Object.keys(scope.bindings)) {
993 const binding = scope.bindings[name];
994 if (binding.kind === kind) ids[name] = binding;
995 }
996 scope = scope.parent;
997 } while (scope);
998 }
999 return ids;
1000};
1001Object.defineProperties(Scope.prototype, {
1002 parentBlock: {
1003 configurable: true,
1004 enumerable: true,
1005 get() {
1006 return this.path.parent;
1007 }
1008 },
1009 hub: {
1010 configurable: true,
1011 enumerable: true,
1012 get() {
1013 return this.path.hub;
1014 }
1015 }
1016});
1017
1018//# sourceMappingURL=index.js.map
Note: See TracBrowser for help on using the repository browser.