eslint-plugin-react-hooks 6.1.0-canary-12bc60f5-20250613 → 6.1.0-canary-06e89951-20250620

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.
@@ -17220,6 +17220,14 @@ function Set_intersect(sets) {
17220
17220
  }
17221
17221
  return result;
17222
17222
  }
17223
+ function Set_isSuperset(a, b) {
17224
+ for (const v of b) {
17225
+ if (!a.has(v)) {
17226
+ return false;
17227
+ }
17228
+ }
17229
+ return true;
17230
+ }
17223
17231
  function Iterable_some(iter, pred) {
17224
17232
  for (const item of iter) {
17225
17233
  if (pred(item)) {
@@ -17657,6 +17665,9 @@ var ValueReason;
17657
17665
  (function (ValueReason) {
17658
17666
  ValueReason["Global"] = "global";
17659
17667
  ValueReason["JsxCaptured"] = "jsx-captured";
17668
+ ValueReason["HookCaptured"] = "hook-captured";
17669
+ ValueReason["HookReturn"] = "hook-return";
17670
+ ValueReason["Effect"] = "effect";
17660
17671
  ValueReason["KnownReturnSignature"] = "known-return-signature";
17661
17672
  ValueReason["Context"] = "context";
17662
17673
  ValueReason["State"] = "state";
@@ -17681,6 +17692,19 @@ const ValueKindSchema = zod.z.enum([
17681
17692
  ValueKind.Mutable,
17682
17693
  ValueKind.Context,
17683
17694
  ]);
17695
+ const ValueReasonSchema = zod.z.enum([
17696
+ ValueReason.Context,
17697
+ ValueReason.Effect,
17698
+ ValueReason.Global,
17699
+ ValueReason.HookCaptured,
17700
+ ValueReason.HookReturn,
17701
+ ValueReason.JsxCaptured,
17702
+ ValueReason.KnownReturnSignature,
17703
+ ValueReason.Other,
17704
+ ValueReason.ReactiveFunctionArgument,
17705
+ ValueReason.ReducerState,
17706
+ ValueReason.State,
17707
+ ]);
17684
17708
  var Effect;
17685
17709
  (function (Effect) {
17686
17710
  Effect["Unknown"] = "<unknown>";
@@ -27056,12 +27080,15 @@ function printFunction(fn) {
27056
27080
  .join(', ') +
27057
27081
  ')';
27058
27082
  }
27083
+ else {
27084
+ definition += '()';
27085
+ }
27059
27086
  if (definition.length !== 0) {
27060
27087
  output.push(definition);
27061
27088
  }
27062
- output.push(printType(fn.returnType));
27063
- output.push(printHIR(fn.body));
27089
+ output.push(`: ${printType(fn.returnType)} @ ${printPlace(fn.returns)}`);
27064
27090
  output.push(...fn.directives);
27091
+ output.push(printHIR(fn.body));
27065
27092
  return output.join('\n');
27066
27093
  }
27067
27094
  function printHIR(ir, options = null) {
@@ -27136,7 +27163,10 @@ function printMixedHIR(value) {
27136
27163
  }
27137
27164
  function printInstruction(instr) {
27138
27165
  const id = `[${instr.id}]`;
27139
- const value = printInstructionValue(instr.value);
27166
+ let value = printInstructionValue(instr.value);
27167
+ if (instr.effects != null) {
27168
+ value += `\n ${instr.effects.map(printAliasingEffect).join('\n ')}`;
27169
+ }
27140
27170
  if (instr.lvalue !== null) {
27141
27171
  return `${id} ${printPlace(instr.lvalue)} = ${value}`;
27142
27172
  }
@@ -27187,6 +27217,9 @@ function printTerminal(terminal) {
27187
27217
  }
27188
27218
  case 'return': {
27189
27219
  value = `[${terminal.id}] Return${terminal.value != null ? ' ' + printPlace(terminal.value) : ''}`;
27220
+ if (terminal.effects != null) {
27221
+ value += `\n ${terminal.effects.map(printAliasingEffect).join('\n ')}`;
27222
+ }
27190
27223
  break;
27191
27224
  }
27192
27225
  case 'goto': {
@@ -27248,6 +27281,9 @@ function printTerminal(terminal) {
27248
27281
  }
27249
27282
  case 'maybe-throw': {
27250
27283
  value = `[${terminal.id}] MaybeThrow continuation=bb${terminal.continuation} handler=bb${terminal.handler}`;
27284
+ if (terminal.effects != null) {
27285
+ value += `\n ${terminal.effects.map(printAliasingEffect).join('\n ')}`;
27286
+ }
27251
27287
  break;
27252
27288
  }
27253
27289
  case 'scope': {
@@ -27288,7 +27324,7 @@ function printObjectPropertyKey(key) {
27288
27324
  }
27289
27325
  }
27290
27326
  function printInstructionValue(instrValue) {
27291
- var _a, _b, _c, _d;
27327
+ var _a, _b, _c, _d, _e, _f, _g;
27292
27328
  let value = '';
27293
27329
  switch (instrValue.kind) {
27294
27330
  case 'ArrayExpression': {
@@ -27471,8 +27507,8 @@ function printInstructionValue(instrValue) {
27471
27507
  return `GlobalMutation`;
27472
27508
  }
27473
27509
  }).join(', ')) !== null && _b !== void 0 ? _b : '';
27474
- const type = printType(instrValue.loweredFunc.func.returnType).trim();
27475
- value = `${kind} ${name} @context[${context}] @effects[${effects}]${type !== '' ? ` return${type}` : ''}:\n${fn}`;
27510
+ const aliasingEffects = (_e = (_d = (_c = instrValue.loweredFunc.func.aliasingEffects) === null || _c === void 0 ? void 0 : _c.map(printAliasingEffect)) === null || _d === void 0 ? void 0 : _d.join(', ')) !== null && _e !== void 0 ? _e : '';
27511
+ value = `${kind} ${name} @context[${context}] @effects[${effects}] @aliasingEffects=[${aliasingEffects}]\n${fn}`;
27476
27512
  break;
27477
27513
  }
27478
27514
  case 'TaggedTemplateExpression': {
@@ -27588,7 +27624,7 @@ function printInstructionValue(instrValue) {
27588
27624
  break;
27589
27625
  }
27590
27626
  case 'StartMemoize': {
27591
- value = `StartMemoize deps=${(_d = (_c = instrValue.deps) === null || _c === void 0 ? void 0 : _c.map(dep => printManualMemoDependency(dep, false))) !== null && _d !== void 0 ? _d : '(none)'}`;
27627
+ value = `StartMemoize deps=${(_g = (_f = instrValue.deps) === null || _f === void 0 ? void 0 : _f.map(dep => printManualMemoDependency(dep, false))) !== null && _g !== void 0 ? _g : '(none)'}`;
27592
27628
  break;
27593
27629
  }
27594
27630
  case 'FinishMemoize': {
@@ -27732,6 +27768,106 @@ function getFunctionName$2(instrValue, defaultValue) {
27732
27768
  return defaultValue;
27733
27769
  }
27734
27770
  }
27771
+ function printAliasingEffect(effect) {
27772
+ switch (effect.kind) {
27773
+ case 'Assign': {
27774
+ return `Assign ${printPlaceForAliasEffect(effect.into)} = ${printPlaceForAliasEffect(effect.from)}`;
27775
+ }
27776
+ case 'Alias': {
27777
+ return `Alias ${printPlaceForAliasEffect(effect.into)} = ${printPlaceForAliasEffect(effect.from)}`;
27778
+ }
27779
+ case 'Capture': {
27780
+ return `Capture ${printPlaceForAliasEffect(effect.into)} <- ${printPlaceForAliasEffect(effect.from)}`;
27781
+ }
27782
+ case 'ImmutableCapture': {
27783
+ return `ImmutableCapture ${printPlaceForAliasEffect(effect.into)} <- ${printPlaceForAliasEffect(effect.from)}`;
27784
+ }
27785
+ case 'Create': {
27786
+ return `Create ${printPlaceForAliasEffect(effect.into)} = ${effect.value}`;
27787
+ }
27788
+ case 'CreateFrom': {
27789
+ return `Create ${printPlaceForAliasEffect(effect.into)} = kindOf(${printPlaceForAliasEffect(effect.from)})`;
27790
+ }
27791
+ case 'CreateFunction': {
27792
+ return `Function ${printPlaceForAliasEffect(effect.into)} = Function captures=[${effect.captures.map(printPlaceForAliasEffect).join(', ')}]`;
27793
+ }
27794
+ case 'Apply': {
27795
+ const receiverCallee = effect.receiver.identifier.id === effect.function.identifier.id
27796
+ ? printPlaceForAliasEffect(effect.receiver)
27797
+ : `${printPlaceForAliasEffect(effect.receiver)}.${printPlaceForAliasEffect(effect.function)}`;
27798
+ const args = effect.args
27799
+ .map(arg => {
27800
+ if (arg.kind === 'Identifier') {
27801
+ return printPlaceForAliasEffect(arg);
27802
+ }
27803
+ else if (arg.kind === 'Hole') {
27804
+ return ' ';
27805
+ }
27806
+ return `...${printPlaceForAliasEffect(arg.place)}`;
27807
+ })
27808
+ .join(', ');
27809
+ let signature = '';
27810
+ if (effect.signature != null) {
27811
+ if (effect.signature.aliasing != null) {
27812
+ signature = printAliasingSignature(effect.signature.aliasing);
27813
+ }
27814
+ else {
27815
+ signature = JSON.stringify(effect.signature, null, 2);
27816
+ }
27817
+ }
27818
+ return `Apply ${printPlaceForAliasEffect(effect.into)} = ${receiverCallee}(${args})${signature != '' ? '\n ' : ''}${signature}`;
27819
+ }
27820
+ case 'Freeze': {
27821
+ return `Freeze ${printPlaceForAliasEffect(effect.value)} ${effect.reason}`;
27822
+ }
27823
+ case 'Mutate':
27824
+ case 'MutateConditionally':
27825
+ case 'MutateTransitive':
27826
+ case 'MutateTransitiveConditionally': {
27827
+ return `${effect.kind} ${printPlaceForAliasEffect(effect.value)}`;
27828
+ }
27829
+ case 'MutateFrozen': {
27830
+ return `MutateFrozen ${printPlaceForAliasEffect(effect.place)} reason=${JSON.stringify(effect.error.reason)}`;
27831
+ }
27832
+ case 'MutateGlobal': {
27833
+ return `MutateGlobal ${printPlaceForAliasEffect(effect.place)} reason=${JSON.stringify(effect.error.reason)}`;
27834
+ }
27835
+ case 'Impure': {
27836
+ return `Impure ${printPlaceForAliasEffect(effect.place)} reason=${JSON.stringify(effect.error.reason)}`;
27837
+ }
27838
+ case 'Render': {
27839
+ return `Render ${printPlaceForAliasEffect(effect.place)}`;
27840
+ }
27841
+ default: {
27842
+ assertExhaustive$1(effect, `Unexpected kind '${effect.kind}'`);
27843
+ }
27844
+ }
27845
+ }
27846
+ function printPlaceForAliasEffect(place) {
27847
+ return printIdentifier(place.identifier);
27848
+ }
27849
+ function printAliasingSignature(signature) {
27850
+ const tokens = ['function '];
27851
+ if (signature.temporaries.length !== 0) {
27852
+ tokens.push('<');
27853
+ tokens.push(signature.temporaries.map(temp => `$${temp.identifier.id}`).join(', '));
27854
+ tokens.push('>');
27855
+ }
27856
+ tokens.push('(');
27857
+ tokens.push('this=$' + String(signature.receiver));
27858
+ for (const param of signature.params) {
27859
+ tokens.push(', $' + String(param));
27860
+ }
27861
+ if (signature.rest != null) {
27862
+ tokens.push(`, ...$${String(signature.rest)}`);
27863
+ }
27864
+ tokens.push('): ');
27865
+ tokens.push('$' + String(signature.returns) + ':');
27866
+ for (const effect of signature.effects) {
27867
+ tokens.push('\n ' + printAliasingEffect(effect));
27868
+ }
27869
+ return tokens.join('');
27870
+ }
27735
27871
 
27736
27872
  var _ScopeBlockTraversal_activeScopes;
27737
27873
  function* eachInstructionLValue(instr) {
@@ -28391,6 +28527,7 @@ function mapTerminalSuccessors(terminal, fn) {
28391
28527
  loc: terminal.loc,
28392
28528
  value: terminal.value,
28393
28529
  id: makeInstructionId(0),
28530
+ effects: terminal.effects,
28394
28531
  };
28395
28532
  }
28396
28533
  case 'throw': {
@@ -28498,6 +28635,7 @@ function mapTerminalSuccessors(terminal, fn) {
28498
28635
  handler,
28499
28636
  id: makeInstructionId(0),
28500
28637
  loc: terminal.loc,
28638
+ effects: terminal.effects,
28501
28639
  };
28502
28640
  }
28503
28641
  case 'try': {
@@ -28993,33 +29131,36 @@ function assertValidBlockNesting(fn) {
28993
29131
  function assertValidMutableRanges(fn) {
28994
29132
  for (const [, block] of fn.body.blocks) {
28995
29133
  for (const phi of block.phis) {
28996
- visitIdentifier(phi.place.identifier);
28997
- for (const [, operand] of phi.operands) {
28998
- visitIdentifier(operand.identifier);
29134
+ visit$2(phi.place, `phi for block bb${block.id}`);
29135
+ for (const [pred, operand] of phi.operands) {
29136
+ visit$2(operand, `phi predecessor bb${pred} for block bb${block.id}`);
28999
29137
  }
29000
29138
  }
29001
29139
  for (const instr of block.instructions) {
29002
29140
  for (const operand of eachInstructionLValue(instr)) {
29003
- visitIdentifier(operand.identifier);
29141
+ visit$2(operand, `instruction [${instr.id}]`);
29004
29142
  }
29005
29143
  for (const operand of eachInstructionOperand(instr)) {
29006
- visitIdentifier(operand.identifier);
29144
+ visit$2(operand, `instruction [${instr.id}]`);
29007
29145
  }
29008
29146
  }
29009
29147
  for (const operand of eachTerminalOperand(block.terminal)) {
29010
- visitIdentifier(operand.identifier);
29148
+ visit$2(operand, `terminal [${block.terminal.id}]`);
29011
29149
  }
29012
29150
  }
29013
29151
  }
29014
- function visitIdentifier(identifier) {
29015
- validateMutableRange(identifier.mutableRange);
29016
- if (identifier.scope !== null) {
29017
- validateMutableRange(identifier.scope.range);
29152
+ function visit$2(place, description) {
29153
+ validateMutableRange(place, place.identifier.mutableRange, description);
29154
+ if (place.identifier.scope !== null) {
29155
+ validateMutableRange(place, place.identifier.scope.range, description);
29018
29156
  }
29019
29157
  }
29020
- function validateMutableRange(mutableRange) {
29021
- invariant((mutableRange.start === 0 && mutableRange.end === 0) ||
29022
- mutableRange.end > mutableRange.start, 'Identifier scope mutableRange was invalid: [%s:%s]', mutableRange.start, mutableRange.end);
29158
+ function validateMutableRange(place, range, description) {
29159
+ CompilerError.invariant((range.start === 0 && range.end === 0) || range.end > range.start, {
29160
+ reason: `Invalid mutable range: [${range.start}:${range.end}]`,
29161
+ description: `${printPlace(place)} in ${description}`,
29162
+ loc: place.loc,
29163
+ });
29023
29164
  }
29024
29165
 
29025
29166
  var _HIRBuilder_instances, _HIRBuilder_completed, _HIRBuilder_current, _HIRBuilder_entry, _HIRBuilder_scopes, _HIRBuilder_context, _HIRBuilder_bindings, _HIRBuilder_env, _HIRBuilder_exceptionHandlerStack, _HIRBuilder_resolveBabelBinding;
@@ -29054,7 +29195,7 @@ class HIRBuilder {
29054
29195
  this.fbtDepth = 0;
29055
29196
  __classPrivateFieldSet(this, _HIRBuilder_env, env, "f");
29056
29197
  __classPrivateFieldSet(this, _HIRBuilder_bindings, (_a = options === null || options === void 0 ? void 0 : options.bindings) !== null && _a !== void 0 ? _a : new Map(), "f");
29057
- __classPrivateFieldSet(this, _HIRBuilder_context, (_b = options === null || options === void 0 ? void 0 : options.context) !== null && _b !== void 0 ? _b : [], "f");
29198
+ __classPrivateFieldSet(this, _HIRBuilder_context, (_b = options === null || options === void 0 ? void 0 : options.context) !== null && _b !== void 0 ? _b : new Map(), "f");
29058
29199
  __classPrivateFieldSet(this, _HIRBuilder_entry, makeBlockId(env.nextBlockId), "f");
29059
29200
  __classPrivateFieldSet(this, _HIRBuilder_current, newBlock(__classPrivateFieldGet(this, _HIRBuilder_entry, "f"), (_c = options === null || options === void 0 ? void 0 : options.entryBlockKind) !== null && _c !== void 0 ? _c : 'block'), "f");
29060
29201
  }
@@ -29072,6 +29213,7 @@ class HIRBuilder {
29072
29213
  handler: exceptionHandler,
29073
29214
  id: makeInstructionId(0),
29074
29215
  loc: instruction.loc,
29216
+ effects: null,
29075
29217
  }, continuationBlock);
29076
29218
  }
29077
29219
  }
@@ -29585,7 +29727,10 @@ function createAnonId() {
29585
29727
  }
29586
29728
  function addFunction(registry, properties, fn, id = null, isConstructor = false) {
29587
29729
  const shapeId = id !== null && id !== void 0 ? id : createAnonId();
29588
- addShape(registry, shapeId, properties, Object.assign(Object.assign({}, fn), { hookKind: null }));
29730
+ const aliasing = fn.aliasing != null
29731
+ ? parseAliasingSignatureConfig(fn.aliasing, '<builtin>', GeneratedSource)
29732
+ : null;
29733
+ addShape(registry, shapeId, properties, Object.assign(Object.assign({}, fn), { aliasing, hookKind: null }));
29589
29734
  return {
29590
29735
  kind: 'Function',
29591
29736
  return: fn.returnType,
@@ -29595,7 +29740,10 @@ function addFunction(registry, properties, fn, id = null, isConstructor = false)
29595
29740
  }
29596
29741
  function addHook(registry, fn, id = null) {
29597
29742
  const shapeId = id !== null && id !== void 0 ? id : createAnonId();
29598
- addShape(registry, shapeId, [], fn);
29743
+ const aliasing = fn.aliasing != null
29744
+ ? parseAliasingSignatureConfig(fn.aliasing, '<builtin>', GeneratedSource)
29745
+ : null;
29746
+ addShape(registry, shapeId, [], Object.assign(Object.assign({}, fn), { aliasing }));
29599
29747
  return {
29600
29748
  kind: 'Function',
29601
29749
  return: fn.returnType,
@@ -29603,6 +29751,119 @@ function addHook(registry, fn, id = null) {
29603
29751
  isConstructor: false,
29604
29752
  };
29605
29753
  }
29754
+ function parseAliasingSignatureConfig(typeConfig, moduleName, loc) {
29755
+ const lifetimes = new Map();
29756
+ function define(temp) {
29757
+ CompilerError.invariant(!lifetimes.has(temp), {
29758
+ reason: `Invalid type configuration for module`,
29759
+ description: `Expected aliasing signature to have unique names for receiver, params, rest, returns, and temporaries in module '${moduleName}'`,
29760
+ loc,
29761
+ });
29762
+ const place = signatureArgument(lifetimes.size);
29763
+ lifetimes.set(temp, place);
29764
+ return place;
29765
+ }
29766
+ function lookup(temp) {
29767
+ const place = lifetimes.get(temp);
29768
+ CompilerError.invariant(place != null, {
29769
+ reason: `Invalid type configuration for module`,
29770
+ description: `Expected aliasing signature effects to reference known names from receiver/params/rest/returns/temporaries, but '${temp}' is not a known name in '${moduleName}'`,
29771
+ loc,
29772
+ });
29773
+ return place;
29774
+ }
29775
+ const receiver = define(typeConfig.receiver);
29776
+ const params = typeConfig.params.map(define);
29777
+ const rest = typeConfig.rest != null ? define(typeConfig.rest) : null;
29778
+ const returns = define(typeConfig.returns);
29779
+ const temporaries = typeConfig.temporaries.map(define);
29780
+ const effects = typeConfig.effects.map((effect) => {
29781
+ switch (effect.kind) {
29782
+ case 'CreateFrom':
29783
+ case 'Capture':
29784
+ case 'Alias':
29785
+ case 'Assign': {
29786
+ const from = lookup(effect.from);
29787
+ const into = lookup(effect.into);
29788
+ return {
29789
+ kind: effect.kind,
29790
+ from,
29791
+ into,
29792
+ };
29793
+ }
29794
+ case 'Mutate':
29795
+ case 'MutateTransitiveConditionally': {
29796
+ const value = lookup(effect.value);
29797
+ return { kind: effect.kind, value };
29798
+ }
29799
+ case 'Create': {
29800
+ const into = lookup(effect.into);
29801
+ return {
29802
+ kind: 'Create',
29803
+ into,
29804
+ reason: effect.reason,
29805
+ value: effect.value,
29806
+ };
29807
+ }
29808
+ case 'Freeze': {
29809
+ const value = lookup(effect.value);
29810
+ return {
29811
+ kind: 'Freeze',
29812
+ value,
29813
+ reason: effect.reason,
29814
+ };
29815
+ }
29816
+ case 'Impure': {
29817
+ const place = lookup(effect.place);
29818
+ return {
29819
+ kind: 'Impure',
29820
+ place,
29821
+ error: CompilerError.throwTodo({
29822
+ reason: 'Support impure effect declarations',
29823
+ loc: GeneratedSource,
29824
+ }),
29825
+ };
29826
+ }
29827
+ case 'Apply': {
29828
+ const receiver = lookup(effect.receiver);
29829
+ const fn = lookup(effect.function);
29830
+ const args = effect.args.map(arg => {
29831
+ if (typeof arg === 'string') {
29832
+ return lookup(arg);
29833
+ }
29834
+ else if (arg.kind === 'Spread') {
29835
+ return { kind: 'Spread', place: lookup(arg.place) };
29836
+ }
29837
+ else {
29838
+ return arg;
29839
+ }
29840
+ });
29841
+ const into = lookup(effect.into);
29842
+ return {
29843
+ kind: 'Apply',
29844
+ receiver,
29845
+ function: fn,
29846
+ mutatesFunction: effect.mutatesFunction,
29847
+ args,
29848
+ into,
29849
+ loc,
29850
+ signature: null,
29851
+ };
29852
+ }
29853
+ default: {
29854
+ assertExhaustive$1(effect, `Unexpected effect kind '${effect.kind}'`);
29855
+ }
29856
+ }
29857
+ });
29858
+ return {
29859
+ receiver: receiver.identifier.id,
29860
+ params: params.map(p => p.identifier.id),
29861
+ rest: rest != null ? rest.identifier.id : null,
29862
+ returns: returns.identifier.id,
29863
+ temporaries,
29864
+ effects,
29865
+ };
29866
+ }
29606
29867
  function addObject(registry, id, properties) {
29607
29868
  const shapeId = id !== null && id !== void 0 ? id : createAnonId();
29608
29869
  addShape(registry, shapeId, properties, null);
@@ -29722,6 +29983,27 @@ addObject(BUILTIN_SHAPES, BuiltInArrayId, [
29722
29983
  returnType: PRIMITIVE_TYPE,
29723
29984
  calleeEffect: Effect.Store,
29724
29985
  returnValueKind: ValueKind.Primitive,
29986
+ aliasing: {
29987
+ receiver: '@receiver',
29988
+ params: [],
29989
+ rest: '@rest',
29990
+ returns: '@returns',
29991
+ temporaries: [],
29992
+ effects: [
29993
+ { kind: 'Mutate', value: '@receiver' },
29994
+ {
29995
+ kind: 'Capture',
29996
+ from: '@rest',
29997
+ into: '@receiver',
29998
+ },
29999
+ {
30000
+ kind: 'Create',
30001
+ into: '@returns',
30002
+ value: ValueKind.Primitive,
30003
+ reason: ValueReason.KnownReturnSignature,
30004
+ },
30005
+ ],
30006
+ },
29725
30007
  }),
29726
30008
  ],
29727
30009
  [
@@ -29747,6 +30029,49 @@ addObject(BUILTIN_SHAPES, BuiltInArrayId, [
29747
30029
  returnValueKind: ValueKind.Mutable,
29748
30030
  noAlias: true,
29749
30031
  mutableOnlyIfOperandsAreMutable: true,
30032
+ aliasing: {
30033
+ receiver: '@receiver',
30034
+ params: ['@callback'],
30035
+ rest: null,
30036
+ returns: '@returns',
30037
+ temporaries: [
30038
+ '@item',
30039
+ '@callbackReturn',
30040
+ '@thisArg',
30041
+ ],
30042
+ effects: [
30043
+ {
30044
+ kind: 'Create',
30045
+ into: '@returns',
30046
+ value: ValueKind.Mutable,
30047
+ reason: ValueReason.KnownReturnSignature,
30048
+ },
30049
+ {
30050
+ kind: 'CreateFrom',
30051
+ from: '@receiver',
30052
+ into: '@item',
30053
+ },
30054
+ {
30055
+ kind: 'Create',
30056
+ into: '@thisArg',
30057
+ value: ValueKind.Primitive,
30058
+ reason: ValueReason.KnownReturnSignature,
30059
+ },
30060
+ {
30061
+ kind: 'Apply',
30062
+ receiver: '@thisArg',
30063
+ args: ['@item', { kind: 'Hole' }, '@receiver'],
30064
+ function: '@callback',
30065
+ into: '@callbackReturn',
30066
+ mutatesFunction: false,
30067
+ },
30068
+ {
30069
+ kind: 'Capture',
30070
+ from: '@callbackReturn',
30071
+ into: '@returns',
30072
+ },
30073
+ ],
30074
+ },
29750
30075
  }),
29751
30076
  ],
29752
30077
  [
@@ -29853,6 +30178,29 @@ addObject(BUILTIN_SHAPES, BuiltInSetId, [
29853
30178
  returnType: { kind: 'Object', shapeId: BuiltInSetId },
29854
30179
  calleeEffect: Effect.Store,
29855
30180
  returnValueKind: ValueKind.Mutable,
30181
+ aliasing: {
30182
+ receiver: '@receiver',
30183
+ params: [],
30184
+ rest: '@rest',
30185
+ returns: '@returns',
30186
+ temporaries: [],
30187
+ effects: [
30188
+ {
30189
+ kind: 'Assign',
30190
+ from: '@receiver',
30191
+ into: '@returns',
30192
+ },
30193
+ {
30194
+ kind: 'Mutate',
30195
+ value: '@receiver',
30196
+ },
30197
+ {
30198
+ kind: 'Capture',
30199
+ from: '@rest',
30200
+ into: '@receiver',
30201
+ },
30202
+ ],
30203
+ },
29856
30204
  }),
29857
30205
  ],
29858
30206
  [
@@ -30390,22 +30738,65 @@ const DefaultNonmutatingHook = addHook(BUILTIN_SHAPES, {
30390
30738
  calleeEffect: Effect.Read,
30391
30739
  hookKind: 'Custom',
30392
30740
  returnValueKind: ValueKind.Frozen,
30741
+ aliasing: {
30742
+ receiver: '@receiver',
30743
+ params: [],
30744
+ rest: '@rest',
30745
+ returns: '@returns',
30746
+ temporaries: [],
30747
+ effects: [
30748
+ {
30749
+ kind: 'Freeze',
30750
+ value: '@rest',
30751
+ reason: ValueReason.HookCaptured,
30752
+ },
30753
+ {
30754
+ kind: 'Create',
30755
+ into: '@returns',
30756
+ value: ValueKind.Frozen,
30757
+ reason: ValueReason.HookReturn,
30758
+ },
30759
+ {
30760
+ kind: 'Alias',
30761
+ from: '@rest',
30762
+ into: '@returns',
30763
+ },
30764
+ ],
30765
+ },
30393
30766
  }, 'DefaultNonmutatingHook');
30767
+ function signatureArgument(id) {
30768
+ const place = {
30769
+ kind: 'Identifier',
30770
+ effect: Effect.Unknown,
30771
+ loc: GeneratedSource,
30772
+ reactive: false,
30773
+ identifier: {
30774
+ declarationId: makeDeclarationId(id),
30775
+ id: makeIdentifierId(id),
30776
+ loc: GeneratedSource,
30777
+ mutableRange: { start: makeInstructionId(0), end: makeInstructionId(0) },
30778
+ name: null,
30779
+ scope: null,
30780
+ type: makeType(),
30781
+ },
30782
+ };
30783
+ return place;
30784
+ }
30394
30785
 
30395
- function lower$1(func, env, bindings = null, capturedRefs = []) {
30786
+ function lower$1(func, env, bindings = null, capturedRefs = new Map()) {
30396
30787
  var _a, _b, _c;
30397
30788
  const builder = new HIRBuilder(env, {
30398
30789
  bindings,
30399
30790
  context: capturedRefs,
30400
30791
  });
30401
30792
  const context = [];
30402
- for (const ref of capturedRefs !== null && capturedRefs !== void 0 ? capturedRefs : []) {
30793
+ for (const [ref, loc] of capturedRefs !== null && capturedRefs !== void 0 ? capturedRefs : []) {
30403
30794
  context.push({
30404
30795
  kind: 'Identifier',
30405
30796
  identifier: builder.resolveBinding(ref),
30406
30797
  effect: Effect.Unknown,
30407
30798
  reactive: false,
30408
- loc: (_a = ref.loc) !== null && _a !== void 0 ? _a : GeneratedSource,
30799
+ loc,
30409
30800
  });
30410
30801
  }
30411
30802
  let id = null;
@@ -30484,6 +30875,7 @@ function lower$1(func, env, bindings = null, capturedRefs = []) {
30484
30875
  loc: GeneratedSource,
30485
30876
  value: lowerExpressionToTemporary(builder, body),
30486
30877
  id: makeInstructionId(0),
30878
+ effects: null,
30487
30879
  };
30488
30880
  builder.terminateWithContinuation(terminal, fallthrough);
30489
30881
  }
@@ -30496,7 +30888,7 @@ function lower$1(func, env, bindings = null, capturedRefs = []) {
30496
30888
  severity: ErrorSeverity.InvalidJS,
30497
30889
  reason: `Unexpected function body kind`,
30498
30890
  description: `Expected function body to be an expression or a block statement, got \`${body.type}\``,
30499
- loc: (_b = body.node.loc) !== null && _b !== void 0 ? _b : null,
30891
+ loc: (_a = body.node.loc) !== null && _a !== void 0 ? _a : null,
30500
30892
  suggestions: null,
30501
30893
  });
30502
30894
  }
@@ -30512,6 +30904,7 @@ function lower$1(func, env, bindings = null, capturedRefs = []) {
30512
30904
  loc: GeneratedSource,
30513
30905
  }),
30514
30906
  id: makeInstructionId(0),
30907
+ effects: null,
30515
30908
  }, null);
30516
30909
  return Ok({
30517
30910
  id,
@@ -30519,6 +30912,7 @@ function lower$1(func, env, bindings = null, capturedRefs = []) {
30519
30912
  fnType: bindings == null ? env.fnType : 'Other',
30520
30913
  returnTypeAnnotation: null,
30521
30914
  returnType: makeType(),
30915
+ returns: createTemporaryPlace(env, (_b = func.node.loc) !== null && _b !== void 0 ? _b : GeneratedSource),
30522
30916
  body: builder.build(),
30523
30917
  context,
30524
30918
  generator: func.node.generator === true,
@@ -30526,6 +30920,7 @@ function lower$1(func, env, bindings = null, capturedRefs = []) {
30526
30920
  loc: (_c = func.node.loc) !== null && _c !== void 0 ? _c : GeneratedSource,
30527
30921
  env,
30528
30922
  effects: null,
30923
+ aliasingEffects: null,
30529
30924
  directives,
30530
30925
  });
30531
30926
  }
@@ -30573,6 +30968,7 @@ function lowerStatement(builder, stmtPath, label = null) {
30573
30968
  loc: (_c = stmt.node.loc) !== null && _c !== void 0 ? _c : GeneratedSource,
30574
30969
  value,
30575
30970
  id: makeInstructionId(0),
30971
+ effects: null,
30576
30972
  };
30577
30973
  builder.terminate(terminal, 'block');
30578
30974
  return;
@@ -31323,6 +31719,7 @@ function lowerStatement(builder, stmtPath, label = null) {
31323
31719
  kind: 'Debugger',
31324
31720
  loc,
31325
31721
  },
31722
+ effects: null,
31326
31723
  loc,
31327
31724
  });
31328
31725
  return;
@@ -31918,6 +32315,7 @@ function lowerExpression(builder, exprPath) {
31918
32315
  place: leftValue,
31919
32316
  loc: exprLoc,
31920
32317
  },
32318
+ effects: null,
31921
32319
  loc: exprLoc,
31922
32320
  });
31923
32321
  builder.terminateWithContinuation({
@@ -32743,6 +33141,7 @@ function lowerOptionalCallExpression(builder, expr, parentAlternate) {
32743
33141
  args,
32744
33142
  loc,
32745
33143
  },
33144
+ effects: null,
32746
33145
  loc,
32747
33146
  });
32748
33147
  }
@@ -32757,6 +33156,7 @@ function lowerOptionalCallExpression(builder, expr, parentAlternate) {
32757
33156
  args,
32758
33157
  loc,
32759
33158
  },
33159
+ effects: null,
32760
33160
  loc,
32761
33161
  });
32762
33162
  }
@@ -33191,10 +33591,7 @@ function lowerFunctionToValue(builder, expr) {
33191
33591
  function lowerFunction(builder, expr) {
33192
33592
  const componentScope = builder.environment.parentFunction.scope;
33193
33593
  const capturedContext = gatherCapturedContext(expr, componentScope);
33194
- const lowering = lower$1(expr, builder.environment, builder.bindings, [
33195
- ...builder.context,
33196
- ...capturedContext,
33197
- ]);
33594
+ const lowering = lower$1(expr, builder.environment, builder.bindings, new Map([...builder.context, ...capturedContext]));
33198
33595
  let loweredFunc;
33199
33596
  if (lowering.isErr()) {
33200
33597
  lowering
@@ -33218,9 +33615,10 @@ function lowerValueToTemporary(builder, value) {
33218
33615
  const place = buildTemporaryPlace(builder, value.loc);
33219
33616
  builder.push({
33220
33617
  id: makeInstructionId(0),
33618
+ lvalue: Object.assign({}, place),
33221
33619
  value: value,
33620
+ effects: null,
33222
33621
  loc: value.loc,
33223
- lvalue: Object.assign({}, place),
33224
33622
  });
33225
33623
  return place;
33226
33624
  }
@@ -33773,12 +34171,13 @@ function captureScopes({ from, to }) {
33773
34171
  return scopes;
33774
34172
  }
33775
34173
  function gatherCapturedContext(fn, componentScope) {
33776
- const capturedIds = new Set();
34174
+ const capturedIds = new Map();
33777
34175
  const pureScopes = captureScopes({
33778
34176
  from: fn.scope.parent,
33779
34177
  to: componentScope,
33780
34178
  });
33781
34179
  function handleMaybeDependency(path) {
34180
+ var _a, _b;
33782
34181
  let baseIdentifier;
33783
34182
  if (path.isJSXOpeningElement()) {
33784
34183
  const name = path.get('name');
@@ -33797,8 +34196,10 @@ function gatherCapturedContext(fn, componentScope) {
33797
34196
  }
33798
34197
  path.skip();
33799
34198
  const binding = baseIdentifier.scope.getBinding(baseIdentifier.node.name);
33800
- if (binding !== undefined && pureScopes.has(binding.scope)) {
33801
- capturedIds.add(binding.identifier);
34199
+ if (binding !== undefined &&
34200
+ pureScopes.has(binding.scope) &&
34201
+ !capturedIds.has(binding.identifier)) {
34202
+ capturedIds.set(binding.identifier, (_b = (_a = path.node.loc) !== null && _a !== void 0 ? _a : binding.identifier.loc) !== null && _b !== void 0 ? _b : GeneratedSource);
33802
34203
  }
33803
34204
  }
33804
34205
  fn.traverse({
@@ -33830,7 +34231,7 @@ function gatherCapturedContext(fn, componentScope) {
33830
34231
  }
33831
34232
  },
33832
34233
  });
33833
- return [...capturedIds.keys()];
34234
+ return capturedIds;
33834
34235
  }
33835
34236
  function notNull(value) {
33836
34237
  return value !== null;
@@ -38175,6 +38576,37 @@ const REACT_APIS = [
38175
38576
  calleeEffect: Effect.Read,
38176
38577
  hookKind: 'useEffect',
38177
38578
  returnValueKind: ValueKind.Frozen,
38579
+ aliasing: {
38580
+ receiver: '@receiver',
38581
+ params: [],
38582
+ rest: '@rest',
38583
+ returns: '@returns',
38584
+ temporaries: ['@effect'],
38585
+ effects: [
38586
+ {
38587
+ kind: 'Freeze',
38588
+ value: '@rest',
38589
+ reason: ValueReason.Effect,
38590
+ },
38591
+ {
38592
+ kind: 'Create',
38593
+ into: '@effect',
38594
+ value: ValueKind.Frozen,
38595
+ reason: ValueReason.KnownReturnSignature,
38596
+ },
38597
+ {
38598
+ kind: 'Capture',
38599
+ from: '@rest',
38600
+ into: '@effect',
38601
+ },
38602
+ {
38603
+ kind: 'Create',
38604
+ into: '@returns',
38605
+ value: ValueKind.Primitive,
38606
+ reason: ValueReason.KnownReturnSignature,
38607
+ },
38608
+ ],
38609
+ },
38178
38610
  }, BuiltInUseEffectHookId),
38179
38611
  ],
38180
38612
  [
@@ -38342,6 +38774,7 @@ function installTypeConfig(globals, shapes, typeConfig, moduleName, loc) {
38342
38774
  returnValueKind: typeConfig.returnValueKind,
38343
38775
  noAlias: typeConfig.noAlias === true,
38344
38776
  mutableOnlyIfOperandsAreMutable: typeConfig.mutableOnlyIfOperandsAreMutable === true,
38777
+ aliasing: typeConfig.aliasing,
38345
38778
  });
38346
38779
  }
38347
38780
  case 'hook': {
@@ -38353,6 +38786,7 @@ function installTypeConfig(globals, shapes, typeConfig, moduleName, loc) {
38353
38786
  returnType: installTypeConfig(globals, shapes, typeConfig.returnType, moduleName, loc),
38354
38787
  returnValueKind: (_c = typeConfig.returnValueKind) !== null && _c !== void 0 ? _c : ValueKind.Frozen,
38355
38788
  noAlias: typeConfig.noAlias === true,
38789
+ aliasing: typeConfig.aliasing,
38356
38790
  });
38357
38791
  }
38358
38792
  case 'object': {
@@ -38455,6 +38889,90 @@ const ObjectTypeSchema = zod.z.object({
38455
38889
  kind: zod.z.literal('object'),
38456
38890
  properties: ObjectPropertiesSchema.nullable(),
38457
38891
  });
38892
+ const LifetimeIdSchema = zod.z.string().refine(id => id.startsWith('@'), {
38893
+ message: "Placeholder names must start with '@'",
38894
+ });
38895
+ const FreezeEffectSchema = zod.z.object({
38896
+ kind: zod.z.literal('Freeze'),
38897
+ value: LifetimeIdSchema,
38898
+ reason: ValueReasonSchema,
38899
+ });
38900
+ const MutateEffectSchema = zod.z.object({
38901
+ kind: zod.z.literal('Mutate'),
38902
+ value: LifetimeIdSchema,
38903
+ });
38904
+ const MutateTransitiveConditionallySchema = zod.z.object({
38905
+ kind: zod.z.literal('MutateTransitiveConditionally'),
38906
+ value: LifetimeIdSchema,
38907
+ });
38908
+ const CreateEffectSchema = zod.z.object({
38909
+ kind: zod.z.literal('Create'),
38910
+ into: LifetimeIdSchema,
38911
+ value: ValueKindSchema,
38912
+ reason: ValueReasonSchema,
38913
+ });
38914
+ const AssignEffectSchema = zod.z.object({
38915
+ kind: zod.z.literal('Assign'),
38916
+ from: LifetimeIdSchema,
38917
+ into: LifetimeIdSchema,
38918
+ });
38919
+ const AliasEffectSchema = zod.z.object({
38920
+ kind: zod.z.literal('Alias'),
38921
+ from: LifetimeIdSchema,
38922
+ into: LifetimeIdSchema,
38923
+ });
38924
+ const CaptureEffectSchema = zod.z.object({
38925
+ kind: zod.z.literal('Capture'),
38926
+ from: LifetimeIdSchema,
38927
+ into: LifetimeIdSchema,
38928
+ });
38929
+ const CreateFromEffectSchema = zod.z.object({
38930
+ kind: zod.z.literal('CreateFrom'),
38931
+ from: LifetimeIdSchema,
38932
+ into: LifetimeIdSchema,
38933
+ });
38934
+ const ApplyArgSchema = zod.z.union([
38935
+ LifetimeIdSchema,
38936
+ zod.z.object({
38937
+ kind: zod.z.literal('Spread'),
38938
+ place: LifetimeIdSchema,
38939
+ }),
38940
+ zod.z.object({
38941
+ kind: zod.z.literal('Hole'),
38942
+ }),
38943
+ ]);
38944
+ const ApplyEffectSchema = zod.z.object({
38945
+ kind: zod.z.literal('Apply'),
38946
+ receiver: LifetimeIdSchema,
38947
+ function: LifetimeIdSchema,
38948
+ mutatesFunction: zod.z.boolean(),
38949
+ args: zod.z.array(ApplyArgSchema),
38950
+ into: LifetimeIdSchema,
38951
+ });
38952
+ const ImpureEffectSchema = zod.z.object({
38953
+ kind: zod.z.literal('Impure'),
38954
+ place: LifetimeIdSchema,
38955
+ });
38956
+ const AliasingEffectSchema = zod.z.union([
38957
+ FreezeEffectSchema,
38958
+ CreateEffectSchema,
38959
+ CreateFromEffectSchema,
38960
+ AssignEffectSchema,
38961
+ AliasEffectSchema,
38962
+ CaptureEffectSchema,
38963
+ ImpureEffectSchema,
38964
+ MutateEffectSchema,
38965
+ MutateTransitiveConditionallySchema,
38966
+ ApplyEffectSchema,
38967
+ ]);
38968
+ const AliasingSignatureSchema = zod.z.object({
38969
+ receiver: LifetimeIdSchema,
38970
+ params: zod.z.array(LifetimeIdSchema),
38971
+ rest: LifetimeIdSchema.nullable(),
38972
+ returns: LifetimeIdSchema,
38973
+ effects: zod.z.array(AliasingEffectSchema),
38974
+ temporaries: zod.z.array(LifetimeIdSchema),
38975
+ });
38458
38976
  const FunctionTypeSchema = zod.z.object({
38459
38977
  kind: zod.z.literal('function'),
38460
38978
  positionalParams: zod.z.array(EffectSchema),
@@ -38466,6 +38984,7 @@ const FunctionTypeSchema = zod.z.object({
38466
38984
  mutableOnlyIfOperandsAreMutable: zod.z.boolean().nullable().optional(),
38467
38985
  impure: zod.z.boolean().nullable().optional(),
38468
38986
  canonicalName: zod.z.string().nullable().optional(),
38987
+ aliasing: AliasingSignatureSchema.nullable().optional(),
38469
38988
  });
38470
38989
  const HookTypeSchema = zod.z.object({
38471
38990
  kind: zod.z.literal('hook'),
@@ -38474,6 +38993,7 @@ const HookTypeSchema = zod.z.object({
38474
38993
  returnType: zod.z.lazy(() => TypeSchema),
38475
38994
  returnValueKind: ValueKindSchema.nullable().optional(),
38476
38995
  noAlias: zod.z.boolean().nullable().optional(),
38996
+ aliasing: AliasingSignatureSchema.nullable().optional(),
38477
38997
  });
38478
38998
  const BuiltInTypeSchema = zod.z.union([
38479
38999
  zod.z.literal('Any'),
@@ -38538,6 +39058,7 @@ const EnvironmentConfigSchema = zod.z.object({
38538
39058
  enablePreserveExistingManualUseMemo: zod.z.boolean().default(false),
38539
39059
  enableForest: zod.z.boolean().default(false),
38540
39060
  enableUseTypeAnnotations: zod.z.boolean().default(false),
39061
+ enableNewMutationAliasingModel: zod.z.boolean().default(true),
38541
39062
  enableOptionalDependencies: zod.z.boolean().default(true),
38542
39063
  enableFire: zod.z.boolean().default(false),
38543
39064
  inferEffectDependencies: zod.z
@@ -38947,20 +39468,22 @@ function mergeConsecutiveBlocks(fn) {
38947
39468
  suggestions: null,
38948
39469
  });
38949
39470
  const operand = Array.from(phi.operands.values())[0];
39471
+ const lvalue = {
39472
+ kind: 'Identifier',
39473
+ identifier: phi.place.identifier,
39474
+ effect: Effect.ConditionallyMutate,
39475
+ reactive: false,
39476
+ loc: GeneratedSource,
39477
+ };
38950
39478
  const instr = {
38951
39479
  id: predecessor.terminal.id,
38952
- lvalue: {
38953
- kind: 'Identifier',
38954
- identifier: phi.place.identifier,
38955
- effect: Effect.ConditionallyMutate,
38956
- reactive: false,
38957
- loc: GeneratedSource,
38958
- },
39480
+ lvalue: Object.assign({}, lvalue),
38959
39481
  value: {
38960
39482
  kind: 'LoadLocal',
38961
39483
  place: Object.assign({}, operand),
38962
39484
  loc: GeneratedSource,
38963
39485
  },
39486
+ effects: [{ kind: 'Alias', from: Object.assign({}, operand), into: Object.assign({}, lvalue) }],
38964
39487
  loc: GeneratedSource,
38965
39488
  };
38966
39489
  predecessor.instructions.push(instr);
@@ -40927,6 +41450,7 @@ function inlineJsxTransform(fn, inlineJsxTransformConfig) {
40927
41450
  type: null,
40928
41451
  loc: instr.value.loc,
40929
41452
  },
41453
+ effects: null,
40930
41454
  loc: instr.loc,
40931
41455
  };
40932
41456
  currentBlockInstructions.push(varInstruction);
@@ -40942,6 +41466,7 @@ function inlineJsxTransform(fn, inlineJsxTransformConfig) {
40942
41466
  },
40943
41467
  loc: instr.value.loc,
40944
41468
  },
41469
+ effects: null,
40945
41470
  loc: instr.loc,
40946
41471
  };
40947
41472
  currentBlockInstructions.push(devGlobalInstruction);
@@ -40987,6 +41512,7 @@ function inlineJsxTransform(fn, inlineJsxTransformConfig) {
40987
41512
  type: null,
40988
41513
  loc: instr.value.loc,
40989
41514
  },
41515
+ effects: null,
40990
41516
  loc: instr.loc,
40991
41517
  };
40992
41518
  thenBlockInstructions.push(reassignElseInstruction);
@@ -41024,6 +41550,7 @@ function inlineJsxTransform(fn, inlineJsxTransformConfig) {
41024
41550
  ],
41025
41551
  loc: instr.value.loc,
41026
41552
  },
41553
+ effects: null,
41027
41554
  loc: instr.loc,
41028
41555
  };
41029
41556
  elseBlockInstructions.push(reactElementInstruction);
@@ -41040,6 +41567,7 @@ function inlineJsxTransform(fn, inlineJsxTransformConfig) {
41040
41567
  type: null,
41041
41568
  loc: instr.value.loc,
41042
41569
  },
41570
+ effects: null,
41043
41571
  loc: instr.loc,
41044
41572
  };
41045
41573
  elseBlockInstructions.push(reassignConditionalInstruction);
@@ -41110,6 +41638,7 @@ function createSymbolProperty(fn, instr, nextInstructions, propertyName, symbolN
41110
41638
  binding: { kind: 'Global', name: 'Symbol' },
41111
41639
  loc: instr.value.loc,
41112
41640
  },
41641
+ effects: null,
41113
41642
  loc: instr.loc,
41114
41643
  };
41115
41644
  nextInstructions.push(symbolInstruction);
@@ -41123,6 +41652,7 @@ function createSymbolProperty(fn, instr, nextInstructions, propertyName, symbolN
41123
41652
  property: makePropertyLiteral('for'),
41124
41653
  loc: instr.value.loc,
41125
41654
  },
41655
+ effects: null,
41126
41656
  loc: instr.loc,
41127
41657
  };
41128
41658
  nextInstructions.push(symbolForInstruction);
@@ -41135,6 +41665,7 @@ function createSymbolProperty(fn, instr, nextInstructions, propertyName, symbolN
41135
41665
  value: symbolName,
41136
41666
  loc: instr.value.loc,
41137
41667
  },
41668
+ effects: null,
41138
41669
  loc: instr.loc,
41139
41670
  };
41140
41671
  nextInstructions.push(symbolValueInstruction);
@@ -41149,6 +41680,7 @@ function createSymbolProperty(fn, instr, nextInstructions, propertyName, symbolN
41149
41680
  args: [symbolValueInstruction.lvalue],
41150
41681
  loc: instr.value.loc,
41151
41682
  },
41683
+ effects: null,
41152
41684
  loc: instr.loc,
41153
41685
  };
41154
41686
  const $$typeofProperty = {
@@ -41173,6 +41705,7 @@ function createTagProperty(fn, instr, nextInstructions, componentTag) {
41173
41705
  value: componentTag.name,
41174
41706
  loc: instr.value.loc,
41175
41707
  },
41708
+ effects: null,
41176
41709
  loc: instr.loc,
41177
41710
  };
41178
41711
  tagProperty = {
@@ -41274,6 +41807,7 @@ function createPropsProperties(fn, instr, nextInstructions, propAttributes, chil
41274
41807
  elements: [...children],
41275
41808
  loc: instr.value.loc,
41276
41809
  },
41810
+ effects: null,
41277
41811
  loc: instr.loc,
41278
41812
  };
41279
41813
  nextInstructions.push(childrenPropInstruction);
@@ -41296,6 +41830,7 @@ function createPropsProperties(fn, instr, nextInstructions, propAttributes, chil
41296
41830
  value: null,
41297
41831
  loc: instr.value.loc,
41298
41832
  },
41833
+ effects: null,
41299
41834
  loc: instr.loc,
41300
41835
  };
41301
41836
  refProperty = {
@@ -41316,6 +41851,7 @@ function createPropsProperties(fn, instr, nextInstructions, propAttributes, chil
41316
41851
  value: null,
41317
41852
  loc: instr.value.loc,
41318
41853
  },
41854
+ effects: null,
41319
41855
  loc: instr.loc,
41320
41856
  };
41321
41857
  keyProperty = {
@@ -41349,6 +41885,7 @@ function createPropsProperties(fn, instr, nextInstructions, propAttributes, chil
41349
41885
  properties: props,
41350
41886
  loc: instr.value.loc,
41351
41887
  },
41888
+ effects: null,
41352
41889
  loc: instr.loc,
41353
41890
  };
41354
41891
  propsProperty = {
@@ -41974,7 +42511,7 @@ let Visitor$a = class Visitor extends ReactiveFunctionVisitor {
41974
42511
 
41975
42512
  var _Context_nextScheduleId, _Context_scheduled, _Context_catchHandlers, _Context_controlFlowStack;
41976
42513
  function buildReactiveFunction(fn) {
41977
- const cx = new Context$2(fn.body);
42514
+ const cx = new Context$3(fn.body);
41978
42515
  const driver = new Driver(cx);
41979
42516
  const body = driver.traverseBlock(cx.block(fn.body.entry));
41980
42517
  return {
@@ -42989,7 +43526,7 @@ class Driver {
42989
43526
  };
42990
43527
  }
42991
43528
  }
42992
- let Context$2 = class Context {
43529
+ let Context$3 = class Context {
42993
43530
  constructor(ir) {
42994
43531
  _Context_nextScheduleId.set(this, 0);
42995
43532
  this.emitted = new Set();
@@ -43303,7 +43840,7 @@ const MEMO_CACHE_SENTINEL = 'react.memo_cache_sentinel';
43303
43840
  const EARLY_RETURN_SENTINEL = 'react.early_return_sentinel';
43304
43841
  function codegenFunction(fn, { uniqueIdentifiers, fbtOperands, }) {
43305
43842
  var _a, _b, _c;
43306
- const cx = new Context$1(fn.env, (_a = fn.id) !== null && _a !== void 0 ? _a : '[[ anonymous ]]', uniqueIdentifiers, fbtOperands, null);
43843
+ const cx = new Context$2(fn.env, (_a = fn.id) !== null && _a !== void 0 ? _a : '[[ anonymous ]]', uniqueIdentifiers, fbtOperands, null);
43307
43844
  let fastRefreshState = null;
43308
43845
  if (fn.env.config.enableResetCacheOnSourceFileChanges &&
43309
43846
  fn.env.code !== null) {
@@ -43391,7 +43928,7 @@ function codegenFunction(fn, { uniqueIdentifiers, fbtOperands, }) {
43391
43928
  pruneUnusedLValues(reactiveFunction);
43392
43929
  pruneHoistedContexts(reactiveFunction);
43393
43930
  const identifiers = renameVariables(reactiveFunction);
43394
- const codegen = codegenReactiveFunction(new Context$1(cx.env, (_c = reactiveFunction.id) !== null && _c !== void 0 ? _c : '[[ anonymous ]]', identifiers, cx.fbtOperands), reactiveFunction);
43931
+ const codegen = codegenReactiveFunction(new Context$2(cx.env, (_c = reactiveFunction.id) !== null && _c !== void 0 ? _c : '[[ anonymous ]]', identifiers, cx.fbtOperands), reactiveFunction);
43395
43932
  if (codegen.isErr()) {
43396
43933
  return codegen;
43397
43934
  }
@@ -43471,7 +44008,7 @@ function convertParameter(param) {
43471
44008
  return libExports$1.restElement(convertIdentifier(param.place.identifier));
43472
44009
  }
43473
44010
  }
43474
- let Context$1 = class Context {
44011
+ let Context$2 = class Context {
43475
44012
  constructor(env, fnName, uniqueIdentifiers, fbtOperands, temporaries = null) {
43476
44013
  _Context_nextCacheIndex.set(this, 0);
43477
44014
  _Context_declarations.set(this, new Set());
@@ -44072,7 +44609,7 @@ function codegenInstructionNullable(cx, instr) {
44072
44609
  });
44073
44610
  CompilerError.invariant((value === null || value === void 0 ? void 0 : value.type) === 'FunctionExpression', {
44074
44611
  reason: 'Expected a function as a function declaration value',
44075
- description: null,
44612
+ description: `Got ${value == null ? String(value) : value.type} at ${printInstruction(instr)}`,
44076
44613
  loc: instr.value.loc,
44077
44614
  suggestions: null,
44078
44615
  });
@@ -44478,7 +45015,7 @@ function codegenInstructionValue(cx, instrValue) {
44478
45015
  const reactiveFunction = buildReactiveFunction(loweredFunc.func);
44479
45016
  pruneUnusedLabels(reactiveFunction);
44480
45017
  pruneUnusedLValues(reactiveFunction);
44481
- const fn = codegenReactiveFunction(new Context$1(cx.env, (_e = reactiveFunction.id) !== null && _e !== void 0 ? _e : '[[ anonymous ]]', cx.uniqueIdentifiers, cx.fbtOperands, cx.temp), reactiveFunction).unwrap();
45018
+ const fn = codegenReactiveFunction(new Context$2(cx.env, (_e = reactiveFunction.id) !== null && _e !== void 0 ? _e : '[[ anonymous ]]', cx.uniqueIdentifiers, cx.fbtOperands, cx.temp), reactiveFunction).unwrap();
44482
45019
  const babelNode = libExports$1.objectMethod('method', key, fn.params, fn.body, false);
44483
45020
  babelNode.async = fn.async;
44484
45021
  babelNode.generator = fn.generator;
@@ -44610,7 +45147,7 @@ function codegenInstructionValue(cx, instrValue) {
44610
45147
  pruneUnusedLabels(reactiveFunction);
44611
45148
  pruneUnusedLValues(reactiveFunction);
44612
45149
  pruneHoistedContexts(reactiveFunction);
44613
- const fn = codegenReactiveFunction(new Context$1(cx.env, (_g = reactiveFunction.id) !== null && _g !== void 0 ? _g : '[[ anonymous ]]', cx.uniqueIdentifiers, cx.fbtOperands, cx.temp), reactiveFunction).unwrap();
45150
+ const fn = codegenReactiveFunction(new Context$2(cx.env, (_g = reactiveFunction.id) !== null && _g !== void 0 ? _g : '[[ anonymous ]]', cx.uniqueIdentifiers, cx.fbtOperands, cx.temp), reactiveFunction).unwrap();
44614
45151
  if (instrValue.type === 'ArrowFunctionExpression') {
44615
45152
  let body = fn.body;
44616
45153
  if (body.body.length === 1 && loweredFunc.directives.length == 0) {
@@ -46242,12 +46779,21 @@ function getWriteErrorReason(abstractValue) {
46242
46779
  else if (abstractValue.reason.has(ValueReason.ReducerState)) {
46243
46780
  return "Mutating a value returned from 'useReducer()', which should not be mutated. Use the dispatch function to update instead";
46244
46781
  }
46782
+ else if (abstractValue.reason.has(ValueReason.Effect)) {
46783
+ return 'Updating a value used previously in an effect function or as an effect dependency is not allowed. Consider moving the mutation before calling useEffect()';
46784
+ }
46785
+ else if (abstractValue.reason.has(ValueReason.HookCaptured)) {
46786
+ return 'Updating a value previously passed as an argument to a hook is not allowed. Consider moving the mutation before calling the hook';
46787
+ }
46788
+ else if (abstractValue.reason.has(ValueReason.HookReturn)) {
46789
+ return 'Updating a value returned from a hook is not allowed. Consider moving the mutation into the hook where the value is constructed';
46790
+ }
46245
46791
  else {
46246
46792
  return 'This mutates a variable that React considers immutable';
46247
46793
  }
46248
46794
  }
46249
46795
 
46250
- var _InferenceState_isFunctionExpression, _InferenceState_values, _InferenceState_variables;
46796
+ var _InferenceState_isFunctionExpression$1, _InferenceState_values$1, _InferenceState_variables$1;
46251
46797
  const UndefinedValue = {
46252
46798
  kind: 'Primitive',
46253
46799
  loc: GeneratedSource,
@@ -46255,7 +46801,7 @@ const UndefinedValue = {
46255
46801
  };
46256
46802
  function inferReferenceEffects(fn, options = { isFunctionExpression: false }) {
46257
46803
  var _a;
46258
- const initialState = InferenceState.empty(fn.env, options.isFunctionExpression);
46804
+ const initialState = InferenceState$1.empty(fn.env, options.isFunctionExpression);
46259
46805
  const value = {
46260
46806
  kind: 'Primitive',
46261
46807
  loc: fn.loc,
@@ -46301,7 +46847,7 @@ function inferReferenceEffects(fn, options = { isFunctionExpression: false }) {
46301
46847
  let value;
46302
46848
  let place;
46303
46849
  if (props) {
46304
- inferParam(props, initialState, paramKind);
46850
+ inferParam$1(props, initialState, paramKind);
46305
46851
  }
46306
46852
  if (ref) {
46307
46853
  if (ref.kind === 'Identifier') {
@@ -46330,7 +46876,7 @@ function inferReferenceEffects(fn, options = { isFunctionExpression: false }) {
46330
46876
  }
46331
46877
  else {
46332
46878
  for (const param of fn.params) {
46333
- inferParam(param, initialState, paramKind);
46879
+ inferParam$1(param, initialState, paramKind);
46334
46880
  }
46335
46881
  }
46336
46882
  const statesByBlock = new Map();
@@ -46361,7 +46907,7 @@ function inferReferenceEffects(fn, options = { isFunctionExpression: false }) {
46361
46907
  }
46362
46908
  statesByBlock.set(blockId, incomingState);
46363
46909
  const state = incomingState.clone();
46364
- inferBlock(fn.env, state, block, functionEffects);
46910
+ inferBlock$1(fn.env, state, block, functionEffects);
46365
46911
  for (const nextBlockId of eachTerminalSuccessor(block.terminal)) {
46366
46912
  queue(nextBlockId, state);
46367
46913
  }
@@ -46375,21 +46921,21 @@ function inferReferenceEffects(fn, options = { isFunctionExpression: false }) {
46375
46921
  return transformFunctionEffectErrors(functionEffects);
46376
46922
  }
46377
46923
  }
46378
- class InferenceState {
46924
+ let InferenceState$1 = class InferenceState {
46379
46925
  constructor(env, isFunctionExpression, values, variables) {
46380
- _InferenceState_isFunctionExpression.set(this, void 0);
46381
- _InferenceState_values.set(this, void 0);
46382
- _InferenceState_variables.set(this, void 0);
46926
+ _InferenceState_isFunctionExpression$1.set(this, void 0);
46927
+ _InferenceState_values$1.set(this, void 0);
46928
+ _InferenceState_variables$1.set(this, void 0);
46383
46929
  this.env = env;
46384
- __classPrivateFieldSet(this, _InferenceState_isFunctionExpression, isFunctionExpression, "f");
46385
- __classPrivateFieldSet(this, _InferenceState_values, values, "f");
46386
- __classPrivateFieldSet(this, _InferenceState_variables, variables, "f");
46930
+ __classPrivateFieldSet(this, _InferenceState_isFunctionExpression$1, isFunctionExpression, "f");
46931
+ __classPrivateFieldSet(this, _InferenceState_values$1, values, "f");
46932
+ __classPrivateFieldSet(this, _InferenceState_variables$1, variables, "f");
46387
46933
  }
46388
46934
  static empty(env, isFunctionExpression) {
46389
46935
  return new InferenceState(env, isFunctionExpression, new Map(), new Map());
46390
46936
  }
46391
46937
  get isFunctionExpression() {
46392
- return __classPrivateFieldGet(this, _InferenceState_isFunctionExpression, "f");
46938
+ return __classPrivateFieldGet(this, _InferenceState_isFunctionExpression$1, "f");
46393
46939
  }
46394
46940
  initialize(value, kind) {
46395
46941
  CompilerError.invariant(value.kind !== 'LoadLocal', {
@@ -46398,10 +46944,10 @@ class InferenceState {
46398
46944
  loc: value.loc,
46399
46945
  suggestions: null,
46400
46946
  });
46401
- __classPrivateFieldGet(this, _InferenceState_values, "f").set(value, kind);
46947
+ __classPrivateFieldGet(this, _InferenceState_values$1, "f").set(value, kind);
46402
46948
  }
46403
46949
  values(place) {
46404
- const values = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(place.identifier.id);
46950
+ const values = __classPrivateFieldGet(this, _InferenceState_variables$1, "f").get(place.identifier.id);
46405
46951
  CompilerError.invariant(values != null, {
46406
46952
  reason: `[hoisting] Expected value kind to be initialized`,
46407
46953
  description: `${printPlace(place)}`,
@@ -46411,7 +46957,7 @@ class InferenceState {
46411
46957
  return Array.from(values);
46412
46958
  }
46413
46959
  kind(place) {
46414
- const values = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(place.identifier.id);
46960
+ const values = __classPrivateFieldGet(this, _InferenceState_variables$1, "f").get(place.identifier.id);
46415
46961
  CompilerError.invariant(values != null, {
46416
46962
  reason: `[hoisting] Expected value kind to be initialized`,
46417
46963
  description: `${printPlace(place)}`,
@@ -46420,9 +46966,9 @@ class InferenceState {
46420
46966
  });
46421
46967
  let mergedKind = null;
46422
46968
  for (const value of values) {
46423
- const kind = __classPrivateFieldGet(this, _InferenceState_values, "f").get(value);
46969
+ const kind = __classPrivateFieldGet(this, _InferenceState_values$1, "f").get(value);
46424
46970
  mergedKind =
46425
- mergedKind !== null ? mergeAbstractValues(mergedKind, kind) : kind;
46971
+ mergedKind !== null ? mergeAbstractValues$1(mergedKind, kind) : kind;
46426
46972
  }
46427
46973
  CompilerError.invariant(mergedKind !== null, {
46428
46974
  reason: `InferReferenceEffects::kind: Expected at least one value`,
@@ -46433,29 +46979,29 @@ class InferenceState {
46433
46979
  return mergedKind;
46434
46980
  }
46435
46981
  alias(place, value) {
46436
- const values = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(value.identifier.id);
46982
+ const values = __classPrivateFieldGet(this, _InferenceState_variables$1, "f").get(value.identifier.id);
46437
46983
  CompilerError.invariant(values != null, {
46438
46984
  reason: `[hoisting] Expected value for identifier to be initialized`,
46439
46985
  description: `${printIdentifier(value.identifier)}`,
46440
46986
  loc: value.loc,
46441
46987
  suggestions: null,
46442
46988
  });
46443
- __classPrivateFieldGet(this, _InferenceState_variables, "f").set(place.identifier.id, new Set(values));
46989
+ __classPrivateFieldGet(this, _InferenceState_variables$1, "f").set(place.identifier.id, new Set(values));
46444
46990
  }
46445
46991
  define(place, value) {
46446
- CompilerError.invariant(__classPrivateFieldGet(this, _InferenceState_values, "f").has(value), {
46992
+ CompilerError.invariant(__classPrivateFieldGet(this, _InferenceState_values$1, "f").has(value), {
46447
46993
  reason: `Expected value to be initialized at '${printSourceLocation(value.loc)}'`,
46448
46994
  description: null,
46449
46995
  loc: value.loc,
46450
46996
  suggestions: null,
46451
46997
  });
46452
- __classPrivateFieldGet(this, _InferenceState_variables, "f").set(place.identifier.id, new Set([value]));
46998
+ __classPrivateFieldGet(this, _InferenceState_variables$1, "f").set(place.identifier.id, new Set([value]));
46453
46999
  }
46454
47000
  isDefined(place) {
46455
- return __classPrivateFieldGet(this, _InferenceState_variables, "f").has(place.identifier.id);
47001
+ return __classPrivateFieldGet(this, _InferenceState_variables$1, "f").has(place.identifier.id);
46456
47002
  }
46457
47003
  referenceAndRecordEffects(freezeActions, place, effectKind, reason) {
46458
- const values = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(place.identifier.id);
47004
+ const values = __classPrivateFieldGet(this, _InferenceState_variables$1, "f").get(place.identifier.id);
46459
47005
  if (values === undefined) {
46460
47006
  CompilerError.invariant(effectKind !== Effect.Store, {
46461
47007
  reason: '[InferReferenceEffects] Unhandled store reference effect',
@@ -46480,7 +47026,7 @@ class InferenceState {
46480
47026
  value.lvalue.kind === InstructionKind.Const))) {
46481
47027
  continue;
46482
47028
  }
46483
- __classPrivateFieldGet(this, _InferenceState_values, "f").set(value, {
47029
+ __classPrivateFieldGet(this, _InferenceState_values$1, "f").set(value, {
46484
47030
  kind: ValueKind.Frozen,
46485
47031
  reason,
46486
47032
  context: new Set(),
@@ -46489,7 +47035,7 @@ class InferenceState {
46489
47035
  (this.env.config.enablePreserveExistingMemoizationGuarantees ||
46490
47036
  this.env.config.enableTransitivelyFreezeFunctionExpressions)) {
46491
47037
  for (const operand of value.loweredFunc.func.context) {
46492
- const operandValues = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(operand.identifier.id);
47038
+ const operandValues = __classPrivateFieldGet(this, _InferenceState_variables$1, "f").get(operand.identifier.id);
46493
47039
  if (operandValues !== undefined) {
46494
47040
  this.freezeValues(operandValues, reason);
46495
47041
  }
@@ -46498,7 +47044,7 @@ class InferenceState {
46498
47044
  }
46499
47045
  }
46500
47046
  reference(place, effectKind, reason) {
46501
- const values = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(place.identifier.id);
47047
+ const values = __classPrivateFieldGet(this, _InferenceState_variables$1, "f").get(place.identifier.id);
46502
47048
  CompilerError.invariant(values !== undefined, {
46503
47049
  reason: '[InferReferenceEffects] Expected value to be initialized',
46504
47050
  description: null,
@@ -46602,25 +47148,25 @@ class InferenceState {
46602
47148
  merge(other) {
46603
47149
  let nextValues = null;
46604
47150
  let nextVariables = null;
46605
- for (const [id, thisValue] of __classPrivateFieldGet(this, _InferenceState_values, "f")) {
46606
- const otherValue = __classPrivateFieldGet(other, _InferenceState_values, "f").get(id);
47151
+ for (const [id, thisValue] of __classPrivateFieldGet(this, _InferenceState_values$1, "f")) {
47152
+ const otherValue = __classPrivateFieldGet(other, _InferenceState_values$1, "f").get(id);
46607
47153
  if (otherValue !== undefined) {
46608
- const mergedValue = mergeAbstractValues(thisValue, otherValue);
47154
+ const mergedValue = mergeAbstractValues$1(thisValue, otherValue);
46609
47155
  if (mergedValue !== thisValue) {
46610
- nextValues = nextValues !== null && nextValues !== void 0 ? nextValues : new Map(__classPrivateFieldGet(this, _InferenceState_values, "f"));
47156
+ nextValues = nextValues !== null && nextValues !== void 0 ? nextValues : new Map(__classPrivateFieldGet(this, _InferenceState_values$1, "f"));
46611
47157
  nextValues.set(id, mergedValue);
46612
47158
  }
46613
47159
  }
46614
47160
  }
46615
- for (const [id, otherValue] of __classPrivateFieldGet(other, _InferenceState_values, "f")) {
46616
- if (__classPrivateFieldGet(this, _InferenceState_values, "f").has(id)) {
47161
+ for (const [id, otherValue] of __classPrivateFieldGet(other, _InferenceState_values$1, "f")) {
47162
+ if (__classPrivateFieldGet(this, _InferenceState_values$1, "f").has(id)) {
46617
47163
  continue;
46618
47164
  }
46619
- nextValues = nextValues !== null && nextValues !== void 0 ? nextValues : new Map(__classPrivateFieldGet(this, _InferenceState_values, "f"));
47165
+ nextValues = nextValues !== null && nextValues !== void 0 ? nextValues : new Map(__classPrivateFieldGet(this, _InferenceState_values$1, "f"));
46620
47166
  nextValues.set(id, otherValue);
46621
47167
  }
46622
- for (const [id, thisValues] of __classPrivateFieldGet(this, _InferenceState_variables, "f")) {
46623
- const otherValues = __classPrivateFieldGet(other, _InferenceState_variables, "f").get(id);
47168
+ for (const [id, thisValues] of __classPrivateFieldGet(this, _InferenceState_variables$1, "f")) {
47169
+ const otherValues = __classPrivateFieldGet(other, _InferenceState_variables$1, "f").get(id);
46624
47170
  if (otherValues !== undefined) {
46625
47171
  let mergedValues = null;
46626
47172
  for (const otherValue of otherValues) {
@@ -46630,27 +47176,27 @@ class InferenceState {
46630
47176
  }
46631
47177
  }
46632
47178
  if (mergedValues !== null) {
46633
- nextVariables = nextVariables !== null && nextVariables !== void 0 ? nextVariables : new Map(__classPrivateFieldGet(this, _InferenceState_variables, "f"));
47179
+ nextVariables = nextVariables !== null && nextVariables !== void 0 ? nextVariables : new Map(__classPrivateFieldGet(this, _InferenceState_variables$1, "f"));
46634
47180
  nextVariables.set(id, mergedValues);
46635
47181
  }
46636
47182
  }
46637
47183
  }
46638
- for (const [id, otherValues] of __classPrivateFieldGet(other, _InferenceState_variables, "f")) {
46639
- if (__classPrivateFieldGet(this, _InferenceState_variables, "f").has(id)) {
47184
+ for (const [id, otherValues] of __classPrivateFieldGet(other, _InferenceState_variables$1, "f")) {
47185
+ if (__classPrivateFieldGet(this, _InferenceState_variables$1, "f").has(id)) {
46640
47186
  continue;
46641
47187
  }
46642
- nextVariables = nextVariables !== null && nextVariables !== void 0 ? nextVariables : new Map(__classPrivateFieldGet(this, _InferenceState_variables, "f"));
47188
+ nextVariables = nextVariables !== null && nextVariables !== void 0 ? nextVariables : new Map(__classPrivateFieldGet(this, _InferenceState_variables$1, "f"));
46643
47189
  nextVariables.set(id, new Set(otherValues));
46644
47190
  }
46645
47191
  if (nextVariables === null && nextValues === null) {
46646
47192
  return null;
46647
47193
  }
46648
47194
  else {
46649
- return new InferenceState(this.env, __classPrivateFieldGet(this, _InferenceState_isFunctionExpression, "f"), nextValues !== null && nextValues !== void 0 ? nextValues : new Map(__classPrivateFieldGet(this, _InferenceState_values, "f")), nextVariables !== null && nextVariables !== void 0 ? nextVariables : new Map(__classPrivateFieldGet(this, _InferenceState_variables, "f")));
47195
+ return new InferenceState(this.env, __classPrivateFieldGet(this, _InferenceState_isFunctionExpression$1, "f"), nextValues !== null && nextValues !== void 0 ? nextValues : new Map(__classPrivateFieldGet(this, _InferenceState_values$1, "f")), nextVariables !== null && nextVariables !== void 0 ? nextVariables : new Map(__classPrivateFieldGet(this, _InferenceState_variables$1, "f")));
46650
47196
  }
46651
47197
  }
46652
47198
  clone() {
46653
- return new InferenceState(this.env, __classPrivateFieldGet(this, _InferenceState_isFunctionExpression, "f"), new Map(__classPrivateFieldGet(this, _InferenceState_values, "f")), new Map(__classPrivateFieldGet(this, _InferenceState_variables, "f")));
47199
+ return new InferenceState(this.env, __classPrivateFieldGet(this, _InferenceState_isFunctionExpression$1, "f"), new Map(__classPrivateFieldGet(this, _InferenceState_values$1, "f")), new Map(__classPrivateFieldGet(this, _InferenceState_variables$1, "f")));
46654
47200
  }
46655
47201
  debug() {
46656
47202
  const result = { values: {}, variables: {} };
@@ -46663,11 +47209,11 @@ class InferenceState {
46663
47209
  }
46664
47210
  return id;
46665
47211
  }
46666
- for (const [value, kind] of __classPrivateFieldGet(this, _InferenceState_values, "f")) {
47212
+ for (const [value, kind] of __classPrivateFieldGet(this, _InferenceState_values$1, "f")) {
46667
47213
  const id = identify(value);
46668
47214
  result.values[id] = { kind, value: printMixedHIR(value) };
46669
47215
  }
46670
- for (const [variable, values] of __classPrivateFieldGet(this, _InferenceState_variables, "f")) {
47216
+ for (const [variable, values] of __classPrivateFieldGet(this, _InferenceState_variables$1, "f")) {
46671
47217
  result.variables[`$${variable}`] = [...values].map(identify);
46672
47218
  }
46673
47219
  return result;
@@ -46675,7 +47221,7 @@ class InferenceState {
46675
47221
  inferPhi(phi) {
46676
47222
  const values = new Set();
46677
47223
  for (const [_, operand] of phi.operands) {
46678
- const operandValues = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(operand.identifier.id);
47224
+ const operandValues = __classPrivateFieldGet(this, _InferenceState_variables$1, "f").get(operand.identifier.id);
46679
47225
  if (operandValues === undefined)
46680
47226
  continue;
46681
47227
  for (const v of operandValues) {
@@ -46683,12 +47229,12 @@ class InferenceState {
46683
47229
  }
46684
47230
  }
46685
47231
  if (values.size > 0) {
46686
- __classPrivateFieldGet(this, _InferenceState_variables, "f").set(phi.place.identifier.id, values);
47232
+ __classPrivateFieldGet(this, _InferenceState_variables$1, "f").set(phi.place.identifier.id, values);
46687
47233
  }
46688
47234
  }
46689
- }
46690
- _InferenceState_isFunctionExpression = new WeakMap(), _InferenceState_values = new WeakMap(), _InferenceState_variables = new WeakMap();
46691
- function inferParam(param, initialState, paramKind) {
47235
+ };
47236
+ _InferenceState_isFunctionExpression$1 = new WeakMap(), _InferenceState_values$1 = new WeakMap(), _InferenceState_variables$1 = new WeakMap();
47237
+ function inferParam$1(param, initialState, paramKind) {
46692
47238
  let value;
46693
47239
  let place;
46694
47240
  if (param.kind === 'Identifier') {
@@ -46710,7 +47256,7 @@ function inferParam(param, initialState, paramKind) {
46710
47256
  initialState.initialize(value, paramKind);
46711
47257
  initialState.define(place, value);
46712
47258
  }
46713
- function mergeValues(a, b) {
47259
+ function mergeValueKinds(a, b) {
46714
47260
  if (a === b) {
46715
47261
  return a;
46716
47262
  }
@@ -46751,20 +47297,12 @@ function mergeValues(a, b) {
46751
47297
  return ValueKind.Primitive;
46752
47298
  }
46753
47299
  }
46754
- function isSuperset(a, b) {
46755
- for (const v of b) {
46756
- if (!a.has(v)) {
46757
- return false;
46758
- }
46759
- }
46760
- return true;
46761
- }
46762
- function mergeAbstractValues(a, b) {
46763
- const kind = mergeValues(a.kind, b.kind);
47300
+ function mergeAbstractValues$1(a, b) {
47301
+ const kind = mergeValueKinds(a.kind, b.kind);
46764
47302
  if (kind === a.kind &&
46765
47303
  kind === b.kind &&
46766
- isSuperset(a.reason, b.reason) &&
46767
- isSuperset(a.context, b.context)) {
47304
+ Set_isSuperset(a.reason, b.reason) &&
47305
+ Set_isSuperset(a.context, b.context)) {
46768
47306
  return a;
46769
47307
  }
46770
47308
  const reason = new Set(a.reason);
@@ -46777,7 +47315,7 @@ function mergeAbstractValues(a, b) {
46777
47315
  }
46778
47316
  return { kind, reason, context };
46779
47317
  }
46780
- function inferBlock(env, state, block, functionEffects) {
47318
+ function inferBlock$1(env, state, block, functionEffects) {
46781
47319
  var _a, _b, _c;
46782
47320
  for (const phi of block.phis) {
46783
47321
  state.inferPhi(phi);
@@ -47466,7 +48004,7 @@ function isKnownMutableEffect(effect) {
47466
48004
  }
47467
48005
  }
47468
48006
  }
47469
- function areArgumentsImmutableAndNonMutating(state, args) {
48007
+ function areArgumentsImmutableAndNonMutating$1(state, args) {
47470
48008
  for (const arg of args) {
47471
48009
  if (arg.kind === 'Identifier' && arg.identifier.type.kind === 'Function') {
47472
48010
  const fnShape = state.env.getFunctionSignature(arg.identifier.type);
@@ -47543,7 +48081,7 @@ function inferCallEffects(state, instr, freezeActions, signature) {
47543
48081
  if (instrValue.kind === 'MethodCall' &&
47544
48082
  signature !== null &&
47545
48083
  signature.mutableOnlyIfOperandsAreMutable &&
47546
- areArgumentsImmutableAndNonMutating(state, instrValue.args)) {
48084
+ areArgumentsImmutableAndNonMutating$1(state, instrValue.args)) {
47547
48085
  for (const arg of instrValue.args) {
47548
48086
  const place = arg.kind === 'Identifier' ? arg : arg.place;
47549
48087
  state.referenceAndRecordEffects(freezeActions, place, Effect.Read, ValueReason.Other);
@@ -48941,156 +49479,2674 @@ function areEqualMaps(a, b) {
48941
49479
  return true;
48942
49480
  }
48943
49481
 
48944
- function analyseFunctions(func) {
48945
- for (const [_, block] of func.body.blocks) {
48946
- for (const instr of block.instructions) {
48947
- switch (instr.value.kind) {
48948
- case 'ObjectMethod':
48949
- case 'FunctionExpression': {
48950
- lower(instr.value.loweredFunc.func);
48951
- infer(instr.value.loweredFunc);
48952
- for (const operand of instr.value.loweredFunc.func.context) {
48953
- operand.identifier.mutableRange.start = makeInstructionId(0);
48954
- operand.identifier.mutableRange.end = makeInstructionId(0);
48955
- operand.identifier.scope = null;
49482
+ function hashEffect(effect) {
49483
+ var _a;
49484
+ switch (effect.kind) {
49485
+ case 'Apply': {
49486
+ return [
49487
+ effect.kind,
49488
+ effect.receiver.identifier.id,
49489
+ effect.function.identifier.id,
49490
+ effect.mutatesFunction,
49491
+ effect.args
49492
+ .map(a => {
49493
+ if (a.kind === 'Hole') {
49494
+ return '';
49495
+ }
49496
+ else if (a.kind === 'Identifier') {
49497
+ return a.identifier.id;
48956
49498
  }
48957
- break;
48958
- }
48959
- }
49499
+ else {
49500
+ return `...${a.place.identifier.id}`;
49501
+ }
49502
+ })
49503
+ .join(','),
49504
+ effect.into.identifier.id,
49505
+ ].join(':');
49506
+ }
49507
+ case 'CreateFrom':
49508
+ case 'ImmutableCapture':
49509
+ case 'Assign':
49510
+ case 'Alias':
49511
+ case 'Capture': {
49512
+ return [
49513
+ effect.kind,
49514
+ effect.from.identifier.id,
49515
+ effect.into.identifier.id,
49516
+ ].join(':');
49517
+ }
49518
+ case 'Create': {
49519
+ return [
49520
+ effect.kind,
49521
+ effect.into.identifier.id,
49522
+ effect.value,
49523
+ effect.reason,
49524
+ ].join(':');
49525
+ }
49526
+ case 'Freeze': {
49527
+ return [effect.kind, effect.value.identifier.id, effect.reason].join(':');
49528
+ }
49529
+ case 'Impure':
49530
+ case 'Render': {
49531
+ return [effect.kind, effect.place.identifier.id].join(':');
49532
+ }
49533
+ case 'MutateFrozen':
49534
+ case 'MutateGlobal': {
49535
+ return [
49536
+ effect.kind,
49537
+ effect.place.identifier.id,
49538
+ effect.error.severity,
49539
+ effect.error.reason,
49540
+ effect.error.description,
49541
+ printSourceLocation((_a = effect.error.loc) !== null && _a !== void 0 ? _a : GeneratedSource),
49542
+ ].join(':');
49543
+ }
49544
+ case 'Mutate':
49545
+ case 'MutateConditionally':
49546
+ case 'MutateTransitive':
49547
+ case 'MutateTransitiveConditionally': {
49548
+ return [effect.kind, effect.value.identifier.id].join(':');
49549
+ }
49550
+ case 'CreateFunction': {
49551
+ return [
49552
+ effect.kind,
49553
+ effect.into.identifier.id,
49554
+ effect.function.loweredFunc.func.returns.identifier.id,
49555
+ effect.captures.map(p => p.identifier.id).join(','),
49556
+ ].join(':');
48960
49557
  }
48961
49558
  }
48962
49559
  }
48963
- function lower(func) {
48964
- var _a, _b;
48965
- analyseFunctions(func);
48966
- inferReferenceEffects(func, { isFunctionExpression: true });
48967
- deadCodeElimination(func);
48968
- inferMutableRanges(func);
48969
- rewriteInstructionKindsBasedOnReassignment(func);
48970
- inferReactiveScopeVariables(func);
48971
- (_b = (_a = func.env.logger) === null || _a === void 0 ? void 0 : _a.debugLogIRs) === null || _b === void 0 ? void 0 : _b.call(_a, {
48972
- kind: 'hir',
48973
- name: 'AnalyseFunction (inner)',
48974
- value: func,
48975
- });
48976
- }
48977
- function infer(loweredFunc) {
48978
- for (const operand of loweredFunc.func.context) {
48979
- const identifier = operand.identifier;
48980
- CompilerError.invariant(operand.effect === Effect.Unknown, {
48981
- reason: '[AnalyseFunctions] Expected Function context effects to not have been set',
48982
- loc: operand.loc,
49560
+
49561
+ var _InferenceState_isFunctionExpression, _InferenceState_values, _InferenceState_variables;
49562
+ function inferMutationAliasingEffects(fn, { isFunctionExpression } = {
49563
+ isFunctionExpression: false,
49564
+ }) {
49565
+ const initialState = InferenceState.empty(fn.env, isFunctionExpression);
49566
+ const statesByBlock = new Map();
49567
+ for (const ref of fn.context) {
49568
+ const value = {
49569
+ kind: 'ObjectExpression',
49570
+ properties: [],
49571
+ loc: ref.loc,
49572
+ };
49573
+ initialState.initialize(value, {
49574
+ kind: ValueKind.Context,
49575
+ reason: new Set([ValueReason.Other]),
48983
49576
  });
48984
- if (isRefOrRefValue(identifier)) {
48985
- operand.effect = Effect.Capture;
49577
+ initialState.define(ref, value);
49578
+ }
49579
+ const paramKind = isFunctionExpression
49580
+ ? {
49581
+ kind: ValueKind.Mutable,
49582
+ reason: new Set([ValueReason.Other]),
48986
49583
  }
48987
- else if (isMutatedOrReassigned(identifier)) {
48988
- operand.effect = Effect.Capture;
49584
+ : {
49585
+ kind: ValueKind.Frozen,
49586
+ reason: new Set([ValueReason.ReactiveFunctionArgument]),
49587
+ };
49588
+ if (fn.fnType === 'Component') {
49589
+ CompilerError.invariant(fn.params.length <= 2, {
49590
+ reason: 'Expected React component to have not more than two parameters: one for props and for ref',
49591
+ description: null,
49592
+ loc: fn.loc,
49593
+ suggestions: null,
49594
+ });
49595
+ const [props, ref] = fn.params;
49596
+ if (props != null) {
49597
+ inferParam(props, initialState, paramKind);
48989
49598
  }
48990
- else {
48991
- operand.effect = Effect.Read;
49599
+ if (ref != null) {
49600
+ const place = ref.kind === 'Identifier' ? ref : ref.place;
49601
+ const value = {
49602
+ kind: 'ObjectExpression',
49603
+ properties: [],
49604
+ loc: place.loc,
49605
+ };
49606
+ initialState.initialize(value, {
49607
+ kind: ValueKind.Mutable,
49608
+ reason: new Set([ValueReason.Other]),
49609
+ });
49610
+ initialState.define(place, value);
48992
49611
  }
48993
49612
  }
48994
- }
48995
- function isMutatedOrReassigned(id) {
48996
- return id.mutableRange.end > id.mutableRange.start;
48997
- }
48998
-
48999
- function collectMaybeMemoDependencies(value, maybeDeps, optional) {
49000
- var _a;
49001
- switch (value.kind) {
49002
- case 'LoadGlobal': {
49003
- return {
49004
- root: {
49005
- kind: 'Global',
49006
- identifierName: value.binding.name,
49007
- },
49008
- path: [],
49009
- };
49613
+ else {
49614
+ for (const param of fn.params) {
49615
+ inferParam(param, initialState, paramKind);
49010
49616
  }
49011
- case 'PropertyLoad': {
49012
- const object = maybeDeps.get(value.object.identifier.id);
49013
- if (object != null) {
49014
- return {
49015
- root: object.root,
49016
- path: [...object.path, { property: value.property, optional }],
49017
- };
49617
+ }
49618
+ const queuedStates = new Map();
49619
+ function queue(blockId, state) {
49620
+ var _a;
49621
+ let queuedState = queuedStates.get(blockId);
49622
+ if (queuedState != null) {
49623
+ state = (_a = queuedState.merge(state)) !== null && _a !== void 0 ? _a : queuedState;
49624
+ queuedStates.set(blockId, state);
49625
+ }
49626
+ else {
49627
+ const prevState = statesByBlock.get(blockId);
49628
+ const nextState = prevState != null ? prevState.merge(state) : state;
49629
+ if (nextState != null) {
49630
+ queuedStates.set(blockId, nextState);
49018
49631
  }
49019
- break;
49020
49632
  }
49021
- case 'LoadLocal':
49022
- case 'LoadContext': {
49023
- const source = maybeDeps.get(value.place.identifier.id);
49024
- if (source != null) {
49025
- return source;
49633
+ }
49634
+ queue(fn.body.entry, initialState);
49635
+ const hoistedContextDeclarations = findHoistedContextDeclarations(fn);
49636
+ const context = new Context$1(isFunctionExpression, fn, hoistedContextDeclarations);
49637
+ let iterationCount = 0;
49638
+ while (queuedStates.size !== 0) {
49639
+ iterationCount++;
49640
+ if (iterationCount > 100) {
49641
+ CompilerError.invariant(false, {
49642
+ reason: `[InferMutationAliasingEffects] Potential infinite loop`,
49643
+ description: `A value, temporary place, or effect was not cached properly`,
49644
+ loc: fn.loc,
49645
+ });
49646
+ }
49647
+ for (const [blockId, block] of fn.body.blocks) {
49648
+ const incomingState = queuedStates.get(blockId);
49649
+ queuedStates.delete(blockId);
49650
+ if (incomingState == null) {
49651
+ continue;
49026
49652
  }
49027
- else if (value.place.identifier.name != null &&
49028
- value.place.identifier.name.kind === 'named') {
49029
- return {
49030
- root: {
49031
- kind: 'NamedLocal',
49032
- value: Object.assign({}, value.place),
49033
- },
49034
- path: [],
49035
- };
49653
+ statesByBlock.set(blockId, incomingState);
49654
+ const state = incomingState.clone();
49655
+ inferBlock(context, state, block);
49656
+ for (const nextBlockId of eachTerminalSuccessor(block.terminal)) {
49657
+ queue(nextBlockId, state);
49036
49658
  }
49037
- break;
49038
49659
  }
49039
- case 'StoreLocal': {
49040
- const lvalue = value.lvalue.place.identifier;
49041
- const rvalue = value.value.identifier.id;
49042
- const aliased = maybeDeps.get(rvalue);
49043
- if (aliased != null && ((_a = lvalue.name) === null || _a === void 0 ? void 0 : _a.kind) !== 'named') {
49044
- maybeDeps.set(lvalue.id, aliased);
49045
- return aliased;
49660
+ }
49661
+ return Ok(undefined);
49662
+ }
49663
+ function findHoistedContextDeclarations(fn) {
49664
+ const hoisted = new Map();
49665
+ function visit(place) {
49666
+ if (hoisted.has(place.identifier.declarationId) &&
49667
+ hoisted.get(place.identifier.declarationId) == null) {
49668
+ hoisted.set(place.identifier.declarationId, place);
49669
+ }
49670
+ }
49671
+ for (const block of fn.body.blocks.values()) {
49672
+ for (const instr of block.instructions) {
49673
+ if (instr.value.kind === 'DeclareContext') {
49674
+ const kind = instr.value.lvalue.kind;
49675
+ if (kind == InstructionKind.HoistedConst ||
49676
+ kind == InstructionKind.HoistedFunction ||
49677
+ kind == InstructionKind.HoistedLet) {
49678
+ hoisted.set(instr.value.lvalue.place.identifier.declarationId, null);
49679
+ }
49046
49680
  }
49047
- break;
49681
+ else {
49682
+ for (const operand of eachInstructionValueOperand(instr.value)) {
49683
+ visit(operand);
49684
+ }
49685
+ }
49686
+ }
49687
+ for (const operand of eachTerminalOperand(block.terminal)) {
49688
+ visit(operand);
49048
49689
  }
49049
49690
  }
49050
- return null;
49691
+ return hoisted;
49051
49692
  }
49052
- function collectTemporaries(instr, env, sidemap) {
49053
- const { value, lvalue } = instr;
49054
- switch (value.kind) {
49055
- case 'FunctionExpression': {
49056
- sidemap.functions.set(instr.lvalue.identifier.id, instr);
49057
- break;
49693
+ let Context$1 = class Context {
49694
+ constructor(isFunctionExpression, fn, hoistedContextDeclarations) {
49695
+ this.internedEffects = new Map();
49696
+ this.instructionSignatureCache = new Map();
49697
+ this.effectInstructionValueCache = new Map();
49698
+ this.applySignatureCache = new Map();
49699
+ this.catchHandlers = new Map();
49700
+ this.functionSignatureCache = new Map();
49701
+ this.isFuctionExpression = isFunctionExpression;
49702
+ this.fn = fn;
49703
+ this.hoistedContextDeclarations = hoistedContextDeclarations;
49704
+ }
49705
+ cacheApplySignature(signature, effect, f) {
49706
+ const inner = getOrInsertDefault(this.applySignatureCache, signature, new Map());
49707
+ return getOrInsertWith(inner, effect, f);
49708
+ }
49709
+ internEffect(effect) {
49710
+ const hash = hashEffect(effect);
49711
+ let interned = this.internedEffects.get(hash);
49712
+ if (interned == null) {
49713
+ this.internedEffects.set(hash, effect);
49714
+ interned = effect;
49715
+ }
49716
+ return interned;
49717
+ }
49718
+ };
49719
+ function inferParam(param, initialState, paramKind) {
49720
+ const place = param.kind === 'Identifier' ? param : param.place;
49721
+ const value = {
49722
+ kind: 'Primitive',
49723
+ loc: place.loc,
49724
+ value: undefined,
49725
+ };
49726
+ initialState.initialize(value, paramKind);
49727
+ initialState.define(place, value);
49728
+ }
49729
+ function inferBlock(context, state, block) {
49730
+ for (const phi of block.phis) {
49731
+ state.inferPhi(phi);
49732
+ }
49733
+ for (const instr of block.instructions) {
49734
+ let instructionSignature = context.instructionSignatureCache.get(instr);
49735
+ if (instructionSignature == null) {
49736
+ instructionSignature = computeSignatureForInstruction(context, state.env, instr);
49737
+ context.instructionSignatureCache.set(instr, instructionSignature);
49738
+ }
49739
+ const effects = applySignature(context, state, instructionSignature, instr);
49740
+ instr.effects = effects;
49741
+ }
49742
+ const terminal = block.terminal;
49743
+ if (terminal.kind === 'try' && terminal.handlerBinding != null) {
49744
+ context.catchHandlers.set(terminal.handler, terminal.handlerBinding);
49745
+ }
49746
+ else if (terminal.kind === 'maybe-throw') {
49747
+ const handlerParam = context.catchHandlers.get(terminal.handler);
49748
+ if (handlerParam != null) {
49749
+ CompilerError.invariant(state.kind(handlerParam) != null, {
49750
+ reason: 'Expected catch binding to be intialized with a DeclareLocal Catch instruction',
49751
+ loc: terminal.loc,
49752
+ });
49753
+ const effects = [];
49754
+ for (const instr of block.instructions) {
49755
+ if (instr.value.kind === 'CallExpression' ||
49756
+ instr.value.kind === 'MethodCall') {
49757
+ state.appendAlias(handlerParam, instr.lvalue);
49758
+ const kind = state.kind(instr.lvalue).kind;
49759
+ if (kind === ValueKind.Mutable || kind == ValueKind.Context) {
49760
+ effects.push(context.internEffect({
49761
+ kind: 'Alias',
49762
+ from: instr.lvalue,
49763
+ into: handlerParam,
49764
+ }));
49765
+ }
49766
+ }
49767
+ }
49768
+ terminal.effects = effects.length !== 0 ? effects : null;
49058
49769
  }
49059
- case 'LoadGlobal': {
49060
- const global = env.getGlobalDeclaration(value.binding, value.loc);
49061
- const hookKind = global !== null ? getHookKindForType(env, global) : null;
49062
- const lvalId = instr.lvalue.identifier.id;
49063
- if (hookKind === 'useMemo' || hookKind === 'useCallback') {
49064
- sidemap.manualMemos.set(lvalId, {
49065
- kind: hookKind,
49066
- loadInstr: instr,
49067
- });
49770
+ }
49771
+ else if (terminal.kind === 'return') {
49772
+ if (!context.isFuctionExpression) {
49773
+ terminal.effects = [
49774
+ context.internEffect({
49775
+ kind: 'Freeze',
49776
+ value: terminal.value,
49777
+ reason: ValueReason.JsxCaptured,
49778
+ }),
49779
+ ];
49780
+ }
49781
+ }
49782
+ }
49783
+ function applySignature(context, state, signature, instruction) {
49784
+ var _a;
49785
+ const effects = [];
49786
+ if (instruction.value.kind === 'FunctionExpression' ||
49787
+ instruction.value.kind === 'ObjectMethod') {
49788
+ const aliasingEffects = (_a = instruction.value.loweredFunc.func.aliasingEffects) !== null && _a !== void 0 ? _a : [];
49789
+ const context = new Set(instruction.value.loweredFunc.func.context.map(p => p.identifier.id));
49790
+ for (const effect of aliasingEffects) {
49791
+ if (effect.kind === 'Mutate' || effect.kind === 'MutateTransitive') {
49792
+ if (!context.has(effect.value.identifier.id)) {
49793
+ continue;
49794
+ }
49795
+ const value = state.kind(effect.value);
49796
+ switch (value.kind) {
49797
+ case ValueKind.Frozen: {
49798
+ const reason = getWriteErrorReason({
49799
+ kind: value.kind,
49800
+ reason: value.reason,
49801
+ context: new Set(),
49802
+ });
49803
+ effects.push({
49804
+ kind: 'MutateFrozen',
49805
+ place: effect.value,
49806
+ error: {
49807
+ severity: ErrorSeverity.InvalidReact,
49808
+ reason,
49809
+ description: effect.value.identifier.name !== null &&
49810
+ effect.value.identifier.name.kind === 'named'
49811
+ ? `Found mutation of \`${effect.value.identifier.name.value}\``
49812
+ : null,
49813
+ loc: effect.value.loc,
49814
+ suggestions: null,
49815
+ },
49816
+ });
49817
+ }
49818
+ }
49068
49819
  }
49069
- else if (value.binding.name === 'React') {
49070
- sidemap.react.add(lvalId);
49820
+ }
49821
+ }
49822
+ const initialized = new Set();
49823
+ for (const effect of signature.effects) {
49824
+ applyEffect(context, state, effect, initialized, effects);
49825
+ }
49826
+ if (!(state.isDefined(instruction.lvalue) && state.kind(instruction.lvalue))) {
49827
+ CompilerError.invariant(false, {
49828
+ reason: `Expected instruction lvalue to be initialized`,
49829
+ loc: instruction.loc,
49830
+ });
49831
+ }
49832
+ return effects.length !== 0 ? effects : null;
49833
+ }
49834
+ function applyEffect(context, state, _effect, initialized, effects) {
49835
+ var _a, _b, _c, _d;
49836
+ const effect = context.internEffect(_effect);
49837
+ switch (effect.kind) {
49838
+ case 'Freeze': {
49839
+ const didFreeze = state.freeze(effect.value, effect.reason);
49840
+ if (didFreeze) {
49841
+ effects.push(effect);
49071
49842
  }
49072
49843
  break;
49073
49844
  }
49074
- case 'PropertyLoad': {
49075
- if (sidemap.react.has(value.object.identifier.id)) {
49076
- const property = value.property;
49077
- if (property === 'useMemo' || property === 'useCallback') {
49078
- sidemap.manualMemos.set(instr.lvalue.identifier.id, {
49079
- kind: property,
49080
- loadInstr: instr,
49081
- });
49082
- }
49845
+ case 'Create': {
49846
+ CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
49847
+ reason: `Cannot re-initialize variable within an instruction`,
49848
+ description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
49849
+ loc: effect.into.loc,
49850
+ });
49851
+ initialized.add(effect.into.identifier.id);
49852
+ let value = context.effectInstructionValueCache.get(effect);
49853
+ if (value == null) {
49854
+ value = {
49855
+ kind: 'ObjectExpression',
49856
+ properties: [],
49857
+ loc: effect.into.loc,
49858
+ };
49859
+ context.effectInstructionValueCache.set(effect, value);
49083
49860
  }
49861
+ state.initialize(value, {
49862
+ kind: effect.value,
49863
+ reason: new Set([effect.reason]),
49864
+ });
49865
+ state.define(effect.into, value);
49866
+ effects.push(effect);
49084
49867
  break;
49085
49868
  }
49086
- case 'ArrayExpression': {
49087
- if (value.elements.every(e => e.kind === 'Identifier')) {
49088
- sidemap.maybeDepsLists.set(instr.lvalue.identifier.id, value.elements);
49869
+ case 'ImmutableCapture': {
49870
+ const kind = state.kind(effect.from).kind;
49871
+ switch (kind) {
49872
+ case ValueKind.Global:
49873
+ case ValueKind.Primitive: {
49874
+ break;
49875
+ }
49876
+ default: {
49877
+ effects.push(effect);
49878
+ }
49089
49879
  }
49090
49880
  break;
49091
49881
  }
49092
- }
49093
- const maybeDep = collectMaybeMemoDependencies(value, sidemap.maybeDeps, sidemap.optionals.has(lvalue.identifier.id));
49882
+ case 'CreateFrom': {
49883
+ CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
49884
+ reason: `Cannot re-initialize variable within an instruction`,
49885
+ description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
49886
+ loc: effect.into.loc,
49887
+ });
49888
+ initialized.add(effect.into.identifier.id);
49889
+ const fromValue = state.kind(effect.from);
49890
+ let value = context.effectInstructionValueCache.get(effect);
49891
+ if (value == null) {
49892
+ value = {
49893
+ kind: 'ObjectExpression',
49894
+ properties: [],
49895
+ loc: effect.into.loc,
49896
+ };
49897
+ context.effectInstructionValueCache.set(effect, value);
49898
+ }
49899
+ state.initialize(value, {
49900
+ kind: fromValue.kind,
49901
+ reason: new Set(fromValue.reason),
49902
+ });
49903
+ state.define(effect.into, value);
49904
+ switch (fromValue.kind) {
49905
+ case ValueKind.Primitive:
49906
+ case ValueKind.Global: {
49907
+ effects.push({
49908
+ kind: 'Create',
49909
+ value: fromValue.kind,
49910
+ into: effect.into,
49911
+ reason: (_a = [...fromValue.reason][0]) !== null && _a !== void 0 ? _a : ValueReason.Other,
49912
+ });
49913
+ break;
49914
+ }
49915
+ case ValueKind.Frozen: {
49916
+ effects.push({
49917
+ kind: 'Create',
49918
+ value: fromValue.kind,
49919
+ into: effect.into,
49920
+ reason: (_b = [...fromValue.reason][0]) !== null && _b !== void 0 ? _b : ValueReason.Other,
49921
+ });
49922
+ applyEffect(context, state, {
49923
+ kind: 'ImmutableCapture',
49924
+ from: effect.from,
49925
+ into: effect.into,
49926
+ }, initialized, effects);
49927
+ break;
49928
+ }
49929
+ default: {
49930
+ effects.push(effect);
49931
+ }
49932
+ }
49933
+ break;
49934
+ }
49935
+ case 'CreateFunction': {
49936
+ CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
49937
+ reason: `Cannot re-initialize variable within an instruction`,
49938
+ description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
49939
+ loc: effect.into.loc,
49940
+ });
49941
+ initialized.add(effect.into.identifier.id);
49942
+ effects.push(effect);
49943
+ const hasCaptures = effect.captures.some(capture => {
49944
+ switch (state.kind(capture).kind) {
49945
+ case ValueKind.Context:
49946
+ case ValueKind.Mutable: {
49947
+ return true;
49948
+ }
49949
+ default: {
49950
+ return false;
49951
+ }
49952
+ }
49953
+ });
49954
+ const hasTrackedSideEffects = (_c = effect.function.loweredFunc.func.aliasingEffects) === null || _c === void 0 ? void 0 : _c.some(effect => effect.kind === 'MutateFrozen' ||
49955
+ effect.kind === 'MutateGlobal' ||
49956
+ effect.kind === 'Impure');
49957
+ const capturesRef = effect.function.loweredFunc.func.context.some(operand => isRefOrRefValue(operand.identifier));
49958
+ const isMutable = hasCaptures || hasTrackedSideEffects || capturesRef;
49959
+ for (const operand of effect.function.loweredFunc.func.context) {
49960
+ if (operand.effect !== Effect.Capture) {
49961
+ continue;
49962
+ }
49963
+ const kind = state.kind(operand).kind;
49964
+ if (kind === ValueKind.Primitive ||
49965
+ kind == ValueKind.Frozen ||
49966
+ kind == ValueKind.Global) {
49967
+ operand.effect = Effect.Read;
49968
+ }
49969
+ }
49970
+ state.initialize(effect.function, {
49971
+ kind: isMutable ? ValueKind.Mutable : ValueKind.Frozen,
49972
+ reason: new Set([]),
49973
+ });
49974
+ state.define(effect.into, effect.function);
49975
+ for (const capture of effect.captures) {
49976
+ applyEffect(context, state, {
49977
+ kind: 'Capture',
49978
+ from: capture,
49979
+ into: effect.into,
49980
+ }, initialized, effects);
49981
+ }
49982
+ break;
49983
+ }
49984
+ case 'Alias':
49985
+ case 'Capture': {
49986
+ CompilerError.invariant(effect.kind === 'Capture' || initialized.has(effect.into.identifier.id), {
49987
+ reason: `Expected destination value to already be initialized within this instruction for Alias effect`,
49988
+ description: `Destination ${printPlace(effect.into)} is not initialized in this instruction`,
49989
+ loc: effect.into.loc,
49990
+ });
49991
+ const intoKind = state.kind(effect.into).kind;
49992
+ let isMutableDesination;
49993
+ switch (intoKind) {
49994
+ case ValueKind.Context:
49995
+ case ValueKind.Mutable:
49996
+ case ValueKind.MaybeFrozen: {
49997
+ isMutableDesination = true;
49998
+ break;
49999
+ }
50000
+ default: {
50001
+ isMutableDesination = false;
50002
+ break;
50003
+ }
50004
+ }
50005
+ const fromKind = state.kind(effect.from).kind;
50006
+ let isMutableReferenceType;
50007
+ switch (fromKind) {
50008
+ case ValueKind.Global:
50009
+ case ValueKind.Primitive: {
50010
+ isMutableReferenceType = false;
50011
+ break;
50012
+ }
50013
+ case ValueKind.Frozen: {
50014
+ isMutableReferenceType = false;
50015
+ applyEffect(context, state, {
50016
+ kind: 'ImmutableCapture',
50017
+ from: effect.from,
50018
+ into: effect.into,
50019
+ }, initialized, effects);
50020
+ break;
50021
+ }
50022
+ default: {
50023
+ isMutableReferenceType = true;
50024
+ break;
50025
+ }
50026
+ }
50027
+ if (isMutableDesination && isMutableReferenceType) {
50028
+ effects.push(effect);
50029
+ }
50030
+ break;
50031
+ }
50032
+ case 'Assign': {
50033
+ CompilerError.invariant(!initialized.has(effect.into.identifier.id), {
50034
+ reason: `Cannot re-initialize variable within an instruction`,
50035
+ description: `Re-initialized ${printPlace(effect.into)} in ${printAliasingEffect(effect)}`,
50036
+ loc: effect.into.loc,
50037
+ });
50038
+ initialized.add(effect.into.identifier.id);
50039
+ const fromValue = state.kind(effect.from);
50040
+ const fromKind = fromValue.kind;
50041
+ switch (fromKind) {
50042
+ case ValueKind.Frozen: {
50043
+ applyEffect(context, state, {
50044
+ kind: 'ImmutableCapture',
50045
+ from: effect.from,
50046
+ into: effect.into,
50047
+ }, initialized, effects);
50048
+ let value = context.effectInstructionValueCache.get(effect);
50049
+ if (value == null) {
50050
+ value = {
50051
+ kind: 'Primitive',
50052
+ value: undefined,
50053
+ loc: effect.from.loc,
50054
+ };
50055
+ context.effectInstructionValueCache.set(effect, value);
50056
+ }
50057
+ state.initialize(value, {
50058
+ kind: fromKind,
50059
+ reason: new Set(fromValue.reason),
50060
+ });
50061
+ state.define(effect.into, value);
50062
+ break;
50063
+ }
50064
+ case ValueKind.Global:
50065
+ case ValueKind.Primitive: {
50066
+ let value = context.effectInstructionValueCache.get(effect);
50067
+ if (value == null) {
50068
+ value = {
50069
+ kind: 'Primitive',
50070
+ value: undefined,
50071
+ loc: effect.from.loc,
50072
+ };
50073
+ context.effectInstructionValueCache.set(effect, value);
50074
+ }
50075
+ state.initialize(value, {
50076
+ kind: fromKind,
50077
+ reason: new Set(fromValue.reason),
50078
+ });
50079
+ state.define(effect.into, value);
50080
+ break;
50081
+ }
50082
+ default: {
50083
+ state.assign(effect.into, effect.from);
50084
+ effects.push(effect);
50085
+ break;
50086
+ }
50087
+ }
50088
+ break;
50089
+ }
50090
+ case 'Apply': {
50091
+ const functionValues = state.values(effect.function);
50092
+ if (functionValues.length === 1 &&
50093
+ functionValues[0].kind === 'FunctionExpression') {
50094
+ const functionExpr = functionValues[0];
50095
+ let signature = context.functionSignatureCache.get(functionExpr);
50096
+ if (signature == null) {
50097
+ signature = buildSignatureFromFunctionExpression(state.env, functionExpr);
50098
+ context.functionSignatureCache.set(functionExpr, signature);
50099
+ }
50100
+ const signatureEffects = context.cacheApplySignature(signature, effect, () => computeEffectsForSignature(state.env, signature, effect.into, effect.receiver, effect.args, functionExpr.loweredFunc.func.context, effect.loc));
50101
+ if (signatureEffects != null) {
50102
+ applyEffect(context, state, { kind: 'MutateTransitiveConditionally', value: effect.function }, initialized, effects);
50103
+ for (const signatureEffect of signatureEffects) {
50104
+ applyEffect(context, state, signatureEffect, initialized, effects);
50105
+ }
50106
+ break;
50107
+ }
50108
+ }
50109
+ let signatureEffects = null;
50110
+ if (((_d = effect.signature) === null || _d === void 0 ? void 0 : _d.aliasing) != null) {
50111
+ const signature = effect.signature.aliasing;
50112
+ signatureEffects = context.cacheApplySignature(effect.signature.aliasing, effect, () => computeEffectsForSignature(state.env, signature, effect.into, effect.receiver, effect.args, [], effect.loc));
50113
+ }
50114
+ if (signatureEffects != null) {
50115
+ for (const signatureEffect of signatureEffects) {
50116
+ applyEffect(context, state, signatureEffect, initialized, effects);
50117
+ }
50118
+ }
50119
+ else if (effect.signature != null) {
50120
+ const legacyEffects = computeEffectsForLegacySignature(state, effect.signature, effect.into, effect.receiver, effect.args, effect.loc);
50121
+ for (const legacyEffect of legacyEffects) {
50122
+ applyEffect(context, state, legacyEffect, initialized, effects);
50123
+ }
50124
+ }
50125
+ else {
50126
+ applyEffect(context, state, {
50127
+ kind: 'Create',
50128
+ into: effect.into,
50129
+ value: ValueKind.Mutable,
50130
+ reason: ValueReason.Other,
50131
+ }, initialized, effects);
50132
+ for (const arg of [effect.receiver, effect.function, ...effect.args]) {
50133
+ if (arg.kind === 'Hole') {
50134
+ continue;
50135
+ }
50136
+ const operand = arg.kind === 'Identifier' ? arg : arg.place;
50137
+ if (operand !== effect.function || effect.mutatesFunction) {
50138
+ applyEffect(context, state, {
50139
+ kind: 'MutateTransitiveConditionally',
50140
+ value: operand,
50141
+ }, initialized, effects);
50142
+ }
50143
+ const mutateIterator = arg.kind === 'Spread' ? conditionallyMutateIterator(operand) : null;
50144
+ if (mutateIterator) {
50145
+ applyEffect(context, state, mutateIterator, initialized, effects);
50146
+ }
50147
+ applyEffect(context, state, { kind: 'Alias', from: operand, into: effect.into }, initialized, effects);
50148
+ for (const otherArg of [
50149
+ effect.receiver,
50150
+ effect.function,
50151
+ ...effect.args,
50152
+ ]) {
50153
+ if (otherArg.kind === 'Hole') {
50154
+ continue;
50155
+ }
50156
+ const other = otherArg.kind === 'Identifier' ? otherArg : otherArg.place;
50157
+ if (other === arg) {
50158
+ continue;
50159
+ }
50160
+ applyEffect(context, state, {
50161
+ kind: 'Capture',
50162
+ from: operand,
50163
+ into: other,
50164
+ }, initialized, effects);
50165
+ }
50166
+ }
50167
+ }
50168
+ break;
50169
+ }
50170
+ case 'Mutate':
50171
+ case 'MutateConditionally':
50172
+ case 'MutateTransitive':
50173
+ case 'MutateTransitiveConditionally': {
50174
+ const mutationKind = state.mutate(effect.kind, effect.value);
50175
+ if (mutationKind === 'mutate') {
50176
+ effects.push(effect);
50177
+ }
50178
+ else if (mutationKind === 'mutate-ref') ;
50179
+ else if (mutationKind !== 'none' &&
50180
+ (effect.kind === 'Mutate' || effect.kind === 'MutateTransitive')) {
50181
+ const value = state.kind(effect.value);
50182
+ if (mutationKind === 'mutate-frozen' &&
50183
+ context.hoistedContextDeclarations.has(effect.value.identifier.declarationId)) {
50184
+ const description = effect.value.identifier.name !== null &&
50185
+ effect.value.identifier.name.kind === 'named'
50186
+ ? `Variable \`${effect.value.identifier.name.value}\` is accessed before it is declared`
50187
+ : null;
50188
+ const hoistedAccess = context.hoistedContextDeclarations.get(effect.value.identifier.declarationId);
50189
+ if (hoistedAccess != null && hoistedAccess.loc != effect.value.loc) {
50190
+ applyEffect(context, state, {
50191
+ kind: 'MutateFrozen',
50192
+ place: effect.value,
50193
+ error: {
50194
+ severity: ErrorSeverity.InvalidReact,
50195
+ reason: `This variable is accessed before it is declared, which may prevent it from updating as the assigned value changes over time`,
50196
+ description,
50197
+ loc: hoistedAccess.loc,
50198
+ suggestions: null,
50199
+ },
50200
+ }, initialized, effects);
50201
+ }
50202
+ applyEffect(context, state, {
50203
+ kind: 'MutateFrozen',
50204
+ place: effect.value,
50205
+ error: {
50206
+ severity: ErrorSeverity.InvalidReact,
50207
+ reason: `This variable is accessed before it is declared, which prevents the earlier access from updating when this value changes over time`,
50208
+ description,
50209
+ loc: effect.value.loc,
50210
+ suggestions: null,
50211
+ },
50212
+ }, initialized, effects);
50213
+ }
50214
+ else {
50215
+ const reason = getWriteErrorReason({
50216
+ kind: value.kind,
50217
+ reason: value.reason,
50218
+ context: new Set(),
50219
+ });
50220
+ const description = effect.value.identifier.name !== null &&
50221
+ effect.value.identifier.name.kind === 'named'
50222
+ ? `Found mutation of \`${effect.value.identifier.name.value}\``
50223
+ : null;
50224
+ applyEffect(context, state, {
50225
+ kind: value.kind === ValueKind.Frozen
50226
+ ? 'MutateFrozen'
50227
+ : 'MutateGlobal',
50228
+ place: effect.value,
50229
+ error: {
50230
+ severity: ErrorSeverity.InvalidReact,
50231
+ reason,
50232
+ description,
50233
+ loc: effect.value.loc,
50234
+ suggestions: null,
50235
+ },
50236
+ }, initialized, effects);
50237
+ }
50238
+ }
50239
+ break;
50240
+ }
50241
+ case 'Impure':
50242
+ case 'Render':
50243
+ case 'MutateFrozen':
50244
+ case 'MutateGlobal': {
50245
+ effects.push(effect);
50246
+ break;
50247
+ }
50248
+ default: {
50249
+ assertExhaustive$1(effect, `Unexpected effect kind '${effect.kind}'`);
50250
+ }
50251
+ }
50252
+ }
50253
+ class InferenceState {
50254
+ constructor(env, isFunctionExpression, values, variables) {
50255
+ _InferenceState_isFunctionExpression.set(this, void 0);
50256
+ _InferenceState_values.set(this, void 0);
50257
+ _InferenceState_variables.set(this, void 0);
50258
+ this.env = env;
50259
+ __classPrivateFieldSet(this, _InferenceState_isFunctionExpression, isFunctionExpression, "f");
50260
+ __classPrivateFieldSet(this, _InferenceState_values, values, "f");
50261
+ __classPrivateFieldSet(this, _InferenceState_variables, variables, "f");
50262
+ }
50263
+ static empty(env, isFunctionExpression) {
50264
+ return new InferenceState(env, isFunctionExpression, new Map(), new Map());
50265
+ }
50266
+ get isFunctionExpression() {
50267
+ return __classPrivateFieldGet(this, _InferenceState_isFunctionExpression, "f");
50268
+ }
50269
+ initialize(value, kind) {
50270
+ CompilerError.invariant(value.kind !== 'LoadLocal', {
50271
+ reason: '[InferMutationAliasingEffects] Expected all top-level identifiers to be defined as variables, not values',
50272
+ description: null,
50273
+ loc: value.loc,
50274
+ suggestions: null,
50275
+ });
50276
+ __classPrivateFieldGet(this, _InferenceState_values, "f").set(value, kind);
50277
+ }
50278
+ values(place) {
50279
+ const values = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(place.identifier.id);
50280
+ CompilerError.invariant(values != null, {
50281
+ reason: `[InferMutationAliasingEffects] Expected value kind to be initialized`,
50282
+ description: `${printPlace(place)}`,
50283
+ loc: place.loc,
50284
+ suggestions: null,
50285
+ });
50286
+ return Array.from(values);
50287
+ }
50288
+ kind(place) {
50289
+ const values = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(place.identifier.id);
50290
+ CompilerError.invariant(values != null, {
50291
+ reason: `[InferMutationAliasingEffects] Expected value kind to be initialized`,
50292
+ description: `${printPlace(place)}`,
50293
+ loc: place.loc,
50294
+ suggestions: null,
50295
+ });
50296
+ let mergedKind = null;
50297
+ for (const value of values) {
50298
+ const kind = __classPrivateFieldGet(this, _InferenceState_values, "f").get(value);
50299
+ mergedKind =
50300
+ mergedKind !== null ? mergeAbstractValues(mergedKind, kind) : kind;
50301
+ }
50302
+ CompilerError.invariant(mergedKind !== null, {
50303
+ reason: `[InferMutationAliasingEffects] Expected at least one value`,
50304
+ description: `No value found at \`${printPlace(place)}\``,
50305
+ loc: place.loc,
50306
+ suggestions: null,
50307
+ });
50308
+ return mergedKind;
50309
+ }
50310
+ assign(place, value) {
50311
+ const values = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(value.identifier.id);
50312
+ CompilerError.invariant(values != null, {
50313
+ reason: `[InferMutationAliasingEffects] Expected value for identifier to be initialized`,
50314
+ description: `${printIdentifier(value.identifier)}`,
50315
+ loc: value.loc,
50316
+ suggestions: null,
50317
+ });
50318
+ __classPrivateFieldGet(this, _InferenceState_variables, "f").set(place.identifier.id, new Set(values));
50319
+ }
50320
+ appendAlias(place, value) {
50321
+ const values = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(value.identifier.id);
50322
+ CompilerError.invariant(values != null, {
50323
+ reason: `[InferMutationAliasingEffects] Expected value for identifier to be initialized`,
50324
+ description: `${printIdentifier(value.identifier)}`,
50325
+ loc: value.loc,
50326
+ suggestions: null,
50327
+ });
50328
+ const prevValues = this.values(place);
50329
+ __classPrivateFieldGet(this, _InferenceState_variables, "f").set(place.identifier.id, new Set([...prevValues, ...values]));
50330
+ }
50331
+ define(place, value) {
50332
+ CompilerError.invariant(__classPrivateFieldGet(this, _InferenceState_values, "f").has(value), {
50333
+ reason: `[InferMutationAliasingEffects] Expected value to be initialized at '${printSourceLocation(value.loc)}'`,
50334
+ description: printInstructionValue(value),
50335
+ loc: value.loc,
50336
+ suggestions: null,
50337
+ });
50338
+ __classPrivateFieldGet(this, _InferenceState_variables, "f").set(place.identifier.id, new Set([value]));
50339
+ }
50340
+ isDefined(place) {
50341
+ return __classPrivateFieldGet(this, _InferenceState_variables, "f").has(place.identifier.id);
50342
+ }
50343
+ freeze(place, reason) {
50344
+ const value = this.kind(place);
50345
+ switch (value.kind) {
50346
+ case ValueKind.Context:
50347
+ case ValueKind.Mutable:
50348
+ case ValueKind.MaybeFrozen: {
50349
+ const values = this.values(place);
50350
+ for (const instrValue of values) {
50351
+ this.freezeValue(instrValue, reason);
50352
+ }
50353
+ return true;
50354
+ }
50355
+ case ValueKind.Frozen:
50356
+ case ValueKind.Global:
50357
+ case ValueKind.Primitive: {
50358
+ return false;
50359
+ }
50360
+ default: {
50361
+ assertExhaustive$1(value.kind, `Unexpected value kind '${value.kind}'`);
50362
+ }
50363
+ }
50364
+ }
50365
+ freezeValue(value, reason) {
50366
+ __classPrivateFieldGet(this, _InferenceState_values, "f").set(value, {
50367
+ kind: ValueKind.Frozen,
50368
+ reason: new Set([reason]),
50369
+ });
50370
+ if (value.kind === 'FunctionExpression' &&
50371
+ (this.env.config.enablePreserveExistingMemoizationGuarantees ||
50372
+ this.env.config.enableTransitivelyFreezeFunctionExpressions)) {
50373
+ for (const place of value.loweredFunc.func.context) {
50374
+ this.freeze(place, reason);
50375
+ }
50376
+ }
50377
+ }
50378
+ mutate(variant, place) {
50379
+ if (isRefOrRefValue(place.identifier)) {
50380
+ return 'mutate-ref';
50381
+ }
50382
+ const kind = this.kind(place).kind;
50383
+ switch (variant) {
50384
+ case 'MutateConditionally':
50385
+ case 'MutateTransitiveConditionally': {
50386
+ switch (kind) {
50387
+ case ValueKind.Mutable:
50388
+ case ValueKind.Context: {
50389
+ return 'mutate';
50390
+ }
50391
+ default: {
50392
+ return 'none';
50393
+ }
50394
+ }
50395
+ }
50396
+ case 'Mutate':
50397
+ case 'MutateTransitive': {
50398
+ switch (kind) {
50399
+ case ValueKind.Mutable:
50400
+ case ValueKind.Context: {
50401
+ return 'mutate';
50402
+ }
50403
+ case ValueKind.Primitive: {
50404
+ return 'none';
50405
+ }
50406
+ case ValueKind.Frozen: {
50407
+ return 'mutate-frozen';
50408
+ }
50409
+ case ValueKind.Global: {
50410
+ return 'mutate-global';
50411
+ }
50412
+ case ValueKind.MaybeFrozen: {
50413
+ return 'none';
50414
+ }
50415
+ default: {
50416
+ assertExhaustive$1(kind, `Unexpected kind ${kind}`);
50417
+ }
50418
+ }
50419
+ }
50420
+ default: {
50421
+ assertExhaustive$1(variant, `Unexpected mutation variant ${variant}`);
50422
+ }
50423
+ }
50424
+ }
50425
+ merge(other) {
50426
+ let nextValues = null;
50427
+ let nextVariables = null;
50428
+ for (const [id, thisValue] of __classPrivateFieldGet(this, _InferenceState_values, "f")) {
50429
+ const otherValue = __classPrivateFieldGet(other, _InferenceState_values, "f").get(id);
50430
+ if (otherValue !== undefined) {
50431
+ const mergedValue = mergeAbstractValues(thisValue, otherValue);
50432
+ if (mergedValue !== thisValue) {
50433
+ nextValues = nextValues !== null && nextValues !== void 0 ? nextValues : new Map(__classPrivateFieldGet(this, _InferenceState_values, "f"));
50434
+ nextValues.set(id, mergedValue);
50435
+ }
50436
+ }
50437
+ }
50438
+ for (const [id, otherValue] of __classPrivateFieldGet(other, _InferenceState_values, "f")) {
50439
+ if (__classPrivateFieldGet(this, _InferenceState_values, "f").has(id)) {
50440
+ continue;
50441
+ }
50442
+ nextValues = nextValues !== null && nextValues !== void 0 ? nextValues : new Map(__classPrivateFieldGet(this, _InferenceState_values, "f"));
50443
+ nextValues.set(id, otherValue);
50444
+ }
50445
+ for (const [id, thisValues] of __classPrivateFieldGet(this, _InferenceState_variables, "f")) {
50446
+ const otherValues = __classPrivateFieldGet(other, _InferenceState_variables, "f").get(id);
50447
+ if (otherValues !== undefined) {
50448
+ let mergedValues = null;
50449
+ for (const otherValue of otherValues) {
50450
+ if (!thisValues.has(otherValue)) {
50451
+ mergedValues = mergedValues !== null && mergedValues !== void 0 ? mergedValues : new Set(thisValues);
50452
+ mergedValues.add(otherValue);
50453
+ }
50454
+ }
50455
+ if (mergedValues !== null) {
50456
+ nextVariables = nextVariables !== null && nextVariables !== void 0 ? nextVariables : new Map(__classPrivateFieldGet(this, _InferenceState_variables, "f"));
50457
+ nextVariables.set(id, mergedValues);
50458
+ }
50459
+ }
50460
+ }
50461
+ for (const [id, otherValues] of __classPrivateFieldGet(other, _InferenceState_variables, "f")) {
50462
+ if (__classPrivateFieldGet(this, _InferenceState_variables, "f").has(id)) {
50463
+ continue;
50464
+ }
50465
+ nextVariables = nextVariables !== null && nextVariables !== void 0 ? nextVariables : new Map(__classPrivateFieldGet(this, _InferenceState_variables, "f"));
50466
+ nextVariables.set(id, new Set(otherValues));
50467
+ }
50468
+ if (nextVariables === null && nextValues === null) {
50469
+ return null;
50470
+ }
50471
+ else {
50472
+ return new InferenceState(this.env, __classPrivateFieldGet(this, _InferenceState_isFunctionExpression, "f"), nextValues !== null && nextValues !== void 0 ? nextValues : new Map(__classPrivateFieldGet(this, _InferenceState_values, "f")), nextVariables !== null && nextVariables !== void 0 ? nextVariables : new Map(__classPrivateFieldGet(this, _InferenceState_variables, "f")));
50473
+ }
50474
+ }
50475
+ clone() {
50476
+ return new InferenceState(this.env, __classPrivateFieldGet(this, _InferenceState_isFunctionExpression, "f"), new Map(__classPrivateFieldGet(this, _InferenceState_values, "f")), new Map(__classPrivateFieldGet(this, _InferenceState_variables, "f")));
50477
+ }
50478
+ debug() {
50479
+ const result = { values: {}, variables: {} };
50480
+ const objects = new Map();
50481
+ function identify(value) {
50482
+ let id = objects.get(value);
50483
+ if (id == null) {
50484
+ id = objects.size;
50485
+ objects.set(value, id);
50486
+ }
50487
+ return id;
50488
+ }
50489
+ for (const [value, kind] of __classPrivateFieldGet(this, _InferenceState_values, "f")) {
50490
+ const id = identify(value);
50491
+ result.values[id] = {
50492
+ abstract: this.debugAbstractValue(kind),
50493
+ value: printInstructionValue(value),
50494
+ };
50495
+ }
50496
+ for (const [variable, values] of __classPrivateFieldGet(this, _InferenceState_variables, "f")) {
50497
+ result.variables[`$${variable}`] = [...values].map(identify);
50498
+ }
50499
+ return result;
50500
+ }
50501
+ debugAbstractValue(value) {
50502
+ return {
50503
+ kind: value.kind,
50504
+ reason: [...value.reason],
50505
+ };
50506
+ }
50507
+ inferPhi(phi) {
50508
+ const values = new Set();
50509
+ for (const [_, operand] of phi.operands) {
50510
+ const operandValues = __classPrivateFieldGet(this, _InferenceState_variables, "f").get(operand.identifier.id);
50511
+ if (operandValues === undefined)
50512
+ continue;
50513
+ for (const v of operandValues) {
50514
+ values.add(v);
50515
+ }
50516
+ }
50517
+ if (values.size > 0) {
50518
+ __classPrivateFieldGet(this, _InferenceState_variables, "f").set(phi.place.identifier.id, values);
50519
+ }
50520
+ }
50521
+ }
50522
+ _InferenceState_isFunctionExpression = new WeakMap(), _InferenceState_values = new WeakMap(), _InferenceState_variables = new WeakMap();
50523
+ function mergeAbstractValues(a, b) {
50524
+ const kind = mergeValueKinds(a.kind, b.kind);
50525
+ if (kind === a.kind &&
50526
+ kind === b.kind &&
50527
+ Set_isSuperset(a.reason, b.reason)) {
50528
+ return a;
50529
+ }
50530
+ const reason = new Set(a.reason);
50531
+ for (const r of b.reason) {
50532
+ reason.add(r);
50533
+ }
50534
+ return { kind, reason };
50535
+ }
50536
+ function conditionallyMutateIterator(place) {
50537
+ if (!(isArrayType(place.identifier) ||
50538
+ isSetType(place.identifier) ||
50539
+ isMapType(place.identifier))) {
50540
+ return {
50541
+ kind: 'MutateTransitiveConditionally',
50542
+ value: place,
50543
+ };
50544
+ }
50545
+ return null;
50546
+ }
50547
+ function computeSignatureForInstruction(context, env, instr) {
50548
+ const { lvalue, value } = instr;
50549
+ const effects = [];
50550
+ switch (value.kind) {
50551
+ case 'ArrayExpression': {
50552
+ effects.push({
50553
+ kind: 'Create',
50554
+ into: lvalue,
50555
+ value: ValueKind.Mutable,
50556
+ reason: ValueReason.Other,
50557
+ });
50558
+ for (const element of value.elements) {
50559
+ if (element.kind === 'Identifier') {
50560
+ effects.push({
50561
+ kind: 'Capture',
50562
+ from: element,
50563
+ into: lvalue,
50564
+ });
50565
+ }
50566
+ else if (element.kind === 'Spread') {
50567
+ const mutateIterator = conditionallyMutateIterator(element.place);
50568
+ if (mutateIterator != null) {
50569
+ effects.push(mutateIterator);
50570
+ }
50571
+ effects.push({
50572
+ kind: 'Capture',
50573
+ from: element.place,
50574
+ into: lvalue,
50575
+ });
50576
+ }
50577
+ else {
50578
+ continue;
50579
+ }
50580
+ }
50581
+ break;
50582
+ }
50583
+ case 'ObjectExpression': {
50584
+ effects.push({
50585
+ kind: 'Create',
50586
+ into: lvalue,
50587
+ value: ValueKind.Mutable,
50588
+ reason: ValueReason.Other,
50589
+ });
50590
+ for (const property of value.properties) {
50591
+ if (property.kind === 'ObjectProperty') {
50592
+ effects.push({
50593
+ kind: 'Capture',
50594
+ from: property.place,
50595
+ into: lvalue,
50596
+ });
50597
+ }
50598
+ else {
50599
+ effects.push({
50600
+ kind: 'Capture',
50601
+ from: property.place,
50602
+ into: lvalue,
50603
+ });
50604
+ }
50605
+ }
50606
+ break;
50607
+ }
50608
+ case 'Await': {
50609
+ effects.push({
50610
+ kind: 'Create',
50611
+ into: lvalue,
50612
+ value: ValueKind.Mutable,
50613
+ reason: ValueReason.Other,
50614
+ });
50615
+ effects.push({ kind: 'MutateTransitiveConditionally', value: value.value });
50616
+ effects.push({
50617
+ kind: 'Capture',
50618
+ from: value.value,
50619
+ into: lvalue,
50620
+ });
50621
+ break;
50622
+ }
50623
+ case 'NewExpression':
50624
+ case 'CallExpression':
50625
+ case 'MethodCall': {
50626
+ let callee;
50627
+ let receiver;
50628
+ let mutatesCallee;
50629
+ if (value.kind === 'NewExpression') {
50630
+ callee = value.callee;
50631
+ receiver = value.callee;
50632
+ mutatesCallee = false;
50633
+ }
50634
+ else if (value.kind === 'CallExpression') {
50635
+ callee = value.callee;
50636
+ receiver = value.callee;
50637
+ mutatesCallee = true;
50638
+ }
50639
+ else if (value.kind === 'MethodCall') {
50640
+ callee = value.property;
50641
+ receiver = value.receiver;
50642
+ mutatesCallee = false;
50643
+ }
50644
+ else {
50645
+ assertExhaustive$1(value, `Unexpected value kind '${value.kind}'`);
50646
+ }
50647
+ const signature = getFunctionCallSignature(env, callee.identifier.type);
50648
+ effects.push({
50649
+ kind: 'Apply',
50650
+ receiver,
50651
+ function: callee,
50652
+ mutatesFunction: mutatesCallee,
50653
+ args: value.args,
50654
+ into: lvalue,
50655
+ signature,
50656
+ loc: value.loc,
50657
+ });
50658
+ break;
50659
+ }
50660
+ case 'PropertyDelete':
50661
+ case 'ComputedDelete': {
50662
+ effects.push({
50663
+ kind: 'Create',
50664
+ into: lvalue,
50665
+ value: ValueKind.Primitive,
50666
+ reason: ValueReason.Other,
50667
+ });
50668
+ effects.push({ kind: 'Mutate', value: value.object });
50669
+ break;
50670
+ }
50671
+ case 'PropertyLoad':
50672
+ case 'ComputedLoad': {
50673
+ if (isPrimitiveType(lvalue.identifier)) {
50674
+ effects.push({
50675
+ kind: 'Create',
50676
+ into: lvalue,
50677
+ value: ValueKind.Primitive,
50678
+ reason: ValueReason.Other,
50679
+ });
50680
+ }
50681
+ else {
50682
+ effects.push({
50683
+ kind: 'CreateFrom',
50684
+ from: value.object,
50685
+ into: lvalue,
50686
+ });
50687
+ }
50688
+ break;
50689
+ }
50690
+ case 'PropertyStore':
50691
+ case 'ComputedStore': {
50692
+ effects.push({ kind: 'Mutate', value: value.object });
50693
+ effects.push({
50694
+ kind: 'Capture',
50695
+ from: value.value,
50696
+ into: value.object,
50697
+ });
50698
+ effects.push({
50699
+ kind: 'Create',
50700
+ into: lvalue,
50701
+ value: ValueKind.Primitive,
50702
+ reason: ValueReason.Other,
50703
+ });
50704
+ break;
50705
+ }
50706
+ case 'ObjectMethod':
50707
+ case 'FunctionExpression': {
50708
+ effects.push({
50709
+ kind: 'CreateFunction',
50710
+ into: lvalue,
50711
+ function: value,
50712
+ captures: value.loweredFunc.func.context.filter(operand => operand.effect === Effect.Capture),
50713
+ });
50714
+ break;
50715
+ }
50716
+ case 'GetIterator': {
50717
+ effects.push({
50718
+ kind: 'Create',
50719
+ into: lvalue,
50720
+ value: ValueKind.Mutable,
50721
+ reason: ValueReason.Other,
50722
+ });
50723
+ if (isArrayType(value.collection.identifier) ||
50724
+ isMapType(value.collection.identifier) ||
50725
+ isSetType(value.collection.identifier)) {
50726
+ effects.push({
50727
+ kind: 'Capture',
50728
+ from: value.collection,
50729
+ into: lvalue,
50730
+ });
50731
+ }
50732
+ else {
50733
+ effects.push({ kind: 'Alias', from: value.collection, into: lvalue });
50734
+ effects.push({
50735
+ kind: 'MutateTransitiveConditionally',
50736
+ value: value.collection,
50737
+ });
50738
+ }
50739
+ break;
50740
+ }
50741
+ case 'IteratorNext': {
50742
+ effects.push({ kind: 'MutateConditionally', value: value.iterator });
50743
+ effects.push({
50744
+ kind: 'CreateFrom',
50745
+ from: value.collection,
50746
+ into: lvalue,
50747
+ });
50748
+ break;
50749
+ }
50750
+ case 'NextPropertyOf': {
50751
+ effects.push({
50752
+ kind: 'Create',
50753
+ into: lvalue,
50754
+ value: ValueKind.Primitive,
50755
+ reason: ValueReason.Other,
50756
+ });
50757
+ break;
50758
+ }
50759
+ case 'JsxExpression':
50760
+ case 'JsxFragment': {
50761
+ effects.push({
50762
+ kind: 'Create',
50763
+ into: lvalue,
50764
+ value: ValueKind.Frozen,
50765
+ reason: ValueReason.JsxCaptured,
50766
+ });
50767
+ for (const operand of eachInstructionValueOperand(value)) {
50768
+ effects.push({
50769
+ kind: 'Freeze',
50770
+ value: operand,
50771
+ reason: ValueReason.JsxCaptured,
50772
+ });
50773
+ effects.push({
50774
+ kind: 'Capture',
50775
+ from: operand,
50776
+ into: lvalue,
50777
+ });
50778
+ }
50779
+ if (value.kind === 'JsxExpression') {
50780
+ if (value.tag.kind === 'Identifier') {
50781
+ effects.push({
50782
+ kind: 'Render',
50783
+ place: value.tag,
50784
+ });
50785
+ }
50786
+ if (value.children != null) {
50787
+ for (const child of value.children) {
50788
+ effects.push({
50789
+ kind: 'Render',
50790
+ place: child,
50791
+ });
50792
+ }
50793
+ }
50794
+ }
50795
+ break;
50796
+ }
50797
+ case 'DeclareLocal': {
50798
+ effects.push({
50799
+ kind: 'Create',
50800
+ into: value.lvalue.place,
50801
+ value: ValueKind.Primitive,
50802
+ reason: ValueReason.Other,
50803
+ });
50804
+ effects.push({
50805
+ kind: 'Create',
50806
+ into: lvalue,
50807
+ value: ValueKind.Primitive,
50808
+ reason: ValueReason.Other,
50809
+ });
50810
+ break;
50811
+ }
50812
+ case 'Destructure': {
50813
+ for (const patternLValue of eachInstructionValueLValue(value)) {
50814
+ if (isPrimitiveType(patternLValue.identifier)) {
50815
+ effects.push({
50816
+ kind: 'Create',
50817
+ into: patternLValue,
50818
+ value: ValueKind.Primitive,
50819
+ reason: ValueReason.Other,
50820
+ });
50821
+ }
50822
+ else {
50823
+ effects.push({
50824
+ kind: 'CreateFrom',
50825
+ from: value.value,
50826
+ into: patternLValue,
50827
+ });
50828
+ }
50829
+ }
50830
+ effects.push({ kind: 'Assign', from: value.value, into: lvalue });
50831
+ break;
50832
+ }
50833
+ case 'LoadContext': {
50834
+ effects.push({ kind: 'CreateFrom', from: value.place, into: lvalue });
50835
+ break;
50836
+ }
50837
+ case 'DeclareContext': {
50838
+ const kind = value.lvalue.kind;
50839
+ if (!context.hoistedContextDeclarations.has(value.lvalue.place.identifier.declarationId) ||
50840
+ kind === InstructionKind.HoistedConst ||
50841
+ kind === InstructionKind.HoistedFunction ||
50842
+ kind === InstructionKind.HoistedLet) {
50843
+ effects.push({
50844
+ kind: 'Create',
50845
+ into: value.lvalue.place,
50846
+ value: ValueKind.Mutable,
50847
+ reason: ValueReason.Other,
50848
+ });
50849
+ }
50850
+ else {
50851
+ effects.push({ kind: 'Mutate', value: value.lvalue.place });
50852
+ }
50853
+ effects.push({
50854
+ kind: 'Create',
50855
+ into: lvalue,
50856
+ value: ValueKind.Primitive,
50857
+ reason: ValueReason.Other,
50858
+ });
50859
+ break;
50860
+ }
50861
+ case 'StoreContext': {
50862
+ if (value.lvalue.kind === InstructionKind.Reassign ||
50863
+ context.hoistedContextDeclarations.has(value.lvalue.place.identifier.declarationId)) {
50864
+ effects.push({ kind: 'Mutate', value: value.lvalue.place });
50865
+ }
50866
+ else {
50867
+ effects.push({
50868
+ kind: 'Create',
50869
+ into: value.lvalue.place,
50870
+ value: ValueKind.Mutable,
50871
+ reason: ValueReason.Other,
50872
+ });
50873
+ }
50874
+ effects.push({
50875
+ kind: 'Capture',
50876
+ from: value.value,
50877
+ into: value.lvalue.place,
50878
+ });
50879
+ effects.push({ kind: 'Assign', from: value.value, into: lvalue });
50880
+ break;
50881
+ }
50882
+ case 'LoadLocal': {
50883
+ effects.push({ kind: 'Assign', from: value.place, into: lvalue });
50884
+ break;
50885
+ }
50886
+ case 'StoreLocal': {
50887
+ effects.push({
50888
+ kind: 'Assign',
50889
+ from: value.value,
50890
+ into: value.lvalue.place,
50891
+ });
50892
+ effects.push({ kind: 'Assign', from: value.value, into: lvalue });
50893
+ break;
50894
+ }
50895
+ case 'PostfixUpdate':
50896
+ case 'PrefixUpdate': {
50897
+ effects.push({
50898
+ kind: 'Create',
50899
+ into: lvalue,
50900
+ value: ValueKind.Primitive,
50901
+ reason: ValueReason.Other,
50902
+ });
50903
+ effects.push({
50904
+ kind: 'Create',
50905
+ into: value.lvalue,
50906
+ value: ValueKind.Primitive,
50907
+ reason: ValueReason.Other,
50908
+ });
50909
+ break;
50910
+ }
50911
+ case 'StoreGlobal': {
50912
+ effects.push({
50913
+ kind: 'MutateGlobal',
50914
+ place: value.value,
50915
+ error: {
50916
+ reason: 'Unexpected reassignment of a variable which was defined outside of the component. Components and hooks should be pure and side-effect free, but variable reassignment is a form of side-effect. If this variable is used in rendering, use useState instead. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#side-effects-must-run-outside-of-render)',
50917
+ loc: instr.loc,
50918
+ suggestions: null,
50919
+ severity: ErrorSeverity.InvalidReact,
50920
+ },
50921
+ });
50922
+ effects.push({ kind: 'Assign', from: value.value, into: lvalue });
50923
+ break;
50924
+ }
50925
+ case 'TypeCastExpression': {
50926
+ effects.push({ kind: 'Assign', from: value.value, into: lvalue });
50927
+ break;
50928
+ }
50929
+ case 'LoadGlobal': {
50930
+ effects.push({
50931
+ kind: 'Create',
50932
+ into: lvalue,
50933
+ value: ValueKind.Global,
50934
+ reason: ValueReason.Global,
50935
+ });
50936
+ break;
50937
+ }
50938
+ case 'StartMemoize':
50939
+ case 'FinishMemoize': {
50940
+ if (env.config.enablePreserveExistingMemoizationGuarantees) {
50941
+ for (const operand of eachInstructionValueOperand(value)) {
50942
+ effects.push({
50943
+ kind: 'Freeze',
50944
+ value: operand,
50945
+ reason: ValueReason.Other,
50946
+ });
50947
+ }
50948
+ }
50949
+ effects.push({
50950
+ kind: 'Create',
50951
+ into: lvalue,
50952
+ value: ValueKind.Primitive,
50953
+ reason: ValueReason.Other,
50954
+ });
50955
+ break;
50956
+ }
50957
+ case 'TaggedTemplateExpression':
50958
+ case 'BinaryExpression':
50959
+ case 'Debugger':
50960
+ case 'JSXText':
50961
+ case 'MetaProperty':
50962
+ case 'Primitive':
50963
+ case 'RegExpLiteral':
50964
+ case 'TemplateLiteral':
50965
+ case 'UnaryExpression':
50966
+ case 'UnsupportedNode': {
50967
+ effects.push({
50968
+ kind: 'Create',
50969
+ into: lvalue,
50970
+ value: ValueKind.Primitive,
50971
+ reason: ValueReason.Other,
50972
+ });
50973
+ break;
50974
+ }
50975
+ }
50976
+ return {
50977
+ effects,
50978
+ };
50979
+ }
50980
+ function computeEffectsForLegacySignature(state, signature, lvalue, receiver, args, loc) {
50981
+ var _a, _b;
50982
+ const returnValueReason = (_a = signature.returnValueReason) !== null && _a !== void 0 ? _a : ValueReason.Other;
50983
+ const effects = [];
50984
+ effects.push({
50985
+ kind: 'Create',
50986
+ into: lvalue,
50987
+ value: signature.returnValueKind,
50988
+ reason: returnValueReason,
50989
+ });
50990
+ if (signature.impure && state.env.config.validateNoImpureFunctionsInRender) {
50991
+ effects.push({
50992
+ kind: 'Impure',
50993
+ place: receiver,
50994
+ error: {
50995
+ reason: 'Calling an impure function can produce unstable results. (https://react.dev/reference/rules/components-and-hooks-must-be-pure#components-and-hooks-must-be-idempotent)',
50996
+ description: signature.canonicalName != null
50997
+ ? `\`${signature.canonicalName}\` is an impure function whose results may change on every call`
50998
+ : null,
50999
+ severity: ErrorSeverity.InvalidReact,
51000
+ loc,
51001
+ suggestions: null,
51002
+ },
51003
+ });
51004
+ }
51005
+ const stores = [];
51006
+ const captures = [];
51007
+ function visit(place, effect) {
51008
+ switch (effect) {
51009
+ case Effect.Store: {
51010
+ effects.push({
51011
+ kind: 'Mutate',
51012
+ value: place,
51013
+ });
51014
+ stores.push(place);
51015
+ break;
51016
+ }
51017
+ case Effect.Capture: {
51018
+ captures.push(place);
51019
+ break;
51020
+ }
51021
+ case Effect.ConditionallyMutate: {
51022
+ effects.push({
51023
+ kind: 'MutateTransitiveConditionally',
51024
+ value: place,
51025
+ });
51026
+ break;
51027
+ }
51028
+ case Effect.ConditionallyMutateIterator: {
51029
+ const mutateIterator = conditionallyMutateIterator(place);
51030
+ if (mutateIterator != null) {
51031
+ effects.push(mutateIterator);
51032
+ captures.push(place);
51033
+ }
51034
+ effects.push({
51035
+ kind: 'Capture',
51036
+ from: place,
51037
+ into: lvalue,
51038
+ });
51039
+ break;
51040
+ }
51041
+ case Effect.Freeze: {
51042
+ effects.push({
51043
+ kind: 'Freeze',
51044
+ value: place,
51045
+ reason: returnValueReason,
51046
+ });
51047
+ break;
51048
+ }
51049
+ case Effect.Mutate: {
51050
+ effects.push({ kind: 'MutateTransitive', value: place });
51051
+ break;
51052
+ }
51053
+ case Effect.Read: {
51054
+ effects.push({
51055
+ kind: 'ImmutableCapture',
51056
+ from: place,
51057
+ into: lvalue,
51058
+ });
51059
+ break;
51060
+ }
51061
+ }
51062
+ }
51063
+ if (signature.mutableOnlyIfOperandsAreMutable &&
51064
+ areArgumentsImmutableAndNonMutating(state, args)) {
51065
+ effects.push({
51066
+ kind: 'Alias',
51067
+ from: receiver,
51068
+ into: lvalue,
51069
+ });
51070
+ for (const arg of args) {
51071
+ if (arg.kind === 'Hole') {
51072
+ continue;
51073
+ }
51074
+ const place = arg.kind === 'Identifier' ? arg : arg.place;
51075
+ effects.push({
51076
+ kind: 'ImmutableCapture',
51077
+ from: place,
51078
+ into: lvalue,
51079
+ });
51080
+ }
51081
+ return effects;
51082
+ }
51083
+ if (signature.calleeEffect !== Effect.Capture) {
51084
+ effects.push({
51085
+ kind: 'Alias',
51086
+ from: receiver,
51087
+ into: lvalue,
51088
+ });
51089
+ }
51090
+ visit(receiver, signature.calleeEffect);
51091
+ for (let i = 0; i < args.length; i++) {
51092
+ const arg = args[i];
51093
+ if (arg.kind === 'Hole') {
51094
+ continue;
51095
+ }
51096
+ const place = arg.kind === 'Identifier' ? arg : arg.place;
51097
+ const signatureEffect = arg.kind === 'Identifier' && i < signature.positionalParams.length
51098
+ ? signature.positionalParams[i]
51099
+ : ((_b = signature.restParam) !== null && _b !== void 0 ? _b : Effect.ConditionallyMutate);
51100
+ const effect = getArgumentEffect(signatureEffect, arg);
51101
+ visit(place, effect);
51102
+ }
51103
+ if (captures.length !== 0) {
51104
+ if (stores.length === 0) {
51105
+ for (const capture of captures) {
51106
+ effects.push({ kind: 'Alias', from: capture, into: lvalue });
51107
+ }
51108
+ }
51109
+ else {
51110
+ for (const capture of captures) {
51111
+ for (const store of stores) {
51112
+ effects.push({ kind: 'Capture', from: capture, into: store });
51113
+ }
51114
+ }
51115
+ }
51116
+ }
51117
+ return effects;
51118
+ }
51119
+ function areArgumentsImmutableAndNonMutating(state, args) {
51120
+ for (const arg of args) {
51121
+ if (arg.kind === 'Hole') {
51122
+ continue;
51123
+ }
51124
+ if (arg.kind === 'Identifier' && arg.identifier.type.kind === 'Function') {
51125
+ const fnShape = state.env.getFunctionSignature(arg.identifier.type);
51126
+ if (fnShape != null) {
51127
+ return (!fnShape.positionalParams.some(isKnownMutableEffect) &&
51128
+ (fnShape.restParam == null ||
51129
+ !isKnownMutableEffect(fnShape.restParam)));
51130
+ }
51131
+ }
51132
+ const place = arg.kind === 'Identifier' ? arg : arg.place;
51133
+ const kind = state.kind(place).kind;
51134
+ switch (kind) {
51135
+ case ValueKind.Primitive:
51136
+ case ValueKind.Frozen: {
51137
+ break;
51138
+ }
51139
+ default: {
51140
+ return false;
51141
+ }
51142
+ }
51143
+ const values = state.values(place);
51144
+ for (const value of values) {
51145
+ if (value.kind === 'FunctionExpression' &&
51146
+ value.loweredFunc.func.params.some(param => {
51147
+ const place = param.kind === 'Identifier' ? param : param.place;
51148
+ const range = place.identifier.mutableRange;
51149
+ return range.end > range.start + 1;
51150
+ })) {
51151
+ return false;
51152
+ }
51153
+ }
51154
+ }
51155
+ return true;
51156
+ }
51157
+ function computeEffectsForSignature(env, signature, lvalue, receiver, args, context = [], loc) {
51158
+ var _a, _b, _c, _d, _e, _f, _g;
51159
+ if (signature.params.length > args.length ||
51160
+ (args.length > signature.params.length && signature.rest == null)) {
51161
+ return null;
51162
+ }
51163
+ const mutableSpreads = new Set();
51164
+ const substitutions = new Map();
51165
+ substitutions.set(signature.receiver, [receiver]);
51166
+ substitutions.set(signature.returns, [lvalue]);
51167
+ const params = signature.params;
51168
+ for (let i = 0; i < args.length; i++) {
51169
+ const arg = args[i];
51170
+ if (arg.kind === 'Hole') {
51171
+ continue;
51172
+ }
51173
+ else if (params == null || i >= params.length || arg.kind === 'Spread') {
51174
+ if (signature.rest == null) {
51175
+ return null;
51176
+ }
51177
+ const place = arg.kind === 'Identifier' ? arg : arg.place;
51178
+ getOrInsertWith(substitutions, signature.rest, () => []).push(place);
51179
+ if (arg.kind === 'Spread') {
51180
+ const mutateIterator = conditionallyMutateIterator(arg.place);
51181
+ if (mutateIterator != null) {
51182
+ mutableSpreads.add(arg.place.identifier.id);
51183
+ }
51184
+ }
51185
+ }
51186
+ else {
51187
+ const param = params[i];
51188
+ substitutions.set(param, [arg]);
51189
+ }
51190
+ }
51191
+ for (const operand of context) {
51192
+ substitutions.set(operand.identifier.id, [operand]);
51193
+ }
51194
+ const effects = [];
51195
+ for (const signatureTemporary of signature.temporaries) {
51196
+ const temp = createTemporaryPlace(env, receiver.loc);
51197
+ substitutions.set(signatureTemporary.identifier.id, [temp]);
51198
+ }
51199
+ for (const effect of signature.effects) {
51200
+ switch (effect.kind) {
51201
+ case 'Assign':
51202
+ case 'ImmutableCapture':
51203
+ case 'Alias':
51204
+ case 'CreateFrom':
51205
+ case 'Capture': {
51206
+ const from = (_a = substitutions.get(effect.from.identifier.id)) !== null && _a !== void 0 ? _a : [];
51207
+ const to = (_b = substitutions.get(effect.into.identifier.id)) !== null && _b !== void 0 ? _b : [];
51208
+ for (const fromId of from) {
51209
+ for (const toId of to) {
51210
+ effects.push({
51211
+ kind: effect.kind,
51212
+ from: fromId,
51213
+ into: toId,
51214
+ });
51215
+ }
51216
+ }
51217
+ break;
51218
+ }
51219
+ case 'Impure':
51220
+ case 'MutateFrozen':
51221
+ case 'MutateGlobal': {
51222
+ const values = (_c = substitutions.get(effect.place.identifier.id)) !== null && _c !== void 0 ? _c : [];
51223
+ for (const value of values) {
51224
+ effects.push({ kind: effect.kind, place: value, error: effect.error });
51225
+ }
51226
+ break;
51227
+ }
51228
+ case 'Render': {
51229
+ const values = (_d = substitutions.get(effect.place.identifier.id)) !== null && _d !== void 0 ? _d : [];
51230
+ for (const value of values) {
51231
+ effects.push({ kind: effect.kind, place: value });
51232
+ }
51233
+ break;
51234
+ }
51235
+ case 'Mutate':
51236
+ case 'MutateTransitive':
51237
+ case 'MutateTransitiveConditionally':
51238
+ case 'MutateConditionally': {
51239
+ const values = (_e = substitutions.get(effect.value.identifier.id)) !== null && _e !== void 0 ? _e : [];
51240
+ for (const id of values) {
51241
+ effects.push({ kind: effect.kind, value: id });
51242
+ }
51243
+ break;
51244
+ }
51245
+ case 'Freeze': {
51246
+ const values = (_f = substitutions.get(effect.value.identifier.id)) !== null && _f !== void 0 ? _f : [];
51247
+ for (const value of values) {
51248
+ if (mutableSpreads.has(value.identifier.id)) {
51249
+ CompilerError.throwTodo({
51250
+ reason: 'Support spread syntax for hook arguments',
51251
+ loc: value.loc,
51252
+ });
51253
+ }
51254
+ effects.push({ kind: 'Freeze', value, reason: effect.reason });
51255
+ }
51256
+ break;
51257
+ }
51258
+ case 'Create': {
51259
+ const into = (_g = substitutions.get(effect.into.identifier.id)) !== null && _g !== void 0 ? _g : [];
51260
+ for (const value of into) {
51261
+ effects.push({
51262
+ kind: 'Create',
51263
+ into: value,
51264
+ value: effect.value,
51265
+ reason: effect.reason,
51266
+ });
51267
+ }
51268
+ break;
51269
+ }
51270
+ case 'Apply': {
51271
+ const applyReceiver = substitutions.get(effect.receiver.identifier.id);
51272
+ if (applyReceiver == null || applyReceiver.length !== 1) {
51273
+ return null;
51274
+ }
51275
+ const applyFunction = substitutions.get(effect.function.identifier.id);
51276
+ if (applyFunction == null || applyFunction.length !== 1) {
51277
+ return null;
51278
+ }
51279
+ const applyInto = substitutions.get(effect.into.identifier.id);
51280
+ if (applyInto == null || applyInto.length !== 1) {
51281
+ return null;
51282
+ }
51283
+ const applyArgs = [];
51284
+ for (const arg of effect.args) {
51285
+ if (arg.kind === 'Hole') {
51286
+ applyArgs.push(arg);
51287
+ }
51288
+ else if (arg.kind === 'Identifier') {
51289
+ const applyArg = substitutions.get(arg.identifier.id);
51290
+ if (applyArg == null || applyArg.length !== 1) {
51291
+ return null;
51292
+ }
51293
+ applyArgs.push(applyArg[0]);
51294
+ }
51295
+ else {
51296
+ const applyArg = substitutions.get(arg.place.identifier.id);
51297
+ if (applyArg == null || applyArg.length !== 1) {
51298
+ return null;
51299
+ }
51300
+ applyArgs.push({ kind: 'Spread', place: applyArg[0] });
51301
+ }
51302
+ }
51303
+ effects.push({
51304
+ kind: 'Apply',
51305
+ mutatesFunction: effect.mutatesFunction,
51306
+ receiver: applyReceiver[0],
51307
+ args: applyArgs,
51308
+ function: applyFunction[0],
51309
+ into: applyInto[0],
51310
+ signature: effect.signature,
51311
+ loc,
51312
+ });
51313
+ break;
51314
+ }
51315
+ case 'CreateFunction': {
51316
+ CompilerError.throwTodo({
51317
+ reason: `Support CreateFrom effects in signatures`,
51318
+ loc: receiver.loc,
51319
+ });
51320
+ }
51321
+ default: {
51322
+ assertExhaustive$1(effect, `Unexpected effect kind '${effect.kind}'`);
51323
+ }
51324
+ }
51325
+ }
51326
+ return effects;
51327
+ }
51328
+ function buildSignatureFromFunctionExpression(env, fn) {
51329
+ var _a;
51330
+ let rest = null;
51331
+ const params = [];
51332
+ for (const param of fn.loweredFunc.func.params) {
51333
+ if (param.kind === 'Identifier') {
51334
+ params.push(param.identifier.id);
51335
+ }
51336
+ else {
51337
+ rest = param.place.identifier.id;
51338
+ }
51339
+ }
51340
+ return {
51341
+ receiver: makeIdentifierId(0),
51342
+ params,
51343
+ rest: rest !== null && rest !== void 0 ? rest : createTemporaryPlace(env, fn.loc).identifier.id,
51344
+ returns: fn.loweredFunc.func.returns.identifier.id,
51345
+ effects: (_a = fn.loweredFunc.func.aliasingEffects) !== null && _a !== void 0 ? _a : [],
51346
+ temporaries: [],
51347
+ };
51348
+ }
51349
+
51350
+ function inferFunctionExpressionAliasingEffectsSignature(fn) {
51351
+ const effects = [];
51352
+ const tracked = new Map();
51353
+ tracked.set(fn.returns.identifier.id, fn.returns);
51354
+ for (const operand of [...fn.context, ...fn.params]) {
51355
+ const place = operand.kind === 'Identifier' ? operand : operand.place;
51356
+ tracked.set(place.identifier.id, place);
51357
+ }
51358
+ const dataFlow = new Map();
51359
+ function lookup(place, kind) {
51360
+ var _a, _b;
51361
+ if (tracked.has(place.identifier.id)) {
51362
+ return [{ kind, place }];
51363
+ }
51364
+ return ((_b = (_a = dataFlow.get(place.identifier.id)) === null || _a === void 0 ? void 0 : _a.map(aliased => ({
51365
+ kind: joinEffects(aliased.kind, kind),
51366
+ place: aliased.place,
51367
+ }))) !== null && _b !== void 0 ? _b : null);
51368
+ }
51369
+ for (const block of fn.body.blocks.values()) {
51370
+ for (const phi of block.phis) {
51371
+ const operands = [];
51372
+ for (const operand of phi.operands.values()) {
51373
+ const inputs = lookup(operand, 'Alias');
51374
+ if (inputs != null) {
51375
+ operands.push(...inputs);
51376
+ }
51377
+ }
51378
+ if (operands.length !== 0) {
51379
+ dataFlow.set(phi.place.identifier.id, operands);
51380
+ }
51381
+ }
51382
+ for (const instr of block.instructions) {
51383
+ if (instr.effects == null)
51384
+ continue;
51385
+ for (const effect of instr.effects) {
51386
+ if (effect.kind === 'Assign' ||
51387
+ effect.kind === 'Capture' ||
51388
+ effect.kind === 'Alias' ||
51389
+ effect.kind === 'CreateFrom') {
51390
+ const from = lookup(effect.from, effect.kind);
51391
+ if (from == null) {
51392
+ continue;
51393
+ }
51394
+ const into = lookup(effect.into, 'Alias');
51395
+ if (into == null) {
51396
+ getOrInsertDefault(dataFlow, effect.into.identifier.id, []).push(...from);
51397
+ }
51398
+ else {
51399
+ for (const aliased of into) {
51400
+ getOrInsertDefault(dataFlow, aliased.place.identifier.id, []).push(...from);
51401
+ }
51402
+ }
51403
+ }
51404
+ else if (effect.kind === 'Create' ||
51405
+ effect.kind === 'CreateFunction') {
51406
+ getOrInsertDefault(dataFlow, effect.into.identifier.id, [
51407
+ { kind: 'Alias', place: effect.into },
51408
+ ]);
51409
+ }
51410
+ else if (effect.kind === 'MutateFrozen' ||
51411
+ effect.kind === 'MutateGlobal' ||
51412
+ effect.kind === 'Impure' ||
51413
+ effect.kind === 'Render') {
51414
+ effects.push(effect);
51415
+ }
51416
+ }
51417
+ }
51418
+ if (block.terminal.kind === 'return') {
51419
+ const from = lookup(block.terminal.value, 'Alias');
51420
+ if (from != null) {
51421
+ getOrInsertDefault(dataFlow, fn.returns.identifier.id, []).push(...from);
51422
+ }
51423
+ }
51424
+ }
51425
+ let hasReturn = false;
51426
+ for (const [into, from] of dataFlow) {
51427
+ const input = tracked.get(into);
51428
+ if (input == null) {
51429
+ continue;
51430
+ }
51431
+ for (const aliased of from) {
51432
+ if (aliased.place.identifier.id === input.identifier.id ||
51433
+ !tracked.has(aliased.place.identifier.id)) {
51434
+ continue;
51435
+ }
51436
+ const effect = { kind: aliased.kind, from: aliased.place, into: input };
51437
+ effects.push(effect);
51438
+ if (into === fn.returns.identifier.id &&
51439
+ (aliased.kind === 'Assign' || aliased.kind === 'CreateFrom')) {
51440
+ hasReturn = true;
51441
+ }
51442
+ }
51443
+ }
51444
+ if (!hasReturn) {
51445
+ effects.unshift({
51446
+ kind: 'Create',
51447
+ into: fn.returns,
51448
+ value: fn.returnType.kind === 'Primitive'
51449
+ ? ValueKind.Primitive
51450
+ : ValueKind.Mutable,
51451
+ reason: ValueReason.KnownReturnSignature,
51452
+ });
51453
+ }
51454
+ return effects;
51455
+ }
51456
+ var MutationKind;
51457
+ (function (MutationKind) {
51458
+ MutationKind[MutationKind["None"] = 0] = "None";
51459
+ MutationKind[MutationKind["Conditional"] = 1] = "Conditional";
51460
+ MutationKind[MutationKind["Definite"] = 2] = "Definite";
51461
+ })(MutationKind || (MutationKind = {}));
51462
+ function joinEffects(effect1, effect2) {
51463
+ if (effect1 === 'Capture' || effect2 === 'Capture') {
51464
+ return 'Capture';
51465
+ }
51466
+ else if (effect1 === 'Assign' || effect2 === 'Assign') {
51467
+ return 'Assign';
51468
+ }
51469
+ else {
51470
+ return 'Alias';
51471
+ }
51472
+ }
51473
+
51474
+ function inferMutationAliasingRanges(fn, { isFunctionExpression }) {
51475
+ var _a, _b, _c, _d, _e, _f, _g;
51476
+ const state = new AliasingState();
51477
+ const pendingPhis = new Map();
51478
+ const mutations = [];
51479
+ const renders = [];
51480
+ let index = 0;
51481
+ const errors = new CompilerError();
51482
+ for (const param of [...fn.params, ...fn.context, fn.returns]) {
51483
+ const place = param.kind === 'Identifier' ? param : param.place;
51484
+ state.create(place, { kind: 'Object' });
51485
+ }
51486
+ const seenBlocks = new Set();
51487
+ for (const block of fn.body.blocks.values()) {
51488
+ for (const phi of block.phis) {
51489
+ state.create(phi.place, { kind: 'Phi' });
51490
+ for (const [pred, operand] of phi.operands) {
51491
+ if (!seenBlocks.has(pred)) {
51492
+ const blockPhis = getOrInsertWith(pendingPhis, pred, () => []);
51493
+ blockPhis.push({ from: operand, into: phi.place, index: index++ });
51494
+ }
51495
+ else {
51496
+ state.assign(index++, operand, phi.place);
51497
+ }
51498
+ }
51499
+ }
51500
+ seenBlocks.add(block.id);
51501
+ for (const instr of block.instructions) {
51502
+ if (instr.effects == null)
51503
+ continue;
51504
+ for (const effect of instr.effects) {
51505
+ if (effect.kind === 'Create') {
51506
+ state.create(effect.into, { kind: 'Object' });
51507
+ }
51508
+ else if (effect.kind === 'CreateFunction') {
51509
+ state.create(effect.into, {
51510
+ kind: 'Function',
51511
+ function: effect.function.loweredFunc.func,
51512
+ });
51513
+ }
51514
+ else if (effect.kind === 'CreateFrom') {
51515
+ state.createFrom(index++, effect.from, effect.into);
51516
+ }
51517
+ else if (effect.kind === 'Assign') {
51518
+ if (!state.nodes.has(effect.into.identifier)) {
51519
+ state.create(effect.into, { kind: 'Object' });
51520
+ }
51521
+ state.assign(index++, effect.from, effect.into);
51522
+ }
51523
+ else if (effect.kind === 'Alias') {
51524
+ state.assign(index++, effect.from, effect.into);
51525
+ }
51526
+ else if (effect.kind === 'Capture') {
51527
+ state.capture(index++, effect.from, effect.into);
51528
+ }
51529
+ else if (effect.kind === 'MutateTransitive' ||
51530
+ effect.kind === 'MutateTransitiveConditionally') {
51531
+ mutations.push({
51532
+ index: index++,
51533
+ id: instr.id,
51534
+ transitive: true,
51535
+ kind: effect.kind === 'MutateTransitive'
51536
+ ? MutationKind.Definite
51537
+ : MutationKind.Conditional,
51538
+ place: effect.value,
51539
+ });
51540
+ }
51541
+ else if (effect.kind === 'Mutate' ||
51542
+ effect.kind === 'MutateConditionally') {
51543
+ mutations.push({
51544
+ index: index++,
51545
+ id: instr.id,
51546
+ transitive: false,
51547
+ kind: effect.kind === 'Mutate'
51548
+ ? MutationKind.Definite
51549
+ : MutationKind.Conditional,
51550
+ place: effect.value,
51551
+ });
51552
+ }
51553
+ else if (effect.kind === 'MutateFrozen' ||
51554
+ effect.kind === 'MutateGlobal' ||
51555
+ effect.kind === 'Impure') {
51556
+ errors.push(effect.error);
51557
+ }
51558
+ else if (effect.kind === 'Render') {
51559
+ renders.push({ index: index++, place: effect.place });
51560
+ }
51561
+ }
51562
+ }
51563
+ const blockPhis = pendingPhis.get(block.id);
51564
+ if (blockPhis != null) {
51565
+ for (const { from, into, index } of blockPhis) {
51566
+ state.assign(index, from, into);
51567
+ }
51568
+ }
51569
+ if (block.terminal.kind === 'return') {
51570
+ state.assign(index++, block.terminal.value, fn.returns);
51571
+ }
51572
+ if ((block.terminal.kind === 'maybe-throw' ||
51573
+ block.terminal.kind === 'return') &&
51574
+ block.terminal.effects != null) {
51575
+ for (const effect of block.terminal.effects) {
51576
+ if (effect.kind === 'Alias') {
51577
+ state.assign(index++, effect.from, effect.into);
51578
+ }
51579
+ else {
51580
+ CompilerError.invariant(effect.kind === 'Freeze', {
51581
+ reason: `Unexpected '${effect.kind}' effect for MaybeThrow terminal`,
51582
+ loc: block.terminal.loc,
51583
+ });
51584
+ }
51585
+ }
51586
+ }
51587
+ }
51588
+ for (const mutation of mutations) {
51589
+ state.mutate(mutation.index, mutation.place.identifier, makeInstructionId(mutation.id + 1), mutation.transitive, mutation.kind, mutation.place.loc, errors);
51590
+ }
51591
+ for (const render of renders) {
51592
+ state.render(render.index, render.place.identifier, errors);
51593
+ }
51594
+ (_a = fn.aliasingEffects) !== null && _a !== void 0 ? _a : (fn.aliasingEffects = []);
51595
+ for (const param of [...fn.context, ...fn.params]) {
51596
+ const place = param.kind === 'Identifier' ? param : param.place;
51597
+ const node = state.nodes.get(place.identifier);
51598
+ if (node == null) {
51599
+ continue;
51600
+ }
51601
+ let mutated = false;
51602
+ if (node.local != null) {
51603
+ if (node.local.kind === MutationKind.Conditional) {
51604
+ mutated = true;
51605
+ fn.aliasingEffects.push({
51606
+ kind: 'MutateConditionally',
51607
+ value: Object.assign(Object.assign({}, place), { loc: node.local.loc }),
51608
+ });
51609
+ }
51610
+ else if (node.local.kind === MutationKind.Definite) {
51611
+ mutated = true;
51612
+ fn.aliasingEffects.push({
51613
+ kind: 'Mutate',
51614
+ value: Object.assign(Object.assign({}, place), { loc: node.local.loc }),
51615
+ });
51616
+ }
51617
+ }
51618
+ if (node.transitive != null) {
51619
+ if (node.transitive.kind === MutationKind.Conditional) {
51620
+ mutated = true;
51621
+ fn.aliasingEffects.push({
51622
+ kind: 'MutateTransitiveConditionally',
51623
+ value: Object.assign(Object.assign({}, place), { loc: node.transitive.loc }),
51624
+ });
51625
+ }
51626
+ else if (node.transitive.kind === MutationKind.Definite) {
51627
+ mutated = true;
51628
+ fn.aliasingEffects.push({
51629
+ kind: 'MutateTransitive',
51630
+ value: Object.assign(Object.assign({}, place), { loc: node.transitive.loc }),
51631
+ });
51632
+ }
51633
+ }
51634
+ if (mutated) {
51635
+ place.effect = Effect.Capture;
51636
+ }
51637
+ }
51638
+ for (const block of fn.body.blocks.values()) {
51639
+ for (const phi of block.phis) {
51640
+ phi.place.effect = Effect.Store;
51641
+ const isPhiMutatedAfterCreation = phi.place.identifier.mutableRange.end >
51642
+ ((_c = (_b = block.instructions.at(0)) === null || _b === void 0 ? void 0 : _b.id) !== null && _c !== void 0 ? _c : block.terminal.id);
51643
+ for (const operand of phi.operands.values()) {
51644
+ operand.effect = isPhiMutatedAfterCreation
51645
+ ? Effect.Capture
51646
+ : Effect.Read;
51647
+ }
51648
+ if (isPhiMutatedAfterCreation &&
51649
+ phi.place.identifier.mutableRange.start === 0) {
51650
+ const firstInstructionIdOfBlock = (_e = (_d = block.instructions.at(0)) === null || _d === void 0 ? void 0 : _d.id) !== null && _e !== void 0 ? _e : block.terminal.id;
51651
+ phi.place.identifier.mutableRange.start = makeInstructionId(firstInstructionIdOfBlock - 1);
51652
+ }
51653
+ }
51654
+ for (const instr of block.instructions) {
51655
+ for (const lvalue of eachInstructionLValue(instr)) {
51656
+ lvalue.effect = Effect.ConditionallyMutate;
51657
+ if (lvalue.identifier.mutableRange.start === 0) {
51658
+ lvalue.identifier.mutableRange.start = instr.id;
51659
+ }
51660
+ if (lvalue.identifier.mutableRange.end === 0) {
51661
+ lvalue.identifier.mutableRange.end = makeInstructionId(Math.max(instr.id + 1, lvalue.identifier.mutableRange.end));
51662
+ }
51663
+ }
51664
+ for (const operand of eachInstructionValueOperand(instr.value)) {
51665
+ operand.effect = Effect.Read;
51666
+ }
51667
+ if (instr.effects == null) {
51668
+ continue;
51669
+ }
51670
+ const operandEffects = new Map();
51671
+ for (const effect of instr.effects) {
51672
+ switch (effect.kind) {
51673
+ case 'Assign':
51674
+ case 'Alias':
51675
+ case 'Capture':
51676
+ case 'CreateFrom': {
51677
+ const isMutatedOrReassigned = effect.into.identifier.mutableRange.end > instr.id;
51678
+ if (isMutatedOrReassigned) {
51679
+ operandEffects.set(effect.from.identifier.id, Effect.Capture);
51680
+ operandEffects.set(effect.into.identifier.id, Effect.Store);
51681
+ }
51682
+ else {
51683
+ operandEffects.set(effect.from.identifier.id, Effect.Read);
51684
+ operandEffects.set(effect.into.identifier.id, Effect.Store);
51685
+ }
51686
+ break;
51687
+ }
51688
+ case 'CreateFunction':
51689
+ case 'Create': {
51690
+ break;
51691
+ }
51692
+ case 'Mutate': {
51693
+ operandEffects.set(effect.value.identifier.id, Effect.Store);
51694
+ break;
51695
+ }
51696
+ case 'Apply': {
51697
+ CompilerError.invariant(false, {
51698
+ reason: `[AnalyzeFunctions] Expected Apply effects to be replaced with more precise effects`,
51699
+ loc: effect.function.loc,
51700
+ });
51701
+ }
51702
+ case 'MutateTransitive':
51703
+ case 'MutateConditionally':
51704
+ case 'MutateTransitiveConditionally': {
51705
+ operandEffects.set(effect.value.identifier.id, Effect.ConditionallyMutate);
51706
+ break;
51707
+ }
51708
+ case 'Freeze': {
51709
+ operandEffects.set(effect.value.identifier.id, Effect.Freeze);
51710
+ break;
51711
+ }
51712
+ case 'ImmutableCapture': {
51713
+ break;
51714
+ }
51715
+ case 'Impure':
51716
+ case 'Render':
51717
+ case 'MutateFrozen':
51718
+ case 'MutateGlobal': {
51719
+ break;
51720
+ }
51721
+ default: {
51722
+ assertExhaustive$1(effect, `Unexpected effect kind ${effect.kind}`);
51723
+ }
51724
+ }
51725
+ }
51726
+ for (const lvalue of eachInstructionLValue(instr)) {
51727
+ const effect = (_f = operandEffects.get(lvalue.identifier.id)) !== null && _f !== void 0 ? _f : Effect.ConditionallyMutate;
51728
+ lvalue.effect = effect;
51729
+ }
51730
+ for (const operand of eachInstructionValueOperand(instr.value)) {
51731
+ if (operand.identifier.mutableRange.end > instr.id &&
51732
+ operand.identifier.mutableRange.start === 0) {
51733
+ operand.identifier.mutableRange.start = instr.id;
51734
+ }
51735
+ const effect = (_g = operandEffects.get(operand.identifier.id)) !== null && _g !== void 0 ? _g : Effect.Read;
51736
+ operand.effect = effect;
51737
+ }
51738
+ if (instr.value.kind === 'StoreContext' &&
51739
+ instr.value.value.identifier.mutableRange.end <= instr.id) {
51740
+ instr.value.value.identifier.mutableRange.end = makeInstructionId(instr.id + 1);
51741
+ }
51742
+ }
51743
+ if (block.terminal.kind === 'return') {
51744
+ block.terminal.value.effect = isFunctionExpression
51745
+ ? Effect.Read
51746
+ : Effect.Freeze;
51747
+ }
51748
+ else {
51749
+ for (const operand of eachTerminalOperand(block.terminal)) {
51750
+ operand.effect = Effect.Read;
51751
+ }
51752
+ }
51753
+ }
51754
+ return errors.asResult();
51755
+ }
51756
+ function appendFunctionErrors(errors, fn) {
51757
+ var _a;
51758
+ for (const effect of (_a = fn.aliasingEffects) !== null && _a !== void 0 ? _a : []) {
51759
+ switch (effect.kind) {
51760
+ case 'Impure':
51761
+ case 'MutateFrozen':
51762
+ case 'MutateGlobal': {
51763
+ errors.push(effect.error);
51764
+ break;
51765
+ }
51766
+ }
51767
+ }
51768
+ }
51769
+ class AliasingState {
51770
+ constructor() {
51771
+ this.nodes = new Map();
51772
+ }
51773
+ create(place, value) {
51774
+ this.nodes.set(place.identifier, {
51775
+ id: place.identifier,
51776
+ createdFrom: new Map(),
51777
+ captures: new Map(),
51778
+ aliases: new Map(),
51779
+ edges: [],
51780
+ transitive: null,
51781
+ local: null,
51782
+ value,
51783
+ });
51784
+ }
51785
+ createFrom(index, from, into) {
51786
+ this.create(into, { kind: 'Object' });
51787
+ const fromNode = this.nodes.get(from.identifier);
51788
+ const toNode = this.nodes.get(into.identifier);
51789
+ if (fromNode == null || toNode == null) {
51790
+ return;
51791
+ }
51792
+ fromNode.edges.push({ index, node: into.identifier, kind: 'alias' });
51793
+ if (!toNode.createdFrom.has(from.identifier)) {
51794
+ toNode.createdFrom.set(from.identifier, index);
51795
+ }
51796
+ }
51797
+ capture(index, from, into) {
51798
+ const fromNode = this.nodes.get(from.identifier);
51799
+ const toNode = this.nodes.get(into.identifier);
51800
+ if (fromNode == null || toNode == null) {
51801
+ return;
51802
+ }
51803
+ fromNode.edges.push({ index, node: into.identifier, kind: 'capture' });
51804
+ if (!toNode.captures.has(from.identifier)) {
51805
+ toNode.captures.set(from.identifier, index);
51806
+ }
51807
+ }
51808
+ assign(index, from, into) {
51809
+ const fromNode = this.nodes.get(from.identifier);
51810
+ const toNode = this.nodes.get(into.identifier);
51811
+ if (fromNode == null || toNode == null) {
51812
+ return;
51813
+ }
51814
+ fromNode.edges.push({ index, node: into.identifier, kind: 'alias' });
51815
+ if (!toNode.aliases.has(from.identifier)) {
51816
+ toNode.aliases.set(from.identifier, index);
51817
+ }
51818
+ }
51819
+ render(index, start, errors) {
51820
+ const seen = new Set();
51821
+ const queue = [start];
51822
+ while (queue.length !== 0) {
51823
+ const current = queue.pop();
51824
+ if (seen.has(current)) {
51825
+ continue;
51826
+ }
51827
+ seen.add(current);
51828
+ const node = this.nodes.get(current);
51829
+ if (node == null || node.transitive != null || node.local != null) {
51830
+ continue;
51831
+ }
51832
+ if (node.value.kind === 'Function') {
51833
+ appendFunctionErrors(errors, node.value.function);
51834
+ }
51835
+ for (const [alias, when] of node.createdFrom) {
51836
+ if (when >= index) {
51837
+ continue;
51838
+ }
51839
+ queue.push(alias);
51840
+ }
51841
+ for (const [alias, when] of node.aliases) {
51842
+ if (when >= index) {
51843
+ continue;
51844
+ }
51845
+ queue.push(alias);
51846
+ }
51847
+ for (const [capture, when] of node.captures) {
51848
+ if (when >= index) {
51849
+ continue;
51850
+ }
51851
+ queue.push(capture);
51852
+ }
51853
+ }
51854
+ }
51855
+ mutate(index, start, end, transitive, kind, loc, errors) {
51856
+ const seen = new Set();
51857
+ const queue = [{ place: start, transitive, direction: 'backwards' }];
51858
+ while (queue.length !== 0) {
51859
+ const { place: current, transitive, direction } = queue.pop();
51860
+ if (seen.has(current)) {
51861
+ continue;
51862
+ }
51863
+ seen.add(current);
51864
+ const node = this.nodes.get(current);
51865
+ if (node == null) {
51866
+ continue;
51867
+ }
51868
+ node.id.mutableRange.end = makeInstructionId(Math.max(node.id.mutableRange.end, end));
51869
+ if (node.value.kind === 'Function' &&
51870
+ node.transitive == null &&
51871
+ node.local == null) {
51872
+ appendFunctionErrors(errors, node.value.function);
51873
+ }
51874
+ if (transitive) {
51875
+ if (node.transitive == null || node.transitive.kind < kind) {
51876
+ node.transitive = { kind, loc };
51877
+ }
51878
+ }
51879
+ else {
51880
+ if (node.local == null || node.local.kind < kind) {
51881
+ node.local = { kind, loc };
51882
+ }
51883
+ }
51884
+ for (const edge of node.edges) {
51885
+ if (edge.index >= index) {
51886
+ break;
51887
+ }
51888
+ queue.push({ place: edge.node, transitive, direction: 'forwards' });
51889
+ }
51890
+ for (const [alias, when] of node.createdFrom) {
51891
+ if (when >= index) {
51892
+ continue;
51893
+ }
51894
+ queue.push({ place: alias, transitive: true, direction: 'backwards' });
51895
+ }
51896
+ if (direction === 'backwards' || node.value.kind !== 'Phi') {
51897
+ for (const [alias, when] of node.aliases) {
51898
+ if (when >= index) {
51899
+ continue;
51900
+ }
51901
+ queue.push({ place: alias, transitive, direction: 'backwards' });
51902
+ }
51903
+ }
51904
+ if (transitive) {
51905
+ for (const [capture, when] of node.captures) {
51906
+ if (when >= index) {
51907
+ continue;
51908
+ }
51909
+ queue.push({ place: capture, transitive, direction: 'backwards' });
51910
+ }
51911
+ }
51912
+ }
51913
+ }
51914
+ }
51915
+
51916
+ function analyseFunctions(func) {
51917
+ for (const [_, block] of func.body.blocks) {
51918
+ for (const instr of block.instructions) {
51919
+ switch (instr.value.kind) {
51920
+ case 'ObjectMethod':
51921
+ case 'FunctionExpression': {
51922
+ if (!func.env.config.enableNewMutationAliasingModel) {
51923
+ lower(instr.value.loweredFunc.func);
51924
+ infer(instr.value.loweredFunc);
51925
+ }
51926
+ else {
51927
+ lowerWithMutationAliasing(instr.value.loweredFunc.func);
51928
+ }
51929
+ for (const operand of instr.value.loweredFunc.func.context) {
51930
+ operand.identifier.mutableRange = {
51931
+ start: makeInstructionId(0),
51932
+ end: makeInstructionId(0),
51933
+ };
51934
+ operand.identifier.scope = null;
51935
+ }
51936
+ break;
51937
+ }
51938
+ }
51939
+ }
51940
+ }
51941
+ }
51942
+ function lowerWithMutationAliasing(fn) {
51943
+ var _a, _b, _c, _d;
51944
+ analyseFunctions(fn);
51945
+ inferMutationAliasingEffects(fn, { isFunctionExpression: true });
51946
+ deadCodeElimination(fn);
51947
+ inferMutationAliasingRanges(fn, { isFunctionExpression: true });
51948
+ rewriteInstructionKindsBasedOnReassignment(fn);
51949
+ inferReactiveScopeVariables(fn);
51950
+ const effects = inferFunctionExpressionAliasingEffectsSignature(fn);
51951
+ (_b = (_a = fn.env.logger) === null || _a === void 0 ? void 0 : _a.debugLogIRs) === null || _b === void 0 ? void 0 : _b.call(_a, {
51952
+ kind: 'hir',
51953
+ name: 'AnalyseFunction (inner)',
51954
+ value: fn,
51955
+ });
51956
+ if (effects != null) {
51957
+ (_c = fn.aliasingEffects) !== null && _c !== void 0 ? _c : (fn.aliasingEffects = []);
51958
+ (_d = fn.aliasingEffects) === null || _d === void 0 ? void 0 : _d.push(...effects);
51959
+ }
51960
+ if (fn.aliasingEffects != null) {
51961
+ const seen = new Set();
51962
+ retainWhere(fn.aliasingEffects, effect => {
51963
+ const hash = hashEffect(effect);
51964
+ if (seen.has(hash)) {
51965
+ return false;
51966
+ }
51967
+ seen.add(hash);
51968
+ return true;
51969
+ });
51970
+ }
51971
+ const capturedOrMutated = new Set();
51972
+ for (const effect of effects !== null && effects !== void 0 ? effects : []) {
51973
+ switch (effect.kind) {
51974
+ case 'Assign':
51975
+ case 'Alias':
51976
+ case 'Capture':
51977
+ case 'CreateFrom': {
51978
+ capturedOrMutated.add(effect.from.identifier.id);
51979
+ break;
51980
+ }
51981
+ case 'Apply': {
51982
+ CompilerError.invariant(false, {
51983
+ reason: `[AnalyzeFunctions] Expected Apply effects to be replaced with more precise effects`,
51984
+ loc: effect.function.loc,
51985
+ });
51986
+ }
51987
+ case 'Mutate':
51988
+ case 'MutateConditionally':
51989
+ case 'MutateTransitive':
51990
+ case 'MutateTransitiveConditionally': {
51991
+ capturedOrMutated.add(effect.value.identifier.id);
51992
+ break;
51993
+ }
51994
+ case 'Impure':
51995
+ case 'Render':
51996
+ case 'MutateFrozen':
51997
+ case 'MutateGlobal':
51998
+ case 'CreateFunction':
51999
+ case 'Create':
52000
+ case 'Freeze':
52001
+ case 'ImmutableCapture': {
52002
+ break;
52003
+ }
52004
+ default: {
52005
+ assertExhaustive$1(effect, `Unexpected effect kind ${effect.kind}`);
52006
+ }
52007
+ }
52008
+ }
52009
+ for (const operand of fn.context) {
52010
+ if (capturedOrMutated.has(operand.identifier.id) ||
52011
+ operand.effect === Effect.Capture) {
52012
+ operand.effect = Effect.Capture;
52013
+ }
52014
+ else {
52015
+ operand.effect = Effect.Read;
52016
+ }
52017
+ }
52018
+ }
52019
+ function lower(func) {
52020
+ var _a, _b;
52021
+ analyseFunctions(func);
52022
+ inferReferenceEffects(func, { isFunctionExpression: true });
52023
+ deadCodeElimination(func);
52024
+ inferMutableRanges(func);
52025
+ rewriteInstructionKindsBasedOnReassignment(func);
52026
+ inferReactiveScopeVariables(func);
52027
+ (_b = (_a = func.env.logger) === null || _a === void 0 ? void 0 : _a.debugLogIRs) === null || _b === void 0 ? void 0 : _b.call(_a, {
52028
+ kind: 'hir',
52029
+ name: 'AnalyseFunction (inner)',
52030
+ value: func,
52031
+ });
52032
+ }
52033
+ function infer(loweredFunc) {
52034
+ for (const operand of loweredFunc.func.context) {
52035
+ const identifier = operand.identifier;
52036
+ CompilerError.invariant(operand.effect === Effect.Unknown, {
52037
+ reason: '[AnalyseFunctions] Expected Function context effects to not have been set',
52038
+ loc: operand.loc,
52039
+ });
52040
+ if (isRefOrRefValue(identifier)) {
52041
+ operand.effect = Effect.Capture;
52042
+ }
52043
+ else if (isMutatedOrReassigned(identifier)) {
52044
+ operand.effect = Effect.Capture;
52045
+ }
52046
+ else {
52047
+ operand.effect = Effect.Read;
52048
+ }
52049
+ }
52050
+ }
52051
+ function isMutatedOrReassigned(id) {
52052
+ return id.mutableRange.end > id.mutableRange.start;
52053
+ }
52054
+
52055
+ function collectMaybeMemoDependencies(value, maybeDeps, optional) {
52056
+ var _a;
52057
+ switch (value.kind) {
52058
+ case 'LoadGlobal': {
52059
+ return {
52060
+ root: {
52061
+ kind: 'Global',
52062
+ identifierName: value.binding.name,
52063
+ },
52064
+ path: [],
52065
+ };
52066
+ }
52067
+ case 'PropertyLoad': {
52068
+ const object = maybeDeps.get(value.object.identifier.id);
52069
+ if (object != null) {
52070
+ return {
52071
+ root: object.root,
52072
+ path: [...object.path, { property: value.property, optional }],
52073
+ };
52074
+ }
52075
+ break;
52076
+ }
52077
+ case 'LoadLocal':
52078
+ case 'LoadContext': {
52079
+ const source = maybeDeps.get(value.place.identifier.id);
52080
+ if (source != null) {
52081
+ return source;
52082
+ }
52083
+ else if (value.place.identifier.name != null &&
52084
+ value.place.identifier.name.kind === 'named') {
52085
+ return {
52086
+ root: {
52087
+ kind: 'NamedLocal',
52088
+ value: Object.assign({}, value.place),
52089
+ },
52090
+ path: [],
52091
+ };
52092
+ }
52093
+ break;
52094
+ }
52095
+ case 'StoreLocal': {
52096
+ const lvalue = value.lvalue.place.identifier;
52097
+ const rvalue = value.value.identifier.id;
52098
+ const aliased = maybeDeps.get(rvalue);
52099
+ if (aliased != null && ((_a = lvalue.name) === null || _a === void 0 ? void 0 : _a.kind) !== 'named') {
52100
+ maybeDeps.set(lvalue.id, aliased);
52101
+ return aliased;
52102
+ }
52103
+ break;
52104
+ }
52105
+ }
52106
+ return null;
52107
+ }
52108
+ function collectTemporaries(instr, env, sidemap) {
52109
+ const { value, lvalue } = instr;
52110
+ switch (value.kind) {
52111
+ case 'FunctionExpression': {
52112
+ sidemap.functions.set(instr.lvalue.identifier.id, instr);
52113
+ break;
52114
+ }
52115
+ case 'LoadGlobal': {
52116
+ const global = env.getGlobalDeclaration(value.binding, value.loc);
52117
+ const hookKind = global !== null ? getHookKindForType(env, global) : null;
52118
+ const lvalId = instr.lvalue.identifier.id;
52119
+ if (hookKind === 'useMemo' || hookKind === 'useCallback') {
52120
+ sidemap.manualMemos.set(lvalId, {
52121
+ kind: hookKind,
52122
+ loadInstr: instr,
52123
+ });
52124
+ }
52125
+ else if (value.binding.name === 'React') {
52126
+ sidemap.react.add(lvalId);
52127
+ }
52128
+ break;
52129
+ }
52130
+ case 'PropertyLoad': {
52131
+ if (sidemap.react.has(value.object.identifier.id)) {
52132
+ const property = value.property;
52133
+ if (property === 'useMemo' || property === 'useCallback') {
52134
+ sidemap.manualMemos.set(instr.lvalue.identifier.id, {
52135
+ kind: property,
52136
+ loadInstr: instr,
52137
+ });
52138
+ }
52139
+ }
52140
+ break;
52141
+ }
52142
+ case 'ArrayExpression': {
52143
+ if (value.elements.every(e => e.kind === 'Identifier')) {
52144
+ sidemap.maybeDepsLists.set(instr.lvalue.identifier.id, value.elements);
52145
+ }
52146
+ break;
52147
+ }
52148
+ }
52149
+ const maybeDep = collectMaybeMemoDependencies(value, sidemap.maybeDeps, sidemap.optionals.has(lvalue.identifier.id));
49094
52150
  if (maybeDep != null) {
49095
52151
  sidemap.maybeDeps.set(lvalue.identifier.id, maybeDep);
49096
52152
  }
@@ -49106,6 +52162,7 @@ function makeManualMemoizationMarkers(fnExpr, env, depsList, memoDecl, manualMem
49106
52162
  deps: depsList,
49107
52163
  loc: fnExpr.loc,
49108
52164
  },
52165
+ effects: null,
49109
52166
  loc: fnExpr.loc,
49110
52167
  },
49111
52168
  {
@@ -49117,6 +52174,7 @@ function makeManualMemoizationMarkers(fnExpr, env, depsList, memoDecl, manualMem
49117
52174
  decl: Object.assign({}, memoDecl),
49118
52175
  loc: fnExpr.loc,
49119
52176
  },
52177
+ effects: null,
49120
52178
  loc: fnExpr.loc,
49121
52179
  },
49122
52180
  ];
@@ -49615,62 +52673,64 @@ function inlineImmediatelyInvokedFunctionExpressions(fn) {
49615
52673
  const inlinedFunctions = new Set();
49616
52674
  const queue = Array.from(fn.body.blocks.values());
49617
52675
  queue: for (const block of queue) {
49618
- for (let ii = 0; ii < block.instructions.length; ii++) {
49619
- const instr = block.instructions[ii];
49620
- switch (instr.value.kind) {
49621
- case 'FunctionExpression': {
49622
- if (instr.lvalue.identifier.name === null) {
49623
- functions.set(instr.lvalue.identifier.id, instr.value);
49624
- }
49625
- break;
49626
- }
49627
- case 'CallExpression': {
49628
- if (instr.value.args.length !== 0) {
49629
- continue;
49630
- }
49631
- const body = functions.get(instr.value.callee.identifier.id);
49632
- if (body === undefined) {
49633
- continue;
52676
+ if (isStatementBlockKind(block.kind)) {
52677
+ for (let ii = 0; ii < block.instructions.length; ii++) {
52678
+ const instr = block.instructions[ii];
52679
+ switch (instr.value.kind) {
52680
+ case 'FunctionExpression': {
52681
+ if (instr.lvalue.identifier.name === null) {
52682
+ functions.set(instr.lvalue.identifier.id, instr.value);
52683
+ }
52684
+ break;
49634
52685
  }
49635
- if (body.loweredFunc.func.params.length > 0 ||
49636
- body.loweredFunc.func.async ||
49637
- body.loweredFunc.func.generator) {
49638
- continue;
52686
+ case 'CallExpression': {
52687
+ if (instr.value.args.length !== 0) {
52688
+ continue;
52689
+ }
52690
+ const body = functions.get(instr.value.callee.identifier.id);
52691
+ if (body === undefined) {
52692
+ continue;
52693
+ }
52694
+ if (body.loweredFunc.func.params.length > 0 ||
52695
+ body.loweredFunc.func.async ||
52696
+ body.loweredFunc.func.generator) {
52697
+ continue;
52698
+ }
52699
+ inlinedFunctions.add(instr.value.callee.identifier.id);
52700
+ const continuationBlockId = fn.env.nextBlockId;
52701
+ const continuationBlock = {
52702
+ id: continuationBlockId,
52703
+ instructions: block.instructions.slice(ii + 1),
52704
+ kind: block.kind,
52705
+ phis: new Set(),
52706
+ preds: new Set(),
52707
+ terminal: block.terminal,
52708
+ };
52709
+ fn.body.blocks.set(continuationBlockId, continuationBlock);
52710
+ block.instructions.length = ii;
52711
+ const newTerminal = {
52712
+ block: body.loweredFunc.func.body.entry,
52713
+ id: makeInstructionId(0),
52714
+ kind: 'label',
52715
+ fallthrough: continuationBlockId,
52716
+ loc: block.terminal.loc,
52717
+ };
52718
+ block.terminal = newTerminal;
52719
+ const result = instr.lvalue;
52720
+ declareTemporary(fn.env, block, result);
52721
+ promoteTemporary(result.identifier);
52722
+ for (const [id, block] of body.loweredFunc.func.body.blocks) {
52723
+ block.preds.clear();
52724
+ rewriteBlock(fn.env, block, continuationBlockId, result);
52725
+ fn.body.blocks.set(id, block);
52726
+ }
52727
+ queue.push(continuationBlock);
52728
+ continue queue;
49639
52729
  }
49640
- inlinedFunctions.add(instr.value.callee.identifier.id);
49641
- const continuationBlockId = fn.env.nextBlockId;
49642
- const continuationBlock = {
49643
- id: continuationBlockId,
49644
- instructions: block.instructions.slice(ii + 1),
49645
- kind: block.kind,
49646
- phis: new Set(),
49647
- preds: new Set(),
49648
- terminal: block.terminal,
49649
- };
49650
- fn.body.blocks.set(continuationBlockId, continuationBlock);
49651
- block.instructions.length = ii;
49652
- const newTerminal = {
49653
- block: body.loweredFunc.func.body.entry,
49654
- id: makeInstructionId(0),
49655
- kind: 'label',
49656
- fallthrough: continuationBlockId,
49657
- loc: block.terminal.loc,
49658
- };
49659
- block.terminal = newTerminal;
49660
- const result = instr.lvalue;
49661
- declareTemporary(fn.env, block, result);
49662
- promoteTemporary(result.identifier);
49663
- for (const [id, block] of body.loweredFunc.func.body.blocks) {
49664
- block.preds.clear();
49665
- rewriteBlock(fn.env, block, continuationBlockId, result);
49666
- fn.body.blocks.set(id, block);
49667
- }
49668
- queue.push(continuationBlock);
49669
- continue queue;
49670
- }
49671
- default: {
49672
- for (const place of eachInstructionValueOperand(instr.value)) {
49673
- functions.delete(place.identifier.id);
52730
+ default: {
52731
+ for (const place of eachInstructionValueOperand(instr.value)) {
52732
+ functions.delete(place.identifier.id);
52733
+ }
49674
52734
  }
49675
52735
  }
49676
52736
  }
@@ -49701,6 +52761,7 @@ function rewriteBlock(env, block, returnTarget, returnValue) {
49701
52761
  type: null,
49702
52762
  loc: terminal.loc,
49703
52763
  },
52764
+ effects: null,
49704
52765
  });
49705
52766
  block.terminal = {
49706
52767
  kind: 'goto',
@@ -49724,6 +52785,7 @@ function declareTemporary(env, block, result) {
49724
52785
  type: null,
49725
52786
  loc: result.loc,
49726
52787
  },
52788
+ effects: null,
49727
52789
  });
49728
52790
  }
49729
52791
 
@@ -50919,6 +53981,7 @@ function writeNonOptionalDependency(dep, env, builder) {
50919
53981
  },
50920
53982
  id: makeInstructionId(1),
50921
53983
  loc: loc,
53984
+ effects: null,
50922
53985
  });
50923
53986
  for (const path of dep.path) {
50924
53987
  const next = makeTemporaryIdentifier(env.nextIdentifierId, loc);
@@ -50944,6 +54007,7 @@ function writeNonOptionalDependency(dep, env, builder) {
50944
54007
  },
50945
54008
  id: makeInstructionId(1),
50946
54009
  loc: loc,
54010
+ effects: null,
50947
54011
  });
50948
54012
  curr = next;
50949
54013
  }
@@ -51192,6 +54256,7 @@ function inferEffectDependencies(fn) {
51192
54256
  loc: GeneratedSource,
51193
54257
  lvalue: Object.assign(Object.assign({}, depsPlace), { effect: Effect.Mutate }),
51194
54258
  value: deps,
54259
+ effects: null,
51195
54260
  },
51196
54261
  });
51197
54262
  value.args.push(Object.assign(Object.assign({}, depsPlace), { effect: Effect.Freeze }));
@@ -51206,6 +54271,7 @@ function inferEffectDependencies(fn) {
51206
54271
  loc: GeneratedSource,
51207
54272
  lvalue: Object.assign(Object.assign({}, depsPlace), { effect: Effect.Mutate }),
51208
54273
  value: deps,
54274
+ effects: null,
51209
54275
  },
51210
54276
  });
51211
54277
  value.args.push(Object.assign(Object.assign({}, depsPlace), { effect: Effect.Freeze }));
@@ -54537,6 +57603,7 @@ function emitLoadLoweredContextCallee(env, importedLowerContextCallee) {
54537
57603
  id: makeInstructionId(0),
54538
57604
  loc: GeneratedSource,
54539
57605
  lvalue: createTemporaryPlace(env, GeneratedSource),
57606
+ effects: null,
54540
57607
  value: loadGlobal,
54541
57608
  };
54542
57609
  }
@@ -54573,6 +57640,7 @@ function emitPropertyLoad(env, obj, property) {
54573
57640
  lvalue: object,
54574
57641
  value: loadObj,
54575
57642
  id: makeInstructionId(0),
57643
+ effects: null,
54576
57644
  loc: GeneratedSource,
54577
57645
  };
54578
57646
  const loadProp = {
@@ -54586,6 +57654,7 @@ function emitPropertyLoad(env, obj, property) {
54586
57654
  lvalue: element,
54587
57655
  value: loadProp,
54588
57656
  id: makeInstructionId(0),
57657
+ effects: null,
54589
57658
  loc: GeneratedSource,
54590
57659
  };
54591
57660
  return {
@@ -54614,6 +57683,7 @@ function emitSelectorFn(env, keys) {
54614
57683
  kind: 'return',
54615
57684
  loc: GeneratedSource,
54616
57685
  value: arrayInstr.lvalue,
57686
+ effects: null,
54617
57687
  },
54618
57688
  preds: new Set(),
54619
57689
  phis: new Set(),
@@ -54626,6 +57696,7 @@ function emitSelectorFn(env, keys) {
54626
57696
  params: [obj],
54627
57697
  returnTypeAnnotation: null,
54628
57698
  returnType: makeType(),
57699
+ returns: createTemporaryPlace(env, GeneratedSource),
54629
57700
  context: [],
54630
57701
  effects: null,
54631
57702
  body: {
@@ -54652,6 +57723,7 @@ function emitSelectorFn(env, keys) {
54652
57723
  loc: GeneratedSource,
54653
57724
  },
54654
57725
  lvalue: createTemporaryPlace(env, GeneratedSource),
57726
+ effects: null,
54655
57727
  loc: GeneratedSource,
54656
57728
  };
54657
57729
  return fnInstr;
@@ -54667,6 +57739,7 @@ function emitArrayInstr(elements, env) {
54667
57739
  id: makeInstructionId(0),
54668
57740
  value: array,
54669
57741
  lvalue: arrayLvalue,
57742
+ effects: null,
54670
57743
  loc: GeneratedSource,
54671
57744
  };
54672
57745
  return arrayInstr;
@@ -54985,6 +58058,7 @@ function emitOutlinedJsx(env, instructions, outlinedProps, outlinedTag) {
54985
58058
  },
54986
58059
  loc: GeneratedSource,
54987
58060
  },
58061
+ effects: null,
54988
58062
  };
54989
58063
  promoteTemporaryJsxTag(loadJsx.lvalue.identifier);
54990
58064
  const jsxExpr = {
@@ -55000,6 +58074,7 @@ function emitOutlinedJsx(env, instructions, outlinedProps, outlinedTag) {
55000
58074
  openingLoc: GeneratedSource,
55001
58075
  closingLoc: GeneratedSource,
55002
58076
  },
58077
+ effects: null,
55003
58078
  };
55004
58079
  return [loadJsx, jsxExpr];
55005
58080
  }
@@ -55026,6 +58101,7 @@ function emitOutlinedFn(env, jsx, oldProps, globals) {
55026
58101
  kind: 'return',
55027
58102
  loc: GeneratedSource,
55028
58103
  value: instructions.at(-1).lvalue,
58104
+ effects: null,
55029
58105
  },
55030
58106
  preds: new Set(),
55031
58107
  phis: new Set(),
@@ -55038,6 +58114,7 @@ function emitOutlinedFn(env, jsx, oldProps, globals) {
55038
58114
  params: [propsObj],
55039
58115
  returnTypeAnnotation: null,
55040
58116
  returnType: makeType(),
58117
+ returns: createTemporaryPlace(env, GeneratedSource),
55041
58118
  context: [],
55042
58119
  effects: null,
55043
58120
  body: {
@@ -55140,6 +58217,7 @@ function emitDestructureProps(env, propsObj, oldToNewProps) {
55140
58217
  loc: GeneratedSource,
55141
58218
  value: propsObj,
55142
58219
  },
58220
+ effects: null,
55143
58221
  };
55144
58222
  return destructurePropsInstr;
55145
58223
  }
@@ -55421,6 +58499,7 @@ function makeLoadUseFireInstruction(env, importedLoadUseFire) {
55421
58499
  value: instrValue,
55422
58500
  lvalue: Object.assign({}, useFirePlace),
55423
58501
  loc: GeneratedSource,
58502
+ effects: null,
55424
58503
  };
55425
58504
  }
55426
58505
  function makeLoadFireCalleeInstruction(env, fireCalleeIdentifier) {
@@ -55441,6 +58520,7 @@ function makeLoadFireCalleeInstruction(env, fireCalleeIdentifier) {
55441
58520
  },
55442
58521
  lvalue: Object.assign({}, loadedFireCallee),
55443
58522
  loc: GeneratedSource,
58523
+ effects: null,
55444
58524
  };
55445
58525
  }
55446
58526
  function makeCallUseFireInstruction(env, useFirePlace, argPlace) {
@@ -55457,6 +58537,7 @@ function makeCallUseFireInstruction(env, useFirePlace, argPlace) {
55457
58537
  value: useFireCall,
55458
58538
  lvalue: Object.assign({}, useFireCallResultPlace),
55459
58539
  loc: GeneratedSource,
58540
+ effects: null,
55460
58541
  };
55461
58542
  }
55462
58543
  function makeStoreUseFireInstruction(env, useFireCallResultPlace, fireFunctionBindingPlace) {
@@ -55476,6 +58557,7 @@ function makeStoreUseFireInstruction(env, useFireCallResultPlace, fireFunctionBi
55476
58557
  },
55477
58558
  lvalue: fireFunctionBindingLValuePlace,
55478
58559
  loc: GeneratedSource,
58560
+ effects: null,
55479
58561
  };
55480
58562
  }
55481
58563
  class Context {
@@ -55701,8 +58783,7 @@ function validateNoFreezingKnownMutableFunctions(fn) {
55701
58783
  const effect = contextMutationEffects.get(operand.identifier.id);
55702
58784
  if (effect != null) {
55703
58785
  errors.push({
55704
- reason: `This argument is a function which modifies local variables when called, which can bypass memoization and cause the UI not to update`,
55705
- description: `Functions that are returned from hooks, passed as arguments to hooks, or passed as props to components may not mutate local variables`,
58786
+ reason: `This argument is a function which may reassign or mutate local variables after render, which can cause inconsistent behavior on subsequent renders. Consider using state instead`,
55706
58787
  loc: operand.loc,
55707
58788
  severity: ErrorSeverity.InvalidReact,
55708
58789
  });
@@ -55746,6 +58827,41 @@ function validateNoFreezingKnownMutableFunctions(fn) {
55746
58827
  if (knownMutation && knownMutation.kind === 'ContextMutation') {
55747
58828
  contextMutationEffects.set(lvalue.identifier.id, knownMutation);
55748
58829
  }
58830
+ else if (fn.env.config.enableNewMutationAliasingModel &&
58831
+ value.loweredFunc.func.aliasingEffects != null) {
58832
+ const context = new Set(value.loweredFunc.func.context.map(p => p.identifier.id));
58833
+ effects: for (const effect of value.loweredFunc.func
58834
+ .aliasingEffects) {
58835
+ switch (effect.kind) {
58836
+ case 'Mutate':
58837
+ case 'MutateTransitive': {
58838
+ const knownMutation = contextMutationEffects.get(effect.value.identifier.id);
58839
+ if (knownMutation != null) {
58840
+ contextMutationEffects.set(lvalue.identifier.id, knownMutation);
58841
+ }
58842
+ else if (context.has(effect.value.identifier.id) &&
58843
+ !isRefOrRefLikeMutableType(effect.value.identifier.type)) {
58844
+ contextMutationEffects.set(lvalue.identifier.id, {
58845
+ kind: 'ContextMutation',
58846
+ effect: Effect.Mutate,
58847
+ loc: effect.value.loc,
58848
+ places: new Set([effect.value]),
58849
+ });
58850
+ break effects;
58851
+ }
58852
+ break;
58853
+ }
58854
+ case 'MutateConditionally':
58855
+ case 'MutateTransitiveConditionally': {
58856
+ const knownMutation = contextMutationEffects.get(effect.value.identifier.id);
58857
+ if (knownMutation != null) {
58858
+ contextMutationEffects.set(lvalue.identifier.id, knownMutation);
58859
+ }
58860
+ break;
58861
+ }
58862
+ }
58863
+ }
58864
+ }
55749
58865
  break;
55750
58866
  }
55751
58867
  default: {
@@ -55829,14 +58945,27 @@ function runWithEnvironment(func, env) {
55829
58945
  log({ kind: 'hir', name: 'OptimizePropsMethodCalls', value: hir });
55830
58946
  analyseFunctions(hir);
55831
58947
  log({ kind: 'hir', name: 'AnalyseFunctions', value: hir });
55832
- const fnEffectErrors = inferReferenceEffects(hir);
55833
- if (env.isInferredMemoEnabled) {
55834
- if (fnEffectErrors.length > 0) {
55835
- CompilerError.throw(fnEffectErrors[0]);
58948
+ if (!env.config.enableNewMutationAliasingModel) {
58949
+ const fnEffectErrors = inferReferenceEffects(hir);
58950
+ if (env.isInferredMemoEnabled) {
58951
+ if (fnEffectErrors.length > 0) {
58952
+ CompilerError.throw(fnEffectErrors[0]);
58953
+ }
58954
+ }
58955
+ log({ kind: 'hir', name: 'InferReferenceEffects', value: hir });
58956
+ }
58957
+ else {
58958
+ const mutabilityAliasingErrors = inferMutationAliasingEffects(hir);
58959
+ log({ kind: 'hir', name: 'InferMutationAliasingEffects', value: hir });
58960
+ if (env.isInferredMemoEnabled) {
58961
+ if (mutabilityAliasingErrors.isErr()) {
58962
+ throw mutabilityAliasingErrors.unwrapErr();
58963
+ }
55836
58964
  }
55837
58965
  }
55838
- log({ kind: 'hir', name: 'InferReferenceEffects', value: hir });
55839
- validateLocalsNotReassignedAfterRender(hir);
58966
+ if (!env.config.enableNewMutationAliasingModel) {
58967
+ validateLocalsNotReassignedAfterRender(hir);
58968
+ }
55840
58969
  deadCodeElimination(hir);
55841
58970
  log({ kind: 'hir', name: 'DeadCodeElimination', value: hir });
55842
58971
  if (env.config.enableInstructionReordering) {
@@ -55845,8 +58974,22 @@ function runWithEnvironment(func, env) {
55845
58974
  }
55846
58975
  pruneMaybeThrows(hir);
55847
58976
  log({ kind: 'hir', name: 'PruneMaybeThrows', value: hir });
55848
- inferMutableRanges(hir);
55849
- log({ kind: 'hir', name: 'InferMutableRanges', value: hir });
58977
+ if (!env.config.enableNewMutationAliasingModel) {
58978
+ inferMutableRanges(hir);
58979
+ log({ kind: 'hir', name: 'InferMutableRanges', value: hir });
58980
+ }
58981
+ else {
58982
+ const mutabilityAliasingErrors = inferMutationAliasingRanges(hir, {
58983
+ isFunctionExpression: false,
58984
+ });
58985
+ log({ kind: 'hir', name: 'InferMutationAliasingRanges', value: hir });
58986
+ if (env.isInferredMemoEnabled) {
58987
+ if (mutabilityAliasingErrors.isErr()) {
58988
+ throw mutabilityAliasingErrors.unwrapErr();
58989
+ }
58990
+ validateLocalsNotReassignedAfterRender(hir);
58991
+ }
58992
+ }
55850
58993
  if (env.isInferredMemoEnabled) {
55851
58994
  if (env.config.assertValidMutableRanges) {
55852
58995
  assertValidMutableRanges(hir);
@@ -55866,7 +59009,8 @@ function runWithEnvironment(func, env) {
55866
59009
  if (env.config.validateNoImpureFunctionsInRender) {
55867
59010
  validateNoImpureFunctionsInRender(hir).unwrap();
55868
59011
  }
55869
- if (env.config.validateNoFreezingKnownMutableFunctions) {
59012
+ if (env.config.validateNoFreezingKnownMutableFunctions ||
59013
+ env.config.enableNewMutationAliasingModel) {
55870
59014
  validateNoFreezingKnownMutableFunctions(hir).unwrap();
55871
59015
  }
55872
59016
  }