source: frontend/node_modules/@babel/helper-define-polyfill-provider/lib/utils.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 2 weeks ago

Fix frontend appearance

  • Property mode set to 100644
File size: 12.6 KB
RevLine 
[9af201e]1"use strict";
2
3exports.__esModule = true;
4exports.PossibleGlobalObjects = void 0;
5exports.createUtilsGetter = createUtilsGetter;
6exports.getImportSource = getImportSource;
7exports.getRequireSource = getRequireSource;
8exports.has = has;
9exports.intersection = intersection;
10exports.resolveKey = resolveKey;
11exports.resolveSource = resolveSource;
12var _babel = _interopRequireWildcard(require("@babel/core"));
13function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
14const {
15 types: t,
16 template: template
17} = _babel.default || _babel;
18const PossibleGlobalObjects = exports.PossibleGlobalObjects = new Set(["global", "globalThis", "self", "window"]);
19function intersection(a, b) {
20 const result = new Set();
21 a.forEach(v => b.has(v) && result.add(v));
22 return result;
23}
24function has(object, key) {
25 return Object.prototype.hasOwnProperty.call(object, key);
26}
27function resolve(path, seen = new Set()) {
28 if (seen.has(path)) return;
29 seen.add(path);
30 if (path.isVariableDeclarator()) {
31 if (path.get("id").isIdentifier()) {
32 return resolve(path.get("init"), seen);
33 }
34 } else if (path.isReferencedIdentifier()) {
35 const binding = path.scope.getBinding(path.node.name);
36 if (!binding) return path;
37 if (!binding.constant) return;
38 return resolve(binding.path, seen);
39 }
40 return path;
41}
42function resolveId(path) {
43 if (path.isIdentifier() && !path.scope.hasBinding(path.node.name, /* noGlobals */true)) {
44 return path.node.name;
45 }
46
47 // globalThis.Object / window.Array / self.Map / global.Set -> resolve to
48 // the property name, because accessing a built-in through a global object
49 // reference is equivalent to accessing it directly.
50 if (path.isMemberExpression() && !path.node.computed) {
51 const object = path.get("object");
52 const property = path.get("property");
53 if (object.isIdentifier() && !object.scope.hasBinding(object.node.name, /* noGlobals */true) && PossibleGlobalObjects.has(object.node.name) && property.isIdentifier()) {
54 return property.node.name;
55 }
56 }
57 const resolved = resolve(path);
58 if (resolved != null && resolved.isIdentifier()) {
59 return resolved.node.name;
60 }
61}
62function resolveKey(path, computed = false) {
63 const {
64 scope
65 } = path;
66 if (path.isStringLiteral()) return path.node.value;
67 const isIdentifier = path.isIdentifier();
68 if (isIdentifier && !(computed || path.parent.computed)) {
69 return path.node.name;
70 }
71 if (computed && path.isMemberExpression() && path.get("object").isIdentifier({
72 name: "Symbol"
73 }) && !scope.hasBinding("Symbol", /* noGlobals */true)) {
74 const sym = resolveKey(path.get("property"), path.node.computed);
75 if (sym) return "Symbol." + sym;
76 }
77 if (isIdentifier ? scope.hasBinding(path.node.name, /* noGlobals */true) : path.isPure()) {
78 const {
79 value
80 } = path.evaluate();
81 if (typeof value === "string") return value;
82 }
83}
84function resolveInstance(obj, seen) {
85 const source = resolveSource(obj, seen);
86 return source.placement === "prototype" ? source.id : null;
87}
88function resolveSource(obj, seen) {
89 if (seen.has(obj)) {
90 return {
91 id: null,
92 placement: null
93 };
94 }
95 seen.add(obj);
96 if (obj.isMemberExpression() && obj.get("property").isIdentifier({
97 name: "prototype"
98 })) {
99 const id = resolveId(obj.get("object"));
100 if (id) {
101 return {
102 id,
103 placement: "prototype"
104 };
105 }
106 return {
107 id: null,
108 placement: null
109 };
110 }
111 const id = resolveId(obj);
112 if (id) {
113 return {
114 id,
115 placement: "static"
116 };
117 }
118 const path = resolve(obj);
119 switch (path == null ? void 0 : path.type) {
120 case "NullLiteral":
121 return {
122 id: null,
123 placement: null
124 };
125 case "RegExpLiteral":
126 return {
127 id: "RegExp",
128 placement: "prototype"
129 };
130 case "StringLiteral":
131 case "TemplateLiteral":
132 return {
133 id: "String",
134 placement: "prototype"
135 };
136 case "NumericLiteral":
137 return {
138 id: "Number",
139 placement: "prototype"
140 };
141 case "BooleanLiteral":
142 return {
143 id: "Boolean",
144 placement: "prototype"
145 };
146 case "BigIntLiteral":
147 return {
148 id: "BigInt",
149 placement: "prototype"
150 };
151 case "ObjectExpression":
152 return {
153 id: "Object",
154 placement: "prototype"
155 };
156 case "ArrayExpression":
157 return {
158 id: "Array",
159 placement: "prototype"
160 };
161 case "FunctionExpression":
162 case "ArrowFunctionExpression":
163 case "ClassExpression":
164 return {
165 id: "Function",
166 placement: "prototype"
167 };
168 // new Constructor() -> resolve the constructor name
169 case "NewExpression":
170 {
171 const calleeId = resolveId(path.get("callee"));
172 if (calleeId) return {
173 id: calleeId,
174 placement: "prototype"
175 };
176 return {
177 id: null,
178 placement: null
179 };
180 }
181 // Unary expressions -> result type depends on operator
182 case "UnaryExpression":
183 {
184 const {
185 operator
186 } = path.node;
187 if (operator === "typeof") return {
188 id: "String",
189 placement: "prototype"
190 };
191 if (operator === "!" || operator === "delete") return {
192 id: "Boolean",
193 placement: "prototype"
194 };
195 // Unary + always produces Number (throws on BigInt)
196 if (operator === "+") return {
197 id: "Number",
198 placement: "prototype"
199 };
200 // Unary - and ~ can produce Number or BigInt depending on operand
201 if (operator === "-" || operator === "~") {
202 const arg = resolveInstance(path.get("argument"), seen);
203 if (arg === "BigInt") return {
204 id: "BigInt",
205 placement: "prototype"
206 };
207 if (arg !== null) return {
208 id: "Number",
209 placement: "prototype"
210 };
211 return {
212 id: null,
213 placement: null
214 };
215 }
216 return {
217 id: null,
218 placement: null
219 };
220 }
221 // ++i, i++ produce Number or BigInt depending on the argument
222 case "UpdateExpression":
223 {
224 const arg = resolveInstance(path.get("argument"), seen);
225 if (arg === "BigInt") return {
226 id: "BigInt",
227 placement: "prototype"
228 };
229 if (arg !== null) return {
230 id: "Number",
231 placement: "prototype"
232 };
233 return {
234 id: null,
235 placement: null
236 };
237 }
238 // Binary expressions -> result type depends on operator
239 case "BinaryExpression":
240 {
241 const {
242 operator
243 } = path.node;
244 if (operator === "==" || operator === "!=" || operator === "===" || operator === "!==" || operator === "<" || operator === ">" || operator === "<=" || operator === ">=" || operator === "instanceof" || operator === "in") {
245 return {
246 id: "Boolean",
247 placement: "prototype"
248 };
249 }
250 // >>> always produces Number
251 if (operator === ">>>") {
252 return {
253 id: "Number",
254 placement: "prototype"
255 };
256 }
257 // Arithmetic and bitwise operators can produce Number or BigInt
258 if (operator === "-" || operator === "*" || operator === "/" || operator === "%" || operator === "**" || operator === "&" || operator === "|" || operator === "^" || operator === "<<" || operator === ">>") {
259 const left = resolveInstance(path.get("left"), seen);
260 const right = resolveInstance(path.get("right"), seen);
261 if (left === "BigInt" && right === "BigInt") {
262 return {
263 id: "BigInt",
264 placement: "prototype"
265 };
266 }
267 if (left !== null && right !== null) {
268 return {
269 id: "Number",
270 placement: "prototype"
271 };
272 }
273 return {
274 id: null,
275 placement: null
276 };
277 }
278 // + depends on operand types: string wins, otherwise number or bigint
279 if (operator === "+") {
280 const left = resolveInstance(path.get("left"), seen);
281 const right = resolveInstance(path.get("right"), seen);
282 if (left === "String" || right === "String") {
283 return {
284 id: "String",
285 placement: "prototype"
286 };
287 }
288 if (left === "Number" && right === "Number") {
289 return {
290 id: "Number",
291 placement: "prototype"
292 };
293 }
294 if (left === "BigInt" && right === "BigInt") {
295 return {
296 id: "BigInt",
297 placement: "prototype"
298 };
299 }
300 }
301 return {
302 id: null,
303 placement: null
304 };
305 }
306 // (a, b, c) -> the result is the last expression
307 case "SequenceExpression":
308 {
309 const expressions = path.get("expressions");
310 return resolveSource(expressions[expressions.length - 1], seen);
311 }
312 // a = b -> the result is the right side
313 case "AssignmentExpression":
314 {
315 if (path.node.operator === "=") {
316 return resolveSource(path.get("right"), seen);
317 }
318 return {
319 id: null,
320 placement: null
321 };
322 }
323 // a ? b : c -> if both branches resolve to the same type, use it
324 case "ConditionalExpression":
325 {
326 const consequent = resolveSource(path.get("consequent"), seen);
327 const alternate = resolveSource(path.get("alternate"), seen);
328 if (consequent.id && consequent.id === alternate.id) {
329 return consequent;
330 }
331 return {
332 id: null,
333 placement: null
334 };
335 }
336 // (expr) -> unwrap parenthesized expressions
337 case "ParenthesizedExpression":
338 return resolveSource(path.get("expression"), seen);
339 // TypeScript / Flow type wrappers -> unwrap to the inner expression
340 case "TSAsExpression":
341 case "TSSatisfiesExpression":
342 case "TSNonNullExpression":
343 case "TSInstantiationExpression":
344 case "TSTypeAssertion":
345 case "TypeCastExpression":
346 return resolveSource(path.get("expression"), seen);
347 }
348 return {
349 id: null,
350 placement: null
351 };
352}
353function getImportSource({
354 node
355}) {
356 if (node.specifiers.length === 0) return node.source.value;
357}
358function getRequireSource({
359 node
360}) {
361 if (!t.isExpressionStatement(node)) return;
362 const {
363 expression
364 } = node;
365 if (t.isCallExpression(expression) && t.isIdentifier(expression.callee) && expression.callee.name === "require" && expression.arguments.length === 1 && t.isStringLiteral(expression.arguments[0])) {
366 return expression.arguments[0].value;
367 }
368}
369function hoist(node) {
370 // @ts-expect-error
371 node._blockHoist = 3;
372 return node;
373}
374function createUtilsGetter(cache) {
375 return path => {
376 const prog = path.findParent(p => p.isProgram());
377 return {
378 injectGlobalImport(url, moduleName) {
379 cache.storeAnonymous(prog, url, moduleName, (isScript, source) => {
380 return isScript ? template.statement.ast`require(${source})` : t.importDeclaration([], source);
381 });
382 },
383 injectNamedImport(url, name, hint = name, moduleName) {
384 return cache.storeNamed(prog, url, name, moduleName, (isScript, source, name) => {
385 const id = prog.scope.generateUidIdentifier(hint);
386 return {
387 node: isScript ? hoist(template.statement.ast`
388 var ${id} = require(${source}).${name}
389 `) : t.importDeclaration([t.importSpecifier(id, name)], source),
390 name: id.name
391 };
392 });
393 },
394 injectDefaultImport(url, hint = url, moduleName) {
395 return cache.storeNamed(prog, url, "default", moduleName, (isScript, source) => {
396 const id = prog.scope.generateUidIdentifier(hint);
397 return {
398 node: isScript ? hoist(template.statement.ast`var ${id} = require(${source})`) : t.importDeclaration([t.importDefaultSpecifier(id)], source),
399 name: id.name
400 };
401 });
402 }
403 };
404 };
405}
Note: See TracBrowser for help on using the repository browser.