16
EnvironmentConfig,
17
ExternalFunction,
18
ReactFunctionType,
19
+ MINIMAL_RETRY_CONFIG,
20
tryParseExternalFunction,
21
} from '../HIR/Environment';
22
import {CodegenFunction} from '../ReactiveScopes';
383
);
384
}
385
385
- let compiledFn: CodegenFunction;
386
- try {
387
- /**
388
- * Note that Babel does not attach comment nodes to nodes; they are dangling off of the
389
- * Program node itself. We need to figure out whether an eslint suppression range
390
- * applies to this function first.
391
- */
392
- const suppressionsInFunction = filterSuppressionsThatAffectFunction(
393
- suppressions,
394
- fn,
395
- );
396
- if (suppressionsInFunction.length > 0) {
397
- const lintError = suppressionsToCompilerError(suppressionsInFunction);
398
- if (optOutDirectives.length > 0) {
399
- logError(lintError, pass, fn.node.loc ?? null);
400
- } else {
401
- handleError(lintError, pass, fn.node.loc ?? null);
402
- }
403
- return null;
386
+ /**
387
+ * Note that Babel does not attach comment nodes to nodes; they are dangling off of the
388
+ * Program node itself. We need to figure out whether an eslint suppression range
389
+ * applies to this function first.
390
+ */
391
+ const suppressionsInFunction = filterSuppressionsThatAffectFunction(
392
+ suppressions,
393
+ fn,
394
+ );
395
+ let compileResult:
396
+ | {kind: 'compile'; compiledFn: CodegenFunction}
397
+ | {kind: 'error'; error: unknown};
398
+ if (suppressionsInFunction.length > 0) {
399
+ compileResult = {
400
+ kind: 'error',
401
+ error: suppressionsToCompilerError(suppressionsInFunction),
402
+ };
403
+ } else {
404
+ try {
405
+ compileResult = {
406
+ kind: 'compile',
407
+ compiledFn: compileFn(
408
+ fn,
409
+ environment,
410
+ fnType,
411
+ useMemoCacheIdentifier.name,
412
+ pass.opts.logger,
413
+ pass.filename,
414
+ pass.code,
415
+ ),
416
+ };
417
+ } catch (err) {
418
+ compileResult = {kind: 'error', error: err};
419
}
405
-
406
- compiledFn = compileFn(
407
- fn,
408
- environment,
409
- fnType,
410
- useMemoCacheIdentifier.name,
411
- pass.opts.logger,
412
- pass.filename,
413
- pass.code,
414
- );
415
- pass.opts.logger?.logEvent(pass.filename, {
416
- kind: 'CompileSuccess',
417
- fnLoc: fn.node.loc ?? null,
418
- fnName: compiledFn.id?.name ?? null,
419
- memoSlots: compiledFn.memoSlotsUsed,
420
- memoBlocks: compiledFn.memoBlocks,
421
- memoValues: compiledFn.memoValues,
422
- prunedMemoBlocks: compiledFn.prunedMemoBlocks,
423
- prunedMemoValues: compiledFn.prunedMemoValues,
424
- });
425
- } catch (err) {
420
+ }
421
+ // If non-memoization features are enabled, retry regardless of error kind
422
+ if (compileResult.kind === 'error' && environment.enableFire) {
423
+ try {
424
+ compileResult = {
425
+ kind: 'compile',
426
+ compiledFn: compileFn(
427
+ fn,
428
+ {
429
+ ...environment,
430
+ ...MINIMAL_RETRY_CONFIG,
431
+ },
432
+ fnType,
433
+ useMemoCacheIdentifier.name,
434
+ pass.opts.logger,
435
+ pass.filename,
436
+ pass.code,
437
+ ),
438
+ };
439
+ } catch (err) {
440
+ compileResult = {kind: 'error', error: err};
441
+ }
442
+ }
443
+ if (compileResult.kind === 'error') {
444
/**
445
* If an opt out directive is present, log only instead of throwing and don't mark as
446
* containing a critical error.
447
*/
430
- if (fn.node.body.type === 'BlockStatement') {
431
- if (optOutDirectives.length > 0) {
432
- logError(err, pass, fn.node.loc ?? null);
433
- return null;
434
- }
448
+ if (optOutDirectives.length > 0) {
449
+ logError(compileResult.error, pass, fn.node.loc ?? null);
450
+ } else {
451
+ handleError(compileResult.error, pass, fn.node.loc ?? null);
452
}
436
- handleError(err, pass, fn.node.loc ?? null);
453
return null;
454
}
455
456
+ pass.opts.logger?.logEvent(pass.filename, {
457
+ kind: 'CompileSuccess',
458
+ fnLoc: fn.node.loc ?? null,
459
+ fnName: compileResult.compiledFn.id?.name ?? null,
460
+ memoSlots: compileResult.compiledFn.memoSlotsUsed,
461
+ memoBlocks: compileResult.compiledFn.memoBlocks,
462
+ memoValues: compileResult.compiledFn.memoValues,
463
+ prunedMemoBlocks: compileResult.compiledFn.prunedMemoBlocks,
464
+ prunedMemoValues: compileResult.compiledFn.prunedMemoValues,
465
+ });
466
+
467
/**
468
* Always compile functions with opt in directives.
469
*/
470
if (optInDirectives.length > 0) {
444
- return compiledFn;
471
+ return compileResult.compiledFn;
472
} else if (pass.opts.compilationMode === 'annotation') {
473
/**
474
* No opt-in directive in annotation mode, so don't insert the compiled function.
494
}
495
496
if (!pass.opts.noEmit) {
470
- return compiledFn;
497
+ return compileResult.compiledFn;
498
}
499
return null;
500
};