source: imaps-frontend/node_modules/@babel/traverse/lib/scope/index.js@ 0c6b92a

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

Pred finalna verzija

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