babel-plugin-react-compiler 0.0.0-experimental-c134c19-20250508 → 0.0.0-experimental-ccdb475-20250509

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.
Files changed (3) hide show
  1. package/dist/index.d.ts +46 -20
  2. package/dist/index.js +276 -173
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1627,22 +1627,6 @@ type Logger = {
1627
1627
  };
1628
1628
  declare function parsePluginOptions(obj: unknown): PluginOptions;
1629
1629
 
1630
- declare class ProgramContext {
1631
- scope: Scope;
1632
- reactRuntimeModule: string;
1633
- hookPattern: string | null;
1634
- knownReferencedNames: Set<string>;
1635
- imports: Map<string, Map<string, NonLocalImportSpecifier>>;
1636
- constructor(program: NodePath$1<t.Program>, reactRuntimeModule: CompilerReactTarget, hookPattern: string | null);
1637
- isHookName(name: string): boolean;
1638
- hasReference(name: string): boolean;
1639
- newUid(name: string): string;
1640
- addMemoCacheImport(): NonLocalImportSpecifier;
1641
- addImportSpecifier({ source: module, importSpecifierName: specifier }: ExternalFunction, nameHint?: string): NonLocalImportSpecifier;
1642
- addNewReference(name: string): void;
1643
- assertGlobalBinding(name: string, localScope?: Scope): Result<void, CompilerError>;
1644
- }
1645
-
1646
1630
  type CompilerPass = {
1647
1631
  opts: PluginOptions;
1648
1632
  filename: string | null;
@@ -1651,17 +1635,59 @@ type CompilerPass = {
1651
1635
  };
1652
1636
  declare const OPT_IN_DIRECTIVES: Set<string>;
1653
1637
  declare const OPT_OUT_DIRECTIVES: Set<string>;
1654
- declare function findDirectiveEnablingMemoization(directives: Array<t.Directive>): Array<t.Directive>;
1655
- declare function findDirectiveDisablingMemoization(directives: Array<t.Directive>): Array<t.Directive>;
1638
+ declare function findDirectiveEnablingMemoization(directives: Array<t.Directive>): t.Directive | null;
1639
+ declare function findDirectiveDisablingMemoization(directives: Array<t.Directive>): t.Directive | null;
1656
1640
  type BabelFn = NodePath$1<t.FunctionDeclaration> | NodePath$1<t.FunctionExpression> | NodePath$1<t.ArrowFunctionExpression>;
1657
- type CompileProgramResult = {
1641
+ type CompileProgramMetadata = {
1658
1642
  retryErrors: Array<{
1659
1643
  fn: BabelFn;
1660
1644
  error: CompilerError;
1661
1645
  }>;
1662
1646
  inferredEffectLocations: Set<t.SourceLocation>;
1663
1647
  };
1664
- declare function compileProgram(program: NodePath$1<t.Program>, pass: CompilerPass): CompileProgramResult | null;
1648
+ declare function compileProgram(program: NodePath$1<t.Program>, pass: CompilerPass): CompileProgramMetadata | null;
1649
+
1650
+ type SuppressionRange = {
1651
+ disableComment: t.Comment;
1652
+ enableComment: t.Comment | null;
1653
+ source: SuppressionSource;
1654
+ };
1655
+ type SuppressionSource = 'Eslint' | 'Flow';
1656
+
1657
+ type ProgramContextOptions = {
1658
+ program: NodePath$1<t.Program>;
1659
+ suppressions: Array<SuppressionRange>;
1660
+ opts: PluginOptions;
1661
+ filename: string | null;
1662
+ code: string | null;
1663
+ hasModuleScopeOptOut: boolean;
1664
+ };
1665
+ declare class ProgramContext {
1666
+ scope: Scope;
1667
+ opts: PluginOptions;
1668
+ filename: string | null;
1669
+ code: string | null;
1670
+ reactRuntimeModule: string;
1671
+ suppressions: Array<SuppressionRange>;
1672
+ hasModuleScopeOptOut: boolean;
1673
+ alreadyCompiled: WeakSet<object> | Set<object>;
1674
+ knownReferencedNames: Set<string>;
1675
+ imports: Map<string, Map<string, NonLocalImportSpecifier>>;
1676
+ retryErrors: Array<{
1677
+ fn: BabelFn;
1678
+ error: CompilerError;
1679
+ }>;
1680
+ inferredEffectLocations: Set<t.SourceLocation>;
1681
+ constructor({ program, suppressions, opts, filename, code, hasModuleScopeOptOut, }: ProgramContextOptions);
1682
+ isHookName(name: string): boolean;
1683
+ hasReference(name: string): boolean;
1684
+ newUid(name: string): string;
1685
+ addMemoCacheImport(): NonLocalImportSpecifier;
1686
+ addImportSpecifier({ source: module, importSpecifierName: specifier }: ExternalFunction, nameHint?: string): NonLocalImportSpecifier;
1687
+ addNewReference(name: string): void;
1688
+ assertGlobalBinding(name: string, localScope?: Scope): Result<void, CompilerError>;
1689
+ logEvent(event: LoggerEvent): void;
1690
+ }
1665
1691
 
1666
1692
  declare function runBabelPluginReactCompiler(text: string, file: string, language: 'flow' | 'typescript', options: Partial<PluginOptions> | null, includeAst?: boolean): BabelCore.BabelFileResult;
1667
1693
 
package/dist/index.js CHANGED
@@ -80158,6 +80158,49 @@ function evaluateInstruction(constants, instr) {
80158
80158
  }
80159
80159
  return null;
80160
80160
  }
80161
+ case "TemplateLiteral": {
80162
+ if (value.subexprs.length === 0) {
80163
+ const result2 = {
80164
+ kind: "Primitive",
80165
+ value: value.quasis.map((q) => q.cooked).join(""),
80166
+ loc: value.loc
80167
+ };
80168
+ instr.value = result2;
80169
+ return result2;
80170
+ }
80171
+ if (value.subexprs.length !== value.quasis.length - 1) {
80172
+ return null;
80173
+ }
80174
+ if (value.quasis.some((q) => q.cooked === void 0)) {
80175
+ return null;
80176
+ }
80177
+ let quasiIndex = 0;
80178
+ let resultString = value.quasis[quasiIndex].cooked;
80179
+ ++quasiIndex;
80180
+ for (const subExpr of value.subexprs) {
80181
+ const subExprValue = read2(constants, subExpr);
80182
+ if (!subExprValue || subExprValue.kind !== "Primitive") {
80183
+ return null;
80184
+ }
80185
+ const expressionValue = subExprValue.value;
80186
+ if (typeof expressionValue !== "number" && typeof expressionValue !== "string" && typeof expressionValue !== "boolean" && !(typeof expressionValue === "object" && expressionValue === null)) {
80187
+ return null;
80188
+ }
80189
+ const suffix = value.quasis[quasiIndex].cooked;
80190
+ ++quasiIndex;
80191
+ if (suffix === void 0) {
80192
+ return null;
80193
+ }
80194
+ resultString = resultString.concat(expressionValue, suffix);
80195
+ }
80196
+ const result = {
80197
+ kind: "Primitive",
80198
+ value: resultString,
80199
+ loc: value.loc
80200
+ };
80201
+ instr.value = result;
80202
+ return result;
80203
+ }
80161
80204
  case "LoadLocal": {
80162
80205
  const placeValue = read2(constants, value.place);
80163
80206
  if (placeValue !== null) {
@@ -97007,14 +97050,16 @@ function suppressionsToCompilerError(suppressionRanges) {
97007
97050
  var OPT_IN_DIRECTIVES = /* @__PURE__ */ new Set(["use forget", "use memo"]);
97008
97051
  var OPT_OUT_DIRECTIVES = /* @__PURE__ */ new Set(["use no forget", "use no memo"]);
97009
97052
  function findDirectiveEnablingMemoization(directives) {
97010
- return directives.filter(
97053
+ var _a;
97054
+ return (_a = directives.find(
97011
97055
  (directive2) => OPT_IN_DIRECTIVES.has(directive2.value.value)
97012
- );
97056
+ )) != null ? _a : null;
97013
97057
  }
97014
97058
  function findDirectiveDisablingMemoization(directives) {
97015
- return directives.filter(
97059
+ var _a;
97060
+ return (_a = directives.find(
97016
97061
  (directive2) => OPT_OUT_DIRECTIVES.has(directive2.value.value)
97017
- );
97062
+ )) != null ? _a : null;
97018
97063
  }
97019
97064
  function isCriticalError(err) {
97020
97065
  return !(err instanceof CompilerError) || err.isCritical();
@@ -97027,12 +97072,12 @@ function isConfigError(err) {
97027
97072
  }
97028
97073
  return false;
97029
97074
  }
97030
- function logError(err, pass, fnLoc) {
97075
+ function logError(err, context, fnLoc) {
97031
97076
  var _a, _b;
97032
- if (pass.opts.logger) {
97077
+ if (context.opts.logger) {
97033
97078
  if (err instanceof CompilerError) {
97034
97079
  for (const detail of err.details) {
97035
- pass.opts.logger.logEvent(pass.filename, {
97080
+ context.opts.logger.logEvent(context.filename, {
97036
97081
  kind: "CompileError",
97037
97082
  fnLoc,
97038
97083
  detail: detail.options
@@ -97045,7 +97090,7 @@ function logError(err, pass, fnLoc) {
97045
97090
  } else {
97046
97091
  stringifiedError = (_b = err == null ? void 0 : err.toString()) != null ? _b : "[ null ]";
97047
97092
  }
97048
- pass.opts.logger.logEvent(pass.filename, {
97093
+ context.opts.logger.logEvent(context.filename, {
97049
97094
  kind: "PipelineError",
97050
97095
  fnLoc,
97051
97096
  data: stringifiedError
@@ -97053,9 +97098,9 @@ function logError(err, pass, fnLoc) {
97053
97098
  }
97054
97099
  }
97055
97100
  }
97056
- function handleError(err, pass, fnLoc) {
97057
- logError(err, pass, fnLoc);
97058
- if (pass.opts.panicThreshold === "all_errors" || pass.opts.panicThreshold === "critical_errors" && isCriticalError(err) || isConfigError(err)) {
97101
+ function handleError(err, context, fnLoc) {
97102
+ logError(err, context, fnLoc);
97103
+ if (context.opts.panicThreshold === "all_errors" || context.opts.panicThreshold === "critical_errors" && isCriticalError(err) || isConfigError(err)) {
97059
97104
  throw err;
97060
97105
  }
97061
97106
  }
@@ -97109,7 +97154,6 @@ function createNewFunctionNode(originalFn, compiledFn) {
97109
97154
  );
97110
97155
  }
97111
97156
  }
97112
- ALREADY_COMPILED.add(transformedFn);
97113
97157
  return transformedFn;
97114
97158
  }
97115
97159
  function insertNewOutlinedFunctionNode(program, originalFn, compiledFn) {
@@ -97156,7 +97200,6 @@ function insertNewOutlinedFunctionNode(program, originalFn, compiledFn) {
97156
97200
  }
97157
97201
  }
97158
97202
  }
97159
- var ALREADY_COMPILED = new (WeakSet != null ? WeakSet : Set)();
97160
97203
  var DEFAULT_ESLINT_SUPPRESSIONS = [
97161
97204
  "react-hooks/exhaustive-deps",
97162
97205
  "react-hooks/rules-of-hooks"
@@ -97173,34 +97216,97 @@ function isFilePartOfSources(sources, filename) {
97173
97216
  return false;
97174
97217
  }
97175
97218
  function compileProgram(program, pass) {
97176
- var _a, _b;
97219
+ var _a;
97177
97220
  if (shouldSkipCompilation(program, pass)) {
97178
97221
  return null;
97179
97222
  }
97180
- const environment = pass.opts.environment;
97181
- const restrictedImportsErr = validateRestrictedImports(program, environment);
97223
+ const restrictedImportsErr = validateRestrictedImports(
97224
+ program,
97225
+ pass.opts.environment
97226
+ );
97182
97227
  if (restrictedImportsErr) {
97183
97228
  handleError(restrictedImportsErr, pass, null);
97184
97229
  return null;
97185
97230
  }
97186
- const programContext = new ProgramContext(
97187
- program,
97188
- pass.opts.target,
97189
- environment.hookPattern
97190
- );
97191
97231
  const suppressions = findProgramSuppressions(
97192
97232
  pass.comments,
97193
97233
  (_a = pass.opts.eslintSuppressionRules) != null ? _a : DEFAULT_ESLINT_SUPPRESSIONS,
97194
97234
  pass.opts.flowSuppressions
97195
97235
  );
97196
- const queue = [];
97236
+ const programContext = new ProgramContext({
97237
+ program,
97238
+ opts: pass.opts,
97239
+ filename: pass.filename,
97240
+ code: pass.code,
97241
+ suppressions,
97242
+ hasModuleScopeOptOut: findDirectiveDisablingMemoization(program.node.directives) != null
97243
+ });
97244
+ const queue = findFunctionsToCompile(
97245
+ program,
97246
+ pass,
97247
+ programContext
97248
+ );
97197
97249
  const compiledFns = [];
97250
+ while (queue.length !== 0) {
97251
+ const current = queue.shift();
97252
+ const compiled = processFn(current.fn, current.fnType, programContext);
97253
+ if (compiled != null) {
97254
+ for (const outlined of compiled.outlined) {
97255
+ CompilerError.invariant(outlined.fn.outlined.length === 0, {
97256
+ reason: "Unexpected nested outlined functions",
97257
+ loc: outlined.fn.loc
97258
+ });
97259
+ const fn = insertNewOutlinedFunctionNode(
97260
+ program,
97261
+ current.fn,
97262
+ outlined.fn
97263
+ );
97264
+ fn.skip();
97265
+ programContext.alreadyCompiled.add(fn.node);
97266
+ if (outlined.type !== null) {
97267
+ queue.push({
97268
+ kind: "outlined",
97269
+ fn,
97270
+ fnType: outlined.type
97271
+ });
97272
+ }
97273
+ }
97274
+ compiledFns.push({
97275
+ kind: current.kind,
97276
+ originalFn: current.fn,
97277
+ compiledFn: compiled
97278
+ });
97279
+ }
97280
+ }
97281
+ if (programContext.hasModuleScopeOptOut) {
97282
+ if (compiledFns.length > 0) {
97283
+ const error = new CompilerError();
97284
+ error.pushErrorDetail(
97285
+ new CompilerErrorDetail({
97286
+ reason: "Unexpected compiled functions when module scope opt-out is present",
97287
+ severity: "Invariant" /* Invariant */,
97288
+ loc: null
97289
+ })
97290
+ );
97291
+ handleError(error, programContext, null);
97292
+ }
97293
+ return null;
97294
+ }
97295
+ applyCompiledFunctions(program, compiledFns, pass, programContext);
97296
+ return {
97297
+ retryErrors: programContext.retryErrors,
97298
+ inferredEffectLocations: programContext.inferredEffectLocations
97299
+ };
97300
+ }
97301
+ function findFunctionsToCompile(program, pass, programContext) {
97302
+ var _a;
97303
+ const queue = [];
97198
97304
  const traverseFunction2 = (fn, pass2) => {
97199
- const fnType = getReactFunctionType(fn, pass2, environment);
97200
- if (fnType === null || ALREADY_COMPILED.has(fn.node)) {
97305
+ const fnType = getReactFunctionType(fn, pass2);
97306
+ if (fnType === null || programContext.alreadyCompiled.has(fn.node)) {
97201
97307
  return;
97202
97308
  }
97203
- ALREADY_COMPILED.add(fn.node);
97309
+ programContext.alreadyCompiled.add(fn.node);
97204
97310
  fn.skip();
97205
97311
  queue.push({ kind: "original", fn, fnType });
97206
97312
  };
@@ -97208,11 +97314,9 @@ function compileProgram(program, pass) {
97208
97314
  {
97209
97315
  ClassDeclaration(node) {
97210
97316
  node.skip();
97211
- return;
97212
97317
  },
97213
97318
  ClassExpression(node) {
97214
97319
  node.skip();
97215
- return;
97216
97320
  },
97217
97321
  FunctionDeclaration: traverseFunction2,
97218
97322
  FunctionExpression: traverseFunction2,
@@ -97220,161 +97324,134 @@ function compileProgram(program, pass) {
97220
97324
  },
97221
97325
  __spreadProps(__spreadValues({}, pass), {
97222
97326
  opts: __spreadValues(__spreadValues({}, pass.opts), pass.opts),
97223
- filename: (_b = pass.filename) != null ? _b : null
97327
+ filename: (_a = pass.filename) != null ? _a : null
97224
97328
  })
97225
97329
  );
97226
- const retryErrors = [];
97227
- const inferredEffectLocations = /* @__PURE__ */ new Set();
97228
- const processFn = (fn, fnType) => {
97229
- var _a2, _b2, _c, _d, _e, _f, _g, _h, _i;
97230
- let optInDirectives = [];
97231
- let optOutDirectives = [];
97232
- if (fn.node.body.type === "BlockStatement") {
97233
- optInDirectives = findDirectiveEnablingMemoization(
97234
- fn.node.body.directives
97235
- );
97236
- optOutDirectives = findDirectiveDisablingMemoization(
97237
- fn.node.body.directives
97238
- );
97239
- }
97240
- const suppressionsInFunction = filterSuppressionsThatAffectFunction(
97241
- suppressions,
97242
- fn
97243
- );
97244
- let compileResult;
97245
- if (suppressionsInFunction.length > 0) {
97246
- compileResult = {
97247
- kind: "error",
97248
- error: suppressionsToCompilerError(suppressionsInFunction)
97249
- };
97330
+ return queue;
97331
+ }
97332
+ function processFn(fn, fnType, programContext) {
97333
+ var _a, _b, _c, _d, _e, _f, _g;
97334
+ let directives;
97335
+ if (fn.node.body.type !== "BlockStatement") {
97336
+ directives = { optIn: null, optOut: null };
97337
+ } else {
97338
+ directives = {
97339
+ optIn: findDirectiveEnablingMemoization(fn.node.body.directives),
97340
+ optOut: findDirectiveDisablingMemoization(fn.node.body.directives)
97341
+ };
97342
+ }
97343
+ let compiledFn;
97344
+ const compileResult = tryCompileFunction(fn, fnType, programContext);
97345
+ if (compileResult.kind === "error") {
97346
+ if (directives.optOut != null) {
97347
+ logError(compileResult.error, programContext, (_a = fn.node.loc) != null ? _a : null);
97250
97348
  } else {
97251
- try {
97252
- compileResult = {
97253
- kind: "compile",
97254
- compiledFn: compileFn(
97255
- fn,
97256
- environment,
97257
- fnType,
97258
- "all_features",
97259
- programContext,
97260
- pass.opts.logger,
97261
- pass.filename,
97262
- pass.code
97263
- )
97264
- };
97265
- } catch (err) {
97266
- compileResult = { kind: "error", error: err };
97267
- }
97268
- }
97269
- if (compileResult.kind === "error") {
97270
- if (optOutDirectives.length > 0) {
97271
- logError(compileResult.error, pass, (_a2 = fn.node.loc) != null ? _a2 : null);
97272
- } else {
97273
- handleError(compileResult.error, pass, (_b2 = fn.node.loc) != null ? _b2 : null);
97274
- }
97275
- if (!(environment.enableFire || environment.inferEffectDependencies != null)) {
97276
- return null;
97277
- }
97278
- try {
97279
- compileResult = {
97280
- kind: "compile",
97281
- compiledFn: compileFn(
97282
- fn,
97283
- environment,
97284
- fnType,
97285
- "no_inferred_memo",
97286
- programContext,
97287
- pass.opts.logger,
97288
- pass.filename,
97289
- pass.code
97290
- )
97291
- };
97292
- if (!compileResult.compiledFn.hasFireRewrite && !compileResult.compiledFn.hasInferredEffect) {
97293
- return null;
97294
- }
97295
- } catch (err) {
97296
- if (err instanceof CompilerError) {
97297
- retryErrors.push({ fn, error: err });
97298
- }
97299
- return null;
97300
- }
97349
+ handleError(compileResult.error, programContext, (_b = fn.node.loc) != null ? _b : null);
97301
97350
  }
97302
- if (pass.opts.ignoreUseNoForget === false && optOutDirectives.length > 0) {
97303
- for (const directive2 of optOutDirectives) {
97304
- (_e = pass.opts.logger) == null ? void 0 : _e.logEvent(pass.filename, {
97305
- kind: "CompileSkip",
97306
- fnLoc: (_c = fn.node.body.loc) != null ? _c : null,
97307
- reason: `Skipped due to '${directive2.value.value}' directive.`,
97308
- loc: (_d = directive2.loc) != null ? _d : null
97309
- });
97310
- }
97351
+ const retryResult = retryCompileFunction(fn, fnType, programContext);
97352
+ if (retryResult == null) {
97311
97353
  return null;
97312
97354
  }
97313
- (_i = pass.opts.logger) == null ? void 0 : _i.logEvent(pass.filename, {
97314
- kind: "CompileSuccess",
97315
- fnLoc: (_f = fn.node.loc) != null ? _f : null,
97316
- fnName: (_h = (_g = compileResult.compiledFn.id) == null ? void 0 : _g.name) != null ? _h : null,
97317
- memoSlots: compileResult.compiledFn.memoSlotsUsed,
97318
- memoBlocks: compileResult.compiledFn.memoBlocks,
97319
- memoValues: compileResult.compiledFn.memoValues,
97320
- prunedMemoBlocks: compileResult.compiledFn.prunedMemoBlocks,
97321
- prunedMemoValues: compileResult.compiledFn.prunedMemoValues
97355
+ compiledFn = retryResult;
97356
+ } else {
97357
+ compiledFn = compileResult.compiledFn;
97358
+ }
97359
+ if (programContext.opts.ignoreUseNoForget === false && directives.optOut != null) {
97360
+ programContext.logEvent({
97361
+ kind: "CompileSkip",
97362
+ fnLoc: (_c = fn.node.body.loc) != null ? _c : null,
97363
+ reason: `Skipped due to '${directives.optOut.value}' directive.`,
97364
+ loc: (_d = directives.optOut.loc) != null ? _d : null
97322
97365
  });
97323
- if (optInDirectives.length > 0) {
97324
- return compileResult.compiledFn;
97325
- } else if (pass.opts.compilationMode === "annotation") {
97326
- return null;
97327
- }
97328
- if (!pass.opts.noEmit) {
97329
- return compileResult.compiledFn;
97330
- }
97331
- for (const loc of compileResult.compiledFn.inferredEffectLocations) {
97332
- if (loc !== GeneratedSource) inferredEffectLocations.add(loc);
97333
- }
97334
97366
  return null;
97335
- };
97336
- while (queue.length !== 0) {
97337
- const current = queue.shift();
97338
- const compiled = processFn(current.fn, current.fnType);
97339
- if (compiled === null) {
97340
- continue;
97341
- }
97342
- for (const outlined of compiled.outlined) {
97343
- CompilerError.invariant(outlined.fn.outlined.length === 0, {
97344
- reason: "Unexpected nested outlined functions",
97345
- loc: outlined.fn.loc
97346
- });
97347
- const fn = insertNewOutlinedFunctionNode(
97348
- program,
97349
- current.fn,
97350
- outlined.fn
97351
- );
97352
- fn.skip();
97353
- ALREADY_COMPILED.add(fn.node);
97354
- if (outlined.type !== null) {
97355
- queue.push({
97356
- kind: "outlined",
97357
- fn,
97358
- fnType: outlined.type
97359
- });
97367
+ }
97368
+ programContext.logEvent({
97369
+ kind: "CompileSuccess",
97370
+ fnLoc: (_e = fn.node.loc) != null ? _e : null,
97371
+ fnName: (_g = (_f = compiledFn.id) == null ? void 0 : _f.name) != null ? _g : null,
97372
+ memoSlots: compiledFn.memoSlotsUsed,
97373
+ memoBlocks: compiledFn.memoBlocks,
97374
+ memoValues: compiledFn.memoValues,
97375
+ prunedMemoBlocks: compiledFn.prunedMemoBlocks,
97376
+ prunedMemoValues: compiledFn.prunedMemoValues
97377
+ });
97378
+ if (programContext.hasModuleScopeOptOut) {
97379
+ return null;
97380
+ } else if (programContext.opts.noEmit) {
97381
+ for (const loc of compiledFn.inferredEffectLocations) {
97382
+ if (loc !== GeneratedSource) {
97383
+ programContext.inferredEffectLocations.add(loc);
97360
97384
  }
97361
97385
  }
97362
- compiledFns.push({
97363
- kind: current.kind,
97364
- compiledFn: compiled,
97365
- originalFn: current.fn
97366
- });
97386
+ return null;
97387
+ } else if (programContext.opts.compilationMode === "annotation" && directives.optIn == null) {
97388
+ return null;
97389
+ } else {
97390
+ return compiledFn;
97367
97391
  }
97368
- const moduleScopeOptOutDirectives = findDirectiveDisablingMemoization(
97369
- program.node.directives
97392
+ }
97393
+ function tryCompileFunction(fn, fnType, programContext) {
97394
+ const suppressionsInFunction = filterSuppressionsThatAffectFunction(
97395
+ programContext.suppressions,
97396
+ fn
97370
97397
  );
97371
- if (moduleScopeOptOutDirectives.length > 0) {
97398
+ if (suppressionsInFunction.length > 0) {
97399
+ return {
97400
+ kind: "error",
97401
+ error: suppressionsToCompilerError(suppressionsInFunction)
97402
+ };
97403
+ }
97404
+ try {
97405
+ return {
97406
+ kind: "compile",
97407
+ compiledFn: compileFn(
97408
+ fn,
97409
+ programContext.opts.environment,
97410
+ fnType,
97411
+ "all_features",
97412
+ programContext,
97413
+ programContext.opts.logger,
97414
+ programContext.filename,
97415
+ programContext.code
97416
+ )
97417
+ };
97418
+ } catch (err) {
97419
+ return { kind: "error", error: err };
97420
+ }
97421
+ }
97422
+ function retryCompileFunction(fn, fnType, programContext) {
97423
+ const environment = programContext.opts.environment;
97424
+ if (!(environment.enableFire || environment.inferEffectDependencies != null)) {
97425
+ return null;
97426
+ }
97427
+ try {
97428
+ const retryResult = compileFn(
97429
+ fn,
97430
+ environment,
97431
+ fnType,
97432
+ "no_inferred_memo",
97433
+ programContext,
97434
+ programContext.opts.logger,
97435
+ programContext.filename,
97436
+ programContext.code
97437
+ );
97438
+ if (!retryResult.hasFireRewrite && !retryResult.hasInferredEffect) {
97439
+ return null;
97440
+ }
97441
+ return retryResult;
97442
+ } catch (err) {
97443
+ if (err instanceof CompilerError) {
97444
+ programContext.retryErrors.push({ fn, error: err });
97445
+ }
97372
97446
  return null;
97373
97447
  }
97448
+ }
97449
+ function applyCompiledFunctions(program, compiledFns, pass, programContext) {
97374
97450
  const referencedBeforeDeclared = pass.opts.gating != null ? getFunctionReferencedBeforeDeclarationAtTopLevel(program, compiledFns) : null;
97375
97451
  for (const result of compiledFns) {
97376
97452
  const { kind, originalFn, compiledFn } = result;
97377
97453
  const transformedFn = createNewFunctionNode(originalFn, compiledFn);
97454
+ programContext.alreadyCompiled.add(transformedFn);
97378
97455
  if (referencedBeforeDeclared != null && kind === "original") {
97379
97456
  CompilerError.invariant(pass.opts.gating != null, {
97380
97457
  reason: "Expected 'gating' import to be present",
@@ -97394,7 +97471,6 @@ function compileProgram(program, pass) {
97394
97471
  if (compiledFns.length > 0) {
97395
97472
  addImportsToProgram(program, programContext);
97396
97473
  }
97397
- return { retryErrors, inferredEffectLocations };
97398
97474
  }
97399
97475
  function shouldSkipCompilation(program, pass) {
97400
97476
  if (pass.opts.sources) {
@@ -97423,11 +97499,11 @@ function shouldSkipCompilation(program, pass) {
97423
97499
  }
97424
97500
  return false;
97425
97501
  }
97426
- function getReactFunctionType(fn, pass, environment) {
97502
+ function getReactFunctionType(fn, pass) {
97427
97503
  var _a, _b;
97428
- const hookPattern = environment.hookPattern;
97504
+ const hookPattern = pass.opts.environment.hookPattern;
97429
97505
  if (fn.node.body.type === "BlockStatement") {
97430
- if (findDirectiveEnablingMemoization(fn.node.body.directives).length > 0)
97506
+ if (findDirectiveEnablingMemoization(fn.node.body.directives) != null)
97431
97507
  return (_a = getComponentOrHookLike(fn, hookPattern)) != null ? _a : "Other";
97432
97508
  }
97433
97509
  let componentSyntaxType = null;
@@ -97757,20 +97833,42 @@ function validateRestrictedImports(path, { validateBlocklistedImports }) {
97757
97833
  }
97758
97834
  }
97759
97835
  var ProgramContext = class {
97760
- constructor(program, reactRuntimeModule, hookPattern) {
97836
+ constructor({
97837
+ program,
97838
+ suppressions,
97839
+ opts,
97840
+ filename,
97841
+ code,
97842
+ hasModuleScopeOptOut
97843
+ }) {
97844
+ /*
97845
+ * This is a hack to work around what seems to be a Babel bug. Babel doesn't
97846
+ * consistently respect the `skip()` function to avoid revisiting a node within
97847
+ * a pass, so we use this set to track nodes that we have compiled.
97848
+ */
97849
+ this.alreadyCompiled = new (WeakSet != null ? WeakSet : Set)();
97761
97850
  // known generated or referenced identifiers in the program
97762
97851
  this.knownReferencedNames = /* @__PURE__ */ new Set();
97763
97852
  // generated imports
97764
97853
  this.imports = /* @__PURE__ */ new Map();
97765
- this.hookPattern = hookPattern;
97854
+ /**
97855
+ * Metadata from compilation
97856
+ */
97857
+ this.retryErrors = [];
97858
+ this.inferredEffectLocations = /* @__PURE__ */ new Set();
97766
97859
  this.scope = program.scope;
97767
- this.reactRuntimeModule = getReactCompilerRuntimeModule(reactRuntimeModule);
97860
+ this.opts = opts;
97861
+ this.filename = filename;
97862
+ this.code = code;
97863
+ this.reactRuntimeModule = getReactCompilerRuntimeModule(opts.target);
97864
+ this.suppressions = suppressions;
97865
+ this.hasModuleScopeOptOut = hasModuleScopeOptOut;
97768
97866
  }
97769
97867
  isHookName(name) {
97770
- if (this.hookPattern == null) {
97868
+ if (this.opts.environment.hookPattern == null) {
97771
97869
  return isHookName(name);
97772
97870
  } else {
97773
- const match = new RegExp(this.hookPattern).exec(name);
97871
+ const match = new RegExp(this.opts.environment.hookPattern).exec(name);
97774
97872
  return match != null && typeof match[1] === "string" && isHookName(match[1]);
97775
97873
  }
97776
97874
  }
@@ -97843,6 +97941,11 @@ var ProgramContext = class {
97843
97941
  });
97844
97942
  return Err(error);
97845
97943
  }
97944
+ logEvent(event) {
97945
+ if (this.opts.logger != null) {
97946
+ this.opts.logger.logEvent(this.filename, event);
97947
+ }
97948
+ }
97846
97949
  };
97847
97950
  function getExistingImports(program) {
97848
97951
  const existingImports = /* @__PURE__ */ new Map();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "babel-plugin-react-compiler",
3
- "version": "0.0.0-experimental-c134c19-20250508",
3
+ "version": "0.0.0-experimental-ccdb475-20250509",
4
4
  "description": "Babel plugin for React Compiler.",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",