source: trip-planner-front/node_modules/@babel/traverse/lib/path/lib/hoister.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 5.3 KB
Line 
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7
8var _t = require("@babel/types");
9
10var _t2 = _t;
11const {
12 react
13} = _t;
14const {
15 cloneNode,
16 jsxExpressionContainer,
17 variableDeclaration,
18 variableDeclarator
19} = _t2;
20const referenceVisitor = {
21 ReferencedIdentifier(path, state) {
22 if (path.isJSXIdentifier() && react.isCompatTag(path.node.name) && !path.parentPath.isJSXMemberExpression()) {
23 return;
24 }
25
26 if (path.node.name === "this") {
27 let scope = path.scope;
28
29 do {
30 if (scope.path.isFunction() && !scope.path.isArrowFunctionExpression()) {
31 break;
32 }
33 } while (scope = scope.parent);
34
35 if (scope) state.breakOnScopePaths.push(scope.path);
36 }
37
38 const binding = path.scope.getBinding(path.node.name);
39 if (!binding) return;
40
41 for (const violation of binding.constantViolations) {
42 if (violation.scope !== binding.path.scope) {
43 state.mutableBinding = true;
44 path.stop();
45 return;
46 }
47 }
48
49 if (binding !== state.scope.getBinding(path.node.name)) return;
50 state.bindings[path.node.name] = binding;
51 }
52
53};
54
55class PathHoister {
56 constructor(path, scope) {
57 this.breakOnScopePaths = void 0;
58 this.bindings = void 0;
59 this.mutableBinding = void 0;
60 this.scopes = void 0;
61 this.scope = void 0;
62 this.path = void 0;
63 this.attachAfter = void 0;
64 this.breakOnScopePaths = [];
65 this.bindings = {};
66 this.mutableBinding = false;
67 this.scopes = [];
68 this.scope = scope;
69 this.path = path;
70 this.attachAfter = false;
71 }
72
73 isCompatibleScope(scope) {
74 for (const key of Object.keys(this.bindings)) {
75 const binding = this.bindings[key];
76
77 if (!scope.bindingIdentifierEquals(key, binding.identifier)) {
78 return false;
79 }
80 }
81
82 return true;
83 }
84
85 getCompatibleScopes() {
86 let scope = this.path.scope;
87
88 do {
89 if (this.isCompatibleScope(scope)) {
90 this.scopes.push(scope);
91 } else {
92 break;
93 }
94
95 if (this.breakOnScopePaths.indexOf(scope.path) >= 0) {
96 break;
97 }
98 } while (scope = scope.parent);
99 }
100
101 getAttachmentPath() {
102 let path = this._getAttachmentPath();
103
104 if (!path) return;
105 let targetScope = path.scope;
106
107 if (targetScope.path === path) {
108 targetScope = path.scope.parent;
109 }
110
111 if (targetScope.path.isProgram() || targetScope.path.isFunction()) {
112 for (const name of Object.keys(this.bindings)) {
113 if (!targetScope.hasOwnBinding(name)) continue;
114 const binding = this.bindings[name];
115
116 if (binding.kind === "param" || binding.path.parentKey === "params") {
117 continue;
118 }
119
120 const bindingParentPath = this.getAttachmentParentForPath(binding.path);
121
122 if (bindingParentPath.key >= path.key) {
123 this.attachAfter = true;
124 path = binding.path;
125
126 for (const violationPath of binding.constantViolations) {
127 if (this.getAttachmentParentForPath(violationPath).key > path.key) {
128 path = violationPath;
129 }
130 }
131 }
132 }
133 }
134
135 return path;
136 }
137
138 _getAttachmentPath() {
139 const scopes = this.scopes;
140 const scope = scopes.pop();
141 if (!scope) return;
142
143 if (scope.path.isFunction()) {
144 if (this.hasOwnParamBindings(scope)) {
145 if (this.scope === scope) return;
146 const bodies = scope.path.get("body").get("body");
147
148 for (let i = 0; i < bodies.length; i++) {
149 if (bodies[i].node._blockHoist) continue;
150 return bodies[i];
151 }
152 } else {
153 return this.getNextScopeAttachmentParent();
154 }
155 } else if (scope.path.isProgram()) {
156 return this.getNextScopeAttachmentParent();
157 }
158 }
159
160 getNextScopeAttachmentParent() {
161 const scope = this.scopes.pop();
162 if (scope) return this.getAttachmentParentForPath(scope.path);
163 }
164
165 getAttachmentParentForPath(path) {
166 do {
167 if (!path.parentPath || Array.isArray(path.container) && path.isStatement()) {
168 return path;
169 }
170 } while (path = path.parentPath);
171 }
172
173 hasOwnParamBindings(scope) {
174 for (const name of Object.keys(this.bindings)) {
175 if (!scope.hasOwnBinding(name)) continue;
176 const binding = this.bindings[name];
177 if (binding.kind === "param" && binding.constant) return true;
178 }
179
180 return false;
181 }
182
183 run() {
184 this.path.traverse(referenceVisitor, this);
185 if (this.mutableBinding) return;
186 this.getCompatibleScopes();
187 const attachTo = this.getAttachmentPath();
188 if (!attachTo) return;
189 if (attachTo.getFunctionParent() === this.path.getFunctionParent()) return;
190 let uid = attachTo.scope.generateUidIdentifier("ref");
191 const declarator = variableDeclarator(uid, this.path.node);
192 const insertFn = this.attachAfter ? "insertAfter" : "insertBefore";
193 const [attached] = attachTo[insertFn]([attachTo.isVariableDeclarator() ? declarator : variableDeclaration("var", [declarator])]);
194 const parent = this.path.parentPath;
195
196 if (parent.isJSXElement() && this.path.container === parent.node.children) {
197 uid = jsxExpressionContainer(uid);
198 }
199
200 this.path.replaceWith(cloneNode(uid));
201 return attachTo.isVariableDeclarator() ? attached.get("init") : attached.get("declarations.0.init");
202 }
203
204}
205
206exports.default = PathHoister;
Note: See TracBrowser for help on using the repository browser.