solid-refresh 0.6.3 → 0.7.0
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.
- package/README.md +38 -10
- package/dist/babel.cjs +580 -283
- package/dist/babel.mjs +580 -283
- package/dist/types/src/babel/core/checks.d.ts +4 -0
- package/dist/types/src/babel/core/checks.d.ts.map +1 -0
- package/dist/types/src/babel/core/constants.d.ts +8 -0
- package/dist/types/src/babel/core/constants.d.ts.map +1 -0
- package/dist/types/src/babel/core/create-registry.d.ts +5 -0
- package/dist/types/src/babel/core/create-registry.d.ts.map +1 -0
- package/dist/types/src/babel/core/generate-unique-name.d.ts +4 -0
- package/dist/types/src/babel/core/generate-unique-name.d.ts.map +1 -0
- package/dist/types/src/babel/core/generator.d.ts +3 -0
- package/dist/types/src/babel/core/generator.d.ts.map +1 -0
- package/dist/types/src/babel/core/get-descriptive-name.d.ts +3 -0
- package/dist/types/src/babel/core/get-descriptive-name.d.ts.map +1 -0
- package/dist/types/src/babel/core/get-foreign-bindings.d.ts +4 -0
- package/dist/types/src/babel/core/get-foreign-bindings.d.ts.map +1 -0
- package/dist/types/src/babel/core/get-hmr-decline-call.d.ts +4 -0
- package/dist/types/src/babel/core/get-hmr-decline-call.d.ts.map +1 -0
- package/dist/types/src/babel/core/get-hot-identifier.d.ts +4 -0
- package/dist/types/src/babel/core/get-hot-identifier.d.ts.map +1 -0
- package/dist/types/src/babel/core/get-import-identifier.d.ts +5 -0
- package/dist/types/src/babel/core/get-import-identifier.d.ts.map +1 -0
- package/dist/types/src/babel/core/get-root-statement-path.d.ts +3 -0
- package/dist/types/src/babel/core/get-root-statement-path.d.ts.map +1 -0
- package/dist/types/src/babel/core/get-statement-path.d.ts +3 -0
- package/dist/types/src/babel/core/get-statement-path.d.ts.map +1 -0
- package/dist/types/src/babel/core/get-vite-hmr-requirement.d.ts +4 -0
- package/dist/types/src/babel/core/get-vite-hmr-requirement.d.ts.map +1 -0
- package/dist/types/src/babel/core/is-valid-callee.d.ts +5 -0
- package/dist/types/src/babel/core/is-valid-callee.d.ts.map +1 -0
- package/dist/types/src/babel/core/register-import-specifiers.d.ts +5 -0
- package/dist/types/src/babel/core/register-import-specifiers.d.ts.map +1 -0
- package/dist/types/src/babel/core/transform-jsx.d.ts +4 -0
- package/dist/types/src/babel/core/transform-jsx.d.ts.map +1 -0
- package/dist/types/src/babel/core/types.d.ts +41 -0
- package/dist/types/src/babel/core/types.d.ts.map +1 -0
- package/dist/types/src/babel/core/unwrap.d.ts +11 -0
- package/dist/types/src/babel/core/unwrap.d.ts.map +1 -0
- package/dist/types/src/babel/core/xxhash32.d.ts +7 -0
- package/dist/types/src/babel/core/xxhash32.d.ts.map +1 -0
- package/dist/types/src/babel/index.d.ts +1 -24
- package/dist/types/src/babel/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/babel.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'path';
|
|
2
2
|
import * as t from '@babel/types';
|
|
3
|
+
import { addNamed, addDefault } from '@babel/helper-module-imports';
|
|
3
4
|
import _generator from '@babel/generator';
|
|
4
|
-
import { addNamed } from '@babel/helper-module-imports';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Copyright (c) 2019 Jason Dent
|
|
@@ -190,79 +190,244 @@ function xxHash32(buffer, seed = 0) {
|
|
|
190
190
|
return acc < 0 ? acc + 4294967296 : acc;
|
|
191
191
|
}
|
|
192
192
|
|
|
193
|
-
// https://github.com/babel/babel/issues/15269
|
|
194
|
-
let generator;
|
|
195
|
-
if (typeof _generator !== 'function') {
|
|
196
|
-
generator = _generator.default;
|
|
197
|
-
}
|
|
198
|
-
else {
|
|
199
|
-
generator = _generator;
|
|
200
|
-
}
|
|
201
|
-
const CWD = process.cwd();
|
|
202
|
-
function getFile(filename) {
|
|
203
|
-
return path.relative(CWD, filename);
|
|
204
|
-
}
|
|
205
193
|
// This is just a Pascal heuristic
|
|
206
194
|
// we only assume a function is a component
|
|
207
195
|
// if the first character is in uppercase
|
|
208
196
|
function isComponentishName(name) {
|
|
209
197
|
return name[0] >= 'A' && name[0] <= 'Z';
|
|
210
198
|
}
|
|
211
|
-
function
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
return
|
|
199
|
+
function getImportSpecifierName(specifier) {
|
|
200
|
+
if (t.isIdentifier(specifier.imported)) {
|
|
201
|
+
return specifier.imported.name;
|
|
202
|
+
}
|
|
203
|
+
return specifier.imported.value;
|
|
216
204
|
}
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
205
|
+
|
|
206
|
+
function registerImportSpecifier(state, id, specifier) {
|
|
207
|
+
if (t.isImportDefaultSpecifier(specifier)) {
|
|
208
|
+
if (id.definition.kind === 'default') {
|
|
209
|
+
state.registrations.identifiers.set(specifier.local, id);
|
|
210
|
+
}
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (t.isImportSpecifier(specifier)) {
|
|
214
|
+
if ((id.definition.kind === 'named' &&
|
|
215
|
+
getImportSpecifierName(specifier) === id.definition.name) ||
|
|
216
|
+
(id.definition.kind === 'default' &&
|
|
217
|
+
getImportSpecifierName(specifier) === 'default')) {
|
|
218
|
+
state.registrations.identifiers.set(specifier.local, id);
|
|
219
|
+
}
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
let current = state.registrations.namespaces.get(specifier.local);
|
|
223
|
+
if (!current) {
|
|
224
|
+
current = [];
|
|
225
|
+
}
|
|
226
|
+
current.push(id);
|
|
227
|
+
state.registrations.namespaces.set(specifier.local, current);
|
|
228
|
+
}
|
|
229
|
+
function registerImportSpecifiers(state, path, definitions) {
|
|
230
|
+
for (let i = 0, len = definitions.length; i < len; i++) {
|
|
231
|
+
const id = definitions[i];
|
|
232
|
+
if (path.node.source.value === id.definition.source) {
|
|
233
|
+
for (let k = 0, klen = path.node.specifiers.length; k < klen; k++) {
|
|
234
|
+
registerImportSpecifier(state, id, path.node.specifiers[k]);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
232
237
|
}
|
|
233
|
-
const newID = addNamed(path, name, SOLID_REFRESH_MODULE);
|
|
234
|
-
state.hooks.set(target, newID);
|
|
235
|
-
return newID;
|
|
236
238
|
}
|
|
239
|
+
|
|
237
240
|
function getHotIdentifier(state) {
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
241
|
+
switch (state.bundler) {
|
|
242
|
+
// vite/esm uses `import.meta.hot`
|
|
243
|
+
case 'esm':
|
|
244
|
+
case 'vite':
|
|
245
|
+
return t.memberExpression(t.memberExpression(t.identifier('import'), t.identifier('meta')), t.identifier('hot'));
|
|
246
|
+
// webpack 5 uses `import.meta.webpackHot`
|
|
247
|
+
// rspack does as well
|
|
248
|
+
case 'webpack5':
|
|
249
|
+
case 'rspack-esm':
|
|
250
|
+
return t.memberExpression(t.memberExpression(t.identifier('import'), t.identifier('meta')), t.identifier('webpackHot'));
|
|
251
|
+
default:
|
|
252
|
+
// `module.hot` is the default.
|
|
253
|
+
return t.memberExpression(t.identifier('module'), t.identifier('hot'));
|
|
242
254
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
function getImportIdentifier(state, path, registration) {
|
|
258
|
+
const name = registration.kind === 'named' ? registration.name : 'default';
|
|
259
|
+
const target = `${registration.source}[${name}]`;
|
|
260
|
+
const current = state.imports.get(target);
|
|
261
|
+
if (current) {
|
|
262
|
+
return current;
|
|
247
263
|
}
|
|
248
|
-
|
|
249
|
-
|
|
264
|
+
const newID = registration.kind === 'named'
|
|
265
|
+
? addNamed(path, registration.name, registration.source)
|
|
266
|
+
: addDefault(path, registration.source);
|
|
267
|
+
state.imports.set(target, newID);
|
|
268
|
+
return newID;
|
|
250
269
|
}
|
|
251
|
-
|
|
252
|
-
|
|
270
|
+
|
|
271
|
+
// Source of solid-refresh (for import)
|
|
272
|
+
const SOLID_REFRESH_MODULE = 'solid-refresh';
|
|
273
|
+
// Exported names from solid-refresh that will be imported
|
|
274
|
+
const IMPORT_REGISTRY = {
|
|
275
|
+
kind: 'named',
|
|
276
|
+
name: '$$registry',
|
|
277
|
+
source: SOLID_REFRESH_MODULE,
|
|
278
|
+
};
|
|
279
|
+
const IMPORT_REFRESH = {
|
|
280
|
+
kind: 'named',
|
|
281
|
+
name: '$$refresh',
|
|
282
|
+
source: SOLID_REFRESH_MODULE,
|
|
283
|
+
};
|
|
284
|
+
const IMPORT_COMPONENT = {
|
|
285
|
+
kind: 'named',
|
|
286
|
+
name: '$$component',
|
|
287
|
+
source: SOLID_REFRESH_MODULE,
|
|
288
|
+
};
|
|
289
|
+
const IMPORT_CONTEXT = {
|
|
290
|
+
kind: 'named',
|
|
291
|
+
name: '$$context',
|
|
292
|
+
source: SOLID_REFRESH_MODULE,
|
|
293
|
+
};
|
|
294
|
+
const IMPORT_DECLINE = {
|
|
295
|
+
kind: 'named',
|
|
296
|
+
name: '$$decline',
|
|
297
|
+
source: SOLID_REFRESH_MODULE,
|
|
298
|
+
};
|
|
299
|
+
const IMPORT_SPECIFIERS = [
|
|
300
|
+
{
|
|
301
|
+
type: 'render',
|
|
302
|
+
definition: { name: 'render', kind: 'named', source: 'solid-js/web' },
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
type: 'render',
|
|
306
|
+
definition: { name: 'hydrate', kind: 'named', source: 'solid-js/web' },
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
type: 'createContext',
|
|
310
|
+
definition: {
|
|
311
|
+
name: 'createContext',
|
|
312
|
+
kind: 'named',
|
|
313
|
+
source: 'solid-js',
|
|
314
|
+
},
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
type: 'createContext',
|
|
318
|
+
definition: {
|
|
319
|
+
name: 'createContext',
|
|
320
|
+
kind: 'named',
|
|
321
|
+
source: 'solid-js/web',
|
|
322
|
+
},
|
|
323
|
+
},
|
|
324
|
+
];
|
|
325
|
+
|
|
326
|
+
function generateViteHMRRequirement(state, statements, pathToHot) {
|
|
327
|
+
if (state.bundler === 'vite') {
|
|
253
328
|
// Vite requires that the owner module has an `import.meta.hot.accept()` call
|
|
254
329
|
statements.push(t.expressionStatement(t.callExpression(t.memberExpression(pathToHot, t.identifier('accept')), [])));
|
|
255
330
|
}
|
|
256
331
|
}
|
|
332
|
+
|
|
257
333
|
function getHMRDeclineCall(state, path) {
|
|
258
|
-
var _a;
|
|
259
334
|
const pathToHot = getHotIdentifier(state);
|
|
260
335
|
const statements = [
|
|
261
|
-
t.expressionStatement(t.callExpression(
|
|
336
|
+
t.expressionStatement(t.callExpression(getImportIdentifier(state, path, IMPORT_DECLINE), [
|
|
337
|
+
t.stringLiteral(state.bundler),
|
|
338
|
+
pathToHot,
|
|
339
|
+
])),
|
|
262
340
|
];
|
|
263
|
-
|
|
341
|
+
generateViteHMRRequirement(state, statements, pathToHot);
|
|
264
342
|
return t.ifStatement(pathToHot, t.blockStatement(statements));
|
|
265
343
|
}
|
|
344
|
+
|
|
345
|
+
function isPathValid(path, key) {
|
|
346
|
+
return key(path.node);
|
|
347
|
+
}
|
|
348
|
+
function isNestedExpression(node) {
|
|
349
|
+
switch (node.type) {
|
|
350
|
+
case 'ParenthesizedExpression':
|
|
351
|
+
case 'TypeCastExpression':
|
|
352
|
+
case 'TSAsExpression':
|
|
353
|
+
case 'TSSatisfiesExpression':
|
|
354
|
+
case 'TSNonNullExpression':
|
|
355
|
+
case 'TSTypeAssertion':
|
|
356
|
+
case 'TSInstantiationExpression':
|
|
357
|
+
return true;
|
|
358
|
+
default:
|
|
359
|
+
return false;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function unwrapNode(node, key) {
|
|
363
|
+
if (key(node)) {
|
|
364
|
+
return node;
|
|
365
|
+
}
|
|
366
|
+
if (isNestedExpression(node)) {
|
|
367
|
+
return unwrapNode(node.expression, key);
|
|
368
|
+
}
|
|
369
|
+
return undefined;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
function isIdentifierValidCallee(state, path, callee, target) {
|
|
373
|
+
const binding = path.scope.getBindingIdentifier(callee.name);
|
|
374
|
+
if (binding) {
|
|
375
|
+
const result = state.registrations.identifiers.get(binding);
|
|
376
|
+
if (result && result.type === target) {
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
function isPropertyValidCallee(result, target, propName) {
|
|
383
|
+
for (let i = 0, len = result.length; i < len; i++) {
|
|
384
|
+
const registration = result[i];
|
|
385
|
+
if (registration.type === target) {
|
|
386
|
+
if (registration.definition.kind === 'named') {
|
|
387
|
+
if (registration.definition.name === propName) {
|
|
388
|
+
return true;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
else if (propName === 'default') {
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
function isMemberExpressionValidCallee(state, path, member, target) {
|
|
399
|
+
if (!t.isIdentifier(member.property)) {
|
|
400
|
+
return false;
|
|
401
|
+
}
|
|
402
|
+
const trueObject = unwrapNode(member.object, t.isIdentifier);
|
|
403
|
+
if (!trueObject) {
|
|
404
|
+
return false;
|
|
405
|
+
}
|
|
406
|
+
const binding = path.scope.getBindingIdentifier(trueObject.name);
|
|
407
|
+
if (!binding) {
|
|
408
|
+
return false;
|
|
409
|
+
}
|
|
410
|
+
const result = state.registrations.namespaces.get(binding);
|
|
411
|
+
if (!result) {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
return isPropertyValidCallee(result, target, member.property.name);
|
|
415
|
+
}
|
|
416
|
+
function isValidCallee(state, path, { callee }, target) {
|
|
417
|
+
if (t.isV8IntrinsicIdentifier(callee)) {
|
|
418
|
+
return false;
|
|
419
|
+
}
|
|
420
|
+
const trueCallee = unwrapNode(callee, t.isIdentifier);
|
|
421
|
+
if (trueCallee) {
|
|
422
|
+
return isIdentifierValidCallee(state, path, trueCallee, target);
|
|
423
|
+
}
|
|
424
|
+
const trueMember = unwrapNode(callee, t.isMemberExpression);
|
|
425
|
+
if (trueMember && !trueMember.computed) {
|
|
426
|
+
return isMemberExpressionValidCallee(state, path, trueMember, target);
|
|
427
|
+
}
|
|
428
|
+
return false;
|
|
429
|
+
}
|
|
430
|
+
|
|
266
431
|
function getStatementPath(path) {
|
|
267
432
|
if (t.isStatement(path.node)) {
|
|
268
433
|
return path;
|
|
@@ -272,40 +437,46 @@ function getStatementPath(path) {
|
|
|
272
437
|
}
|
|
273
438
|
return null;
|
|
274
439
|
}
|
|
440
|
+
|
|
441
|
+
function getRootStatementPath(path) {
|
|
442
|
+
let current = path.parentPath;
|
|
443
|
+
while (current) {
|
|
444
|
+
const next = current.parentPath;
|
|
445
|
+
if (next && t.isProgram(next.node)) {
|
|
446
|
+
return current;
|
|
447
|
+
}
|
|
448
|
+
current = next;
|
|
449
|
+
}
|
|
450
|
+
return path;
|
|
451
|
+
}
|
|
452
|
+
|
|
275
453
|
const REGISTRY = 'REGISTRY';
|
|
276
454
|
function createRegistry(state, path) {
|
|
277
|
-
|
|
278
|
-
const current = state.hooks.get(REGISTRY);
|
|
455
|
+
const current = state.imports.get(REGISTRY);
|
|
279
456
|
if (current) {
|
|
280
457
|
return current;
|
|
281
458
|
}
|
|
282
|
-
const
|
|
283
|
-
const identifier =
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
init: t.callExpression(getSolidRefreshIdentifier(state, path, IMPORTS.registry), []),
|
|
288
|
-
});
|
|
459
|
+
const root = getRootStatementPath(path);
|
|
460
|
+
const identifier = path.scope.generateUidIdentifier(REGISTRY);
|
|
461
|
+
root.insertBefore(t.variableDeclaration('const', [
|
|
462
|
+
t.variableDeclarator(identifier, t.callExpression(getImportIdentifier(state, path, IMPORT_REGISTRY), [])),
|
|
463
|
+
]));
|
|
289
464
|
const pathToHot = getHotIdentifier(state);
|
|
290
465
|
const statements = [
|
|
291
|
-
t.expressionStatement(t.callExpression(
|
|
292
|
-
t.stringLiteral(
|
|
466
|
+
t.expressionStatement(t.callExpression(getImportIdentifier(state, path, IMPORT_REFRESH), [
|
|
467
|
+
t.stringLiteral(state.bundler),
|
|
293
468
|
pathToHot,
|
|
294
469
|
identifier,
|
|
295
470
|
])),
|
|
296
471
|
];
|
|
297
|
-
|
|
298
|
-
|
|
472
|
+
generateViteHMRRequirement(state, statements, pathToHot);
|
|
473
|
+
path.scope.getProgramParent().path.pushContainer('body', [
|
|
299
474
|
t.ifStatement(pathToHot, t.blockStatement(statements)),
|
|
300
475
|
]);
|
|
301
|
-
state.
|
|
476
|
+
state.imports.set(REGISTRY, identifier);
|
|
302
477
|
return identifier;
|
|
303
478
|
}
|
|
304
|
-
|
|
305
|
-
const code = generator(node);
|
|
306
|
-
const result = xxHash32(code.code).toString(16);
|
|
307
|
-
return result;
|
|
308
|
-
}
|
|
479
|
+
|
|
309
480
|
function isForeignBinding(source, current, name) {
|
|
310
481
|
if (source === current) {
|
|
311
482
|
return true;
|
|
@@ -328,13 +499,15 @@ function isInTypescript(path) {
|
|
|
328
499
|
}
|
|
329
500
|
return false;
|
|
330
501
|
}
|
|
331
|
-
function
|
|
502
|
+
function getForeignBindings(path) {
|
|
332
503
|
const identifiers = new Set();
|
|
333
504
|
path.traverse({
|
|
334
505
|
ReferencedIdentifier(p) {
|
|
335
506
|
// Check identifiers that aren't in a TS expression
|
|
336
507
|
if (!isInTypescript(p) && isForeignBinding(path, p, p.node.name)) {
|
|
337
|
-
|
|
508
|
+
if (p.isIdentifier() || p.parentPath.isJSXMemberExpression()) {
|
|
509
|
+
identifiers.add(p.node.name);
|
|
510
|
+
}
|
|
338
511
|
}
|
|
339
512
|
},
|
|
340
513
|
});
|
|
@@ -344,149 +517,266 @@ function getBindings(path) {
|
|
|
344
517
|
}
|
|
345
518
|
return collected;
|
|
346
519
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
source: 'solid-js/web',
|
|
359
|
-
},
|
|
360
|
-
{ type: 'render', name: 'render', kind: 'named', source: 'solid-js/web' },
|
|
361
|
-
{ type: 'render', name: 'hydrate', kind: 'named', source: 'solid-js/web' },
|
|
362
|
-
];
|
|
363
|
-
function getImportSpecifierName(specifier) {
|
|
364
|
-
switch (specifier.imported.type) {
|
|
365
|
-
case 'Identifier':
|
|
366
|
-
return specifier.imported.name;
|
|
367
|
-
case 'StringLiteral':
|
|
368
|
-
return specifier.imported.value;
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
function registerImportSpecifier(state, id, specifier) {
|
|
372
|
-
switch (specifier.type) {
|
|
373
|
-
case 'ImportDefaultSpecifier': {
|
|
374
|
-
if (id.kind === 'default') {
|
|
375
|
-
state.registrations.identifiers.set(specifier.local, id);
|
|
520
|
+
|
|
521
|
+
function getDescriptiveName(path, defaultName) {
|
|
522
|
+
let current = path;
|
|
523
|
+
while (current) {
|
|
524
|
+
switch (current.node.type) {
|
|
525
|
+
case 'FunctionDeclaration':
|
|
526
|
+
case 'FunctionExpression': {
|
|
527
|
+
if (current.node.id) {
|
|
528
|
+
return current.node.id.name;
|
|
529
|
+
}
|
|
530
|
+
break;
|
|
376
531
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
(id.kind === 'default' &&
|
|
383
|
-
getImportSpecifierName(specifier) === 'default')) {
|
|
384
|
-
state.registrations.identifiers.set(specifier.local, id);
|
|
532
|
+
case 'VariableDeclarator': {
|
|
533
|
+
if (current.node.id.type === 'Identifier') {
|
|
534
|
+
return current.node.id.name;
|
|
535
|
+
}
|
|
536
|
+
break;
|
|
385
537
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
538
|
+
case 'ClassPrivateMethod':
|
|
539
|
+
case 'ClassMethod':
|
|
540
|
+
case 'ObjectMethod': {
|
|
541
|
+
switch (current.node.key.type) {
|
|
542
|
+
case 'Identifier':
|
|
543
|
+
return current.node.key.name;
|
|
544
|
+
case 'PrivateName':
|
|
545
|
+
return current.node.key.id.name;
|
|
546
|
+
}
|
|
547
|
+
break;
|
|
392
548
|
}
|
|
393
|
-
current.push(id);
|
|
394
|
-
state.registrations.namespaces.set(specifier.local, current);
|
|
395
|
-
break;
|
|
396
549
|
}
|
|
550
|
+
current = current.parentPath;
|
|
397
551
|
}
|
|
552
|
+
return defaultName;
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
function generateUniqueName(path, name) {
|
|
556
|
+
let uid;
|
|
557
|
+
let i = 1;
|
|
558
|
+
do {
|
|
559
|
+
uid = name + '_' + i;
|
|
560
|
+
i++;
|
|
561
|
+
} while (path.scope.hasLabel(uid) ||
|
|
562
|
+
path.scope.hasBinding(uid) ||
|
|
563
|
+
path.scope.hasGlobal(uid) ||
|
|
564
|
+
path.scope.hasReference(uid));
|
|
565
|
+
const program = path.scope.getProgramParent();
|
|
566
|
+
program.references[uid] = true;
|
|
567
|
+
program.uids[uid] = true;
|
|
568
|
+
return t.identifier(uid);
|
|
398
569
|
}
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
570
|
+
|
|
571
|
+
const REFRESH_JSX_SKIP = /^\s*@refresh jsx-skip\s*$/;
|
|
572
|
+
function shouldSkipJSX(node) {
|
|
573
|
+
// Node without leading comments shouldn't be skipped
|
|
574
|
+
if (node.leadingComments) {
|
|
575
|
+
for (let i = 0, len = node.leadingComments.length; i < len; i++) {
|
|
576
|
+
if (REFRESH_JSX_SKIP.test(node.leadingComments[i].value)) {
|
|
577
|
+
return true;
|
|
405
578
|
}
|
|
406
579
|
}
|
|
407
580
|
}
|
|
581
|
+
return false;
|
|
408
582
|
}
|
|
409
|
-
function
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
583
|
+
function skippableJSX(node) {
|
|
584
|
+
return t.addComment(node, 'leading', '@refresh jsx-skip');
|
|
585
|
+
}
|
|
586
|
+
function pushAttribute(state, replacement) {
|
|
587
|
+
const key = 'v' + state.attributes.length;
|
|
588
|
+
state.attributes.push(t.jsxAttribute(t.jsxIdentifier(key), t.jsxExpressionContainer(replacement)));
|
|
589
|
+
return key;
|
|
590
|
+
}
|
|
591
|
+
function pushAttributeAndReplace(state, target, replacement) {
|
|
592
|
+
const key = pushAttribute(state, replacement);
|
|
593
|
+
target.replaceWith(t.memberExpression(state.props, t.identifier(key)));
|
|
594
|
+
}
|
|
595
|
+
function extractJSXExpressionFromNormalAttribute(state, attr) {
|
|
596
|
+
const value = attr.get('value');
|
|
597
|
+
if (isPathValid(value, t.isJSXElement) ||
|
|
598
|
+
isPathValid(value, t.isJSXFragment)) {
|
|
599
|
+
value.replaceWith(t.jsxExpressionContainer(value.node));
|
|
600
|
+
}
|
|
601
|
+
if (isPathValid(value, t.isJSXExpressionContainer)) {
|
|
602
|
+
extractJSXExpressionsFromJSXExpressionContainer(state, value);
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
function extractJSXExpressionFromRef(state, attr) {
|
|
606
|
+
const value = attr.get('value');
|
|
607
|
+
if (isPathValid(value, t.isJSXExpressionContainer)) {
|
|
608
|
+
const expr = value.get('expression');
|
|
609
|
+
if (isPathValid(expr, t.isExpression)) {
|
|
610
|
+
const unwrappedIdentifier = unwrapNode(expr.node, t.isIdentifier);
|
|
611
|
+
let replacement;
|
|
612
|
+
if (unwrappedIdentifier) {
|
|
613
|
+
const arg = expr.scope.generateUidIdentifier('arg');
|
|
614
|
+
replacement = t.arrowFunctionExpression([arg], t.blockStatement([
|
|
615
|
+
t.ifStatement(t.binaryExpression('===', t.unaryExpression('typeof', unwrappedIdentifier), t.stringLiteral('function')), t.blockStatement([
|
|
616
|
+
t.expressionStatement(t.callExpression(unwrappedIdentifier, [arg])),
|
|
617
|
+
]), t.blockStatement([
|
|
618
|
+
t.expressionStatement(t.assignmentExpression('=', unwrappedIdentifier, arg)),
|
|
619
|
+
])),
|
|
620
|
+
]));
|
|
414
621
|
}
|
|
415
|
-
|
|
416
|
-
|
|
622
|
+
else {
|
|
623
|
+
replacement = expr.node;
|
|
624
|
+
}
|
|
625
|
+
pushAttributeAndReplace(state, expr, replacement);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
417
628
|
}
|
|
418
|
-
function
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
case 'TSAsExpression':
|
|
423
|
-
case 'TSSatisfiesExpression':
|
|
424
|
-
case 'TSNonNullExpression':
|
|
425
|
-
case 'TSInstantiationExpression':
|
|
426
|
-
case 'TSTypeAssertion':
|
|
427
|
-
return unwrapExpression(node.expression, key);
|
|
428
|
-
default:
|
|
429
|
-
return key(node) ? node : undefined;
|
|
629
|
+
function extractJSXExpressionFromUseDirective(state, id, attr) {
|
|
630
|
+
const value = attr.get('value');
|
|
631
|
+
if (isPathValid(value, t.isJSXExpressionContainer)) {
|
|
632
|
+
extractJSXExpressionsFromJSXExpressionContainer(state, value);
|
|
430
633
|
}
|
|
634
|
+
const key = pushAttribute(state, t.identifier(id.name));
|
|
635
|
+
state.vars.push(t.variableDeclarator(t.identifier(id.name), t.memberExpression(state.props, t.identifier(key))));
|
|
431
636
|
}
|
|
432
|
-
function
|
|
433
|
-
const
|
|
434
|
-
if (
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
637
|
+
function extractJSXExpressionFromAttribute(state, attr) {
|
|
638
|
+
const key = attr.get('name');
|
|
639
|
+
if (isPathValid(key, t.isJSXIdentifier)) {
|
|
640
|
+
if (key.node.name === 'ref') {
|
|
641
|
+
extractJSXExpressionFromRef(state, attr);
|
|
642
|
+
}
|
|
643
|
+
else {
|
|
644
|
+
extractJSXExpressionFromNormalAttribute(state, attr);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
else if (isPathValid(key, t.isJSXNamespacedName)) {
|
|
648
|
+
if (key.node.namespace.name === 'use') {
|
|
649
|
+
extractJSXExpressionFromUseDirective(state, key.node.name, attr);
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
extractJSXExpressionFromNormalAttribute(state, attr);
|
|
438
653
|
}
|
|
439
654
|
}
|
|
440
|
-
return false;
|
|
441
655
|
}
|
|
442
|
-
function
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
return true;
|
|
454
|
-
}
|
|
656
|
+
function extractJSXExpressionsFromAttributes(state, path) {
|
|
657
|
+
const openingElement = path.get('openingElement');
|
|
658
|
+
const attrs = openingElement.get('attributes');
|
|
659
|
+
for (let i = 0, len = attrs.length; i < len; i++) {
|
|
660
|
+
const attr = attrs[i];
|
|
661
|
+
if (isPathValid(attr, t.isJSXAttribute)) {
|
|
662
|
+
extractJSXExpressionFromAttribute(state, attr);
|
|
663
|
+
}
|
|
664
|
+
if (isPathValid(attr, t.isJSXSpreadAttribute)) {
|
|
665
|
+
const arg = attr.get('argument');
|
|
666
|
+
pushAttributeAndReplace(state, arg, arg.node);
|
|
455
667
|
}
|
|
456
668
|
}
|
|
457
|
-
return false;
|
|
458
669
|
}
|
|
459
|
-
function
|
|
460
|
-
if (
|
|
461
|
-
return
|
|
670
|
+
function convertJSXOpeningToExpression(node) {
|
|
671
|
+
if (t.isJSXIdentifier(node)) {
|
|
672
|
+
return t.identifier(node.name);
|
|
673
|
+
}
|
|
674
|
+
return t.memberExpression(convertJSXOpeningToExpression(node.object), convertJSXOpeningToExpression(node.property));
|
|
675
|
+
}
|
|
676
|
+
function extractJSXExpressionsFromJSXElement(state, path) {
|
|
677
|
+
const openingElement = path.get('openingElement');
|
|
678
|
+
const openingName = openingElement.get('name');
|
|
679
|
+
if ((isPathValid(openingName, t.isJSXIdentifier) &&
|
|
680
|
+
/^[A-Z_]/.test(openingName.node.name)) ||
|
|
681
|
+
isPathValid(openingName, t.isJSXMemberExpression)) {
|
|
682
|
+
const key = pushAttribute(state, convertJSXOpeningToExpression(openingName.node));
|
|
683
|
+
const replacement = t.jsxMemberExpression(t.jsxIdentifier(state.props.name), t.jsxIdentifier(key));
|
|
684
|
+
openingName.replaceWith(replacement);
|
|
685
|
+
const closingElement = path.get('closingElement');
|
|
686
|
+
if (isPathValid(closingElement, t.isJSXClosingElement)) {
|
|
687
|
+
closingElement.get('name').replaceWith(replacement);
|
|
688
|
+
}
|
|
462
689
|
}
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
690
|
+
extractJSXExpressionsFromAttributes(state, path);
|
|
691
|
+
}
|
|
692
|
+
function extractJSXExpressionsFromJSXExpressionContainer(state, child) {
|
|
693
|
+
const expr = child.get('expression');
|
|
694
|
+
if (isPathValid(expr, t.isExpression)) {
|
|
695
|
+
pushAttributeAndReplace(state, expr, expr.node);
|
|
466
696
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
697
|
+
}
|
|
698
|
+
function extractJSXExpressionsFromJSXSpreadChild(state, child) {
|
|
699
|
+
const arg = child.get('expression');
|
|
700
|
+
pushAttributeAndReplace(state, arg, arg.node);
|
|
701
|
+
}
|
|
702
|
+
function extractJSXExpressions(state, path) {
|
|
703
|
+
if (isPathValid(path, t.isJSXElement)) {
|
|
704
|
+
extractJSXExpressionsFromJSXElement(state, path);
|
|
470
705
|
}
|
|
471
|
-
const
|
|
472
|
-
|
|
473
|
-
|
|
706
|
+
const children = path.get('children');
|
|
707
|
+
for (let i = 0, len = children.length; i < len; i++) {
|
|
708
|
+
const child = children[i];
|
|
709
|
+
if (isPathValid(child, t.isJSXElement) ||
|
|
710
|
+
isPathValid(child, t.isJSXFragment)) {
|
|
711
|
+
extractJSXExpressions(state, child);
|
|
712
|
+
}
|
|
713
|
+
else if (isPathValid(child, t.isJSXExpressionContainer)) {
|
|
714
|
+
extractJSXExpressionsFromJSXExpressionContainer(state, child);
|
|
715
|
+
}
|
|
716
|
+
else if (isPathValid(child, t.isJSXSpreadChild)) {
|
|
717
|
+
extractJSXExpressionsFromJSXSpreadChild(state, child);
|
|
718
|
+
}
|
|
474
719
|
}
|
|
475
|
-
return isPropertyValidCallee(result, target, member.property.name);
|
|
476
720
|
}
|
|
477
|
-
function
|
|
478
|
-
if (
|
|
479
|
-
return
|
|
721
|
+
function transformJSX(path) {
|
|
722
|
+
if (shouldSkipJSX(path.node)) {
|
|
723
|
+
return;
|
|
480
724
|
}
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
|
|
725
|
+
const state = {
|
|
726
|
+
props: path.scope.generateUidIdentifier('props'),
|
|
727
|
+
attributes: [],
|
|
728
|
+
vars: [],
|
|
729
|
+
};
|
|
730
|
+
extractJSXExpressions(state, path);
|
|
731
|
+
const descriptiveName = getDescriptiveName(path, 'template');
|
|
732
|
+
const id = generateUniqueName(path, isComponentishName(descriptiveName)
|
|
733
|
+
? descriptiveName
|
|
734
|
+
: 'JSX_' + descriptiveName);
|
|
735
|
+
const rootPath = getRootStatementPath(path);
|
|
736
|
+
let template = skippableJSX(t.cloneNode(path.node));
|
|
737
|
+
if (state.vars.length) {
|
|
738
|
+
template = t.blockStatement([
|
|
739
|
+
t.variableDeclaration('const', state.vars),
|
|
740
|
+
t.returnStatement(template),
|
|
741
|
+
]);
|
|
484
742
|
}
|
|
485
|
-
const
|
|
486
|
-
if (
|
|
487
|
-
|
|
743
|
+
const templateComp = t.arrowFunctionExpression([state.props], template);
|
|
744
|
+
if (path.node.loc) {
|
|
745
|
+
templateComp.loc = path.node.loc;
|
|
488
746
|
}
|
|
489
|
-
|
|
747
|
+
rootPath.insertBefore(t.variableDeclaration('const', [t.variableDeclarator(id, templateComp)]));
|
|
748
|
+
path.replaceWith(skippableJSX(t.jsxElement(t.jsxOpeningElement(t.jsxIdentifier(id.name), [...state.attributes], true), t.jsxClosingElement(t.jsxIdentifier(id.name)), [], true)));
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
// https://github.com/babel/babel/issues/15269
|
|
752
|
+
let generator;
|
|
753
|
+
if (typeof _generator !== 'function') {
|
|
754
|
+
generator = _generator.default;
|
|
755
|
+
}
|
|
756
|
+
else {
|
|
757
|
+
generator = _generator;
|
|
758
|
+
}
|
|
759
|
+
function generateCode(node) {
|
|
760
|
+
return generator(node).code;
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
const CWD = process.cwd();
|
|
764
|
+
function getFile(filename) {
|
|
765
|
+
return path.relative(CWD, filename);
|
|
766
|
+
}
|
|
767
|
+
function createSignatureValue(node) {
|
|
768
|
+
const code = generateCode(node);
|
|
769
|
+
const result = xxHash32(code).toString(16);
|
|
770
|
+
return result;
|
|
771
|
+
}
|
|
772
|
+
function captureIdentifiers(state, path) {
|
|
773
|
+
path.traverse({
|
|
774
|
+
ImportDeclaration(p) {
|
|
775
|
+
if (p.node.importKind === 'value') {
|
|
776
|
+
registerImportSpecifiers(state, p, state.specifiers);
|
|
777
|
+
}
|
|
778
|
+
},
|
|
779
|
+
});
|
|
490
780
|
}
|
|
491
781
|
function checkValidRenderCall(path) {
|
|
492
782
|
let currentPath = path.parentPath;
|
|
@@ -504,7 +794,7 @@ function checkValidRenderCall(path) {
|
|
|
504
794
|
function fixRenderCalls(state, path) {
|
|
505
795
|
path.traverse({
|
|
506
796
|
ExpressionStatement(p) {
|
|
507
|
-
const trueCallExpr =
|
|
797
|
+
const trueCallExpr = unwrapNode(p.node.expression, t.isCallExpression);
|
|
508
798
|
if (trueCallExpr &&
|
|
509
799
|
checkValidRenderCall(p) &&
|
|
510
800
|
isValidCallee(state, p, trueCallExpr, 'render')) {
|
|
@@ -525,7 +815,7 @@ function wrapComponent(state, path, identifier, component, original = component)
|
|
|
525
815
|
if (statementPath) {
|
|
526
816
|
const registry = createRegistry(state, statementPath);
|
|
527
817
|
const hotName = t.stringLiteral(identifier.name);
|
|
528
|
-
const componentCall =
|
|
818
|
+
const componentCall = getImportIdentifier(state, statementPath, IMPORT_COMPONENT);
|
|
529
819
|
const properties = [];
|
|
530
820
|
if (state.filename && original.loc) {
|
|
531
821
|
const filePath = getFile(state.filename);
|
|
@@ -533,7 +823,7 @@ function wrapComponent(state, path, identifier, component, original = component)
|
|
|
533
823
|
}
|
|
534
824
|
if (state.granular) {
|
|
535
825
|
properties.push(t.objectProperty(t.identifier('signature'), t.stringLiteral(createSignatureValue(component))));
|
|
536
|
-
const dependencies =
|
|
826
|
+
const dependencies = getForeignBindings(path);
|
|
537
827
|
if (dependencies.length) {
|
|
538
828
|
const dependencyKeys = [];
|
|
539
829
|
let id;
|
|
@@ -543,18 +833,12 @@ function wrapComponent(state, path, identifier, component, original = component)
|
|
|
543
833
|
}
|
|
544
834
|
properties.push(t.objectProperty(t.identifier('dependencies'), t.arrowFunctionExpression([], t.objectExpression(dependencyKeys))));
|
|
545
835
|
}
|
|
546
|
-
return t.callExpression(componentCall, [
|
|
547
|
-
registry,
|
|
548
|
-
hotName,
|
|
549
|
-
component,
|
|
550
|
-
t.objectExpression(properties),
|
|
551
|
-
]);
|
|
552
836
|
}
|
|
553
837
|
return t.callExpression(componentCall, [
|
|
554
838
|
registry,
|
|
555
839
|
hotName,
|
|
556
840
|
component,
|
|
557
|
-
|
|
841
|
+
t.objectExpression(properties),
|
|
558
842
|
]);
|
|
559
843
|
}
|
|
560
844
|
return component;
|
|
@@ -564,21 +848,15 @@ function wrapContext(state, path, identifier, context) {
|
|
|
564
848
|
if (statementPath) {
|
|
565
849
|
const registry = createRegistry(state, statementPath);
|
|
566
850
|
const hotName = t.stringLiteral(identifier.name);
|
|
567
|
-
const contextCall =
|
|
851
|
+
const contextCall = getImportIdentifier(state, statementPath, IMPORT_CONTEXT);
|
|
568
852
|
return t.callExpression(contextCall, [registry, hotName, context]);
|
|
569
853
|
}
|
|
570
854
|
return context;
|
|
571
855
|
}
|
|
572
|
-
function setupProgram(state, path) {
|
|
573
|
-
var _a;
|
|
856
|
+
function setupProgram(state, path, comments) {
|
|
574
857
|
let shouldSkip = false;
|
|
575
|
-
const comments = state.file.ast.comments;
|
|
576
858
|
if (comments) {
|
|
577
859
|
for (const { value: comment } of comments) {
|
|
578
|
-
if (/^\s*@refresh granular\s*$/.test(comment)) {
|
|
579
|
-
state.granular = true;
|
|
580
|
-
break;
|
|
581
|
-
}
|
|
582
860
|
if (/^\s*@refresh skip\s*$/.test(comment)) {
|
|
583
861
|
state.processed = true;
|
|
584
862
|
shouldSkip = true;
|
|
@@ -592,39 +870,20 @@ function setupProgram(state, path) {
|
|
|
592
870
|
}
|
|
593
871
|
}
|
|
594
872
|
captureIdentifiers(state, path);
|
|
595
|
-
if (!shouldSkip &&
|
|
873
|
+
if (!shouldSkip && state.fixRender) {
|
|
596
874
|
fixRenderCalls(state, path);
|
|
597
875
|
}
|
|
598
876
|
}
|
|
599
|
-
function transformExportNamedDeclaration(state, path) {
|
|
600
|
-
if (state.processed) {
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
|
-
const decl = path.node.declaration;
|
|
604
|
-
// Check if declaration is FunctionDeclaration
|
|
605
|
-
if (t.isFunctionDeclaration(decl) &&
|
|
606
|
-
!(decl.generator || decl.async) &&
|
|
607
|
-
// Might be component-like, but the only valid components
|
|
608
|
-
// have zero or one parameter
|
|
609
|
-
decl.params.length < 2) {
|
|
610
|
-
// Check if the declaration has an identifier, and then check
|
|
611
|
-
// if the name is component-ish
|
|
612
|
-
if (decl.id && isComponentishName(decl.id.name)) {
|
|
613
|
-
path.node.declaration = t.variableDeclaration('const', [
|
|
614
|
-
t.variableDeclarator(decl.id, wrapComponent(state, path, decl.id, t.functionExpression(decl.id, decl.params, decl.body), decl)),
|
|
615
|
-
]);
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
}
|
|
619
877
|
function isStatementTopLevel(path) {
|
|
878
|
+
let blockParent = path.scope.getBlockParent();
|
|
620
879
|
const programParent = path.scope.getProgramParent();
|
|
621
|
-
|
|
880
|
+
// a FunctionDeclaration binding refers to itself as the block parent
|
|
881
|
+
if (blockParent.path === path) {
|
|
882
|
+
blockParent = blockParent.parent;
|
|
883
|
+
}
|
|
622
884
|
return programParent === blockParent;
|
|
623
885
|
}
|
|
624
886
|
function transformVariableDeclarator(state, path) {
|
|
625
|
-
if (state.processed) {
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
887
|
if (path.parentPath.isVariableDeclaration() &&
|
|
629
888
|
!isStatementTopLevel(path.parentPath)) {
|
|
630
889
|
return;
|
|
@@ -635,8 +894,8 @@ function transformVariableDeclarator(state, path) {
|
|
|
635
894
|
return;
|
|
636
895
|
}
|
|
637
896
|
if (isComponentishName(identifier.name)) {
|
|
638
|
-
const trueFuncExpr =
|
|
639
|
-
|
|
897
|
+
const trueFuncExpr = unwrapNode(init, t.isFunctionExpression) ||
|
|
898
|
+
unwrapNode(init, t.isArrowFunctionExpression);
|
|
640
899
|
// Check for valid FunctionExpression or ArrowFunctionExpression
|
|
641
900
|
if (trueFuncExpr &&
|
|
642
901
|
// Must not be async or generator
|
|
@@ -648,73 +907,111 @@ function transformVariableDeclarator(state, path) {
|
|
|
648
907
|
}
|
|
649
908
|
}
|
|
650
909
|
// For `createContext` calls
|
|
651
|
-
const trueCallExpr =
|
|
910
|
+
const trueCallExpr = unwrapNode(init, t.isCallExpression);
|
|
652
911
|
if (trueCallExpr &&
|
|
653
912
|
isValidCallee(state, path, trueCallExpr, 'createContext')) {
|
|
654
913
|
path.node.init = wrapContext(state, path, identifier, trueCallExpr);
|
|
655
914
|
}
|
|
915
|
+
path.skip();
|
|
916
|
+
}
|
|
917
|
+
function transformFunctionDeclaration(state, path) {
|
|
918
|
+
if (isStatementTopLevel(path)) {
|
|
919
|
+
const decl = path.node;
|
|
920
|
+
// Check if declaration is FunctionDeclaration
|
|
921
|
+
if (
|
|
922
|
+
// Check if the declaration has an identifier, and then check
|
|
923
|
+
decl.id &&
|
|
924
|
+
// if the name is component-ish
|
|
925
|
+
isComponentishName(decl.id.name) &&
|
|
926
|
+
!(decl.generator || decl.async) &&
|
|
927
|
+
// Might be component-like, but the only valid components
|
|
928
|
+
// have zero or one parameter
|
|
929
|
+
decl.params.length < 2) {
|
|
930
|
+
path.replaceWith(t.variableDeclaration('const', [
|
|
931
|
+
t.variableDeclarator(decl.id, wrapComponent(state, path, decl.id, t.functionExpression(decl.id, decl.params, decl.body), decl)),
|
|
932
|
+
]));
|
|
933
|
+
path.skip();
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
function bubbleFunctionDeclaration(program, path) {
|
|
938
|
+
if (isStatementTopLevel(path)) {
|
|
939
|
+
const decl = path.node;
|
|
940
|
+
// Check if declaration is FunctionDeclaration
|
|
941
|
+
if (
|
|
942
|
+
// Check if the declaration has an identifier, and then check
|
|
943
|
+
decl.id &&
|
|
944
|
+
// if the name is component-ish
|
|
945
|
+
isComponentishName(decl.id.name) &&
|
|
946
|
+
!(decl.generator || decl.async) &&
|
|
947
|
+
// Might be component-like, but the only valid components
|
|
948
|
+
// have zero or one parameter
|
|
949
|
+
decl.params.length < 2) {
|
|
950
|
+
const first = program.get('body')[0];
|
|
951
|
+
const [tmp] = first.insertBefore(decl);
|
|
952
|
+
tmp.skip();
|
|
953
|
+
if (path.parentPath.isExportNamedDeclaration()) {
|
|
954
|
+
path.parentPath.replaceWith(t.exportNamedDeclaration(undefined, [
|
|
955
|
+
t.exportSpecifier(decl.id, decl.id),
|
|
956
|
+
]));
|
|
957
|
+
}
|
|
958
|
+
else if (path.parentPath.isExportDefaultDeclaration()) {
|
|
959
|
+
path.replaceWith(decl.id);
|
|
960
|
+
}
|
|
961
|
+
else {
|
|
962
|
+
path.remove();
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
656
966
|
}
|
|
657
967
|
function solidRefreshPlugin() {
|
|
658
968
|
return {
|
|
659
|
-
name: '
|
|
660
|
-
pre() {
|
|
661
|
-
this.hooks = new Map();
|
|
662
|
-
this.processed = false;
|
|
663
|
-
this.granular = false;
|
|
664
|
-
this.registrations = {
|
|
665
|
-
identifiers: new Map(),
|
|
666
|
-
namespaces: new Map(),
|
|
667
|
-
};
|
|
668
|
-
this.imports = [...IMPORT_IDENTITIES, ...(this.opts.imports || [])];
|
|
669
|
-
},
|
|
969
|
+
name: 'solid-refresh',
|
|
670
970
|
visitor: {
|
|
671
|
-
Program(programPath,
|
|
672
|
-
|
|
971
|
+
Program(programPath, context) {
|
|
972
|
+
var _a, _b;
|
|
973
|
+
const state = {
|
|
974
|
+
granular: (_a = context.opts.granular) !== null && _a !== void 0 ? _a : true,
|
|
975
|
+
opts: context.opts,
|
|
976
|
+
specifiers: [...IMPORT_SPECIFIERS],
|
|
977
|
+
imports: new Map(),
|
|
978
|
+
registrations: {
|
|
979
|
+
identifiers: new Map(),
|
|
980
|
+
namespaces: new Map(),
|
|
981
|
+
},
|
|
982
|
+
processed: false,
|
|
983
|
+
filename: context.filename,
|
|
984
|
+
bundler: context.opts.bundler || 'standard',
|
|
985
|
+
fixRender: (_b = context.opts.fixRender) !== null && _b !== void 0 ? _b : true,
|
|
986
|
+
};
|
|
987
|
+
setupProgram(state, programPath, context.file.ast.comments);
|
|
988
|
+
if (state.processed) {
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
673
991
|
programPath.traverse({
|
|
674
|
-
|
|
675
|
-
|
|
992
|
+
FunctionDeclaration(path) {
|
|
993
|
+
bubbleFunctionDeclaration(programPath, path);
|
|
676
994
|
},
|
|
995
|
+
});
|
|
996
|
+
programPath.scope.crawl();
|
|
997
|
+
programPath.traverse({
|
|
998
|
+
JSXElement(path) {
|
|
999
|
+
transformJSX(path);
|
|
1000
|
+
},
|
|
1001
|
+
JSXFragment(path) {
|
|
1002
|
+
transformJSX(path);
|
|
1003
|
+
},
|
|
1004
|
+
});
|
|
1005
|
+
programPath.scope.crawl();
|
|
1006
|
+
programPath.traverse({
|
|
677
1007
|
VariableDeclarator(path) {
|
|
678
1008
|
transformVariableDeclarator(state, path);
|
|
679
1009
|
},
|
|
680
1010
|
FunctionDeclaration(path) {
|
|
681
|
-
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
|
-
if (path.parentPath.isProgram() ||
|
|
685
|
-
path.parentPath.isExportDefaultDeclaration()) {
|
|
686
|
-
const decl = path.node;
|
|
687
|
-
// Check if declaration is FunctionDeclaration
|
|
688
|
-
if (
|
|
689
|
-
// Check if the declaration has an identifier, and then check
|
|
690
|
-
decl.id &&
|
|
691
|
-
// if the name is component-ish
|
|
692
|
-
isComponentishName(decl.id.name) &&
|
|
693
|
-
!(decl.generator || decl.async) &&
|
|
694
|
-
// Might be component-like, but the only valid components
|
|
695
|
-
// have zero or one parameter
|
|
696
|
-
decl.params.length < 2) {
|
|
697
|
-
const replacement = wrapComponent(state, path, decl.id, t.functionExpression(decl.id, decl.params, decl.body), decl);
|
|
698
|
-
const newDecl = t.variableDeclaration('var', [
|
|
699
|
-
t.variableDeclarator(decl.id, replacement),
|
|
700
|
-
]);
|
|
701
|
-
if (path.parentPath.isExportDefaultDeclaration()) {
|
|
702
|
-
const parent = path.parentPath
|
|
703
|
-
.parentPath;
|
|
704
|
-
const first = parent.get('body')[0];
|
|
705
|
-
first.insertBefore(newDecl);
|
|
706
|
-
path.replaceWith(decl.id);
|
|
707
|
-
}
|
|
708
|
-
else {
|
|
709
|
-
const parent = path.parentPath;
|
|
710
|
-
const first = parent.get('body')[0];
|
|
711
|
-
first.insertBefore(newDecl);
|
|
712
|
-
path.remove();
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
}
|
|
1011
|
+
transformFunctionDeclaration(state, path);
|
|
716
1012
|
},
|
|
717
1013
|
});
|
|
1014
|
+
programPath.scope.crawl();
|
|
718
1015
|
},
|
|
719
1016
|
},
|
|
720
1017
|
};
|