eslint-plugin-react-hooks 7.0.0-canary-1324e1bb-20251016 → 7.0.0-canary-f6a48828-20251019

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.
@@ -21185,25 +21185,25 @@ function assertValidBlockNesting(fn) {
21185
21185
  function assertValidMutableRanges(fn) {
21186
21186
  for (const [, block] of fn.body.blocks) {
21187
21187
  for (const phi of block.phis) {
21188
- visit$2(phi.place, `phi for block bb${block.id}`);
21188
+ visit$1(phi.place, `phi for block bb${block.id}`);
21189
21189
  for (const [pred, operand] of phi.operands) {
21190
- visit$2(operand, `phi predecessor bb${pred} for block bb${block.id}`);
21190
+ visit$1(operand, `phi predecessor bb${pred} for block bb${block.id}`);
21191
21191
  }
21192
21192
  }
21193
21193
  for (const instr of block.instructions) {
21194
21194
  for (const operand of eachInstructionLValue(instr)) {
21195
- visit$2(operand, `instruction [${instr.id}]`);
21195
+ visit$1(operand, `instruction [${instr.id}]`);
21196
21196
  }
21197
21197
  for (const operand of eachInstructionOperand(instr)) {
21198
- visit$2(operand, `instruction [${instr.id}]`);
21198
+ visit$1(operand, `instruction [${instr.id}]`);
21199
21199
  }
21200
21200
  }
21201
21201
  for (const operand of eachTerminalOperand(block.terminal)) {
21202
- visit$2(operand, `terminal [${block.terminal.id}]`);
21202
+ visit$1(operand, `terminal [${block.terminal.id}]`);
21203
21203
  }
21204
21204
  }
21205
21205
  }
21206
- function visit$2(place, description) {
21206
+ function visit$1(place, description) {
21207
21207
  validateMutableRange(place, place.identifier.mutableRange, description);
21208
21208
  if (place.identifier.scope !== null) {
21209
21209
  validateMutableRange(place, place.identifier.scope.range, description);
@@ -32072,14 +32072,7 @@ const InstrumentationSchema = v4.z
32072
32072
  .refine(opts => opts.gating != null || opts.globalGating != null, 'Expected at least one of gating or globalGating');
32073
32073
  const USE_FIRE_FUNCTION_NAME = 'useFire';
32074
32074
  const EMIT_FREEZE_GLOBAL_GATING = 'true';
32075
- const MacroMethodSchema = v4.z.union([
32076
- v4.z.object({ type: v4.z.literal('wildcard') }),
32077
- v4.z.object({ type: v4.z.literal('name'), name: v4.z.string() }),
32078
- ]);
32079
- const MacroSchema = v4.z.union([
32080
- v4.z.string(),
32081
- v4.z.tuple([v4.z.string(), v4.z.array(MacroMethodSchema)]),
32082
- ]);
32075
+ const MacroSchema = v4.z.string();
32083
32076
  const HookSchema = v4.z.object({
32084
32077
  effectKind: v4.z.nativeEnum(Effect),
32085
32078
  valueKind: v4.z.nativeEnum(ValueKind),
@@ -37124,174 +37117,189 @@ var GuardKind;
37124
37117
  GuardKind[GuardKind["DisallowHook"] = 3] = "DisallowHook";
37125
37118
  })(GuardKind || (GuardKind = {}));
37126
37119
 
37120
+ var InlineLevel;
37121
+ (function (InlineLevel) {
37122
+ InlineLevel["Transitive"] = "Transitive";
37123
+ InlineLevel["Shallow"] = "Shallow";
37124
+ })(InlineLevel || (InlineLevel = {}));
37125
+ const SHALLOW_MACRO = {
37126
+ level: InlineLevel.Shallow,
37127
+ properties: null,
37128
+ };
37129
+ const TRANSITIVE_MACRO = {
37130
+ level: InlineLevel.Transitive,
37131
+ properties: null,
37132
+ };
37133
+ const FBT_MACRO = {
37134
+ level: InlineLevel.Transitive,
37135
+ properties: new Map([['*', SHALLOW_MACRO]]),
37136
+ };
37137
+ FBT_MACRO.properties.set('enum', FBT_MACRO);
37127
37138
  function memoizeFbtAndMacroOperandsInSameScope(fn) {
37128
37139
  var _a;
37129
- const fbtMacroTags = new Set([
37130
- ...Array.from(FBT_TAGS).map((tag) => [tag, []]),
37131
- ...((_a = fn.env.config.customMacros) !== null && _a !== void 0 ? _a : []),
37140
+ const macroKinds = new Map([
37141
+ ...Array.from(FBT_TAGS.entries()),
37142
+ ...((_a = fn.env.config.customMacros) !== null && _a !== void 0 ? _a : []).map(name => [name, TRANSITIVE_MACRO]),
37132
37143
  ]);
37133
- const macroTagsCalls = new Set();
37134
- const macroValues = new Map();
37135
- const macroMethods = new Map();
37136
- visit$1(fn, fbtMacroTags, macroTagsCalls, macroMethods, macroValues);
37137
- for (const root of macroValues.keys()) {
37138
- const scope = root.scope;
37139
- if (scope == null) {
37140
- continue;
37141
- }
37142
- if (!macroTagsCalls.has(root.id)) {
37143
- continue;
37144
- }
37145
- mergeScopes(root, scope, macroValues, macroTagsCalls);
37146
- }
37147
- return macroTagsCalls;
37148
- }
37149
- const FBT_TAGS = new Set([
37150
- 'fbt',
37151
- 'fbt:param',
37152
- 'fbt:enum',
37153
- 'fbt:plural',
37154
- 'fbs',
37155
- 'fbs:param',
37156
- 'fbs:enum',
37157
- 'fbs:plural',
37144
+ const macroTags = populateMacroTags(fn, macroKinds);
37145
+ const macroValues = mergeMacroArguments(fn, macroTags, macroKinds);
37146
+ return macroValues;
37147
+ }
37148
+ const FBT_TAGS = new Map([
37149
+ ['fbt', FBT_MACRO],
37150
+ ['fbt:param', SHALLOW_MACRO],
37151
+ ['fbt:enum', FBT_MACRO],
37152
+ ['fbt:plural', SHALLOW_MACRO],
37153
+ ['fbs', FBT_MACRO],
37154
+ ['fbs:param', SHALLOW_MACRO],
37155
+ ['fbs:enum', FBT_MACRO],
37156
+ ['fbs:plural', SHALLOW_MACRO],
37158
37157
  ]);
37159
37158
  const SINGLE_CHILD_FBT_TAGS = new Set([
37160
37159
  'fbt:param',
37161
37160
  'fbs:param',
37162
37161
  ]);
37163
- function visit$1(fn, fbtMacroTags, macroTagsCalls, macroMethods, macroValues) {
37164
- for (const [, block] of fn.body.blocks) {
37165
- for (const phi of block.phis) {
37166
- const macroOperands = [];
37167
- for (const operand of phi.operands.values()) {
37168
- if (macroValues.has(operand.identifier)) {
37169
- macroOperands.push(operand.identifier);
37170
- }
37171
- }
37172
- if (macroOperands.length !== 0) {
37173
- macroValues.set(phi.place.identifier, macroOperands);
37174
- }
37175
- }
37176
- for (const instruction of block.instructions) {
37177
- const { lvalue, value } = instruction;
37178
- if (lvalue === null) {
37179
- continue;
37180
- }
37181
- if (value.kind === 'Primitive' &&
37182
- typeof value.value === 'string' &&
37183
- matchesExactTag(value.value, fbtMacroTags)) {
37184
- macroTagsCalls.add(lvalue.identifier.id);
37185
- }
37186
- else if (value.kind === 'LoadGlobal' &&
37187
- matchesExactTag(value.binding.name, fbtMacroTags)) {
37188
- macroTagsCalls.add(lvalue.identifier.id);
37189
- }
37190
- else if (value.kind === 'LoadGlobal' &&
37191
- matchTagRoot(value.binding.name, fbtMacroTags) !== null) {
37192
- const methods = matchTagRoot(value.binding.name, fbtMacroTags);
37193
- macroMethods.set(lvalue.identifier.id, methods);
37194
- }
37195
- else if (value.kind === 'PropertyLoad' &&
37196
- macroMethods.has(value.object.identifier.id)) {
37197
- const methods = macroMethods.get(value.object.identifier.id);
37198
- const newMethods = [];
37199
- for (const method of methods) {
37200
- if (method.length > 0 &&
37201
- (method[0].type === 'wildcard' ||
37202
- (method[0].type === 'name' && method[0].name === value.property))) {
37203
- if (method.length > 1) {
37204
- newMethods.push(method.slice(1));
37205
- }
37206
- else {
37207
- macroTagsCalls.add(lvalue.identifier.id);
37162
+ function populateMacroTags(fn, macroKinds) {
37163
+ var _a;
37164
+ const macroTags = new Map();
37165
+ for (const block of fn.body.blocks.values()) {
37166
+ for (const instr of block.instructions) {
37167
+ const { lvalue, value } = instr;
37168
+ switch (value.kind) {
37169
+ case 'Primitive': {
37170
+ if (typeof value.value === 'string') {
37171
+ const macroDefinition = macroKinds.get(value.value);
37172
+ if (macroDefinition != null) {
37173
+ macroTags.set(lvalue.identifier.id, macroDefinition);
37208
37174
  }
37209
37175
  }
37176
+ break;
37210
37177
  }
37211
- if (newMethods.length > 0) {
37212
- macroMethods.set(lvalue.identifier.id, newMethods);
37178
+ case 'LoadGlobal': {
37179
+ let macroDefinition = macroKinds.get(value.binding.name);
37180
+ if (macroDefinition != null) {
37181
+ macroTags.set(lvalue.identifier.id, macroDefinition);
37182
+ }
37183
+ break;
37213
37184
  }
37214
- }
37215
- else if (value.kind === 'PropertyLoad' &&
37216
- macroTagsCalls.has(value.object.identifier.id)) {
37217
- macroTagsCalls.add(lvalue.identifier.id);
37218
- }
37219
- else if (isFbtJsxExpression(fbtMacroTags, macroTagsCalls, value) ||
37220
- isFbtJsxChild(macroTagsCalls, lvalue, value) ||
37221
- isFbtCallExpression(macroTagsCalls, value)) {
37222
- macroTagsCalls.add(lvalue.identifier.id);
37223
- macroValues.set(lvalue.identifier, Array.from(eachInstructionValueOperand(value), operand => operand.identifier));
37224
- }
37225
- else if (Iterable_some(eachInstructionValueOperand(value), operand => macroValues.has(operand.identifier))) {
37226
- const macroOperands = [];
37227
- for (const operand of eachInstructionValueOperand(value)) {
37228
- if (macroValues.has(operand.identifier)) {
37229
- macroOperands.push(operand.identifier);
37185
+ case 'PropertyLoad': {
37186
+ if (typeof value.property === 'string') {
37187
+ const macroDefinition = macroTags.get(value.object.identifier.id);
37188
+ if (macroDefinition != null) {
37189
+ const propertyDefinition = macroDefinition.properties != null
37190
+ ? ((_a = macroDefinition.properties.get(value.property)) !== null && _a !== void 0 ? _a : macroDefinition.properties.get('*'))
37191
+ : null;
37192
+ const propertyMacro = propertyDefinition !== null && propertyDefinition !== void 0 ? propertyDefinition : macroDefinition;
37193
+ macroTags.set(lvalue.identifier.id, propertyMacro);
37194
+ }
37230
37195
  }
37196
+ break;
37231
37197
  }
37232
- macroValues.set(lvalue.identifier, macroOperands);
37233
37198
  }
37234
37199
  }
37235
37200
  }
37201
+ return macroTags;
37236
37202
  }
37237
- function mergeScopes(root, scope, macroValues, macroTagsCalls) {
37238
- const operands = macroValues.get(root);
37239
- if (operands == null) {
37240
- return;
37241
- }
37242
- for (const operand of operands) {
37243
- operand.scope = scope;
37244
- expandFbtScopeRange(scope.range, operand.mutableRange);
37245
- macroTagsCalls.add(operand.id);
37246
- mergeScopes(operand, scope, macroValues, macroTagsCalls);
37247
- }
37248
- }
37249
- function matchesExactTag(s, tags) {
37250
- return Array.from(tags).some(macro => typeof macro === 'string'
37251
- ? s === macro
37252
- : macro[1].length === 0 && macro[0] === s);
37253
- }
37254
- function matchTagRoot(s, tags) {
37255
- const methods = [];
37256
- for (const macro of tags) {
37257
- if (typeof macro === 'string') {
37258
- continue;
37203
+ function mergeMacroArguments(fn, macroTags, macroKinds) {
37204
+ var _a;
37205
+ const macroValues = new Set(macroTags.keys());
37206
+ for (const block of Array.from(fn.body.blocks.values()).reverse()) {
37207
+ for (let i = block.instructions.length - 1; i >= 0; i--) {
37208
+ const instr = block.instructions[i];
37209
+ const { lvalue, value } = instr;
37210
+ switch (value.kind) {
37211
+ case 'DeclareContext':
37212
+ case 'DeclareLocal':
37213
+ case 'Destructure':
37214
+ case 'LoadContext':
37215
+ case 'LoadLocal':
37216
+ case 'PostfixUpdate':
37217
+ case 'PrefixUpdate':
37218
+ case 'StoreContext':
37219
+ case 'StoreLocal': {
37220
+ break;
37221
+ }
37222
+ case 'CallExpression':
37223
+ case 'MethodCall': {
37224
+ const scope = lvalue.identifier.scope;
37225
+ if (scope == null) {
37226
+ continue;
37227
+ }
37228
+ const callee = value.kind === 'CallExpression' ? value.callee : value.property;
37229
+ const macroDefinition = (_a = macroTags.get(callee.identifier.id)) !== null && _a !== void 0 ? _a : macroTags.get(lvalue.identifier.id);
37230
+ if (macroDefinition != null) {
37231
+ visitOperands(macroDefinition, scope, lvalue, value, macroValues, macroTags);
37232
+ }
37233
+ break;
37234
+ }
37235
+ case 'JsxExpression': {
37236
+ const scope = lvalue.identifier.scope;
37237
+ if (scope == null) {
37238
+ continue;
37239
+ }
37240
+ let macroDefinition;
37241
+ if (value.tag.kind === 'Identifier') {
37242
+ macroDefinition = macroTags.get(value.tag.identifier.id);
37243
+ }
37244
+ else {
37245
+ macroDefinition = macroKinds.get(value.tag.name);
37246
+ }
37247
+ macroDefinition !== null && macroDefinition !== void 0 ? macroDefinition : (macroDefinition = macroTags.get(lvalue.identifier.id));
37248
+ if (macroDefinition != null) {
37249
+ visitOperands(macroDefinition, scope, lvalue, value, macroValues, macroTags);
37250
+ }
37251
+ break;
37252
+ }
37253
+ default: {
37254
+ const scope = lvalue.identifier.scope;
37255
+ if (scope == null) {
37256
+ continue;
37257
+ }
37258
+ const macroDefinition = macroTags.get(lvalue.identifier.id);
37259
+ if (macroDefinition != null) {
37260
+ visitOperands(macroDefinition, scope, lvalue, value, macroValues, macroTags);
37261
+ }
37262
+ break;
37263
+ }
37264
+ }
37259
37265
  }
37260
- const [tag, rest] = macro;
37261
- if (tag === s && rest.length > 0) {
37262
- methods.push(rest);
37266
+ for (const phi of block.phis) {
37267
+ const scope = phi.place.identifier.scope;
37268
+ if (scope == null) {
37269
+ continue;
37270
+ }
37271
+ const macroDefinition = macroTags.get(phi.place.identifier.id);
37272
+ if (macroDefinition == null ||
37273
+ macroDefinition.level === InlineLevel.Shallow) {
37274
+ continue;
37275
+ }
37276
+ macroValues.add(phi.place.identifier.id);
37277
+ for (const operand of phi.operands.values()) {
37278
+ operand.identifier.scope = scope;
37279
+ expandFbtScopeRange(scope.range, operand.identifier.mutableRange);
37280
+ macroTags.set(operand.identifier.id, macroDefinition);
37281
+ macroValues.add(operand.identifier.id);
37282
+ }
37263
37283
  }
37264
37284
  }
37265
- if (methods.length > 0) {
37266
- return methods;
37267
- }
37268
- else {
37269
- return null;
37270
- }
37271
- }
37272
- function isFbtCallExpression(macroTagsCalls, value) {
37273
- return ((value.kind === 'CallExpression' &&
37274
- macroTagsCalls.has(value.callee.identifier.id)) ||
37275
- (value.kind === 'MethodCall' &&
37276
- macroTagsCalls.has(value.property.identifier.id)));
37277
- }
37278
- function isFbtJsxExpression(fbtMacroTags, macroTagsCalls, value) {
37279
- return (value.kind === 'JsxExpression' &&
37280
- ((value.tag.kind === 'Identifier' &&
37281
- macroTagsCalls.has(value.tag.identifier.id)) ||
37282
- (value.tag.kind === 'BuiltinTag' &&
37283
- matchesExactTag(value.tag.name, fbtMacroTags))));
37284
- }
37285
- function isFbtJsxChild(macroTagsCalls, lvalue, value) {
37286
- return ((value.kind === 'JsxExpression' || value.kind === 'JsxFragment') &&
37287
- lvalue !== null &&
37288
- macroTagsCalls.has(lvalue.identifier.id));
37285
+ return macroValues;
37289
37286
  }
37290
37287
  function expandFbtScopeRange(fbtRange, extendWith) {
37291
37288
  if (extendWith.start !== 0) {
37292
37289
  fbtRange.start = makeInstructionId(Math.min(fbtRange.start, extendWith.start));
37293
37290
  }
37294
37291
  }
37292
+ function visitOperands(macroDefinition, scope, lvalue, value, macroValues, macroTags) {
37293
+ macroValues.add(lvalue.identifier.id);
37294
+ for (const operand of eachInstructionValueOperand(value)) {
37295
+ if (macroDefinition.level === InlineLevel.Transitive) {
37296
+ operand.identifier.scope = scope;
37297
+ expandFbtScopeRange(scope.range, operand.identifier.mutableRange);
37298
+ macroTags.set(operand.identifier.id, macroDefinition);
37299
+ }
37300
+ macroValues.add(operand.identifier.id);
37301
+ }
37302
+ }
37295
37303
 
37296
37304
  var _Context_nextCacheIndex, _Context_declarations;
37297
37305
  const MEMO_CACHE_SENTINEL = 'react.memo_cache_sentinel';
@@ -40489,7 +40497,7 @@ function inferMutationAliasingEffects(fn, { isFunctionExpression } = {
40489
40497
  }
40490
40498
  queue(fn.body.entry, initialState);
40491
40499
  const hoistedContextDeclarations = findHoistedContextDeclarations(fn);
40492
- const context = new Context$1(isFunctionExpression, fn, hoistedContextDeclarations);
40500
+ const context = new Context$1(isFunctionExpression, fn, hoistedContextDeclarations, findNonMutatedDestructureSpreads(fn));
40493
40501
  let iterationCount = 0;
40494
40502
  while (queuedStates.size !== 0) {
40495
40503
  iterationCount++;
@@ -40553,7 +40561,7 @@ function findHoistedContextDeclarations(fn) {
40553
40561
  return hoisted;
40554
40562
  }
40555
40563
  let Context$1 = class Context {
40556
- constructor(isFunctionExpression, fn, hoistedContextDeclarations) {
40564
+ constructor(isFunctionExpression, fn, hoistedContextDeclarations, nonMutatingSpreads) {
40557
40565
  this.internedEffects = new Map();
40558
40566
  this.instructionSignatureCache = new Map();
40559
40567
  this.effectInstructionValueCache = new Map();
@@ -40563,6 +40571,7 @@ let Context$1 = class Context {
40563
40571
  this.isFuctionExpression = isFunctionExpression;
40564
40572
  this.fn = fn;
40565
40573
  this.hoistedContextDeclarations = hoistedContextDeclarations;
40574
+ this.nonMutatingSpreads = nonMutatingSpreads;
40566
40575
  }
40567
40576
  cacheApplySignature(signature, effect, f) {
40568
40577
  const inner = getOrInsertDefault(this.applySignatureCache, signature, new Map());
@@ -40578,6 +40587,114 @@ let Context$1 = class Context {
40578
40587
  return interned;
40579
40588
  }
40580
40589
  };
40590
+ function findNonMutatedDestructureSpreads(fn) {
40591
+ const knownFrozen = new Set();
40592
+ if (fn.fnType === 'Component') {
40593
+ const [props] = fn.params;
40594
+ if (props != null && props.kind === 'Identifier') {
40595
+ knownFrozen.add(props.identifier.id);
40596
+ }
40597
+ }
40598
+ else {
40599
+ for (const param of fn.params) {
40600
+ if (param.kind === 'Identifier') {
40601
+ knownFrozen.add(param.identifier.id);
40602
+ }
40603
+ }
40604
+ }
40605
+ const candidateNonMutatingSpreads = new Map();
40606
+ for (const block of fn.body.blocks.values()) {
40607
+ if (candidateNonMutatingSpreads.size !== 0) {
40608
+ for (const phi of block.phis) {
40609
+ for (const operand of phi.operands.values()) {
40610
+ const spread = candidateNonMutatingSpreads.get(operand.identifier.id);
40611
+ if (spread != null) {
40612
+ candidateNonMutatingSpreads.delete(spread);
40613
+ }
40614
+ }
40615
+ }
40616
+ }
40617
+ for (const instr of block.instructions) {
40618
+ const { lvalue, value } = instr;
40619
+ switch (value.kind) {
40620
+ case 'Destructure': {
40621
+ if (!knownFrozen.has(value.value.identifier.id) ||
40622
+ !(value.lvalue.kind === InstructionKind.Let ||
40623
+ value.lvalue.kind === InstructionKind.Const) ||
40624
+ value.lvalue.pattern.kind !== 'ObjectPattern') {
40625
+ continue;
40626
+ }
40627
+ for (const item of value.lvalue.pattern.properties) {
40628
+ if (item.kind !== 'Spread') {
40629
+ continue;
40630
+ }
40631
+ candidateNonMutatingSpreads.set(item.place.identifier.id, item.place.identifier.id);
40632
+ }
40633
+ break;
40634
+ }
40635
+ case 'LoadLocal': {
40636
+ const spread = candidateNonMutatingSpreads.get(value.place.identifier.id);
40637
+ if (spread != null) {
40638
+ candidateNonMutatingSpreads.set(lvalue.identifier.id, spread);
40639
+ }
40640
+ break;
40641
+ }
40642
+ case 'StoreLocal': {
40643
+ const spread = candidateNonMutatingSpreads.get(value.value.identifier.id);
40644
+ if (spread != null) {
40645
+ candidateNonMutatingSpreads.set(lvalue.identifier.id, spread);
40646
+ candidateNonMutatingSpreads.set(value.lvalue.place.identifier.id, spread);
40647
+ }
40648
+ break;
40649
+ }
40650
+ case 'JsxFragment':
40651
+ case 'JsxExpression': {
40652
+ break;
40653
+ }
40654
+ case 'PropertyLoad': {
40655
+ break;
40656
+ }
40657
+ case 'CallExpression':
40658
+ case 'MethodCall': {
40659
+ const callee = value.kind === 'CallExpression' ? value.callee : value.property;
40660
+ if (getHookKind(fn.env, callee.identifier) != null) {
40661
+ if (!isRefOrRefValue(lvalue.identifier)) {
40662
+ knownFrozen.add(lvalue.identifier.id);
40663
+ }
40664
+ }
40665
+ else {
40666
+ if (candidateNonMutatingSpreads.size !== 0) {
40667
+ for (const operand of eachInstructionValueOperand(value)) {
40668
+ const spread = candidateNonMutatingSpreads.get(operand.identifier.id);
40669
+ if (spread != null) {
40670
+ candidateNonMutatingSpreads.delete(spread);
40671
+ }
40672
+ }
40673
+ }
40674
+ }
40675
+ break;
40676
+ }
40677
+ default: {
40678
+ if (candidateNonMutatingSpreads.size !== 0) {
40679
+ for (const operand of eachInstructionValueOperand(value)) {
40680
+ const spread = candidateNonMutatingSpreads.get(operand.identifier.id);
40681
+ if (spread != null) {
40682
+ candidateNonMutatingSpreads.delete(spread);
40683
+ }
40684
+ }
40685
+ }
40686
+ }
40687
+ }
40688
+ }
40689
+ }
40690
+ const nonMutatingSpreads = new Set();
40691
+ for (const [key, value] of candidateNonMutatingSpreads) {
40692
+ if (key === value) {
40693
+ nonMutatingSpreads.add(key);
40694
+ }
40695
+ }
40696
+ return nonMutatingSpreads;
40697
+ }
40581
40698
  function inferParam(param, initialState, paramKind) {
40582
40699
  const place = param.kind === 'Identifier' ? param : param.place;
40583
40700
  const value = {
@@ -41832,7 +41949,9 @@ function computeSignatureForInstruction(context, env, instr) {
41832
41949
  kind: 'Create',
41833
41950
  into: place,
41834
41951
  reason: ValueReason.Other,
41835
- value: ValueKind.Mutable,
41952
+ value: context.nonMutatingSpreads.has(place.identifier.id)
41953
+ ? ValueKind.Frozen
41954
+ : ValueKind.Mutable,
41836
41955
  });
41837
41956
  effects.push({
41838
41957
  kind: 'Capture',
@@ -21176,25 +21176,25 @@ function assertValidBlockNesting(fn) {
21176
21176
  function assertValidMutableRanges(fn) {
21177
21177
  for (const [, block] of fn.body.blocks) {
21178
21178
  for (const phi of block.phis) {
21179
- visit$2(phi.place, `phi for block bb${block.id}`);
21179
+ visit$1(phi.place, `phi for block bb${block.id}`);
21180
21180
  for (const [pred, operand] of phi.operands) {
21181
- visit$2(operand, `phi predecessor bb${pred} for block bb${block.id}`);
21181
+ visit$1(operand, `phi predecessor bb${pred} for block bb${block.id}`);
21182
21182
  }
21183
21183
  }
21184
21184
  for (const instr of block.instructions) {
21185
21185
  for (const operand of eachInstructionLValue(instr)) {
21186
- visit$2(operand, `instruction [${instr.id}]`);
21186
+ visit$1(operand, `instruction [${instr.id}]`);
21187
21187
  }
21188
21188
  for (const operand of eachInstructionOperand(instr)) {
21189
- visit$2(operand, `instruction [${instr.id}]`);
21189
+ visit$1(operand, `instruction [${instr.id}]`);
21190
21190
  }
21191
21191
  }
21192
21192
  for (const operand of eachTerminalOperand(block.terminal)) {
21193
- visit$2(operand, `terminal [${block.terminal.id}]`);
21193
+ visit$1(operand, `terminal [${block.terminal.id}]`);
21194
21194
  }
21195
21195
  }
21196
21196
  }
21197
- function visit$2(place, description) {
21197
+ function visit$1(place, description) {
21198
21198
  validateMutableRange(place, place.identifier.mutableRange, description);
21199
21199
  if (place.identifier.scope !== null) {
21200
21200
  validateMutableRange(place, place.identifier.scope.range, description);
@@ -31899,14 +31899,7 @@ const InstrumentationSchema = v4.z
31899
31899
  .refine(opts => opts.gating != null || opts.globalGating != null, 'Expected at least one of gating or globalGating');
31900
31900
  const USE_FIRE_FUNCTION_NAME = 'useFire';
31901
31901
  const EMIT_FREEZE_GLOBAL_GATING = 'false';
31902
- const MacroMethodSchema = v4.z.union([
31903
- v4.z.object({ type: v4.z.literal('wildcard') }),
31904
- v4.z.object({ type: v4.z.literal('name'), name: v4.z.string() }),
31905
- ]);
31906
- const MacroSchema = v4.z.union([
31907
- v4.z.string(),
31908
- v4.z.tuple([v4.z.string(), v4.z.array(MacroMethodSchema)]),
31909
- ]);
31902
+ const MacroSchema = v4.z.string();
31910
31903
  const HookSchema = v4.z.object({
31911
31904
  effectKind: v4.z.nativeEnum(Effect),
31912
31905
  valueKind: v4.z.nativeEnum(ValueKind),
@@ -36951,174 +36944,189 @@ var GuardKind;
36951
36944
  GuardKind[GuardKind["DisallowHook"] = 3] = "DisallowHook";
36952
36945
  })(GuardKind || (GuardKind = {}));
36953
36946
 
36947
+ var InlineLevel;
36948
+ (function (InlineLevel) {
36949
+ InlineLevel["Transitive"] = "Transitive";
36950
+ InlineLevel["Shallow"] = "Shallow";
36951
+ })(InlineLevel || (InlineLevel = {}));
36952
+ const SHALLOW_MACRO = {
36953
+ level: InlineLevel.Shallow,
36954
+ properties: null,
36955
+ };
36956
+ const TRANSITIVE_MACRO = {
36957
+ level: InlineLevel.Transitive,
36958
+ properties: null,
36959
+ };
36960
+ const FBT_MACRO = {
36961
+ level: InlineLevel.Transitive,
36962
+ properties: new Map([['*', SHALLOW_MACRO]]),
36963
+ };
36964
+ FBT_MACRO.properties.set('enum', FBT_MACRO);
36954
36965
  function memoizeFbtAndMacroOperandsInSameScope(fn) {
36955
36966
  var _a;
36956
- const fbtMacroTags = new Set([
36957
- ...Array.from(FBT_TAGS).map((tag) => [tag, []]),
36958
- ...((_a = fn.env.config.customMacros) !== null && _a !== void 0 ? _a : []),
36967
+ const macroKinds = new Map([
36968
+ ...Array.from(FBT_TAGS.entries()),
36969
+ ...((_a = fn.env.config.customMacros) !== null && _a !== void 0 ? _a : []).map(name => [name, TRANSITIVE_MACRO]),
36959
36970
  ]);
36960
- const macroTagsCalls = new Set();
36961
- const macroValues = new Map();
36962
- const macroMethods = new Map();
36963
- visit$1(fn, fbtMacroTags, macroTagsCalls, macroMethods, macroValues);
36964
- for (const root of macroValues.keys()) {
36965
- const scope = root.scope;
36966
- if (scope == null) {
36967
- continue;
36968
- }
36969
- if (!macroTagsCalls.has(root.id)) {
36970
- continue;
36971
- }
36972
- mergeScopes(root, scope, macroValues, macroTagsCalls);
36973
- }
36974
- return macroTagsCalls;
36975
- }
36976
- const FBT_TAGS = new Set([
36977
- 'fbt',
36978
- 'fbt:param',
36979
- 'fbt:enum',
36980
- 'fbt:plural',
36981
- 'fbs',
36982
- 'fbs:param',
36983
- 'fbs:enum',
36984
- 'fbs:plural',
36971
+ const macroTags = populateMacroTags(fn, macroKinds);
36972
+ const macroValues = mergeMacroArguments(fn, macroTags, macroKinds);
36973
+ return macroValues;
36974
+ }
36975
+ const FBT_TAGS = new Map([
36976
+ ['fbt', FBT_MACRO],
36977
+ ['fbt:param', SHALLOW_MACRO],
36978
+ ['fbt:enum', FBT_MACRO],
36979
+ ['fbt:plural', SHALLOW_MACRO],
36980
+ ['fbs', FBT_MACRO],
36981
+ ['fbs:param', SHALLOW_MACRO],
36982
+ ['fbs:enum', FBT_MACRO],
36983
+ ['fbs:plural', SHALLOW_MACRO],
36985
36984
  ]);
36986
36985
  const SINGLE_CHILD_FBT_TAGS = new Set([
36987
36986
  'fbt:param',
36988
36987
  'fbs:param',
36989
36988
  ]);
36990
- function visit$1(fn, fbtMacroTags, macroTagsCalls, macroMethods, macroValues) {
36991
- for (const [, block] of fn.body.blocks) {
36992
- for (const phi of block.phis) {
36993
- const macroOperands = [];
36994
- for (const operand of phi.operands.values()) {
36995
- if (macroValues.has(operand.identifier)) {
36996
- macroOperands.push(operand.identifier);
36997
- }
36998
- }
36999
- if (macroOperands.length !== 0) {
37000
- macroValues.set(phi.place.identifier, macroOperands);
37001
- }
37002
- }
37003
- for (const instruction of block.instructions) {
37004
- const { lvalue, value } = instruction;
37005
- if (lvalue === null) {
37006
- continue;
37007
- }
37008
- if (value.kind === 'Primitive' &&
37009
- typeof value.value === 'string' &&
37010
- matchesExactTag(value.value, fbtMacroTags)) {
37011
- macroTagsCalls.add(lvalue.identifier.id);
37012
- }
37013
- else if (value.kind === 'LoadGlobal' &&
37014
- matchesExactTag(value.binding.name, fbtMacroTags)) {
37015
- macroTagsCalls.add(lvalue.identifier.id);
37016
- }
37017
- else if (value.kind === 'LoadGlobal' &&
37018
- matchTagRoot(value.binding.name, fbtMacroTags) !== null) {
37019
- const methods = matchTagRoot(value.binding.name, fbtMacroTags);
37020
- macroMethods.set(lvalue.identifier.id, methods);
37021
- }
37022
- else if (value.kind === 'PropertyLoad' &&
37023
- macroMethods.has(value.object.identifier.id)) {
37024
- const methods = macroMethods.get(value.object.identifier.id);
37025
- const newMethods = [];
37026
- for (const method of methods) {
37027
- if (method.length > 0 &&
37028
- (method[0].type === 'wildcard' ||
37029
- (method[0].type === 'name' && method[0].name === value.property))) {
37030
- if (method.length > 1) {
37031
- newMethods.push(method.slice(1));
37032
- }
37033
- else {
37034
- macroTagsCalls.add(lvalue.identifier.id);
36989
+ function populateMacroTags(fn, macroKinds) {
36990
+ var _a;
36991
+ const macroTags = new Map();
36992
+ for (const block of fn.body.blocks.values()) {
36993
+ for (const instr of block.instructions) {
36994
+ const { lvalue, value } = instr;
36995
+ switch (value.kind) {
36996
+ case 'Primitive': {
36997
+ if (typeof value.value === 'string') {
36998
+ const macroDefinition = macroKinds.get(value.value);
36999
+ if (macroDefinition != null) {
37000
+ macroTags.set(lvalue.identifier.id, macroDefinition);
37035
37001
  }
37036
37002
  }
37003
+ break;
37037
37004
  }
37038
- if (newMethods.length > 0) {
37039
- macroMethods.set(lvalue.identifier.id, newMethods);
37005
+ case 'LoadGlobal': {
37006
+ let macroDefinition = macroKinds.get(value.binding.name);
37007
+ if (macroDefinition != null) {
37008
+ macroTags.set(lvalue.identifier.id, macroDefinition);
37009
+ }
37010
+ break;
37040
37011
  }
37041
- }
37042
- else if (value.kind === 'PropertyLoad' &&
37043
- macroTagsCalls.has(value.object.identifier.id)) {
37044
- macroTagsCalls.add(lvalue.identifier.id);
37045
- }
37046
- else if (isFbtJsxExpression(fbtMacroTags, macroTagsCalls, value) ||
37047
- isFbtJsxChild(macroTagsCalls, lvalue, value) ||
37048
- isFbtCallExpression(macroTagsCalls, value)) {
37049
- macroTagsCalls.add(lvalue.identifier.id);
37050
- macroValues.set(lvalue.identifier, Array.from(eachInstructionValueOperand(value), operand => operand.identifier));
37051
- }
37052
- else if (Iterable_some(eachInstructionValueOperand(value), operand => macroValues.has(operand.identifier))) {
37053
- const macroOperands = [];
37054
- for (const operand of eachInstructionValueOperand(value)) {
37055
- if (macroValues.has(operand.identifier)) {
37056
- macroOperands.push(operand.identifier);
37012
+ case 'PropertyLoad': {
37013
+ if (typeof value.property === 'string') {
37014
+ const macroDefinition = macroTags.get(value.object.identifier.id);
37015
+ if (macroDefinition != null) {
37016
+ const propertyDefinition = macroDefinition.properties != null
37017
+ ? ((_a = macroDefinition.properties.get(value.property)) !== null && _a !== void 0 ? _a : macroDefinition.properties.get('*'))
37018
+ : null;
37019
+ const propertyMacro = propertyDefinition !== null && propertyDefinition !== void 0 ? propertyDefinition : macroDefinition;
37020
+ macroTags.set(lvalue.identifier.id, propertyMacro);
37021
+ }
37057
37022
  }
37023
+ break;
37058
37024
  }
37059
- macroValues.set(lvalue.identifier, macroOperands);
37060
37025
  }
37061
37026
  }
37062
37027
  }
37028
+ return macroTags;
37063
37029
  }
37064
- function mergeScopes(root, scope, macroValues, macroTagsCalls) {
37065
- const operands = macroValues.get(root);
37066
- if (operands == null) {
37067
- return;
37068
- }
37069
- for (const operand of operands) {
37070
- operand.scope = scope;
37071
- expandFbtScopeRange(scope.range, operand.mutableRange);
37072
- macroTagsCalls.add(operand.id);
37073
- mergeScopes(operand, scope, macroValues, macroTagsCalls);
37074
- }
37075
- }
37076
- function matchesExactTag(s, tags) {
37077
- return Array.from(tags).some(macro => typeof macro === 'string'
37078
- ? s === macro
37079
- : macro[1].length === 0 && macro[0] === s);
37080
- }
37081
- function matchTagRoot(s, tags) {
37082
- const methods = [];
37083
- for (const macro of tags) {
37084
- if (typeof macro === 'string') {
37085
- continue;
37030
+ function mergeMacroArguments(fn, macroTags, macroKinds) {
37031
+ var _a;
37032
+ const macroValues = new Set(macroTags.keys());
37033
+ for (const block of Array.from(fn.body.blocks.values()).reverse()) {
37034
+ for (let i = block.instructions.length - 1; i >= 0; i--) {
37035
+ const instr = block.instructions[i];
37036
+ const { lvalue, value } = instr;
37037
+ switch (value.kind) {
37038
+ case 'DeclareContext':
37039
+ case 'DeclareLocal':
37040
+ case 'Destructure':
37041
+ case 'LoadContext':
37042
+ case 'LoadLocal':
37043
+ case 'PostfixUpdate':
37044
+ case 'PrefixUpdate':
37045
+ case 'StoreContext':
37046
+ case 'StoreLocal': {
37047
+ break;
37048
+ }
37049
+ case 'CallExpression':
37050
+ case 'MethodCall': {
37051
+ const scope = lvalue.identifier.scope;
37052
+ if (scope == null) {
37053
+ continue;
37054
+ }
37055
+ const callee = value.kind === 'CallExpression' ? value.callee : value.property;
37056
+ const macroDefinition = (_a = macroTags.get(callee.identifier.id)) !== null && _a !== void 0 ? _a : macroTags.get(lvalue.identifier.id);
37057
+ if (macroDefinition != null) {
37058
+ visitOperands(macroDefinition, scope, lvalue, value, macroValues, macroTags);
37059
+ }
37060
+ break;
37061
+ }
37062
+ case 'JsxExpression': {
37063
+ const scope = lvalue.identifier.scope;
37064
+ if (scope == null) {
37065
+ continue;
37066
+ }
37067
+ let macroDefinition;
37068
+ if (value.tag.kind === 'Identifier') {
37069
+ macroDefinition = macroTags.get(value.tag.identifier.id);
37070
+ }
37071
+ else {
37072
+ macroDefinition = macroKinds.get(value.tag.name);
37073
+ }
37074
+ macroDefinition !== null && macroDefinition !== void 0 ? macroDefinition : (macroDefinition = macroTags.get(lvalue.identifier.id));
37075
+ if (macroDefinition != null) {
37076
+ visitOperands(macroDefinition, scope, lvalue, value, macroValues, macroTags);
37077
+ }
37078
+ break;
37079
+ }
37080
+ default: {
37081
+ const scope = lvalue.identifier.scope;
37082
+ if (scope == null) {
37083
+ continue;
37084
+ }
37085
+ const macroDefinition = macroTags.get(lvalue.identifier.id);
37086
+ if (macroDefinition != null) {
37087
+ visitOperands(macroDefinition, scope, lvalue, value, macroValues, macroTags);
37088
+ }
37089
+ break;
37090
+ }
37091
+ }
37086
37092
  }
37087
- const [tag, rest] = macro;
37088
- if (tag === s && rest.length > 0) {
37089
- methods.push(rest);
37093
+ for (const phi of block.phis) {
37094
+ const scope = phi.place.identifier.scope;
37095
+ if (scope == null) {
37096
+ continue;
37097
+ }
37098
+ const macroDefinition = macroTags.get(phi.place.identifier.id);
37099
+ if (macroDefinition == null ||
37100
+ macroDefinition.level === InlineLevel.Shallow) {
37101
+ continue;
37102
+ }
37103
+ macroValues.add(phi.place.identifier.id);
37104
+ for (const operand of phi.operands.values()) {
37105
+ operand.identifier.scope = scope;
37106
+ expandFbtScopeRange(scope.range, operand.identifier.mutableRange);
37107
+ macroTags.set(operand.identifier.id, macroDefinition);
37108
+ macroValues.add(operand.identifier.id);
37109
+ }
37090
37110
  }
37091
37111
  }
37092
- if (methods.length > 0) {
37093
- return methods;
37094
- }
37095
- else {
37096
- return null;
37097
- }
37098
- }
37099
- function isFbtCallExpression(macroTagsCalls, value) {
37100
- return ((value.kind === 'CallExpression' &&
37101
- macroTagsCalls.has(value.callee.identifier.id)) ||
37102
- (value.kind === 'MethodCall' &&
37103
- macroTagsCalls.has(value.property.identifier.id)));
37104
- }
37105
- function isFbtJsxExpression(fbtMacroTags, macroTagsCalls, value) {
37106
- return (value.kind === 'JsxExpression' &&
37107
- ((value.tag.kind === 'Identifier' &&
37108
- macroTagsCalls.has(value.tag.identifier.id)) ||
37109
- (value.tag.kind === 'BuiltinTag' &&
37110
- matchesExactTag(value.tag.name, fbtMacroTags))));
37111
- }
37112
- function isFbtJsxChild(macroTagsCalls, lvalue, value) {
37113
- return ((value.kind === 'JsxExpression' || value.kind === 'JsxFragment') &&
37114
- lvalue !== null &&
37115
- macroTagsCalls.has(lvalue.identifier.id));
37112
+ return macroValues;
37116
37113
  }
37117
37114
  function expandFbtScopeRange(fbtRange, extendWith) {
37118
37115
  if (extendWith.start !== 0) {
37119
37116
  fbtRange.start = makeInstructionId(Math.min(fbtRange.start, extendWith.start));
37120
37117
  }
37121
37118
  }
37119
+ function visitOperands(macroDefinition, scope, lvalue, value, macroValues, macroTags) {
37120
+ macroValues.add(lvalue.identifier.id);
37121
+ for (const operand of eachInstructionValueOperand(value)) {
37122
+ if (macroDefinition.level === InlineLevel.Transitive) {
37123
+ operand.identifier.scope = scope;
37124
+ expandFbtScopeRange(scope.range, operand.identifier.mutableRange);
37125
+ macroTags.set(operand.identifier.id, macroDefinition);
37126
+ }
37127
+ macroValues.add(operand.identifier.id);
37128
+ }
37129
+ }
37122
37130
 
37123
37131
  var _Context_nextCacheIndex, _Context_declarations;
37124
37132
  const MEMO_CACHE_SENTINEL = 'react.memo_cache_sentinel';
@@ -40316,7 +40324,7 @@ function inferMutationAliasingEffects(fn, { isFunctionExpression } = {
40316
40324
  }
40317
40325
  queue(fn.body.entry, initialState);
40318
40326
  const hoistedContextDeclarations = findHoistedContextDeclarations(fn);
40319
- const context = new Context$1(isFunctionExpression, fn, hoistedContextDeclarations);
40327
+ const context = new Context$1(isFunctionExpression, fn, hoistedContextDeclarations, findNonMutatedDestructureSpreads(fn));
40320
40328
  let iterationCount = 0;
40321
40329
  while (queuedStates.size !== 0) {
40322
40330
  iterationCount++;
@@ -40380,7 +40388,7 @@ function findHoistedContextDeclarations(fn) {
40380
40388
  return hoisted;
40381
40389
  }
40382
40390
  let Context$1 = class Context {
40383
- constructor(isFunctionExpression, fn, hoistedContextDeclarations) {
40391
+ constructor(isFunctionExpression, fn, hoistedContextDeclarations, nonMutatingSpreads) {
40384
40392
  this.internedEffects = new Map();
40385
40393
  this.instructionSignatureCache = new Map();
40386
40394
  this.effectInstructionValueCache = new Map();
@@ -40390,6 +40398,7 @@ let Context$1 = class Context {
40390
40398
  this.isFuctionExpression = isFunctionExpression;
40391
40399
  this.fn = fn;
40392
40400
  this.hoistedContextDeclarations = hoistedContextDeclarations;
40401
+ this.nonMutatingSpreads = nonMutatingSpreads;
40393
40402
  }
40394
40403
  cacheApplySignature(signature, effect, f) {
40395
40404
  const inner = getOrInsertDefault(this.applySignatureCache, signature, new Map());
@@ -40405,6 +40414,114 @@ let Context$1 = class Context {
40405
40414
  return interned;
40406
40415
  }
40407
40416
  };
40417
+ function findNonMutatedDestructureSpreads(fn) {
40418
+ const knownFrozen = new Set();
40419
+ if (fn.fnType === 'Component') {
40420
+ const [props] = fn.params;
40421
+ if (props != null && props.kind === 'Identifier') {
40422
+ knownFrozen.add(props.identifier.id);
40423
+ }
40424
+ }
40425
+ else {
40426
+ for (const param of fn.params) {
40427
+ if (param.kind === 'Identifier') {
40428
+ knownFrozen.add(param.identifier.id);
40429
+ }
40430
+ }
40431
+ }
40432
+ const candidateNonMutatingSpreads = new Map();
40433
+ for (const block of fn.body.blocks.values()) {
40434
+ if (candidateNonMutatingSpreads.size !== 0) {
40435
+ for (const phi of block.phis) {
40436
+ for (const operand of phi.operands.values()) {
40437
+ const spread = candidateNonMutatingSpreads.get(operand.identifier.id);
40438
+ if (spread != null) {
40439
+ candidateNonMutatingSpreads.delete(spread);
40440
+ }
40441
+ }
40442
+ }
40443
+ }
40444
+ for (const instr of block.instructions) {
40445
+ const { lvalue, value } = instr;
40446
+ switch (value.kind) {
40447
+ case 'Destructure': {
40448
+ if (!knownFrozen.has(value.value.identifier.id) ||
40449
+ !(value.lvalue.kind === InstructionKind.Let ||
40450
+ value.lvalue.kind === InstructionKind.Const) ||
40451
+ value.lvalue.pattern.kind !== 'ObjectPattern') {
40452
+ continue;
40453
+ }
40454
+ for (const item of value.lvalue.pattern.properties) {
40455
+ if (item.kind !== 'Spread') {
40456
+ continue;
40457
+ }
40458
+ candidateNonMutatingSpreads.set(item.place.identifier.id, item.place.identifier.id);
40459
+ }
40460
+ break;
40461
+ }
40462
+ case 'LoadLocal': {
40463
+ const spread = candidateNonMutatingSpreads.get(value.place.identifier.id);
40464
+ if (spread != null) {
40465
+ candidateNonMutatingSpreads.set(lvalue.identifier.id, spread);
40466
+ }
40467
+ break;
40468
+ }
40469
+ case 'StoreLocal': {
40470
+ const spread = candidateNonMutatingSpreads.get(value.value.identifier.id);
40471
+ if (spread != null) {
40472
+ candidateNonMutatingSpreads.set(lvalue.identifier.id, spread);
40473
+ candidateNonMutatingSpreads.set(value.lvalue.place.identifier.id, spread);
40474
+ }
40475
+ break;
40476
+ }
40477
+ case 'JsxFragment':
40478
+ case 'JsxExpression': {
40479
+ break;
40480
+ }
40481
+ case 'PropertyLoad': {
40482
+ break;
40483
+ }
40484
+ case 'CallExpression':
40485
+ case 'MethodCall': {
40486
+ const callee = value.kind === 'CallExpression' ? value.callee : value.property;
40487
+ if (getHookKind(fn.env, callee.identifier) != null) {
40488
+ if (!isRefOrRefValue(lvalue.identifier)) {
40489
+ knownFrozen.add(lvalue.identifier.id);
40490
+ }
40491
+ }
40492
+ else {
40493
+ if (candidateNonMutatingSpreads.size !== 0) {
40494
+ for (const operand of eachInstructionValueOperand(value)) {
40495
+ const spread = candidateNonMutatingSpreads.get(operand.identifier.id);
40496
+ if (spread != null) {
40497
+ candidateNonMutatingSpreads.delete(spread);
40498
+ }
40499
+ }
40500
+ }
40501
+ }
40502
+ break;
40503
+ }
40504
+ default: {
40505
+ if (candidateNonMutatingSpreads.size !== 0) {
40506
+ for (const operand of eachInstructionValueOperand(value)) {
40507
+ const spread = candidateNonMutatingSpreads.get(operand.identifier.id);
40508
+ if (spread != null) {
40509
+ candidateNonMutatingSpreads.delete(spread);
40510
+ }
40511
+ }
40512
+ }
40513
+ }
40514
+ }
40515
+ }
40516
+ }
40517
+ const nonMutatingSpreads = new Set();
40518
+ for (const [key, value] of candidateNonMutatingSpreads) {
40519
+ if (key === value) {
40520
+ nonMutatingSpreads.add(key);
40521
+ }
40522
+ }
40523
+ return nonMutatingSpreads;
40524
+ }
40408
40525
  function inferParam(param, initialState, paramKind) {
40409
40526
  const place = param.kind === 'Identifier' ? param : param.place;
40410
40527
  const value = {
@@ -41659,7 +41776,9 @@ function computeSignatureForInstruction(context, env, instr) {
41659
41776
  kind: 'Create',
41660
41777
  into: place,
41661
41778
  reason: ValueReason.Other,
41662
- value: ValueKind.Mutable,
41779
+ value: context.nonMutatingSpreads.has(place.identifier.id)
41780
+ ? ValueKind.Frozen
41781
+ : ValueKind.Mutable,
41663
41782
  });
41664
41783
  effects.push({
41665
41784
  kind: 'Capture',
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "eslint-plugin-react-hooks",
3
3
  "description": "ESLint rules for React Hooks",
4
- "version": "7.0.0-canary-1324e1bb-20251016",
4
+ "version": "7.0.0-canary-f6a48828-20251019",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/facebook/react.git",