babel-plugin-react-compiler 0.0.0-experimental-63a5f0f-20250501 → 0.0.0-experimental-7bde208-20250505

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/dist/index.d.ts CHANGED
@@ -242,6 +242,7 @@ declare const EnvironmentConfigSchema: z.ZodObject<{
242
242
  validateNoCapitalizedCalls: z.ZodDefault<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
243
243
  validateBlocklistedImports: z.ZodDefault<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
244
244
  validateNoImpureFunctionsInRender: z.ZodDefault<z.ZodBoolean>;
245
+ validateNoFreezingKnownMutableFunctions: z.ZodDefault<z.ZodBoolean>;
245
246
  enableAssumeHooksFollowRulesOfReact: z.ZodDefault<z.ZodBoolean>;
246
247
  enableTransitivelyFreezeFunctionExpressions: z.ZodDefault<z.ZodBoolean>;
247
248
  enableEmitFreeze: z.ZodDefault<z.ZodNullable<z.ZodObject<{
@@ -402,6 +403,7 @@ declare const EnvironmentConfigSchema: z.ZodObject<{
402
403
  validateNoCapitalizedCalls: string[] | null;
403
404
  validateBlocklistedImports: string[] | null;
404
405
  validateNoImpureFunctionsInRender: boolean;
406
+ validateNoFreezingKnownMutableFunctions: boolean;
405
407
  enableAssumeHooksFollowRulesOfReact: boolean;
406
408
  enableTransitivelyFreezeFunctionExpressions: boolean;
407
409
  enableEmitFreeze: {
@@ -486,6 +488,7 @@ declare const EnvironmentConfigSchema: z.ZodObject<{
486
488
  validateNoCapitalizedCalls?: string[] | null | undefined;
487
489
  validateBlocklistedImports?: string[] | null | undefined;
488
490
  validateNoImpureFunctionsInRender?: boolean | undefined;
491
+ validateNoFreezingKnownMutableFunctions?: boolean | undefined;
489
492
  enableAssumeHooksFollowRulesOfReact?: boolean | undefined;
490
493
  enableTransitivelyFreezeFunctionExpressions?: boolean | undefined;
491
494
  enableEmitFreeze?: {
package/dist/index.js CHANGED
@@ -5855,7 +5855,7 @@ var require_parentheses = __commonJS({
5855
5855
  exports2.DoExpression = DoExpression;
5856
5856
  exports2.FunctionExpression = FunctionExpression7;
5857
5857
  exports2.FunctionTypeAnnotation = FunctionTypeAnnotation;
5858
- exports2.Identifier = Identifier27;
5858
+ exports2.Identifier = Identifier28;
5859
5859
  exports2.LogicalExpression = LogicalExpression;
5860
5860
  exports2.NullableTypeAnnotation = NullableTypeAnnotation;
5861
5861
  exports2.ObjectExpression = ObjectExpression;
@@ -6070,7 +6070,7 @@ var require_parentheses = __commonJS({
6070
6070
  return parent.operator !== "??";
6071
6071
  }
6072
6072
  }
6073
- function Identifier27(node, parent, tokenContext, _inForInit, getRawIdentifier) {
6073
+ function Identifier28(node, parent, tokenContext, _inForInit, getRawIdentifier) {
6074
6074
  var _node$extra;
6075
6075
  const parentType = parent.type;
6076
6076
  if ((_node$extra = node.extra) != null && _node$extra.parenthesized && parentType === "AssignmentExpression" && parent.left === node) {
@@ -8040,7 +8040,7 @@ var require_types = __commonJS({
8040
8040
  exports2.ArrayPattern = exports2.ArrayExpression = ArrayExpression5;
8041
8041
  exports2.BigIntLiteral = BigIntLiteral;
8042
8042
  exports2.BooleanLiteral = BooleanLiteral;
8043
- exports2.Identifier = Identifier27;
8043
+ exports2.Identifier = Identifier28;
8044
8044
  exports2.NullLiteral = NullLiteral;
8045
8045
  exports2.NumericLiteral = NumericLiteral;
8046
8046
  exports2.ObjectPattern = exports2.ObjectExpression = ObjectExpression;
@@ -8077,7 +8077,7 @@ var require_types = __commonJS({
8077
8077
  }
8078
8078
  return lastRawIdentResult = node.name;
8079
8079
  }
8080
- function Identifier27(node) {
8080
+ function Identifier28(node) {
8081
8081
  var _node$loc;
8082
8082
  this.sourceIdentifierName(((_node$loc = node.loc) == null ? void 0 : _node$loc.identifierName) || node.name);
8083
8083
  this.word(this.tokenMap ? this._getRawIdentifier(node) : node.name);
@@ -34766,7 +34766,7 @@ var require_parentheses2 = __commonJS({
34766
34766
  exports2.DoExpression = DoExpression;
34767
34767
  exports2.FunctionExpression = FunctionExpression7;
34768
34768
  exports2.FunctionTypeAnnotation = FunctionTypeAnnotation;
34769
- exports2.Identifier = Identifier27;
34769
+ exports2.Identifier = Identifier28;
34770
34770
  exports2.LogicalExpression = LogicalExpression;
34771
34771
  exports2.NullableTypeAnnotation = NullableTypeAnnotation;
34772
34772
  exports2.ObjectExpression = ObjectExpression;
@@ -34981,7 +34981,7 @@ var require_parentheses2 = __commonJS({
34981
34981
  return parent.operator !== "??";
34982
34982
  }
34983
34983
  }
34984
- function Identifier27(node, parent, tokenContext, _inForInit, getRawIdentifier) {
34984
+ function Identifier28(node, parent, tokenContext, _inForInit, getRawIdentifier) {
34985
34985
  var _node$extra;
34986
34986
  const parentType = parent.type;
34987
34987
  if ((_node$extra = node.extra) != null && _node$extra.parenthesized && parentType === "AssignmentExpression" && parent.left === node) {
@@ -36951,7 +36951,7 @@ var require_types2 = __commonJS({
36951
36951
  exports2.ArrayPattern = exports2.ArrayExpression = ArrayExpression5;
36952
36952
  exports2.BigIntLiteral = BigIntLiteral;
36953
36953
  exports2.BooleanLiteral = BooleanLiteral;
36954
- exports2.Identifier = Identifier27;
36954
+ exports2.Identifier = Identifier28;
36955
36955
  exports2.NullLiteral = NullLiteral;
36956
36956
  exports2.NumericLiteral = NumericLiteral;
36957
36957
  exports2.ObjectPattern = exports2.ObjectExpression = ObjectExpression;
@@ -36988,7 +36988,7 @@ var require_types2 = __commonJS({
36988
36988
  }
36989
36989
  return lastRawIdentResult = node.name;
36990
36990
  }
36991
- function Identifier27(node) {
36991
+ function Identifier28(node) {
36992
36992
  var _node$loc;
36993
36993
  this.sourceIdentifierName(((_node$loc = node.loc) == null ? void 0 : _node$loc.identifierName) || node.name);
36994
36994
  this.word(this.tokenMap ? this._getRawIdentifier(node) : node.name);
@@ -59070,7 +59070,7 @@ var require_types3 = __commonJS({
59070
59070
  Object.defineProperty(exports2, "__esModule", {
59071
59071
  value: true
59072
59072
  });
59073
- exports2.Identifier = Identifier27;
59073
+ exports2.Identifier = Identifier28;
59074
59074
  exports2.SpreadElement = exports2.RestElement = RestElement;
59075
59075
  exports2.ObjectPattern = exports2.ObjectExpression = ObjectExpression;
59076
59076
  exports2.ObjectMethod = ObjectMethod3;
@@ -59120,7 +59120,7 @@ var require_types3 = __commonJS({
59120
59120
  return newObj;
59121
59121
  }
59122
59122
  }
59123
- function Identifier27(node) {
59123
+ function Identifier28(node) {
59124
59124
  this.exactSource(node.loc, () => {
59125
59125
  this.word(node.name);
59126
59126
  });
@@ -68579,6 +68579,9 @@ function isUseStateType(id) {
68579
68579
  function isRefOrRefValue(id) {
68580
68580
  return isUseRefType(id) || isRefValueType(id);
68581
68581
  }
68582
+ function isRefOrRefLikeMutableType(type) {
68583
+ return type.kind === "Object" && (type.shapeId === "BuiltInUseRefId" || type.shapeId == "ReanimatedSharedValueId");
68584
+ }
68582
68585
  function isSetStateType(id) {
68583
68586
  return id.type.kind === "Function" && id.type.shapeId === "BuiltInSetState";
68584
68587
  }
@@ -71773,6 +71776,8 @@ var BuiltInPropsId = "BuiltInProps";
71773
71776
  var BuiltInArrayId = "BuiltInArray";
71774
71777
  var BuiltInSetId = "BuiltInSet";
71775
71778
  var BuiltInMapId = "BuiltInMap";
71779
+ var BuiltInWeakSetId = "BuiltInWeakSet";
71780
+ var BuiltInWeakMapId = "BuiltInWeakMap";
71776
71781
  var BuiltInFunctionId = "BuiltInFunction";
71777
71782
  var BuiltInJsxId = "BuiltInJsx";
71778
71783
  var BuiltInObjectId = "BuiltInObject";
@@ -71794,6 +71799,7 @@ var BuiltInUseTransitionId = "BuiltInUseTransition";
71794
71799
  var BuiltInStartTransitionId = "BuiltInStartTransition";
71795
71800
  var BuiltInFireId = "BuiltInFire";
71796
71801
  var BuiltInFireFunctionId = "BuiltInFireFunction";
71802
+ var ReanimatedSharedValueId = "ReanimatedSharedValueId";
71797
71803
  var BUILTIN_SHAPES = /* @__PURE__ */ new Map();
71798
71804
  addObject(BUILTIN_SHAPES, BuiltInPropsId, [
71799
71805
  ["ref", { kind: "Object", shapeId: BuiltInUseRefId }]
@@ -72323,6 +72329,99 @@ addObject(BUILTIN_SHAPES, BuiltInMapId, [
72323
72329
  })
72324
72330
  ]
72325
72331
  ]);
72332
+ addObject(BUILTIN_SHAPES, BuiltInWeakSetId, [
72333
+ [
72334
+ /**
72335
+ * add(value)
72336
+ * Parameters
72337
+ * value: the value of the element to add to the Set object.
72338
+ * Returns the Set object with added value.
72339
+ */
72340
+ "add",
72341
+ addFunction(BUILTIN_SHAPES, [], {
72342
+ positionalParams: ["capture" /* Capture */],
72343
+ restParam: null,
72344
+ returnType: { kind: "Object", shapeId: BuiltInWeakSetId },
72345
+ calleeEffect: "store" /* Store */,
72346
+ // returnValueKind is technically dependent on the ValueKind of the set itself
72347
+ returnValueKind: "mutable" /* Mutable */
72348
+ })
72349
+ ],
72350
+ [
72351
+ /**
72352
+ * setInstance.delete(value)
72353
+ * Returns true if value was already in Set; otherwise false.
72354
+ */
72355
+ "delete",
72356
+ addFunction(BUILTIN_SHAPES, [], {
72357
+ positionalParams: ["read" /* Read */],
72358
+ restParam: null,
72359
+ returnType: PRIMITIVE_TYPE,
72360
+ calleeEffect: "store" /* Store */,
72361
+ returnValueKind: "primitive" /* Primitive */
72362
+ })
72363
+ ],
72364
+ [
72365
+ "has",
72366
+ addFunction(BUILTIN_SHAPES, [], {
72367
+ positionalParams: ["read" /* Read */],
72368
+ restParam: null,
72369
+ returnType: PRIMITIVE_TYPE,
72370
+ calleeEffect: "read" /* Read */,
72371
+ returnValueKind: "primitive" /* Primitive */
72372
+ })
72373
+ ]
72374
+ ]);
72375
+ addObject(BUILTIN_SHAPES, BuiltInWeakMapId, [
72376
+ [
72377
+ "delete",
72378
+ addFunction(BUILTIN_SHAPES, [], {
72379
+ positionalParams: ["read" /* Read */],
72380
+ restParam: null,
72381
+ returnType: PRIMITIVE_TYPE,
72382
+ calleeEffect: "store" /* Store */,
72383
+ returnValueKind: "primitive" /* Primitive */
72384
+ })
72385
+ ],
72386
+ [
72387
+ "get",
72388
+ addFunction(BUILTIN_SHAPES, [], {
72389
+ positionalParams: ["read" /* Read */],
72390
+ restParam: null,
72391
+ returnType: { kind: "Poly" },
72392
+ calleeEffect: "capture" /* Capture */,
72393
+ returnValueKind: "mutable" /* Mutable */
72394
+ })
72395
+ ],
72396
+ [
72397
+ "has",
72398
+ addFunction(BUILTIN_SHAPES, [], {
72399
+ positionalParams: ["read" /* Read */],
72400
+ restParam: null,
72401
+ returnType: PRIMITIVE_TYPE,
72402
+ calleeEffect: "read" /* Read */,
72403
+ returnValueKind: "primitive" /* Primitive */
72404
+ })
72405
+ ],
72406
+ [
72407
+ /**
72408
+ * Params
72409
+ * key: the key of the element to add to the Map object. The key may be
72410
+ * any JavaScript type (any primitive value or any type of JavaScript
72411
+ * object).
72412
+ * value: the value of the element to add to the Map object.
72413
+ * Returns the Map object.
72414
+ */
72415
+ "set",
72416
+ addFunction(BUILTIN_SHAPES, [], {
72417
+ positionalParams: ["capture" /* Capture */, "capture" /* Capture */],
72418
+ restParam: null,
72419
+ returnType: { kind: "Object", shapeId: BuiltInWeakMapId },
72420
+ calleeEffect: "store" /* Store */,
72421
+ returnValueKind: "mutable" /* Mutable */
72422
+ })
72423
+ ]
72424
+ ]);
72326
72425
  addObject(BUILTIN_SHAPES, BuiltInUseStateId, [
72327
72426
  ["0", { kind: "Poly" }],
72328
72427
  [
@@ -77066,6 +77165,38 @@ var TYPED_GLOBALS = [
77066
77165
  null,
77067
77166
  true
77068
77167
  )
77168
+ ],
77169
+ [
77170
+ "WeakMap",
77171
+ addFunction(
77172
+ DEFAULT_SHAPES,
77173
+ [],
77174
+ {
77175
+ positionalParams: ["mutate-iterator?" /* ConditionallyMutateIterator */],
77176
+ restParam: null,
77177
+ returnType: { kind: "Object", shapeId: BuiltInWeakMapId },
77178
+ calleeEffect: "read" /* Read */,
77179
+ returnValueKind: "mutable" /* Mutable */
77180
+ },
77181
+ null,
77182
+ true
77183
+ )
77184
+ ],
77185
+ [
77186
+ "WeakSet",
77187
+ addFunction(
77188
+ DEFAULT_SHAPES,
77189
+ [],
77190
+ {
77191
+ positionalParams: ["mutate-iterator?" /* ConditionallyMutateIterator */],
77192
+ restParam: null,
77193
+ returnType: { kind: "Object", shapeId: BuiltInWeakSetId },
77194
+ calleeEffect: "read" /* Read */,
77195
+ returnValueKind: "mutable" /* Mutable */
77196
+ },
77197
+ null,
77198
+ true
77199
+ )
77069
77200
  ]
77070
77201
  // TODO: rest of Global objects
77071
77202
  ];
@@ -77457,7 +77588,7 @@ function getReanimatedModuleType(registry) {
77457
77588
  addHook(registry, {
77458
77589
  positionalParams: [],
77459
77590
  restParam: "freeze" /* Freeze */,
77460
- returnType: { kind: "Poly" },
77591
+ returnType: { kind: "Object", shapeId: ReanimatedSharedValueId },
77461
77592
  returnValueKind: "mutable" /* Mutable */,
77462
77593
  noAlias: true,
77463
77594
  calleeEffect: "read" /* Read */,
@@ -77796,6 +77927,10 @@ var EnvironmentConfigSchema = z.object({
77796
77927
  * Validate against impure functions called during render
77797
77928
  */
77798
77929
  validateNoImpureFunctionsInRender: z.boolean().default(false),
77930
+ /**
77931
+ * Validate against passing mutable functions to hooks
77932
+ */
77933
+ validateNoFreezingKnownMutableFunctions: z.boolean().default(false),
77799
77934
  /*
77800
77935
  * When enabled, the compiler assumes that hooks follow the Rules of React:
77801
77936
  * - Hooks may memoize computation based on any of their parameters, thus
@@ -85025,7 +85160,7 @@ function codegenInstructionValue(cx, instrValue) {
85025
85160
  }
85026
85161
  return value;
85027
85162
  }
85028
- var STRING_REQUIRES_EXPR_CONTAINER_PATTERN = /[\u{0000}-\u{001F}\u{007F}\u{0080}-\u{FFFF}]|"|\\/u;
85163
+ var STRING_REQUIRES_EXPR_CONTAINER_PATTERN = /[\u{0000}-\u{001F}\u{007F}\u{0080}-\u{FFFF}\u{010000}-\u{10FFFF}]|"|\\/u;
85029
85164
  function codegenJsxAttribute(cx, attribute) {
85030
85165
  switch (attribute.kind) {
85031
85166
  case "JsxAttribute": {
@@ -86274,7 +86409,8 @@ var EMPTY = new Empty();
86274
86409
  // src/ReactiveScopes/PruneHoistedContexts.ts
86275
86410
  function pruneHoistedContexts(fn) {
86276
86411
  visitReactiveFunction(fn, new Visitor3(), {
86277
- activeScopes: empty()
86412
+ activeScopes: empty(),
86413
+ uninitialized: /* @__PURE__ */ new Map()
86278
86414
  });
86279
86415
  }
86280
86416
  var Visitor3 = class extends ReactiveFunctionTransform {
@@ -86282,16 +86418,39 @@ var Visitor3 = class extends ReactiveFunctionTransform {
86282
86418
  state.activeScopes = state.activeScopes.push(
86283
86419
  new Set(scope.scope.declarations.keys())
86284
86420
  );
86421
+ for (const decl of scope.scope.declarations.values()) {
86422
+ state.uninitialized.set(decl.identifier.id, { kind: "unknown-kind" });
86423
+ }
86285
86424
  this.traverseScope(scope, state);
86286
86425
  state.activeScopes.pop();
86426
+ for (const decl of scope.scope.declarations.values()) {
86427
+ state.uninitialized.delete(decl.identifier.id);
86428
+ }
86429
+ }
86430
+ visitPlace(_id, place, state) {
86431
+ const maybeHoistedFn = state.uninitialized.get(place.identifier.id);
86432
+ if ((maybeHoistedFn == null ? void 0 : maybeHoistedFn.kind) === "func" && maybeHoistedFn.definition !== place) {
86433
+ CompilerError.throwTodo({
86434
+ reason: "[PruneHoistedContexts] Rewrite hoisted function references",
86435
+ loc: place.loc
86436
+ });
86437
+ }
86287
86438
  }
86288
86439
  transformInstruction(instruction, state) {
86289
- this.visitInstruction(instruction, state);
86290
86440
  if (instruction.value.kind === "DeclareContext") {
86291
86441
  const maybeNonHoisted = convertHoistedLValueKind(
86292
86442
  instruction.value.lvalue.kind
86293
86443
  );
86294
86444
  if (maybeNonHoisted != null) {
86445
+ if (maybeNonHoisted === "Function" /* Function */ && state.uninitialized.has(instruction.value.lvalue.place.identifier.id)) {
86446
+ state.uninitialized.set(
86447
+ instruction.value.lvalue.place.identifier.id,
86448
+ {
86449
+ kind: "func",
86450
+ definition: null
86451
+ }
86452
+ );
86453
+ }
86295
86454
  return { kind: "remove" };
86296
86455
  }
86297
86456
  }
@@ -86301,9 +86460,28 @@ var Visitor3 = class extends ReactiveFunctionTransform {
86301
86460
  (scope) => scope.has(lvalueId)
86302
86461
  );
86303
86462
  if (isDeclaredByScope) {
86304
- instruction.value.lvalue.kind = "Reassign" /* Reassign */;
86463
+ if (instruction.value.lvalue.kind === "Let" /* Let */ || instruction.value.lvalue.kind === "Const" /* Const */) {
86464
+ instruction.value.lvalue.kind = "Reassign" /* Reassign */;
86465
+ } else if (instruction.value.lvalue.kind === "Function" /* Function */) {
86466
+ const maybeHoistedFn = state.uninitialized.get(lvalueId);
86467
+ if (maybeHoistedFn != null) {
86468
+ CompilerError.invariant(maybeHoistedFn.kind === "func", {
86469
+ reason: "[PruneHoistedContexts] Unexpected hoisted function",
86470
+ loc: instruction.loc
86471
+ });
86472
+ maybeHoistedFn.definition = instruction.value.lvalue.place;
86473
+ state.uninitialized.delete(lvalueId);
86474
+ }
86475
+ } else {
86476
+ CompilerError.throwTodo({
86477
+ reason: "[PruneHoistedContexts] Unexpected kind",
86478
+ description: `(${instruction.value.lvalue.kind})`,
86479
+ loc: instruction.loc
86480
+ });
86481
+ }
86305
86482
  }
86306
86483
  }
86484
+ this.visitInstruction(instruction, state);
86307
86485
  return { kind: "keep" };
86308
86486
  }
86309
86487
  };
@@ -89204,6 +89382,48 @@ var RewriteBlockIds = class extends ReactiveFunctionVisitor {
89204
89382
  }
89205
89383
  };
89206
89384
 
89385
+ // src/Inference/InerAliasForUncalledFunctions.ts
89386
+ function inferAliasForUncalledFunctions(fn, aliases) {
89387
+ var _a;
89388
+ for (const block of fn.body.blocks.values()) {
89389
+ instrs: for (const instr of block.instructions) {
89390
+ const { lvalue, value } = instr;
89391
+ if (value.kind !== "ObjectMethod" && value.kind !== "FunctionExpression") {
89392
+ continue;
89393
+ }
89394
+ const range = lvalue.identifier.mutableRange;
89395
+ if (range.end > range.start + 1) {
89396
+ continue;
89397
+ }
89398
+ for (const operand of eachInstructionValueOperand(value)) {
89399
+ if (isMutable2(instr, operand)) {
89400
+ continue instrs;
89401
+ }
89402
+ }
89403
+ const operands = /* @__PURE__ */ new Set();
89404
+ for (const effect of (_a = value.loweredFunc.func.effects) != null ? _a : []) {
89405
+ if (effect.kind !== "ContextMutation") {
89406
+ continue;
89407
+ }
89408
+ if (effect.effect === "store" /* Store */ || effect.effect === "mutate" /* Mutate */) {
89409
+ for (const operand of effect.places) {
89410
+ if (isMutableEffect(operand.effect, operand.loc) && !isRefOrRefLikeMutableType(operand.identifier.type)) {
89411
+ operands.add(operand.identifier);
89412
+ }
89413
+ }
89414
+ }
89415
+ }
89416
+ if (operands.size !== 0) {
89417
+ operands.add(lvalue.identifier);
89418
+ aliases.union([...operands]);
89419
+ for (const operand of operands) {
89420
+ operand.mutableRange.end = makeInstructionId(instr.id + 1);
89421
+ }
89422
+ }
89423
+ }
89424
+ }
89425
+ }
89426
+
89207
89427
  // src/Inference/InferAlias.ts
89208
89428
  function inferAliases(func) {
89209
89429
  const aliases = new DisjointSet();
@@ -89455,6 +89675,7 @@ function inferMutableRanges(ir) {
89455
89675
  while (true) {
89456
89676
  inferMutableRangesForAlias(ir, aliases);
89457
89677
  inferAliasForPhis(ir, aliases);
89678
+ inferAliasForUncalledFunctions(ir, aliases);
89458
89679
  const nextAliases = aliases.canonicalize();
89459
89680
  if (areEqualMaps(prevAliases, nextAliases)) {
89460
89681
  break;
@@ -94432,14 +94653,14 @@ function merge2(a, b) {
94432
94653
  function getCompareDependencyResultDescription(result) {
94433
94654
  switch (result) {
94434
94655
  case 0 /* Ok */:
94435
- return "dependencies equal";
94656
+ return "Dependencies equal";
94436
94657
  case 1 /* RootDifference */:
94437
94658
  case 2 /* PathDifference */:
94438
- return "inferred different dependency than source";
94659
+ return "Inferred different dependency than source";
94439
94660
  case 4 /* RefAccessDifference */:
94440
- return "differences in ref.current access";
94661
+ return "Differences in ref.current access";
94441
94662
  case 3 /* Subpath */:
94442
- return "inferred less specific property than source";
94663
+ return "Inferred less specific property than source";
94443
94664
  }
94444
94665
  }
94445
94666
  function compareDeps(inferred, source2) {
@@ -94516,9 +94737,10 @@ function validateInferredDep(dep, temporaries, declsWithinMemoBlock, validDepsIn
94516
94737
  errorState.push({
94517
94738
  severity: "CannotPreserveMemoization" /* CannotPreserveMemoization */,
94518
94739
  reason: "React Compiler has skipped optimizing this component because the existing manual memoization could not be preserved. The inferred dependencies did not match the manually specified dependencies, which could cause the value to change more or less frequently than expected",
94519
- description: DEBUG4 ? `The inferred dependency was \`${prettyPrintScopeDependency(
94740
+ description: DEBUG4 || // If the dependency is a named variable then we can report it. Otherwise only print in debug mode
94741
+ dep.identifier.name != null && dep.identifier.name.kind === "named" ? `The inferred dependency was \`${prettyPrintScopeDependency(
94520
94742
  dep
94521
- )}\`, but the source dependencies were [${validDepsInMemoBlock.map((dep2) => printManualMemoDependency(dep2, true)).join(", ")}]. Detail: ${errorDiagnostic ? getCompareDependencyResultDescription(errorDiagnostic) : "none"}` : null,
94743
+ )}\`, but the source dependencies were [${validDepsInMemoBlock.map((dep2) => printManualMemoDependency(dep2, true)).join(", ")}]. ${errorDiagnostic ? getCompareDependencyResultDescription(errorDiagnostic) : "Inferred dependency not present in source"}` : null,
94522
94744
  loc: memoLocation,
94523
94745
  suggestions: null
94524
94746
  });
@@ -96376,6 +96598,78 @@ function validateStaticComponents(fn) {
96376
96598
  return error.asResult();
96377
96599
  }
96378
96600
 
96601
+ // src/Validation/ValidateNoFreezingKnownMutableFunctions.ts
96602
+ function validateNoFreezingKnownMutableFunctions(fn) {
96603
+ var _a;
96604
+ const errors = new CompilerError();
96605
+ const contextMutationEffects = /* @__PURE__ */ new Map();
96606
+ function visitOperand(operand) {
96607
+ if (operand.effect === "freeze" /* Freeze */) {
96608
+ const effect = contextMutationEffects.get(operand.identifier.id);
96609
+ if (effect != null) {
96610
+ errors.push({
96611
+ reason: `This argument is a function which modifies local variables when called, which can bypass memoization and cause the UI not to update`,
96612
+ description: `Functions that are returned from hooks, passed as arguments to hooks, or passed as props to components may not mutate local variables`,
96613
+ loc: operand.loc,
96614
+ severity: "InvalidReact" /* InvalidReact */
96615
+ });
96616
+ errors.push({
96617
+ reason: `The function modifies a local variable here`,
96618
+ loc: effect.loc,
96619
+ severity: "InvalidReact" /* InvalidReact */
96620
+ });
96621
+ }
96622
+ }
96623
+ }
96624
+ for (const block of fn.body.blocks.values()) {
96625
+ for (const instr of block.instructions) {
96626
+ const { lvalue, value } = instr;
96627
+ switch (value.kind) {
96628
+ case "LoadLocal": {
96629
+ const effect = contextMutationEffects.get(value.place.identifier.id);
96630
+ if (effect != null) {
96631
+ contextMutationEffects.set(lvalue.identifier.id, effect);
96632
+ }
96633
+ break;
96634
+ }
96635
+ case "StoreLocal": {
96636
+ const effect = contextMutationEffects.get(value.value.identifier.id);
96637
+ if (effect != null) {
96638
+ contextMutationEffects.set(lvalue.identifier.id, effect);
96639
+ contextMutationEffects.set(
96640
+ value.lvalue.place.identifier.id,
96641
+ effect
96642
+ );
96643
+ }
96644
+ break;
96645
+ }
96646
+ case "FunctionExpression": {
96647
+ const knownMutation = ((_a = value.loweredFunc.func.effects) != null ? _a : []).find(
96648
+ (effect) => {
96649
+ return effect.kind === "ContextMutation" && (effect.effect === "store" /* Store */ || effect.effect === "mutate" /* Mutate */) && Iterable_some(effect.places, (place) => {
96650
+ return isMutableEffect(place.effect, place.loc) && !isRefOrRefLikeMutableType(place.identifier.type);
96651
+ });
96652
+ }
96653
+ );
96654
+ if (knownMutation && knownMutation.kind === "ContextMutation") {
96655
+ contextMutationEffects.set(lvalue.identifier.id, knownMutation);
96656
+ }
96657
+ break;
96658
+ }
96659
+ default: {
96660
+ for (const operand of eachInstructionValueOperand(value)) {
96661
+ visitOperand(operand);
96662
+ }
96663
+ }
96664
+ }
96665
+ }
96666
+ for (const operand of eachTerminalOperand(block.terminal)) {
96667
+ visitOperand(operand);
96668
+ }
96669
+ }
96670
+ return errors.asResult();
96671
+ }
96672
+
96379
96673
  // src/Entrypoint/Pipeline.ts
96380
96674
  function run(func, config, fnType, mode, programContext, logger, filename, code) {
96381
96675
  var _a, _b;
@@ -96488,6 +96782,9 @@ function runWithEnvironment(func, env) {
96488
96782
  if (env.config.validateNoImpureFunctionsInRender) {
96489
96783
  validateNoImpureFunctionsInRender(hir).unwrap();
96490
96784
  }
96785
+ if (env.config.validateNoFreezingKnownMutableFunctions) {
96786
+ validateNoFreezingKnownMutableFunctions(hir).unwrap();
96787
+ }
96491
96788
  }
96492
96789
  inferReactivePlaces(hir);
96493
96790
  log2({ kind: "hir", name: "InferReactivePlaces", value: hir });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "babel-plugin-react-compiler",
3
- "version": "0.0.0-experimental-63a5f0f-20250501",
3
+ "version": "0.0.0-experimental-7bde208-20250505",
4
4
  "description": "Babel plugin for React Compiler.",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",