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

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

Update repo after prototype presentation

  • Property mode set to 100644
File size: 28.9 KB
RevLine 
[d565449]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.has("id") && !path.get("id").node[NOT_LOCAL_BINDING]) {
275 path.scope.registerBinding("local", path.get("id"), path);
276 }
277 },
278 ClassExpression(path) {
279 if (path.has("id") && !path.get("id").node[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.labels = void 0;
294 this.inited = 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 get parentBlock() {
329 return this.path.parent;
330 }
331 get hub() {
332 return this.path.hub;
333 }
334 traverse(node, opts, state) {
335 (0, _index.default)(node, opts, this, state, this.path);
336 }
337 generateDeclaredUidIdentifier(name) {
338 const id = this.generateUidIdentifier(name);
339 this.push({
340 id
341 });
342 return cloneNode(id);
343 }
344 generateUidIdentifier(name) {
345 return identifier(this.generateUid(name));
346 }
347 generateUid(name = "temp") {
348 name = toIdentifier(name).replace(/^_+/, "").replace(/\d+$/g, "");
349 let uid;
350 let i = 1;
351 do {
352 uid = this._generateUid(name, i);
353 i++;
354 } while (this.hasLabel(uid) || this.hasBinding(uid) || this.hasGlobal(uid) || this.hasReference(uid));
355 const program = this.getProgramParent();
356 program.references[uid] = true;
357 program.uids[uid] = true;
358 return uid;
359 }
360 _generateUid(name, i) {
361 let id = name;
362 if (i > 1) id += i;
363 return `_${id}`;
364 }
365 generateUidBasedOnNode(node, defaultName) {
366 const parts = [];
367 gatherNodeParts(node, parts);
368 let id = parts.join("$");
369 id = id.replace(/^_/, "") || defaultName || "ref";
370 return this.generateUid(id.slice(0, 20));
371 }
372 generateUidIdentifierBasedOnNode(node, defaultName) {
373 return identifier(this.generateUidBasedOnNode(node, defaultName));
374 }
375 isStatic(node) {
376 if (isThisExpression(node) || isSuper(node) || isTopicReference(node)) {
377 return true;
378 }
379 if (isIdentifier(node)) {
380 const binding = this.getBinding(node.name);
381 if (binding) {
382 return binding.constant;
383 } else {
384 return this.hasBinding(node.name);
385 }
386 }
387 return false;
388 }
389 maybeGenerateMemoised(node, dontPush) {
390 if (this.isStatic(node)) {
391 return null;
392 } else {
393 const id = this.generateUidIdentifierBasedOnNode(node);
394 if (!dontPush) {
395 this.push({
396 id
397 });
398 return cloneNode(id);
399 }
400 return id;
401 }
402 }
403 checkBlockScopedCollisions(local, kind, name, id) {
404 if (kind === "param") return;
405 if (local.kind === "local") return;
406 const duplicate = kind === "let" || local.kind === "let" || local.kind === "const" || local.kind === "module" || local.kind === "param" && kind === "const";
407 if (duplicate) {
408 throw this.hub.buildError(id, `Duplicate declaration "${name}"`, TypeError);
409 }
410 }
411 rename(oldName, newName) {
412 const binding = this.getBinding(oldName);
413 if (binding) {
414 newName || (newName = this.generateUidIdentifier(oldName).name);
415 const renamer = new _renamer.default(binding, oldName, newName);
416 {
417 renamer.rename(arguments[2]);
418 }
419 }
420 }
421 _renameFromMap(map, oldName, newName, value) {
422 if (map[oldName]) {
423 map[newName] = value;
424 map[oldName] = null;
425 }
426 }
427 dump() {
428 const sep = "-".repeat(60);
429 console.log(sep);
430 let scope = this;
431 do {
432 console.log("#", scope.block.type);
433 for (const name of Object.keys(scope.bindings)) {
434 const binding = scope.bindings[name];
435 console.log(" -", name, {
436 constant: binding.constant,
437 references: binding.references,
438 violations: binding.constantViolations.length,
439 kind: binding.kind
440 });
441 }
442 } while (scope = scope.parent);
443 console.log(sep);
444 }
445 toArray(node, i, arrayLikeIsIterable) {
446 if (isIdentifier(node)) {
447 const binding = this.getBinding(node.name);
448 if (binding != null && binding.constant && binding.path.isGenericType("Array")) {
449 return node;
450 }
451 }
452 if (isArrayExpression(node)) {
453 return node;
454 }
455 if (isIdentifier(node, {
456 name: "arguments"
457 })) {
458 return callExpression(memberExpression(memberExpression(memberExpression(identifier("Array"), identifier("prototype")), identifier("slice")), identifier("call")), [node]);
459 }
460 let helperName;
461 const args = [node];
462 if (i === true) {
463 helperName = "toConsumableArray";
464 } else if (typeof i === "number") {
465 args.push(numericLiteral(i));
466 helperName = "slicedToArray";
467 } else {
468 helperName = "toArray";
469 }
470 if (arrayLikeIsIterable) {
471 args.unshift(this.hub.addHelper(helperName));
472 helperName = "maybeArrayLike";
473 }
474 return callExpression(this.hub.addHelper(helperName), args);
475 }
476 hasLabel(name) {
477 return !!this.getLabel(name);
478 }
479 getLabel(name) {
480 return this.labels.get(name);
481 }
482 registerLabel(path) {
483 this.labels.set(path.node.label.name, path);
484 }
485 registerDeclaration(path) {
486 if (path.isLabeledStatement()) {
487 this.registerLabel(path);
488 } else if (path.isFunctionDeclaration()) {
489 this.registerBinding("hoisted", path.get("id"), path);
490 } else if (path.isVariableDeclaration()) {
491 const declarations = path.get("declarations");
492 const {
493 kind
494 } = path.node;
495 for (const declar of declarations) {
496 this.registerBinding(kind === "using" || kind === "await using" ? "const" : kind, declar);
497 }
498 } else if (path.isClassDeclaration()) {
499 if (path.node.declare) return;
500 this.registerBinding("let", path);
501 } else if (path.isImportDeclaration()) {
502 const isTypeDeclaration = path.node.importKind === "type" || path.node.importKind === "typeof";
503 const specifiers = path.get("specifiers");
504 for (const specifier of specifiers) {
505 const isTypeSpecifier = isTypeDeclaration || specifier.isImportSpecifier() && (specifier.node.importKind === "type" || specifier.node.importKind === "typeof");
506 this.registerBinding(isTypeSpecifier ? "unknown" : "module", specifier);
507 }
508 } else if (path.isExportDeclaration()) {
509 const declar = path.get("declaration");
510 if (declar.isClassDeclaration() || declar.isFunctionDeclaration() || declar.isVariableDeclaration()) {
511 this.registerDeclaration(declar);
512 }
513 } else {
514 this.registerBinding("unknown", path);
515 }
516 }
517 buildUndefinedNode() {
518 return buildUndefinedNode();
519 }
520 registerConstantViolation(path) {
521 const ids = path.getAssignmentIdentifiers();
522 for (const name of Object.keys(ids)) {
523 var _this$getBinding;
524 (_this$getBinding = this.getBinding(name)) == null || _this$getBinding.reassign(path);
525 }
526 }
527 registerBinding(kind, path, bindingPath = path) {
528 if (!kind) throw new ReferenceError("no `kind`");
529 if (path.isVariableDeclaration()) {
530 const declarators = path.get("declarations");
531 for (const declar of declarators) {
532 this.registerBinding(kind, declar);
533 }
534 return;
535 }
536 const parent = this.getProgramParent();
537 const ids = path.getOuterBindingIdentifiers(true);
538 for (const name of Object.keys(ids)) {
539 parent.references[name] = true;
540 for (const id of ids[name]) {
541 const local = this.getOwnBinding(name);
542 if (local) {
543 if (local.identifier === id) continue;
544 this.checkBlockScopedCollisions(local, kind, name, id);
545 }
546 if (local) {
547 local.reassign(bindingPath);
548 } else {
549 this.bindings[name] = new _binding.default({
550 identifier: id,
551 scope: this,
552 path: bindingPath,
553 kind: kind
554 });
555 }
556 }
557 }
558 }
559 addGlobal(node) {
560 this.globals[node.name] = node;
561 }
562 hasUid(name) {
563 let scope = this;
564 do {
565 if (scope.uids[name]) return true;
566 } while (scope = scope.parent);
567 return false;
568 }
569 hasGlobal(name) {
570 let scope = this;
571 do {
572 if (scope.globals[name]) return true;
573 } while (scope = scope.parent);
574 return false;
575 }
576 hasReference(name) {
577 return !!this.getProgramParent().references[name];
578 }
579 isPure(node, constantsOnly) {
580 if (isIdentifier(node)) {
581 const binding = this.getBinding(node.name);
582 if (!binding) return false;
583 if (constantsOnly) return binding.constant;
584 return true;
585 } else if (isThisExpression(node) || isMetaProperty(node) || isTopicReference(node) || isPrivateName(node)) {
586 return true;
587 } else if (isClass(node)) {
588 var _node$decorators;
589 if (node.superClass && !this.isPure(node.superClass, constantsOnly)) {
590 return false;
591 }
592 if (((_node$decorators = node.decorators) == null ? void 0 : _node$decorators.length) > 0) {
593 return false;
594 }
595 return this.isPure(node.body, constantsOnly);
596 } else if (isClassBody(node)) {
597 for (const method of node.body) {
598 if (!this.isPure(method, constantsOnly)) return false;
599 }
600 return true;
601 } else if (isBinary(node)) {
602 return this.isPure(node.left, constantsOnly) && this.isPure(node.right, constantsOnly);
603 } else if (isArrayExpression(node) || isTupleExpression(node)) {
604 for (const elem of node.elements) {
605 if (elem !== null && !this.isPure(elem, constantsOnly)) return false;
606 }
607 return true;
608 } else if (isObjectExpression(node) || isRecordExpression(node)) {
609 for (const prop of node.properties) {
610 if (!this.isPure(prop, constantsOnly)) return false;
611 }
612 return true;
613 } else if (isMethod(node)) {
614 var _node$decorators2;
615 if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
616 if (((_node$decorators2 = node.decorators) == null ? void 0 : _node$decorators2.length) > 0) {
617 return false;
618 }
619 return true;
620 } else if (isProperty(node)) {
621 var _node$decorators3;
622 if (node.computed && !this.isPure(node.key, constantsOnly)) return false;
623 if (((_node$decorators3 = node.decorators) == null ? void 0 : _node$decorators3.length) > 0) {
624 return false;
625 }
626 if (isObjectProperty(node) || node.static) {
627 if (node.value !== null && !this.isPure(node.value, constantsOnly)) {
628 return false;
629 }
630 }
631 return true;
632 } else if (isUnaryExpression(node)) {
633 return this.isPure(node.argument, constantsOnly);
634 } else if (isTemplateLiteral(node)) {
635 for (const expression of node.expressions) {
636 if (!this.isPure(expression, constantsOnly)) return false;
637 }
638 return true;
639 } else if (isTaggedTemplateExpression(node)) {
640 return matchesPattern(node.tag, "String.raw") && !this.hasBinding("String", {
641 noGlobals: true
642 }) && this.isPure(node.quasi, constantsOnly);
643 } else if (isMemberExpression(node)) {
644 return !node.computed && isIdentifier(node.object) && node.object.name === "Symbol" && isIdentifier(node.property) && node.property.name !== "for" && !this.hasBinding("Symbol", {
645 noGlobals: true
646 });
647 } else if (isCallExpression(node)) {
648 return matchesPattern(node.callee, "Symbol.for") && !this.hasBinding("Symbol", {
649 noGlobals: true
650 }) && node.arguments.length === 1 && t.isStringLiteral(node.arguments[0]);
651 } else {
652 return isPureish(node);
653 }
654 }
655 setData(key, val) {
656 return this.data[key] = val;
657 }
658 getData(key) {
659 let scope = this;
660 do {
661 const data = scope.data[key];
662 if (data != null) return data;
663 } while (scope = scope.parent);
664 }
665 removeData(key) {
666 let scope = this;
667 do {
668 const data = scope.data[key];
669 if (data != null) scope.data[key] = null;
670 } while (scope = scope.parent);
671 }
672 init() {
673 if (!this.inited) {
674 this.inited = true;
675 this.crawl();
676 }
677 }
678 crawl() {
679 const path = this.path;
680 this.references = Object.create(null);
681 this.bindings = Object.create(null);
682 this.globals = Object.create(null);
683 this.uids = Object.create(null);
684 this.data = Object.create(null);
685 const programParent = this.getProgramParent();
686 if (programParent.crawling) return;
687 const state = {
688 references: [],
689 constantViolations: [],
690 assignments: []
691 };
692 this.crawling = true;
693 if (path.type !== "Program" && (0, _visitors.isExplodedVisitor)(collectorVisitor)) {
694 for (const visit of collectorVisitor.enter) {
695 visit.call(state, path, state);
696 }
697 const typeVisitors = collectorVisitor[path.type];
698 if (typeVisitors) {
699 for (const visit of typeVisitors.enter) {
700 visit.call(state, path, state);
701 }
702 }
703 }
704 path.traverse(collectorVisitor, state);
705 this.crawling = false;
706 for (const path of state.assignments) {
707 const ids = path.getAssignmentIdentifiers();
708 for (const name of Object.keys(ids)) {
709 if (path.scope.getBinding(name)) continue;
710 programParent.addGlobal(ids[name]);
711 }
712 path.scope.registerConstantViolation(path);
713 }
714 for (const ref of state.references) {
715 const binding = ref.scope.getBinding(ref.node.name);
716 if (binding) {
717 binding.reference(ref);
718 } else {
719 programParent.addGlobal(ref.node);
720 }
721 }
722 for (const path of state.constantViolations) {
723 path.scope.registerConstantViolation(path);
724 }
725 }
726 push(opts) {
727 let path = this.path;
728 if (path.isPattern()) {
729 path = this.getPatternParent().path;
730 } else if (!path.isBlockStatement() && !path.isProgram()) {
731 path = this.getBlockParent().path;
732 }
733 if (path.isSwitchStatement()) {
734 path = (this.getFunctionParent() || this.getProgramParent()).path;
735 }
736 const {
737 init,
738 unique,
739 kind = "var",
740 id
741 } = opts;
742 if (!init && !unique && (kind === "var" || kind === "let") && path.isFunction() && !path.node.name && isCallExpression(path.parent, {
743 callee: path.node
744 }) && path.parent.arguments.length <= path.node.params.length && isIdentifier(id)) {
745 path.pushContainer("params", id);
746 path.scope.registerBinding("param", path.get("params")[path.node.params.length - 1]);
747 return;
748 }
749 if (path.isLoop() || path.isCatchClause() || path.isFunction()) {
750 path.ensureBlock();
751 path = path.get("body");
752 }
753 const blockHoist = opts._blockHoist == null ? 2 : opts._blockHoist;
754 const dataKey = `declaration:${kind}:${blockHoist}`;
755 let declarPath = !unique && path.getData(dataKey);
756 if (!declarPath) {
757 const declar = variableDeclaration(kind, []);
758 declar._blockHoist = blockHoist;
759 [declarPath] = path.unshiftContainer("body", [declar]);
760 if (!unique) path.setData(dataKey, declarPath);
761 }
762 const declarator = variableDeclarator(id, init);
763 const len = declarPath.node.declarations.push(declarator);
764 path.scope.registerBinding(kind, declarPath.get("declarations")[len - 1]);
765 }
766 getProgramParent() {
767 let scope = this;
768 do {
769 if (scope.path.isProgram()) {
770 return scope;
771 }
772 } while (scope = scope.parent);
773 throw new Error("Couldn't find a Program");
774 }
775 getFunctionParent() {
776 let scope = this;
777 do {
778 if (scope.path.isFunctionParent()) {
779 return scope;
780 }
781 } while (scope = scope.parent);
782 return null;
783 }
784 getBlockParent() {
785 let scope = this;
786 do {
787 if (scope.path.isBlockParent()) {
788 return scope;
789 }
790 } while (scope = scope.parent);
791 throw new Error("We couldn't find a BlockStatement, For, Switch, Function, Loop or Program...");
792 }
793 getPatternParent() {
794 let scope = this;
795 do {
796 if (!scope.path.isPattern()) {
797 return scope.getBlockParent();
798 }
799 } while (scope = scope.parent.parent);
800 throw new Error("We couldn't find a BlockStatement, For, Switch, Function, Loop or Program...");
801 }
802 getAllBindings() {
803 const ids = Object.create(null);
804 let scope = this;
805 do {
806 for (const key of Object.keys(scope.bindings)) {
807 if (key in ids === false) {
808 ids[key] = scope.bindings[key];
809 }
810 }
811 scope = scope.parent;
812 } while (scope);
813 return ids;
814 }
815 getAllBindingsOfKind(...kinds) {
816 const ids = Object.create(null);
817 for (const kind of kinds) {
818 let scope = this;
819 do {
820 for (const name of Object.keys(scope.bindings)) {
821 const binding = scope.bindings[name];
822 if (binding.kind === kind) ids[name] = binding;
823 }
824 scope = scope.parent;
825 } while (scope);
826 }
827 return ids;
828 }
829 bindingIdentifierEquals(name, node) {
830 return this.getBindingIdentifier(name) === node;
831 }
832 getBinding(name) {
833 let scope = this;
834 let previousPath;
835 do {
836 const binding = scope.getOwnBinding(name);
837 if (binding) {
838 var _previousPath;
839 if ((_previousPath = previousPath) != null && _previousPath.isPattern() && binding.kind !== "param" && binding.kind !== "local") {} else {
840 return binding;
841 }
842 } else if (!binding && name === "arguments" && scope.path.isFunction() && !scope.path.isArrowFunctionExpression()) {
843 break;
844 }
845 previousPath = scope.path;
846 } while (scope = scope.parent);
847 }
848 getOwnBinding(name) {
849 return this.bindings[name];
850 }
851 getBindingIdentifier(name) {
852 var _this$getBinding2;
853 return (_this$getBinding2 = this.getBinding(name)) == null ? void 0 : _this$getBinding2.identifier;
854 }
855 getOwnBindingIdentifier(name) {
856 const binding = this.bindings[name];
857 return binding == null ? void 0 : binding.identifier;
858 }
859 hasOwnBinding(name) {
860 return !!this.getOwnBinding(name);
861 }
862 hasBinding(name, opts) {
863 if (!name) return false;
864 let scope = this;
865 do {
866 if (scope.hasOwnBinding(name)) {
867 return true;
868 }
869 } while (scope = scope.parent);
870 let noGlobals;
871 let noUids;
872 if (typeof opts === "object") {
873 noGlobals = opts.noGlobals;
874 noUids = opts.noUids;
875 } else if (typeof opts === "boolean") {
876 noGlobals = opts;
877 }
878 if (!noUids && this.hasUid(name)) return true;
879 if (!noGlobals && Scope.globals.includes(name)) return true;
880 if (!noGlobals && Scope.contextVariables.includes(name)) return true;
881 return false;
882 }
883 parentHasBinding(name, opts) {
884 var _this$parent;
885 return (_this$parent = this.parent) == null ? void 0 : _this$parent.hasBinding(name, opts);
886 }
887 moveBindingTo(name, scope) {
888 const info = this.getBinding(name);
889 if (info) {
890 info.scope.removeOwnBinding(name);
891 info.scope = scope;
892 scope.bindings[name] = info;
893 }
894 }
895 removeOwnBinding(name) {
896 delete this.bindings[name];
897 }
898 removeBinding(name) {
899 var _this$getBinding3;
900 (_this$getBinding3 = this.getBinding(name)) == null || _this$getBinding3.scope.removeOwnBinding(name);
901 let scope = this;
902 do {
903 if (scope.uids[name]) {
904 scope.uids[name] = false;
905 }
906 } while (scope = scope.parent);
907 }
908 hoistVariables(emit = id => this.push({
909 id
910 })) {
911 this.crawl();
912 const seen = new Set();
913 for (const name of Object.keys(this.bindings)) {
914 const binding = this.bindings[name];
915 if (!binding) continue;
916 const {
917 path
918 } = binding;
919 if (!path.isVariableDeclarator()) continue;
920 const {
921 parent,
922 parentPath
923 } = path;
924 if (parent.kind !== "var" || seen.has(parent)) continue;
925 seen.add(path.parent);
926 let firstId;
927 const init = [];
928 for (const decl of parent.declarations) {
929 var _firstId;
930 (_firstId = firstId) != null ? _firstId : firstId = decl.id;
931 if (decl.init) {
932 init.push(assignmentExpression("=", decl.id, decl.init));
933 }
934 const ids = Object.keys(getBindingIdentifiers(decl, false, true, true));
935 for (const name of ids) {
936 emit(identifier(name), decl.init != null);
937 }
938 }
939 if (parentPath.parentPath.isFor({
940 left: parent
941 })) {
942 parentPath.replaceWith(firstId);
943 } else if (init.length === 0) {
944 parentPath.remove();
945 } else {
946 const expr = init.length === 1 ? init[0] : sequenceExpression(init);
947 if (parentPath.parentPath.isForStatement({
948 init: parent
949 })) {
950 parentPath.replaceWith(expr);
951 } else {
952 parentPath.replaceWith(expressionStatement(expr));
953 }
954 }
955 }
956 }
957}
958exports.default = Scope;
959Scope.globals = Object.keys(_globals.builtin);
960Scope.contextVariables = ["arguments", "undefined", "Infinity", "NaN"];
961
962//# sourceMappingURL=index.js.map
Note: See TracBrowser for help on using the repository browser.