react-refresh 0.16.0-canary-33a32441e9-20240418 → 0.16.0-canary-cb151849e1-20240424

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license React
3
- * react-refresh-babel.production.min.js
3
+ * react-refresh-babel.production.js
4
4
  *
5
5
  * Copyright (c) Meta Platforms, Inc. and affiliates.
6
6
  *
@@ -8,849 +8,579 @@
8
8
  * LICENSE file in the root directory of this source tree.
9
9
  */
10
10
 
11
- 'use strict';
12
-
13
- function ReactFreshBabelPlugin (babel) {
14
- let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
15
-
16
- if (typeof babel.env === 'function') {
17
- // Only available in Babel 7.
18
- const env = babel.env();
19
-
20
- if (env !== 'development' && !opts.skipEnvCheck) {
21
- throw new Error('React Refresh Babel transform should only be enabled in development environment. ' + 'Instead, the environment is: "' + env + '". If you want to override this check, pass {skipEnvCheck: true} as plugin options.');
22
- }
23
- }
24
-
25
- const t = babel.types;
26
- const refreshReg = t.identifier(opts.refreshReg || '$RefreshReg$');
27
- const refreshSig = t.identifier(opts.refreshSig || '$RefreshSig$');
28
- const registrationsByProgramPath = new Map();
29
-
11
+ "use strict";
12
+ module.exports = function (babel) {
30
13
  function createRegistration(programPath, persistentID) {
31
- const handle = programPath.scope.generateUidIdentifier('c');
32
-
33
- if (!registrationsByProgramPath.has(programPath)) {
14
+ var handle = programPath.scope.generateUidIdentifier("c");
15
+ registrationsByProgramPath.has(programPath) ||
34
16
  registrationsByProgramPath.set(programPath, []);
35
- }
36
-
37
- const registrations = registrationsByProgramPath.get(programPath);
38
- registrations.push({
39
- handle,
40
- persistentID
41
- });
17
+ registrationsByProgramPath
18
+ .get(programPath)
19
+ .push({ handle: handle, persistentID: persistentID });
42
20
  return handle;
43
21
  }
44
-
45
22
  function isComponentishName(name) {
46
- return typeof name === 'string' && name[0] >= 'A' && name[0] <= 'Z';
23
+ return "string" === typeof name && "A" <= name[0] && "Z" >= name[0];
47
24
  }
48
-
49
25
  function findInnerComponents(inferredName, path, callback) {
50
- const node = path.node;
51
-
26
+ var node = path.node;
52
27
  switch (node.type) {
53
- case 'Identifier':
54
- {
55
- if (!isComponentishName(node.name)) {
56
- return false;
57
- } // export default hoc(Foo)
58
- // const X = hoc(Foo)
59
-
60
-
61
- callback(inferredName, node, null);
62
- return true;
63
- }
64
-
65
- case 'FunctionDeclaration':
66
- {
67
- // function Foo() {}
68
- // export function Foo() {}
69
- // export default function Foo() {}
70
- callback(inferredName, node.id, null);
71
- return true;
72
- }
73
-
74
- case 'ArrowFunctionExpression':
75
- {
76
- if (node.body.type === 'ArrowFunctionExpression') {
77
- return false;
78
- } // let Foo = () => {}
79
- // export default hoc1(hoc2(() => {}))
80
-
81
-
82
- callback(inferredName, node, path);
83
- return true;
84
- }
85
-
86
- case 'FunctionExpression':
87
- {
88
- // let Foo = function() {}
89
- // const Foo = hoc1(forwardRef(function renderFoo() {}))
90
- // export default memo(function() {})
91
- callback(inferredName, node, path);
92
- return true;
93
- }
94
-
95
- case 'CallExpression':
96
- {
97
- const argsPath = path.get('arguments');
98
-
99
- if (argsPath === undefined || argsPath.length === 0) {
100
- return false;
101
- }
102
-
103
- const calleePath = path.get('callee');
104
-
105
- switch (calleePath.node.type) {
106
- case 'MemberExpression':
107
- case 'Identifier':
108
- {
109
- const calleeSource = calleePath.getSource();
110
- const firstArgPath = argsPath[0];
111
- const innerName = inferredName + '$' + calleeSource;
112
- const foundInside = findInnerComponents(innerName, firstArgPath, callback);
113
-
114
- if (!foundInside) {
115
- return false;
116
- } // const Foo = hoc1(hoc2(() => {}))
117
- // export default memo(React.forwardRef(function() {}))
118
-
119
-
120
- callback(inferredName, node, path);
121
- return true;
122
- }
123
-
124
- default:
125
- {
126
- return false;
127
- }
128
- }
28
+ case "Identifier":
29
+ if (!isComponentishName(node.name)) break;
30
+ callback(inferredName, node, null);
31
+ return !0;
32
+ case "FunctionDeclaration":
33
+ return callback(inferredName, node.id, null), !0;
34
+ case "ArrowFunctionExpression":
35
+ if ("ArrowFunctionExpression" === node.body.type) break;
36
+ callback(inferredName, node, path);
37
+ return !0;
38
+ case "FunctionExpression":
39
+ return callback(inferredName, node, path), !0;
40
+ case "CallExpression":
41
+ var argsPath = path.get("arguments");
42
+ if (void 0 === argsPath || 0 === argsPath.length) break;
43
+ var calleePath = path.get("callee");
44
+ switch (calleePath.node.type) {
45
+ case "MemberExpression":
46
+ case "Identifier":
47
+ calleePath = calleePath.getSource();
48
+ if (
49
+ !findInnerComponents(
50
+ inferredName + "$" + calleePath,
51
+ argsPath[0],
52
+ callback
53
+ )
54
+ )
55
+ return !1;
56
+ callback(inferredName, node, path);
57
+ return !0;
58
+ default:
59
+ return !1;
129
60
  }
130
-
131
- case 'VariableDeclarator':
132
- {
133
- const init = node.init;
134
-
135
- if (init === null) {
136
- return false;
137
- }
138
-
139
- const name = node.id.name;
140
-
141
- if (!isComponentishName(name)) {
142
- return false;
143
- }
144
-
145
- switch (init.type) {
146
- case 'ArrowFunctionExpression':
147
- case 'FunctionExpression':
148
- // Likely component definitions.
61
+ case "VariableDeclarator":
62
+ if (
63
+ ((argsPath = node.init),
64
+ null !== argsPath &&
65
+ ((calleePath = node.id.name), isComponentishName(calleePath)))
66
+ ) {
67
+ switch (argsPath.type) {
68
+ case "ArrowFunctionExpression":
69
+ case "FunctionExpression":
149
70
  break;
150
-
151
- case 'CallExpression':
152
- {
153
- // Maybe a HOC.
154
- // Try to determine if this is some form of import.
155
- const callee = init.callee;
156
- const calleeType = callee.type;
157
-
158
- if (calleeType === 'Import') {
159
- return false;
160
- } else if (calleeType === 'Identifier') {
161
- if (callee.name.indexOf('require') === 0) {
162
- return false;
163
- } else if (callee.name.indexOf('import') === 0) {
164
- return false;
165
- } // Neither require nor import. Might be a HOC.
166
- // Pass through.
167
-
168
- } else ;
169
-
170
- break;
171
- }
172
-
173
- case 'TaggedTemplateExpression':
174
- // Maybe something like styled.div`...`
71
+ case "CallExpression":
72
+ node = argsPath.callee;
73
+ var calleeType = node.type;
74
+ if (
75
+ "Import" === calleeType ||
76
+ ("Identifier" === calleeType &&
77
+ (0 === node.name.indexOf("require") ||
78
+ 0 === node.name.indexOf("import")))
79
+ )
80
+ return !1;
81
+ break;
82
+ case "TaggedTemplateExpression":
175
83
  break;
176
-
177
84
  default:
178
- return false;
179
- }
180
-
181
- const initPath = path.get('init');
182
- const foundInside = findInnerComponents(inferredName, initPath, callback);
183
-
184
- if (foundInside) {
185
- return true;
186
- } // See if this identifier is used in JSX. Then it's a component.
187
-
188
-
189
- const binding = path.scope.getBinding(name);
190
-
191
- if (binding === undefined) {
192
- return;
85
+ return !1;
193
86
  }
194
-
195
- let isLikelyUsedAsType = false;
196
- const referencePaths = binding.referencePaths;
197
-
198
- for (let i = 0; i < referencePaths.length; i++) {
199
- const ref = referencePaths[i];
200
-
201
- if (ref.node && ref.node.type !== 'JSXIdentifier' && ref.node.type !== 'Identifier') {
202
- continue;
203
- }
204
-
205
- const refParent = ref.parent;
206
-
207
- if (refParent.type === 'JSXOpeningElement') {
208
- isLikelyUsedAsType = true;
209
- } else if (refParent.type === 'CallExpression') {
210
- const callee = refParent.callee;
211
- let fnName;
212
-
213
- switch (callee.type) {
214
- case 'Identifier':
215
- fnName = callee.name;
216
- break;
217
-
218
- case 'MemberExpression':
219
- fnName = callee.property.name;
220
- break;
221
- }
222
-
223
- switch (fnName) {
224
- case 'createElement':
225
- case 'jsx':
226
- case 'jsxDEV':
227
- case 'jsxs':
228
- isLikelyUsedAsType = true;
229
- break;
87
+ node = path.get("init");
88
+ if (findInnerComponents(inferredName, node, callback)) return !0;
89
+ calleePath = path.scope.getBinding(calleePath);
90
+ if (void 0 === calleePath) return;
91
+ path = !1;
92
+ calleePath = calleePath.referencePaths;
93
+ for (calleeType = 0; calleeType < calleePath.length; calleeType++) {
94
+ var ref = calleePath[calleeType];
95
+ if (
96
+ !ref.node ||
97
+ "JSXIdentifier" === ref.node.type ||
98
+ "Identifier" === ref.node.type
99
+ ) {
100
+ ref = ref.parent;
101
+ if ("JSXOpeningElement" === ref.type) path = !0;
102
+ else if ("CallExpression" === ref.type) {
103
+ ref = ref.callee;
104
+ var fnName = void 0;
105
+ switch (ref.type) {
106
+ case "Identifier":
107
+ fnName = ref.name;
108
+ break;
109
+ case "MemberExpression":
110
+ fnName = ref.property.name;
111
+ }
112
+ switch (fnName) {
113
+ case "createElement":
114
+ case "jsx":
115
+ case "jsxDEV":
116
+ case "jsxs":
117
+ path = !0;
118
+ }
230
119
  }
231
- }
232
-
233
- if (isLikelyUsedAsType) {
234
- // const X = ... + later <X />
235
- callback(inferredName, init, initPath);
236
- return true;
120
+ if (path) return callback(inferredName, argsPath, node), !0;
237
121
  }
238
122
  }
239
123
  }
240
124
  }
241
-
242
- return false;
125
+ return !1;
243
126
  }
244
-
245
- function isBuiltinHook(hookName) {
246
- switch (hookName) {
247
- case 'useState':
248
- case 'React.useState':
249
- case 'useReducer':
250
- case 'React.useReducer':
251
- case 'useEffect':
252
- case 'React.useEffect':
253
- case 'useLayoutEffect':
254
- case 'React.useLayoutEffect':
255
- case 'useMemo':
256
- case 'React.useMemo':
257
- case 'useCallback':
258
- case 'React.useCallback':
259
- case 'useRef':
260
- case 'React.useRef':
261
- case 'useContext':
262
- case 'React.useContext':
263
- case 'useImperativeHandle':
264
- case 'React.useImperativeHandle':
265
- case 'useDebugValue':
266
- case 'React.useDebugValue':
267
- case 'useId':
268
- case 'React.useId':
269
- case 'useDeferredValue':
270
- case 'React.useDeferredValue':
271
- case 'useTransition':
272
- case 'React.useTransition':
273
- case 'useInsertionEffect':
274
- case 'React.useInsertionEffect':
275
- case 'useSyncExternalStore':
276
- case 'React.useSyncExternalStore':
277
- case 'useFormStatus':
278
- case 'React.useFormStatus':
279
- case 'useFormState':
280
- case 'React.useFormState':
281
- case 'useActionState':
282
- case 'React.useActionState':
283
- case 'useOptimistic':
284
- case 'React.useOptimistic':
285
- return true;
286
-
287
- default:
288
- return false;
289
- }
290
- }
291
-
292
127
  function getHookCallsSignature(functionNode) {
293
- const fnHookCalls = hookCalls.get(functionNode);
294
-
295
- if (fnHookCalls === undefined) {
296
- return null;
297
- }
298
-
299
- return {
300
- key: fnHookCalls.map(call => call.name + '{' + call.key + '}').join('\n'),
301
- customHooks: fnHookCalls.filter(call => !isBuiltinHook(call.name)).map(call => t.cloneDeep(call.callee))
302
- };
128
+ functionNode = hookCalls.get(functionNode);
129
+ return void 0 === functionNode
130
+ ? null
131
+ : {
132
+ key: functionNode
133
+ .map(function (call) {
134
+ return call.name + "{" + call.key + "}";
135
+ })
136
+ .join("\n"),
137
+ customHooks: functionNode
138
+ .filter(function (call) {
139
+ a: switch (call.name) {
140
+ case "useState":
141
+ case "React.useState":
142
+ case "useReducer":
143
+ case "React.useReducer":
144
+ case "useEffect":
145
+ case "React.useEffect":
146
+ case "useLayoutEffect":
147
+ case "React.useLayoutEffect":
148
+ case "useMemo":
149
+ case "React.useMemo":
150
+ case "useCallback":
151
+ case "React.useCallback":
152
+ case "useRef":
153
+ case "React.useRef":
154
+ case "useContext":
155
+ case "React.useContext":
156
+ case "useImperativeHandle":
157
+ case "React.useImperativeHandle":
158
+ case "useDebugValue":
159
+ case "React.useDebugValue":
160
+ case "useId":
161
+ case "React.useId":
162
+ case "useDeferredValue":
163
+ case "React.useDeferredValue":
164
+ case "useTransition":
165
+ case "React.useTransition":
166
+ case "useInsertionEffect":
167
+ case "React.useInsertionEffect":
168
+ case "useSyncExternalStore":
169
+ case "React.useSyncExternalStore":
170
+ case "useFormStatus":
171
+ case "React.useFormStatus":
172
+ case "useFormState":
173
+ case "React.useFormState":
174
+ case "useActionState":
175
+ case "React.useActionState":
176
+ case "useOptimistic":
177
+ case "React.useOptimistic":
178
+ call = !0;
179
+ break a;
180
+ default:
181
+ call = !1;
182
+ }
183
+ return !call;
184
+ })
185
+ .map(function (call) {
186
+ return t.cloneDeep(call.callee);
187
+ })
188
+ };
303
189
  }
304
-
305
- const hasForceResetCommentByFile = new WeakMap(); // We let user do /* @refresh reset */ to reset state in the whole file.
306
-
307
190
  function hasForceResetComment(path) {
308
- const file = path.hub.file;
309
- let hasForceReset = hasForceResetCommentByFile.get(file);
310
-
311
- if (hasForceReset !== undefined) {
312
- return hasForceReset;
313
- }
314
-
315
- hasForceReset = false;
316
- const comments = file.ast.comments;
317
-
318
- for (let i = 0; i < comments.length; i++) {
319
- const cmt = comments[i];
320
-
321
- if (cmt.value.indexOf('@refresh reset') !== -1) {
322
- hasForceReset = true;
191
+ path = path.hub.file;
192
+ var hasForceReset = hasForceResetCommentByFile.get(path);
193
+ if (void 0 !== hasForceReset) return hasForceReset;
194
+ hasForceReset = !1;
195
+ for (var comments = path.ast.comments, i = 0; i < comments.length; i++)
196
+ if (-1 !== comments[i].value.indexOf("@refresh reset")) {
197
+ hasForceReset = !0;
323
198
  break;
324
199
  }
325
- }
326
-
327
- hasForceResetCommentByFile.set(file, hasForceReset);
200
+ hasForceResetCommentByFile.set(path, hasForceReset);
328
201
  return hasForceReset;
329
202
  }
330
-
331
203
  function createArgumentsForSignature(node, signature, scope) {
332
- const key = signature.key,
333
- customHooks = signature.customHooks;
334
- let forceReset = hasForceResetComment(scope.path);
335
- const customHooksInScope = [];
336
- customHooks.forEach(callee => {
337
- // Check if a corresponding binding exists where we emit the signature.
338
- let bindingName;
339
-
204
+ var key = signature.key;
205
+ signature = signature.customHooks;
206
+ var forceReset = hasForceResetComment(scope.path),
207
+ customHooksInScope = [];
208
+ signature.forEach(function (callee) {
340
209
  switch (callee.type) {
341
- case 'MemberExpression':
342
- if (callee.object.type === 'Identifier') {
343
- bindingName = callee.object.name;
344
- }
345
-
210
+ case "MemberExpression":
211
+ if ("Identifier" === callee.object.type)
212
+ var bindingName = callee.object.name;
346
213
  break;
347
-
348
- case 'Identifier':
214
+ case "Identifier":
349
215
  bindingName = callee.name;
350
- break;
351
- }
352
-
353
- if (scope.hasBinding(bindingName)) {
354
- customHooksInScope.push(callee);
355
- } else {
356
- // We don't have anything to put in the array because Hook is out of scope.
357
- // Since it could potentially have been edited, remount the component.
358
- forceReset = true;
359
216
  }
217
+ scope.hasBinding(bindingName)
218
+ ? customHooksInScope.push(callee)
219
+ : (forceReset = !0);
360
220
  });
361
- let finalKey = key;
362
-
363
- if (typeof require === 'function' && !opts.emitFullSignatures) {
364
- // Prefer to hash when we can (e.g. outside of ASTExplorer).
365
- // This makes it deterministically compact, even if there's
366
- // e.g. a useState initializer with some code inside.
367
- // We also need it for www that has transforms like cx()
368
- // that don't understand if something is part of a string.
369
- finalKey = require('crypto').createHash('sha1').update(key).digest('base64');
370
- }
371
-
372
- const args = [node, t.stringLiteral(finalKey)];
373
-
374
- if (forceReset || customHooksInScope.length > 0) {
375
- args.push(t.booleanLiteral(forceReset));
376
- }
377
-
378
- if (customHooksInScope.length > 0) {
379
- args.push( // TODO: We could use an arrow here to be more compact.
380
- // However, don't do it until AMA can run them natively.
381
- t.functionExpression(null, [], t.blockStatement([t.returnStatement(t.arrayExpression(customHooksInScope))])));
382
- }
383
-
384
- return args;
221
+ signature = key;
222
+ "function" !== typeof require ||
223
+ opts.emitFullSignatures ||
224
+ (signature = require("crypto")
225
+ .createHash("sha1")
226
+ .update(key)
227
+ .digest("base64"));
228
+ node = [node, t.stringLiteral(signature)];
229
+ (forceReset || 0 < customHooksInScope.length) &&
230
+ node.push(t.booleanLiteral(forceReset));
231
+ 0 < customHooksInScope.length &&
232
+ node.push(
233
+ t.functionExpression(
234
+ null,
235
+ [],
236
+ t.blockStatement([
237
+ t.returnStatement(t.arrayExpression(customHooksInScope))
238
+ ])
239
+ )
240
+ );
241
+ return node;
385
242
  }
386
-
387
243
  function findHOCCallPathsAbove(path) {
388
- const calls = [];
389
-
390
- while (true) {
391
- if (!path) {
392
- return calls;
393
- }
394
-
395
- const parentPath = path.parentPath;
396
-
397
- if (!parentPath) {
398
- return calls;
399
- }
400
-
401
- if ( // hoc(_c = function() { })
402
- parentPath.node.type === 'AssignmentExpression' && path.node === parentPath.node.right) {
403
- // Ignore registrations.
244
+ for (var calls = []; ; ) {
245
+ if (!path) return calls;
246
+ var parentPath = path.parentPath;
247
+ if (!parentPath) return calls;
248
+ if (
249
+ "AssignmentExpression" === parentPath.node.type &&
250
+ path.node === parentPath.node.right
251
+ )
404
252
  path = parentPath;
405
- continue;
406
- }
407
-
408
- if ( // hoc1(hoc2(...))
409
- parentPath.node.type === 'CallExpression' && path.node !== parentPath.node.callee) {
410
- calls.push(parentPath);
411
- path = parentPath;
412
- continue;
413
- }
414
-
415
- return calls; // Stop at other types.
253
+ else if (
254
+ "CallExpression" === parentPath.node.type &&
255
+ path.node !== parentPath.node.callee
256
+ )
257
+ calls.push(parentPath), (path = parentPath);
258
+ else return calls;
416
259
  }
417
260
  }
418
-
419
- const seenForRegistration = new WeakSet();
420
- const seenForSignature = new WeakSet();
421
- const seenForOutro = new WeakSet();
422
- const hookCalls = new WeakMap();
423
- const HookCallsVisitor = {
424
- CallExpression(path) {
425
- const node = path.node;
426
- const callee = node.callee; // Note: this visitor MUST NOT mutate the tree in any way.
427
- // It runs early in a separate traversal and should be very fast.
428
-
429
- let name = null;
430
-
431
- switch (callee.type) {
432
- case 'Identifier':
433
- name = callee.name;
434
- break;
435
-
436
- case 'MemberExpression':
437
- name = callee.property.name;
438
- break;
439
- }
440
-
441
- if (name === null || !/^use[A-Z]/.test(name)) {
442
- return;
443
- }
444
-
445
- const fnScope = path.scope.getFunctionParent();
446
-
447
- if (fnScope === null) {
448
- return;
449
- } // This is a Hook call. Record it.
450
-
451
-
452
- const fnNode = fnScope.block;
453
-
454
- if (!hookCalls.has(fnNode)) {
455
- hookCalls.set(fnNode, []);
456
- }
457
-
458
- const hookCallsForFn = hookCalls.get(fnNode);
459
- let key = '';
460
-
461
- if (path.parent.type === 'VariableDeclarator') {
462
- // TODO: if there is no LHS, consider some other heuristic.
463
- key = path.parentPath.get('id').getSource();
464
- } // Some built-in Hooks reset on edits to arguments.
465
-
466
-
467
- const args = path.get('arguments');
468
-
469
- if (name === 'useState' && args.length > 0) {
470
- // useState second argument is initial state.
471
- key += '(' + args[0].getSource() + ')';
472
- } else if (name === 'useReducer' && args.length > 1) {
473
- // useReducer second argument is initial state.
474
- key += '(' + args[1].getSource() + ')';
261
+ var opts =
262
+ 1 < arguments.length && void 0 !== arguments[1] ? arguments[1] : {};
263
+ if ("function" === typeof babel.env) {
264
+ var env = babel.env();
265
+ if ("development" !== env && !opts.skipEnvCheck)
266
+ throw Error(
267
+ 'React Refresh Babel transform should only be enabled in development environment. Instead, the environment is: "' +
268
+ env +
269
+ '". If you want to override this check, pass {skipEnvCheck: true} as plugin options.'
270
+ );
271
+ }
272
+ var t = babel.types,
273
+ refreshReg = t.identifier(opts.refreshReg || "$RefreshReg$"),
274
+ refreshSig = t.identifier(opts.refreshSig || "$RefreshSig$"),
275
+ registrationsByProgramPath = new Map(),
276
+ hasForceResetCommentByFile = new WeakMap(),
277
+ seenForRegistration = new WeakSet(),
278
+ seenForSignature = new WeakSet(),
279
+ seenForOutro = new WeakSet(),
280
+ hookCalls = new WeakMap(),
281
+ HookCallsVisitor = {
282
+ CallExpression: function (path) {
283
+ var callee = path.node.callee,
284
+ name = null;
285
+ switch (callee.type) {
286
+ case "Identifier":
287
+ name = callee.name;
288
+ break;
289
+ case "MemberExpression":
290
+ name = callee.property.name;
291
+ }
292
+ if (
293
+ null !== name &&
294
+ /^use[A-Z]/.test(name) &&
295
+ ((callee = path.scope.getFunctionParent()), null !== callee)
296
+ ) {
297
+ callee = callee.block;
298
+ hookCalls.has(callee) || hookCalls.set(callee, []);
299
+ callee = hookCalls.get(callee);
300
+ var key = "";
301
+ "VariableDeclarator" === path.parent.type &&
302
+ (key = path.parentPath.get("id").getSource());
303
+ var args = path.get("arguments");
304
+ "useState" === name && 0 < args.length
305
+ ? (key += "(" + args[0].getSource() + ")")
306
+ : "useReducer" === name &&
307
+ 1 < args.length &&
308
+ (key += "(" + args[1].getSource() + ")");
309
+ callee.push({ callee: path.node.callee, name: name, key: key });
310
+ }
475
311
  }
476
-
477
- hookCallsForFn.push({
478
- callee: path.node.callee,
479
- name,
480
- key
481
- });
482
- }
483
-
484
- };
312
+ };
485
313
  return {
486
314
  visitor: {
487
- ExportDefaultDeclaration(path) {
488
- const node = path.node;
489
- const decl = node.declaration;
490
- const declPath = path.get('declaration');
491
-
492
- if (decl.type !== 'CallExpression') {
493
- // For now, we only support possible HOC calls here.
494
- // Named function declarations are handled in FunctionDeclaration.
495
- // Anonymous direct exports like export default function() {}
496
- // are currently ignored.
497
- return;
498
- } // Make sure we're not mutating the same tree twice.
499
- // This can happen if another Babel plugin replaces parents.
500
-
501
-
502
- if (seenForRegistration.has(node)) {
503
- return;
315
+ ExportDefaultDeclaration: function (path) {
316
+ var node = path.node,
317
+ decl = node.declaration,
318
+ declPath = path.get("declaration");
319
+ if ("CallExpression" === decl.type && !seenForRegistration.has(node)) {
320
+ seenForRegistration.add(node);
321
+ var programPath = path.parentPath;
322
+ findInnerComponents(
323
+ "%default%",
324
+ declPath,
325
+ function (persistentID, targetExpr, targetPath) {
326
+ null !== targetPath &&
327
+ ((persistentID = createRegistration(programPath, persistentID)),
328
+ targetPath.replaceWith(
329
+ t.assignmentExpression("=", persistentID, targetExpr)
330
+ ));
331
+ }
332
+ );
504
333
  }
505
-
506
- seenForRegistration.add(node); // Don't mutate the tree above this point.
507
- // This code path handles nested cases like:
508
- // export default memo(() => {})
509
- // In those cases it is more plausible people will omit names
510
- // so they're worth handling despite possible false positives.
511
- // More importantly, it handles the named case:
512
- // export default memo(function Named() {})
513
-
514
- const inferredName = '%default%';
515
- const programPath = path.parentPath;
516
- findInnerComponents(inferredName, declPath, (persistentID, targetExpr, targetPath) => {
517
- if (targetPath === null) {
518
- // For case like:
519
- // export default hoc(Foo)
520
- // we don't want to wrap Foo inside the call.
521
- // Instead we assume it's registered at definition.
522
- return;
523
- }
524
-
525
- const handle = createRegistration(programPath, persistentID);
526
- targetPath.replaceWith(t.assignmentExpression('=', handle, targetExpr));
527
- });
528
334
  },
529
-
530
335
  FunctionDeclaration: {
531
- enter(path) {
532
- const node = path.node;
533
- let programPath;
534
- let insertAfterPath;
535
- let modulePrefix = '';
536
-
336
+ enter: function (path) {
337
+ var node = path.node,
338
+ modulePrefix = "";
537
339
  switch (path.parent.type) {
538
- case 'Program':
539
- insertAfterPath = path;
540
- programPath = path.parentPath;
340
+ case "Program":
341
+ var insertAfterPath = path;
342
+ var programPath = path.parentPath;
541
343
  break;
542
-
543
- case 'TSModuleBlock':
344
+ case "TSModuleBlock":
544
345
  insertAfterPath = path;
545
346
  programPath = insertAfterPath.parentPath.parentPath;
546
347
  break;
547
-
548
- case 'ExportNamedDeclaration':
348
+ case "ExportNamedDeclaration":
549
349
  insertAfterPath = path.parentPath;
550
350
  programPath = insertAfterPath.parentPath;
551
351
  break;
552
-
553
- case 'ExportDefaultDeclaration':
352
+ case "ExportDefaultDeclaration":
554
353
  insertAfterPath = path.parentPath;
555
354
  programPath = insertAfterPath.parentPath;
556
355
  break;
557
-
558
356
  default:
559
357
  return;
560
- } // These types can be nested in typescript namespace
561
- // We need to find the export chain
562
- // Or return if it stays local
563
-
564
-
565
- if (path.parent.type === 'TSModuleBlock' || path.parent.type === 'ExportNamedDeclaration') {
566
- while (programPath.type !== 'Program') {
567
- if (programPath.type === 'TSModuleDeclaration') {
568
- if (programPath.parentPath.type !== 'Program' && programPath.parentPath.type !== 'ExportNamedDeclaration') {
358
+ }
359
+ if (
360
+ "TSModuleBlock" === path.parent.type ||
361
+ "ExportNamedDeclaration" === path.parent.type
362
+ )
363
+ for (; "Program" !== programPath.type; ) {
364
+ if ("TSModuleDeclaration" === programPath.type) {
365
+ if (
366
+ "Program" !== programPath.parentPath.type &&
367
+ "ExportNamedDeclaration" !== programPath.parentPath.type
368
+ )
569
369
  return;
570
- }
571
-
572
- modulePrefix = programPath.node.id.name + '$' + modulePrefix;
370
+ modulePrefix = programPath.node.id.name + "$" + modulePrefix;
573
371
  }
574
-
575
372
  programPath = programPath.parentPath;
576
373
  }
577
- }
578
-
579
- const id = node.id;
580
-
581
- if (id === null) {
582
- // We don't currently handle anonymous default exports.
583
- return;
584
- }
585
-
586
- const inferredName = id.name;
587
-
588
- if (!isComponentishName(inferredName)) {
589
- return;
590
- } // Make sure we're not mutating the same tree twice.
591
- // This can happen if another Babel plugin replaces parents.
592
-
593
-
594
- if (seenForRegistration.has(node)) {
595
- return;
596
- }
597
-
598
- seenForRegistration.add(node); // Don't mutate the tree above this point.
599
-
600
- const innerName = modulePrefix + inferredName; // export function Named() {}
601
- // function Named() {}
602
-
603
- findInnerComponents(innerName, path, (persistentID, targetExpr) => {
604
- const handle = createRegistration(programPath, persistentID);
605
- insertAfterPath.insertAfter(t.expressionStatement(t.assignmentExpression('=', handle, targetExpr)));
606
- });
374
+ var id = node.id;
375
+ null !== id &&
376
+ ((id = id.name),
377
+ isComponentishName(id) &&
378
+ !seenForRegistration.has(node) &&
379
+ (seenForRegistration.add(node),
380
+ findInnerComponents(
381
+ modulePrefix + id,
382
+ path,
383
+ function (persistentID, targetExpr) {
384
+ persistentID = createRegistration(programPath, persistentID);
385
+ insertAfterPath.insertAfter(
386
+ t.expressionStatement(
387
+ t.assignmentExpression("=", persistentID, targetExpr)
388
+ )
389
+ );
390
+ }
391
+ )));
607
392
  },
608
-
609
- exit(path) {
610
- const node = path.node;
611
- const id = node.id;
612
-
613
- if (id === null) {
614
- return;
615
- }
616
-
617
- const signature = getHookCallsSignature(node);
618
-
619
- if (signature === null) {
620
- return;
621
- } // Make sure we're not mutating the same tree twice.
622
- // This can happen if another Babel plugin replaces parents.
623
-
624
-
625
- if (seenForSignature.has(node)) {
626
- return;
627
- }
628
-
629
- seenForSignature.add(node); // Don't mutate the tree above this point.
630
-
631
- const sigCallID = path.scope.generateUidIdentifier('_s');
632
- path.scope.parent.push({
633
- id: sigCallID,
634
- init: t.callExpression(refreshSig, [])
635
- }); // The signature call is split in two parts. One part is called inside the function.
636
- // This is used to signal when first render happens.
637
-
638
- path.get('body').unshiftContainer('body', t.expressionStatement(t.callExpression(sigCallID, []))); // The second call is around the function itself.
639
- // This is used to associate a type with a signature.
640
- // Unlike with $RefreshReg$, this needs to work for nested
641
- // declarations too. So we need to search for a path where
642
- // we can insert a statement rather than hard coding it.
643
-
644
- let insertAfterPath = null;
645
- path.find(p => {
646
- if (p.parentPath.isBlock()) {
647
- insertAfterPath = p;
648
- return true;
393
+ exit: function (path) {
394
+ var node = path.node,
395
+ id = node.id;
396
+ if (null !== id) {
397
+ var signature = getHookCallsSignature(node);
398
+ if (null !== signature && !seenForSignature.has(node)) {
399
+ seenForSignature.add(node);
400
+ node = path.scope.generateUidIdentifier("_s");
401
+ path.scope.parent.push({
402
+ id: node,
403
+ init: t.callExpression(refreshSig, [])
404
+ });
405
+ path
406
+ .get("body")
407
+ .unshiftContainer(
408
+ "body",
409
+ t.expressionStatement(t.callExpression(node, []))
410
+ );
411
+ var insertAfterPath = null;
412
+ path.find(function (p) {
413
+ if (p.parentPath.isBlock()) return (insertAfterPath = p), !0;
414
+ });
415
+ null !== insertAfterPath &&
416
+ insertAfterPath.insertAfter(
417
+ t.expressionStatement(
418
+ t.callExpression(
419
+ node,
420
+ createArgumentsForSignature(
421
+ id,
422
+ signature,
423
+ insertAfterPath.scope
424
+ )
425
+ )
426
+ )
427
+ );
649
428
  }
650
- });
651
-
652
- if (insertAfterPath === null) {
653
- return;
654
429
  }
655
-
656
- insertAfterPath.insertAfter(t.expressionStatement(t.callExpression(sigCallID, createArgumentsForSignature(id, signature, insertAfterPath.scope))));
657
430
  }
658
-
659
431
  },
660
- 'ArrowFunctionExpression|FunctionExpression': {
661
- exit(path) {
662
- const node = path.node;
663
- const signature = getHookCallsSignature(node);
664
-
665
- if (signature === null) {
666
- return;
667
- } // Make sure we're not mutating the same tree twice.
668
- // This can happen if another Babel plugin replaces parents.
669
-
670
-
671
- if (seenForSignature.has(node)) {
672
- return;
673
- }
674
-
675
- seenForSignature.add(node); // Don't mutate the tree above this point.
676
-
677
- const sigCallID = path.scope.generateUidIdentifier('_s');
678
- path.scope.parent.push({
679
- id: sigCallID,
680
- init: t.callExpression(refreshSig, [])
681
- }); // The signature call is split in two parts. One part is called inside the function.
682
- // This is used to signal when first render happens.
683
-
684
- if (path.node.body.type !== 'BlockStatement') {
685
- path.node.body = t.blockStatement([t.returnStatement(path.node.body)]);
686
- }
687
-
688
- path.get('body').unshiftContainer('body', t.expressionStatement(t.callExpression(sigCallID, []))); // The second call is around the function itself.
689
- // This is used to associate a type with a signature.
690
-
691
- if (path.parent.type === 'VariableDeclarator') {
692
- let insertAfterPath = null;
693
- path.find(p => {
694
- if (p.parentPath.isBlock()) {
695
- insertAfterPath = p;
696
- return true;
697
- }
432
+ "ArrowFunctionExpression|FunctionExpression": {
433
+ exit: function (path) {
434
+ var node = path.node,
435
+ signature = getHookCallsSignature(node);
436
+ if (null !== signature && !seenForSignature.has(node)) {
437
+ seenForSignature.add(node);
438
+ var sigCallID = path.scope.generateUidIdentifier("_s");
439
+ path.scope.parent.push({
440
+ id: sigCallID,
441
+ init: t.callExpression(refreshSig, [])
698
442
  });
699
-
700
- if (insertAfterPath === null) {
701
- return;
702
- } // Special case when a function would get an inferred name:
703
- // let Foo = () => {}
704
- // let Foo = function() {}
705
- // We'll add signature it on next line so that
706
- // we don't mess up the inferred 'Foo' function name.
707
-
708
-
709
- insertAfterPath.insertAfter(t.expressionStatement(t.callExpression(sigCallID, createArgumentsForSignature(path.parent.id, signature, insertAfterPath.scope)))); // Result: let Foo = () => {}; __signature(Foo, ...);
710
- } else {
711
- // let Foo = hoc(() => {})
712
- const paths = [path].concat(findHOCCallPathsAbove(path));
713
- paths.forEach(p => {
714
- p.replaceWith(t.callExpression(sigCallID, createArgumentsForSignature(p.node, signature, p.scope)));
715
- }); // Result: let Foo = __signature(hoc(__signature(() => {}, ...)), ...)
443
+ "BlockStatement" !== path.node.body.type &&
444
+ (path.node.body = t.blockStatement([
445
+ t.returnStatement(path.node.body)
446
+ ]));
447
+ path
448
+ .get("body")
449
+ .unshiftContainer(
450
+ "body",
451
+ t.expressionStatement(t.callExpression(sigCallID, []))
452
+ );
453
+ if ("VariableDeclarator" === path.parent.type) {
454
+ var insertAfterPath = null;
455
+ path.find(function (p) {
456
+ if (p.parentPath.isBlock()) return (insertAfterPath = p), !0;
457
+ });
458
+ null !== insertAfterPath &&
459
+ insertAfterPath.insertAfter(
460
+ t.expressionStatement(
461
+ t.callExpression(
462
+ sigCallID,
463
+ createArgumentsForSignature(
464
+ path.parent.id,
465
+ signature,
466
+ insertAfterPath.scope
467
+ )
468
+ )
469
+ )
470
+ );
471
+ } else
472
+ [path].concat(findHOCCallPathsAbove(path)).forEach(function (p) {
473
+ p.replaceWith(
474
+ t.callExpression(
475
+ sigCallID,
476
+ createArgumentsForSignature(p.node, signature, p.scope)
477
+ )
478
+ );
479
+ });
716
480
  }
717
481
  }
718
-
719
482
  },
720
-
721
- VariableDeclaration(path) {
722
- const node = path.node;
723
- let programPath;
724
- let insertAfterPath;
725
- let modulePrefix = '';
726
-
483
+ VariableDeclaration: function (path) {
484
+ var node = path.node,
485
+ modulePrefix = "";
727
486
  switch (path.parent.type) {
728
- case 'Program':
729
- insertAfterPath = path;
730
- programPath = path.parentPath;
487
+ case "Program":
488
+ var insertAfterPath = path;
489
+ var programPath = path.parentPath;
731
490
  break;
732
-
733
- case 'TSModuleBlock':
491
+ case "TSModuleBlock":
734
492
  insertAfterPath = path;
735
493
  programPath = insertAfterPath.parentPath.parentPath;
736
494
  break;
737
-
738
- case 'ExportNamedDeclaration':
495
+ case "ExportNamedDeclaration":
739
496
  insertAfterPath = path.parentPath;
740
497
  programPath = insertAfterPath.parentPath;
741
498
  break;
742
-
743
- case 'ExportDefaultDeclaration':
499
+ case "ExportDefaultDeclaration":
744
500
  insertAfterPath = path.parentPath;
745
501
  programPath = insertAfterPath.parentPath;
746
502
  break;
747
-
748
503
  default:
749
504
  return;
750
- } // These types can be nested in typescript namespace
751
- // We need to find the export chain
752
- // Or return if it stays local
753
-
754
-
755
- if (path.parent.type === 'TSModuleBlock' || path.parent.type === 'ExportNamedDeclaration') {
756
- while (programPath.type !== 'Program') {
757
- if (programPath.type === 'TSModuleDeclaration') {
758
- if (programPath.parentPath.type !== 'Program' && programPath.parentPath.type !== 'ExportNamedDeclaration') {
505
+ }
506
+ if (
507
+ "TSModuleBlock" === path.parent.type ||
508
+ "ExportNamedDeclaration" === path.parent.type
509
+ )
510
+ for (; "Program" !== programPath.type; ) {
511
+ if ("TSModuleDeclaration" === programPath.type) {
512
+ if (
513
+ "Program" !== programPath.parentPath.type &&
514
+ "ExportNamedDeclaration" !== programPath.parentPath.type
515
+ )
759
516
  return;
760
- }
761
-
762
- modulePrefix = programPath.node.id.name + '$' + modulePrefix;
517
+ modulePrefix = programPath.node.id.name + "$" + modulePrefix;
763
518
  }
764
-
765
519
  programPath = programPath.parentPath;
766
520
  }
767
- } // Make sure we're not mutating the same tree twice.
768
- // This can happen if another Babel plugin replaces parents.
769
-
770
-
771
- if (seenForRegistration.has(node)) {
772
- return;
773
- }
774
-
775
- seenForRegistration.add(node); // Don't mutate the tree above this point.
776
-
777
- const declPaths = path.get('declarations');
778
-
779
- if (declPaths.length !== 1) {
780
- return;
521
+ if (
522
+ !seenForRegistration.has(node) &&
523
+ (seenForRegistration.add(node),
524
+ (path = path.get("declarations")),
525
+ 1 === path.length)
526
+ ) {
527
+ var declPath = path[0];
528
+ findInnerComponents(
529
+ modulePrefix + declPath.node.id.name,
530
+ declPath,
531
+ function (persistentID, targetExpr, targetPath) {
532
+ null !== targetPath &&
533
+ ((persistentID = createRegistration(programPath, persistentID)),
534
+ "VariableDeclarator" === targetPath.parent.type
535
+ ? insertAfterPath.insertAfter(
536
+ t.expressionStatement(
537
+ t.assignmentExpression(
538
+ "=",
539
+ persistentID,
540
+ declPath.node.id
541
+ )
542
+ )
543
+ )
544
+ : targetPath.replaceWith(
545
+ t.assignmentExpression("=", persistentID, targetExpr)
546
+ ));
547
+ }
548
+ );
781
549
  }
782
-
783
- const declPath = declPaths[0];
784
- const inferredName = declPath.node.id.name;
785
- const innerName = modulePrefix + inferredName;
786
- findInnerComponents(innerName, declPath, (persistentID, targetExpr, targetPath) => {
787
- if (targetPath === null) {
788
- // For case like:
789
- // export const Something = hoc(Foo)
790
- // we don't want to wrap Foo inside the call.
791
- // Instead we assume it's registered at definition.
792
- return;
793
- }
794
-
795
- const handle = createRegistration(programPath, persistentID);
796
-
797
- if (targetPath.parent.type === 'VariableDeclarator') {
798
- // Special case when a variable would get an inferred name:
799
- // let Foo = () => {}
800
- // let Foo = function() {}
801
- // let Foo = styled.div``;
802
- // We'll register it on next line so that
803
- // we don't mess up the inferred 'Foo' function name.
804
- // (eg: with @babel/plugin-transform-react-display-name or
805
- // babel-plugin-styled-components)
806
- insertAfterPath.insertAfter(t.expressionStatement(t.assignmentExpression('=', handle, declPath.node.id))); // Result: let Foo = () => {}; _c1 = Foo;
807
- } else {
808
- // let Foo = hoc(() => {})
809
- targetPath.replaceWith(t.assignmentExpression('=', handle, targetExpr)); // Result: let Foo = hoc(_c1 = () => {})
810
- }
811
- });
812
550
  },
813
-
814
551
  Program: {
815
- enter(path) {
816
- // This is a separate early visitor because we need to collect Hook calls
817
- // and "const [foo, setFoo] = ..." signatures before the destructuring
818
- // transform mangles them. This extra traversal is not ideal for perf,
819
- // but it's the best we can do until we stop transpiling destructuring.
552
+ enter: function (path) {
820
553
  path.traverse(HookCallsVisitor);
821
554
  },
822
-
823
- exit(path) {
824
- const registrations = registrationsByProgramPath.get(path);
825
-
826
- if (registrations === undefined) {
827
- return;
828
- } // Make sure we're not mutating the same tree twice.
829
- // This can happen if another Babel plugin replaces parents.
830
-
831
-
832
- const node = path.node;
833
-
834
- if (seenForOutro.has(node)) {
835
- return;
555
+ exit: function (path) {
556
+ var registrations = registrationsByProgramPath.get(path);
557
+ if (void 0 !== registrations) {
558
+ var node = path.node;
559
+ if (!seenForOutro.has(node)) {
560
+ seenForOutro.add(node);
561
+ registrationsByProgramPath.delete(path);
562
+ var declarators = [];
563
+ path.pushContainer(
564
+ "body",
565
+ t.variableDeclaration("var", declarators)
566
+ );
567
+ registrations.forEach(function (_ref) {
568
+ var handle = _ref.handle;
569
+ path.pushContainer(
570
+ "body",
571
+ t.expressionStatement(
572
+ t.callExpression(refreshReg, [
573
+ handle,
574
+ t.stringLiteral(_ref.persistentID)
575
+ ])
576
+ )
577
+ );
578
+ declarators.push(t.variableDeclarator(handle));
579
+ });
580
+ }
836
581
  }
837
-
838
- seenForOutro.add(node); // Don't mutate the tree above this point.
839
-
840
- registrationsByProgramPath.delete(path);
841
- const declarators = [];
842
- path.pushContainer('body', t.variableDeclaration('var', declarators));
843
- registrations.forEach((_ref) => {
844
- let handle = _ref.handle,
845
- persistentID = _ref.persistentID;
846
- path.pushContainer('body', t.expressionStatement(t.callExpression(refreshReg, [handle, t.stringLiteral(persistentID)])));
847
- declarators.push(t.variableDeclarator(handle));
848
- });
849
582
  }
850
-
851
583
  }
852
584
  }
853
585
  };
854
- }
855
-
856
- module.exports = ReactFreshBabelPlugin;
586
+ };