babel-plugin-react-compiler 0.0.0-experimental-334f00b-20240725 → 0.0.0-experimental-0725353-20240806

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -135625,6 +135625,14 @@ function getOrInsertDefault(m, key, defaultValue) {
135625
135625
  return defaultValue;
135626
135626
  }
135627
135627
  }
135628
+ function Iterable_some(iter, pred) {
135629
+ for (const item of iter) {
135630
+ if (pred(item)) {
135631
+ return true;
135632
+ }
135633
+ }
135634
+ return false;
135635
+ }
135628
135636
  function hasNode(input) {
135629
135637
  return input.node != null;
135630
135638
  }
@@ -135902,6 +135910,17 @@ var InstructionKind;
135902
135910
  InstructionKind['Catch'] = 'Catch';
135903
135911
  InstructionKind['HoistedConst'] = 'HoistedConst';
135904
135912
  })(InstructionKind || (InstructionKind = {}));
135913
+ function makeTemporaryIdentifier(id, loc) {
135914
+ return {
135915
+ id: id,
135916
+ name: null,
135917
+ declarationId: makeDeclarationId(id),
135918
+ mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
135919
+ scope: null,
135920
+ type: makeType(),
135921
+ loc: loc,
135922
+ };
135923
+ }
135905
135924
  function makeIdentifierName(name) {
135906
135925
  CompilerError.invariant(t__namespace.isValidIdentifier(name), {
135907
135926
  reason: `Expected a valid identifier name`,
@@ -135918,7 +135937,7 @@ function promoteTemporary(identifier) {
135918
135937
  description: `Identifier already has a name, \`${identifier.name}\``,
135919
135938
  suggestions: null,
135920
135939
  });
135921
- identifier.name = {kind: 'promoted', value: `#t${identifier.id}`};
135940
+ identifier.name = {kind: 'promoted', value: `#t${identifier.declarationId}`};
135922
135941
  }
135923
135942
  function isPromotedTemporary(name) {
135924
135943
  return name.startsWith('#t');
@@ -135930,7 +135949,7 @@ function promoteTemporaryJsxTag(identifier) {
135930
135949
  description: `Identifier already has a name, \`${identifier.name}\``,
135931
135950
  suggestions: null,
135932
135951
  });
135933
- identifier.name = {kind: 'promoted', value: `#T${identifier.id}`};
135952
+ identifier.name = {kind: 'promoted', value: `#T${identifier.declarationId}`};
135934
135953
  }
135935
135954
  function isPromotedJsxTemporary(name) {
135936
135955
  return name.startsWith('#T');
@@ -136017,6 +136036,15 @@ function makeIdentifierId(id) {
136017
136036
  });
136018
136037
  return id;
136019
136038
  }
136039
+ function makeDeclarationId(id) {
136040
+ CompilerError.invariant(id >= 0 && Number.isInteger(id), {
136041
+ reason: 'Expected declaration id to be a non-negative integer',
136042
+ description: null,
136043
+ loc: null,
136044
+ suggestions: null,
136045
+ });
136046
+ return id;
136047
+ }
136020
136048
  function makeInstructionId(id) {
136021
136049
  CompilerError.invariant(id >= 0 && Number.isInteger(id), {
136022
136050
  reason: 'Expected instruction id to be a non-negative integer',
@@ -138666,6 +138694,7 @@ class HIRBuilder {
138666
138694
  _HIRBuilder_env.set(this, void 0);
138667
138695
  _HIRBuilder_exceptionHandlerStack.set(this, []);
138668
138696
  this.errors = new CompilerError();
138697
+ this.fbtDepth = 0;
138669
138698
  __classPrivateFieldSet(this, _HIRBuilder_env, env, 'f');
138670
138699
  __classPrivateFieldSet(
138671
138700
  this,
@@ -138736,14 +138765,7 @@ class HIRBuilder {
138736
138765
  }
138737
138766
  makeTemporary(loc) {
138738
138767
  const id = this.nextIdentifierId;
138739
- return {
138740
- id: id,
138741
- name: null,
138742
- mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
138743
- scope: null,
138744
- type: makeType(),
138745
- loc: loc,
138746
- };
138768
+ return makeTemporaryIdentifier(id, loc);
138747
138769
  }
138748
138770
  resolveIdentifier(path) {
138749
138771
  const originalName = path.node.name;
@@ -138823,7 +138845,13 @@ class HIRBuilder {
138823
138845
  }
138824
138846
  }
138825
138847
  resolveBinding(node) {
138826
- var _a;
138848
+ var _a, _b;
138849
+ if (node.name === 'fbt') {
138850
+ CompilerError.throwTodo({
138851
+ reason: 'Support local variables named "fbt"',
138852
+ loc: (_a = node.loc) !== null && _a !== void 0 ? _a : null,
138853
+ });
138854
+ }
138827
138855
  const originalName = node.name;
138828
138856
  let name = originalName;
138829
138857
  let index = 0;
@@ -138837,6 +138865,7 @@ class HIRBuilder {
138837
138865
  const id = this.nextIdentifierId;
138838
138866
  const identifier = {
138839
138867
  id: id,
138868
+ declarationId: makeDeclarationId(id),
138840
138869
  name: makeIdentifierName(name),
138841
138870
  mutableRange: {
138842
138871
  start: makeInstructionId(0),
@@ -138844,7 +138873,7 @@ class HIRBuilder {
138844
138873
  },
138845
138874
  scope: null,
138846
138875
  type: makeType(),
138847
- loc: (_a = node.loc) !== null && _a !== void 0 ? _a : GeneratedSource,
138876
+ loc: (_b = node.loc) !== null && _b !== void 0 ? _b : GeneratedSource,
138848
138877
  };
138849
138878
  __classPrivateFieldGet(this, _HIRBuilder_bindings, 'f').set(name, {
138850
138879
  node: node,
@@ -139280,19 +139309,19 @@ function removeUnnecessaryTryCatch(fn) {
139280
139309
  function createTemporaryPlace(env, loc) {
139281
139310
  return {
139282
139311
  kind: 'Identifier',
139283
- identifier: {
139284
- id: env.nextIdentifierId,
139285
- mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
139286
- name: null,
139287
- scope: null,
139288
- type: makeType(),
139289
- loc: loc,
139290
- },
139312
+ identifier: makeTemporaryIdentifier(env.nextIdentifierId, loc),
139291
139313
  reactive: false,
139292
139314
  effect: exports.Effect.Unknown,
139293
139315
  loc: GeneratedSource,
139294
139316
  };
139295
139317
  }
139318
+ function clonePlaceToTemporary(env, place) {
139319
+ const temp = createTemporaryPlace(env, place.loc);
139320
+ temp.effect = place.effect;
139321
+ temp.identifier.type = place.identifier.type;
139322
+ temp.reactive = place.reactive;
139323
+ return temp;
139324
+ }
139296
139325
  const PRIMITIVE_TYPE = {kind: 'Primitive'};
139297
139326
  let nextAnonId = 0;
139298
139327
  function createAnonId() {
@@ -139347,6 +139376,7 @@ const BuiltInUseInsertionEffectHookId = 'BuiltInUseInsertionEffectHook';
139347
139376
  const BuiltInUseOperatorId = 'BuiltInUseOperator';
139348
139377
  const BuiltInUseReducerId = 'BuiltInUseReducer';
139349
139378
  const BuiltInDispatchId = 'BuiltInDispatch';
139379
+ const BuiltInUseContextHookId = 'BuiltInUseContextHook';
139350
139380
  const BUILTIN_SHAPES = new Map();
139351
139381
  addObject(BUILTIN_SHAPES, BuiltInPropsId, [
139352
139382
  ['ref', {kind: 'Object', shapeId: BuiltInUseRefId}],
@@ -141660,7 +141690,6 @@ function lowerExpression(builder, exprPath) {
141660
141690
  switch (leftNode.type) {
141661
141691
  case 'Identifier': {
141662
141692
  const leftExpr = left;
141663
- const identifier = lowerIdentifier(builder, leftExpr);
141664
141693
  const leftPlace = lowerExpressionToTemporary(builder, leftExpr);
141665
141694
  const right = lowerExpressionToTemporary(builder, expr.get('right'));
141666
141695
  const binaryPlace = lowerValueToTemporary(builder, {
@@ -141670,30 +141699,42 @@ function lowerExpression(builder, exprPath) {
141670
141699
  right: right,
141671
141700
  loc: exprLoc,
141672
141701
  });
141673
- const kind = getStoreKind(builder, leftExpr);
141674
- if (kind === 'StoreLocal') {
141675
- lowerValueToTemporary(builder, {
141676
- kind: 'StoreLocal',
141677
- lvalue: {
141678
- place: Object.assign({}, identifier),
141679
- kind: InstructionKind.Reassign,
141680
- },
141681
- value: Object.assign({}, binaryPlace),
141682
- type: null,
141683
- loc: exprLoc,
141684
- });
141685
- return {kind: 'LoadLocal', place: identifier, loc: exprLoc};
141702
+ const binding = builder.resolveIdentifier(leftExpr);
141703
+ if (binding.kind === 'Identifier') {
141704
+ const identifier = lowerIdentifier(builder, leftExpr);
141705
+ const kind = getStoreKind(builder, leftExpr);
141706
+ if (kind === 'StoreLocal') {
141707
+ lowerValueToTemporary(builder, {
141708
+ kind: 'StoreLocal',
141709
+ lvalue: {
141710
+ place: Object.assign({}, identifier),
141711
+ kind: InstructionKind.Reassign,
141712
+ },
141713
+ value: Object.assign({}, binaryPlace),
141714
+ type: null,
141715
+ loc: exprLoc,
141716
+ });
141717
+ return {kind: 'LoadLocal', place: identifier, loc: exprLoc};
141718
+ } else {
141719
+ lowerValueToTemporary(builder, {
141720
+ kind: 'StoreContext',
141721
+ lvalue: {
141722
+ place: Object.assign({}, identifier),
141723
+ kind: InstructionKind.Reassign,
141724
+ },
141725
+ value: Object.assign({}, binaryPlace),
141726
+ loc: exprLoc,
141727
+ });
141728
+ return {kind: 'LoadContext', place: identifier, loc: exprLoc};
141729
+ }
141686
141730
  } else {
141687
- lowerValueToTemporary(builder, {
141688
- kind: 'StoreContext',
141689
- lvalue: {
141690
- place: Object.assign({}, identifier),
141691
- kind: InstructionKind.Reassign,
141692
- },
141731
+ const temporary = lowerValueToTemporary(builder, {
141732
+ kind: 'StoreGlobal',
141733
+ name: leftExpr.node.name,
141693
141734
  value: Object.assign({}, binaryPlace),
141694
141735
  loc: exprLoc,
141695
141736
  });
141696
- return {kind: 'LoadContext', place: identifier, loc: exprLoc};
141737
+ return {kind: 'LoadLocal', place: temporary, loc: temporary.loc};
141697
141738
  }
141698
141739
  }
141699
141740
  case 'MemberExpression': {
@@ -141856,18 +141897,17 @@ function lowerExpression(builder, exprPath) {
141856
141897
  }
141857
141898
  props.push({kind: 'JsxAttribute', name: propName, place: value});
141858
141899
  }
141859
- if (
141860
- tag.kind === 'BuiltinTag' &&
141861
- (tag.name === 'fbt' || tag.name === 'fbs')
141862
- ) {
141900
+ const isFbt =
141901
+ tag.kind === 'BuiltinTag' && (tag.name === 'fbt' || tag.name === 'fbs');
141902
+ if (isFbt) {
141863
141903
  const tagName = tag.name;
141864
141904
  const openingIdentifier = opening.get('name');
141865
141905
  const tagIdentifier = openingIdentifier.isJSXIdentifier()
141866
141906
  ? builder.resolveIdentifier(openingIdentifier)
141867
141907
  : null;
141868
- if (tagIdentifier != null && tagIdentifier.kind === 'Identifier') {
141869
- CompilerError.throwTodo({
141870
- reason: `Support <${tagName}> tags where '${tagName}' is a local variable instead of a global`,
141908
+ if (tagIdentifier != null) {
141909
+ CompilerError.invariant(tagIdentifier.kind !== 'Identifier', {
141910
+ reason: `<${tagName}> tags should be module-level imports`,
141871
141911
  loc:
141872
141912
  (_3 = openingIdentifier.node.loc) !== null && _3 !== void 0
141873
141913
  ? _3
@@ -141876,63 +141916,64 @@ function lowerExpression(builder, exprPath) {
141876
141916
  suggestions: null,
141877
141917
  });
141878
141918
  }
141879
- const fbtEnumLocations = [];
141919
+ const fbtLocations = {
141920
+ enum: new Array(),
141921
+ plural: new Array(),
141922
+ pronoun: new Array(),
141923
+ };
141880
141924
  expr.traverse({
141925
+ JSXClosingElement(path) {
141926
+ path.skip();
141927
+ },
141881
141928
  JSXNamespacedName(path) {
141882
- var _a;
141883
- if (
141884
- path.node.namespace.name === tagName &&
141885
- path.node.name.name === 'enum'
141886
- ) {
141887
- fbtEnumLocations.push(
141888
- (_a = path.node.loc) !== null && _a !== void 0
141889
- ? _a
141890
- : GeneratedSource
141891
- );
141929
+ var _a, _b, _c;
141930
+ if (path.node.namespace.name === tagName) {
141931
+ switch (path.node.name.name) {
141932
+ case 'enum':
141933
+ fbtLocations.enum.push(
141934
+ (_a = path.node.loc) !== null && _a !== void 0
141935
+ ? _a
141936
+ : GeneratedSource
141937
+ );
141938
+ break;
141939
+ case 'plural':
141940
+ fbtLocations.plural.push(
141941
+ (_b = path.node.loc) !== null && _b !== void 0
141942
+ ? _b
141943
+ : GeneratedSource
141944
+ );
141945
+ break;
141946
+ case 'pronoun':
141947
+ fbtLocations.pronoun.push(
141948
+ (_c = path.node.loc) !== null && _c !== void 0
141949
+ ? _c
141950
+ : GeneratedSource
141951
+ );
141952
+ break;
141953
+ }
141892
141954
  }
141893
141955
  },
141894
141956
  });
141895
- if (fbtEnumLocations.length > 1) {
141896
- CompilerError.throwTodo({
141897
- reason: `Support <${tagName}> tags with multiple <${tagName}:enum> values`,
141898
- loc:
141899
- (_4 = fbtEnumLocations.at(-1)) !== null && _4 !== void 0
141900
- ? _4
141901
- : GeneratedSource,
141902
- description: null,
141903
- suggestions: null,
141904
- });
141957
+ for (const [name, locations] of Object.entries(fbtLocations)) {
141958
+ if (locations.length > 1) {
141959
+ CompilerError.throwTodo({
141960
+ reason: `Support <${tagName}> tags with multiple <${tagName}:${name}> values`,
141961
+ loc:
141962
+ (_4 = locations.at(-1)) !== null && _4 !== void 0
141963
+ ? _4
141964
+ : GeneratedSource,
141965
+ description: null,
141966
+ suggestions: null,
141967
+ });
141968
+ }
141905
141969
  }
141906
141970
  }
141907
- let children;
141908
- if (
141909
- tag.kind === 'BuiltinTag' &&
141910
- (tag.name === 'fbt' || tag.name === 'fbs')
141911
- ) {
141912
- children = expr
141913
- .get('children')
141914
- .map(child => {
141915
- var _a;
141916
- if (child.isJSXText()) {
141917
- const text = child.node.value.replace(/[^\S\u00A0]+/g, ' ');
141918
- return lowerValueToTemporary(builder, {
141919
- kind: 'JSXText',
141920
- value: text,
141921
- loc:
141922
- (_a = child.node.loc) !== null && _a !== void 0
141923
- ? _a
141924
- : GeneratedSource,
141925
- });
141926
- }
141927
- return lowerJsxElement(builder, child);
141928
- })
141929
- .filter(notNull);
141930
- } else {
141931
- children = expr
141932
- .get('children')
141933
- .map(child => lowerJsxElement(builder, child))
141934
- .filter(notNull);
141935
- }
141971
+ isFbt && builder.fbtDepth++;
141972
+ const children = expr
141973
+ .get('children')
141974
+ .map(child => lowerJsxElement(builder, child))
141975
+ .filter(notNull);
141976
+ isFbt && builder.fbtDepth--;
141936
141977
  return {
141937
141978
  kind: 'JsxExpression',
141938
141979
  tag: tag,
@@ -142788,7 +142829,12 @@ function lowerJsxElement(builder, exprPath) {
142788
142829
  return lowerExpressionToTemporary(builder, expression);
142789
142830
  }
142790
142831
  } else if (exprPath.isJSXText()) {
142791
- const text = trimJsxText(exprPath.node.value);
142832
+ let text;
142833
+ if (builder.fbtDepth > 0) {
142834
+ text = exprPath.node.value;
142835
+ } else {
142836
+ text = trimJsxText(exprPath.node.value);
142837
+ }
142792
142838
  if (text === null) {
142793
142839
  return null;
142794
142840
  }
@@ -142872,7 +142918,7 @@ function lowerFunctionToValue(builder, expr) {
142872
142918
  return {
142873
142919
  kind: 'FunctionExpression',
142874
142920
  name: name,
142875
- expr: expr.node,
142921
+ type: expr.node.type,
142876
142922
  loc: exprLoc,
142877
142923
  loweredFunc: loweredFunc,
142878
142924
  };
@@ -149706,15 +149752,19 @@ const TYPED_GLOBALS = [
149706
149752
  const REACT_APIS = [
149707
149753
  [
149708
149754
  'useContext',
149709
- addHook(DEFAULT_SHAPES, {
149710
- positionalParams: [],
149711
- restParam: exports.Effect.Read,
149712
- returnType: {kind: 'Poly'},
149713
- calleeEffect: exports.Effect.Read,
149714
- hookKind: 'useContext',
149715
- returnValueKind: exports.ValueKind.Frozen,
149716
- returnValueReason: ValueReason.Context,
149717
- }),
149755
+ addHook(
149756
+ DEFAULT_SHAPES,
149757
+ {
149758
+ positionalParams: [],
149759
+ restParam: exports.Effect.Read,
149760
+ returnType: {kind: 'Poly'},
149761
+ calleeEffect: exports.Effect.Read,
149762
+ hookKind: 'useContext',
149763
+ returnValueKind: exports.ValueKind.Frozen,
149764
+ returnValueReason: ValueReason.Context,
149765
+ },
149766
+ BuiltInUseContextHookId
149767
+ ),
149718
149768
  ],
149719
149769
  [
149720
149770
  'useState',
@@ -150031,6 +150081,7 @@ const EnvironmentConfigSchema = z.object({
150031
150081
  enableCustomTypeDefinitionForReanimated: z.boolean().default(false),
150032
150082
  hookPattern: z.string().nullable().default(null),
150033
150083
  enableTreatRefLikeIdentifiersAsRefs: z.boolean().nullable().default(false),
150084
+ enableLowerContextAccess: z.boolean().nullable().default(false),
150034
150085
  });
150035
150086
  function parseConfigPragma(pragma) {
150036
150087
  const maybeConfig = {};
@@ -150055,6 +150106,10 @@ function parseConfigPragma(pragma) {
150055
150106
  };
150056
150107
  continue;
150057
150108
  }
150109
+ if (key === 'customMacros' && val) {
150110
+ maybeConfig[key] = [val];
150111
+ continue;
150112
+ }
150058
150113
  if (typeof defaultConfig[key] !== 'boolean') {
150059
150114
  continue;
150060
150115
  }
@@ -153260,6 +153315,12 @@ function mayAllocate(env, instruction) {
153260
153315
  function findDisjointMutableValues(fn) {
153261
153316
  var _a, _b;
153262
153317
  const scopeIdentifiers = new DisjointSet();
153318
+ const declarations = new Map();
153319
+ function declareIdentifier(lvalue) {
153320
+ if (!declarations.has(lvalue.identifier.declarationId)) {
153321
+ declarations.set(lvalue.identifier.declarationId, lvalue.identifier);
153322
+ }
153323
+ }
153263
153324
  for (const [_, block] of fn.body.blocks) {
153264
153325
  for (const phi of block.phis) {
153265
153326
  if (
@@ -153272,9 +153333,15 @@ function findDisjointMutableValues(fn) {
153272
153333
  ? _b
153273
153334
  : block.terminal.id)
153274
153335
  ) {
153275
- for (const [, phiId] of phi.operands) {
153276
- scopeIdentifiers.union([phi.id, phiId]);
153336
+ const operands = [phi.id];
153337
+ const declaration = declarations.get(phi.id.declarationId);
153338
+ if (declaration !== undefined) {
153339
+ operands.push(declaration);
153277
153340
  }
153341
+ for (const [_, phiId] of phi.operands) {
153342
+ operands.push(phiId);
153343
+ }
153344
+ scopeIdentifiers.union(operands);
153278
153345
  } else if (fn.env.config.enableForest) {
153279
153346
  for (const [, phiId] of phi.operands) {
153280
153347
  scopeIdentifiers.union([phi.id, phiId]);
@@ -153288,9 +153355,15 @@ function findDisjointMutableValues(fn) {
153288
153355
  operands.push(instr.lvalue.identifier);
153289
153356
  }
153290
153357
  if (
153358
+ instr.value.kind === 'DeclareLocal' ||
153359
+ instr.value.kind === 'DeclareContext'
153360
+ ) {
153361
+ declareIdentifier(instr.value.lvalue.place);
153362
+ } else if (
153291
153363
  instr.value.kind === 'StoreLocal' ||
153292
153364
  instr.value.kind === 'StoreContext'
153293
153365
  ) {
153366
+ declareIdentifier(instr.value.lvalue.place);
153294
153367
  if (
153295
153368
  instr.value.lvalue.place.identifier.mutableRange.end >
153296
153369
  instr.value.lvalue.place.identifier.mutableRange.start + 1
@@ -153305,6 +153378,7 @@ function findDisjointMutableValues(fn) {
153305
153378
  }
153306
153379
  } else if (instr.value.kind === 'Destructure') {
153307
153380
  for (const place of eachPatternOperand(instr.value.lvalue.pattern)) {
153381
+ declareIdentifier(place);
153308
153382
  if (
153309
153383
  place.identifier.mutableRange.end >
153310
153384
  place.identifier.mutableRange.start + 1
@@ -153925,10 +153999,10 @@ function eliminateRedundantPhi(fn, sharedRewrites) {
153925
153999
  }
153926
154000
  for (const instr of block.instructions) {
153927
154001
  for (const place of eachInstructionLValue(instr)) {
153928
- rewritePlace$1(place, rewrites);
154002
+ rewritePlace(place, rewrites);
153929
154003
  }
153930
154004
  for (const place of eachInstructionOperand(instr)) {
153931
- rewritePlace$1(place, rewrites);
154005
+ rewritePlace(place, rewrites);
153932
154006
  }
153933
154007
  if (
153934
154008
  instr.value.kind === 'FunctionExpression' ||
@@ -153936,19 +154010,19 @@ function eliminateRedundantPhi(fn, sharedRewrites) {
153936
154010
  ) {
153937
154011
  const {context: context} = instr.value.loweredFunc.func;
153938
154012
  for (const place of context) {
153939
- rewritePlace$1(place, rewrites);
154013
+ rewritePlace(place, rewrites);
153940
154014
  }
153941
154015
  eliminateRedundantPhi(instr.value.loweredFunc.func, rewrites);
153942
154016
  }
153943
154017
  }
153944
154018
  const {terminal: terminal} = block;
153945
154019
  for (const place of eachTerminalOperand(terminal)) {
153946
- rewritePlace$1(place, rewrites);
154020
+ rewritePlace(place, rewrites);
153947
154021
  }
153948
154022
  }
153949
154023
  } while (rewrites.size > size && hasBackEdge);
153950
154024
  }
153951
- function rewritePlace$1(place, rewrites) {
154025
+ function rewritePlace(place, rewrites) {
153952
154026
  const rewrite = rewrites.get(place.identifier);
153953
154027
  if (rewrite != null) {
153954
154028
  place.identifier = rewrite;
@@ -154002,6 +154076,7 @@ class SSABuilder {
154002
154076
  makeId(oldId) {
154003
154077
  return {
154004
154078
  id: this.nextSsaId,
154079
+ declarationId: oldId.declarationId,
154005
154080
  name: oldId.name,
154006
154081
  mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
154007
154082
  scope: null,
@@ -154205,355 +154280,165 @@ function enterSSAImpl(func, builder, rootEntry) {
154205
154280
  }
154206
154281
  }
154207
154282
  }
154208
- function leaveSSA(fn) {
154209
- var _a, _b, _c;
154283
+ function rewriteInstructionKindsBasedOnReassignment(fn) {
154210
154284
  const declarations = new Map();
154211
154285
  for (const param of fn.params) {
154212
154286
  let place = param.kind === 'Identifier' ? param : param.place;
154213
154287
  if (place.identifier.name !== null) {
154214
- declarations.set(place.identifier.name.value, {
154215
- lvalue: {kind: InstructionKind.Let, place: place},
154288
+ declarations.set(place.identifier.declarationId, {
154289
+ kind: InstructionKind.Let,
154216
154290
  place: place,
154217
154291
  });
154218
154292
  }
154219
154293
  }
154220
- const rewrites = new Map();
154221
- const seen = new Set();
154222
- const backEdgePhis = new Set();
154223
- for (const [, block] of fn.body.blocks) {
154224
- for (const phi of block.phis) {
154225
- for (const [pred] of phi.operands) {
154226
- if (!seen.has(pred)) {
154227
- backEdgePhis.add(phi);
154228
- break;
154229
- }
154230
- }
154294
+ for (const place of fn.context) {
154295
+ if (place.identifier.name !== null) {
154296
+ declarations.set(place.identifier.declarationId, {
154297
+ kind: InstructionKind.Let,
154298
+ place: place,
154299
+ });
154231
154300
  }
154232
- seen.add(block.id);
154233
154301
  }
154234
154302
  for (const [, block] of fn.body.blocks) {
154235
154303
  for (const instr of block.instructions) {
154236
- const {lvalue: lvalue, value: value} = instr;
154237
- if (value.kind === 'DeclareLocal') {
154238
- const name = value.lvalue.place.identifier.name;
154239
- if (name !== null) {
154240
- CompilerError.invariant(!declarations.has(name.value), {
154241
- reason: `Unexpected duplicate declaration`,
154242
- description: `Found duplicate declaration for \`${name.value}\``,
154243
- loc: value.lvalue.place.loc,
154244
- suggestions: null,
154245
- });
154246
- declarations.set(name.value, {
154247
- lvalue: value.lvalue,
154248
- place: value.lvalue.place,
154249
- });
154250
- }
154251
- } else if (
154252
- value.kind === 'PrefixUpdate' ||
154253
- value.kind === 'PostfixUpdate'
154254
- ) {
154255
- CompilerError.invariant(value.lvalue.identifier.name !== null, {
154256
- reason: `Expected update expression to be applied to a named variable`,
154257
- description: null,
154258
- loc: value.lvalue.loc,
154259
- suggestions: null,
154260
- });
154261
- const originalLVal = declarations.get(
154262
- value.lvalue.identifier.name.value
154263
- );
154264
- CompilerError.invariant(originalLVal !== undefined, {
154265
- reason: `Expected update expression to be applied to a previously defined variable`,
154266
- description: null,
154267
- loc: value.lvalue.loc,
154268
- suggestions: null,
154269
- });
154270
- originalLVal.lvalue.kind = InstructionKind.Let;
154271
- } else if (value.kind === 'StoreLocal') {
154272
- if (value.lvalue.place.identifier.name != null) {
154273
- const originalLVal = declarations.get(
154274
- value.lvalue.place.identifier.name.value
154304
+ const {value: value} = instr;
154305
+ switch (value.kind) {
154306
+ case 'DeclareLocal': {
154307
+ const lvalue = value.lvalue;
154308
+ CompilerError.invariant(
154309
+ !declarations.has(lvalue.place.identifier.declarationId),
154310
+ {
154311
+ reason: `Expected variable not to be defined prior to declaration`,
154312
+ description: `${printPlace(lvalue.place)} was already defined`,
154313
+ loc: lvalue.place.loc,
154314
+ }
154275
154315
  );
154276
- if (
154277
- originalLVal === undefined ||
154278
- originalLVal.lvalue === value.lvalue
154279
- ) {
154280
- CompilerError.invariant(
154281
- originalLVal !== undefined ||
154282
- block.kind === 'block' ||
154283
- block.kind === 'catch',
154284
- {
154285
- reason: `TODO: Handle reassignment in a value block where the original declaration was removed by dead code elimination (DCE)`,
154286
- description: null,
154287
- loc: value.lvalue.place.loc,
154288
- suggestions: null,
154289
- }
154290
- );
154291
- declarations.set(value.lvalue.place.identifier.name.value, {
154292
- lvalue: value.lvalue,
154293
- place: value.lvalue.place,
154294
- });
154295
- value.lvalue.kind = InstructionKind.Const;
154296
- } else {
154297
- originalLVal.lvalue.kind = InstructionKind.Let;
154298
- value.lvalue.kind = InstructionKind.Reassign;
154299
- }
154300
- } else if (rewrites.has(value.lvalue.place.identifier)) {
154301
- value.lvalue.kind = InstructionKind.Const;
154316
+ declarations.set(lvalue.place.identifier.declarationId, lvalue);
154317
+ break;
154302
154318
  }
154303
- } else if (value.kind === 'Destructure') {
154304
- let kind = null;
154305
- for (const place of eachPatternOperand(value.lvalue.pattern)) {
154306
- if (place.identifier.name == null) {
154307
- CompilerError.invariant(
154308
- kind === null || kind === InstructionKind.Const,
154309
- {
154310
- reason: `Expected consistent kind for destructuring`,
154311
- description: `other places were \`${kind}\` but '${printPlace(place)}' is const`,
154312
- loc: place.loc,
154313
- suggestions: null,
154314
- }
154319
+ case 'StoreLocal': {
154320
+ const lvalue = value.lvalue;
154321
+ if (lvalue.place.identifier.name !== null) {
154322
+ const declaration = declarations.get(
154323
+ lvalue.place.identifier.declarationId
154315
154324
  );
154316
- kind = InstructionKind.Const;
154317
- } else {
154318
- const originalLVal = declarations.get(place.identifier.name.value);
154319
- if (
154320
- originalLVal === undefined ||
154321
- originalLVal.lvalue === value.lvalue
154322
- ) {
154325
+ if (declaration === undefined) {
154323
154326
  CompilerError.invariant(
154324
- originalLVal !== undefined || block.kind !== 'value',
154327
+ !declarations.has(lvalue.place.identifier.declarationId),
154325
154328
  {
154326
- reason: `TODO: Handle reassignment in a value block where the original declaration was removed by dead code elimination (DCE)`,
154327
- description: null,
154328
- loc: place.loc,
154329
- suggestions: null,
154329
+ reason: `Expected variable not to be defined prior to declaration`,
154330
+ description: `${printPlace(lvalue.place)} was already defined`,
154331
+ loc: lvalue.place.loc,
154330
154332
  }
154331
154333
  );
154332
- declarations.set(place.identifier.name.value, {
154333
- lvalue: value.lvalue,
154334
- place: place,
154335
- });
154334
+ declarations.set(lvalue.place.identifier.declarationId, lvalue);
154335
+ lvalue.kind = InstructionKind.Const;
154336
+ } else {
154337
+ declaration.kind = InstructionKind.Let;
154338
+ lvalue.kind = InstructionKind.Reassign;
154339
+ }
154340
+ }
154341
+ break;
154342
+ }
154343
+ case 'Destructure': {
154344
+ const lvalue = value.lvalue;
154345
+ let kind = null;
154346
+ for (const place of eachPatternOperand(lvalue.pattern)) {
154347
+ if (place.identifier.name === null) {
154336
154348
  CompilerError.invariant(
154337
154349
  kind === null || kind === InstructionKind.Const,
154338
154350
  {
154339
154351
  reason: `Expected consistent kind for destructuring`,
154340
- description: `Other places were \`${kind}\` but '${printPlace(place)}' is const`,
154352
+ description: `other places were \`${kind}\` but '${printPlace(place)}' is const`,
154341
154353
  loc: place.loc,
154342
154354
  suggestions: null,
154343
154355
  }
154344
154356
  );
154345
154357
  kind = InstructionKind.Const;
154346
154358
  } else {
154347
- CompilerError.invariant(
154348
- kind === null || kind === InstructionKind.Reassign,
154349
- {
154350
- reason: `Expected consistent kind for destructuring`,
154351
- description: `Other places were \`${kind}\` but '${printPlace(place)}' is reassigned`,
154359
+ const declaration = declarations.get(
154360
+ place.identifier.declarationId
154361
+ );
154362
+ if (declaration === undefined) {
154363
+ CompilerError.invariant(block.kind !== 'value', {
154364
+ reason: `TODO: Handle reassignment in a value block where the original declaration was removed by dead code elimination (DCE)`,
154365
+ description: null,
154352
154366
  loc: place.loc,
154353
154367
  suggestions: null,
154354
- }
154355
- );
154356
- kind = InstructionKind.Reassign;
154357
- originalLVal.lvalue.kind = InstructionKind.Let;
154368
+ });
154369
+ declarations.set(place.identifier.declarationId, lvalue);
154370
+ CompilerError.invariant(
154371
+ kind === null || kind === InstructionKind.Const,
154372
+ {
154373
+ reason: `Expected consistent kind for destructuring`,
154374
+ description: `Other places were \`${kind}\` but '${printPlace(place)}' is const`,
154375
+ loc: place.loc,
154376
+ suggestions: null,
154377
+ }
154378
+ );
154379
+ kind = InstructionKind.Const;
154380
+ } else {
154381
+ CompilerError.invariant(
154382
+ kind === null || kind === InstructionKind.Reassign,
154383
+ {
154384
+ reason: `Expected consistent kind for destructuring`,
154385
+ description: `Other places were \`${kind}\` but '${printPlace(place)}' is reassigned`,
154386
+ loc: place.loc,
154387
+ suggestions: null,
154388
+ }
154389
+ );
154390
+ kind = InstructionKind.Reassign;
154391
+ declaration.kind = InstructionKind.Let;
154392
+ }
154358
154393
  }
154359
154394
  }
154395
+ CompilerError.invariant(kind !== null, {
154396
+ reason: 'Expected at least one operand',
154397
+ description: null,
154398
+ loc: null,
154399
+ suggestions: null,
154400
+ });
154401
+ lvalue.kind = kind;
154402
+ break;
154403
+ }
154404
+ case 'PostfixUpdate':
154405
+ case 'PrefixUpdate': {
154406
+ const lvalue = value.lvalue;
154407
+ const declaration = declarations.get(lvalue.identifier.declarationId);
154408
+ CompilerError.invariant(declaration !== undefined, {
154409
+ reason: `Expected variable to have been defined`,
154410
+ description: `No declaration for ${printPlace(lvalue)}`,
154411
+ loc: lvalue.loc,
154412
+ });
154413
+ declaration.kind = InstructionKind.Let;
154414
+ break;
154360
154415
  }
154361
- CompilerError.invariant(kind !== null, {
154362
- reason: 'Expected at least one operand',
154363
- description: null,
154364
- loc: null,
154365
- suggestions: null,
154366
- });
154367
- value.lvalue.kind = kind;
154368
- }
154369
- rewritePlace(lvalue, rewrites, declarations);
154370
- for (const operand of eachInstructionLValue(instr)) {
154371
- rewritePlace(operand, rewrites, declarations);
154372
- }
154373
- for (const operand of eachInstructionValueOperand(instr.value)) {
154374
- rewritePlace(operand, rewrites, declarations);
154375
154416
  }
154376
154417
  }
154377
- const terminal = block.terminal;
154378
- for (const operand of eachTerminalOperand(terminal)) {
154379
- rewritePlace(operand, rewrites, declarations);
154418
+ }
154419
+ }
154420
+ function constantPropagation(fn) {
154421
+ const constants = new Map();
154422
+ constantPropagationImpl(fn, constants);
154423
+ }
154424
+ function constantPropagationImpl(fn, constants) {
154425
+ while (true) {
154426
+ const haveTerminalsChanged = applyConstantPropagation(fn, constants);
154427
+ if (!haveTerminalsChanged) {
154428
+ break;
154380
154429
  }
154381
- const reassignmentPhis = [];
154382
- const rewritePhis = [];
154383
- function pushPhis(phiBlock) {
154384
- for (const phi of phiBlock.phis) {
154385
- if (phi.id.name === null) {
154386
- rewritePhis.push({phi: phi, block: phiBlock});
154387
- } else {
154388
- reassignmentPhis.push({phi: phi, block: phiBlock});
154389
- }
154390
- }
154391
- }
154392
- const fallthroughId = terminalFallthrough(terminal);
154393
- if (fallthroughId !== null) {
154394
- const fallthrough = fn.body.blocks.get(fallthroughId);
154395
- pushPhis(fallthrough);
154396
- }
154397
- if (terminal.kind === 'while' || terminal.kind === 'for') {
154398
- const test = fn.body.blocks.get(terminal.test);
154399
- pushPhis(test);
154400
- const loop = fn.body.blocks.get(terminal.loop);
154401
- pushPhis(loop);
154402
- }
154403
- if (
154404
- terminal.kind === 'for' ||
154405
- terminal.kind === 'for-of' ||
154406
- terminal.kind === 'for-in'
154407
- ) {
154408
- let init = fn.body.blocks.get(terminal.init);
154409
- pushPhis(init);
154410
- let initContinuation =
154411
- terminal.kind === 'for' ? terminal.test : terminal.loop;
154412
- const queue = [init.id];
154413
- while (queue.length !== 0) {
154414
- const blockId = queue.shift();
154415
- if (blockId === initContinuation) {
154416
- break;
154417
- }
154418
- const block = fn.body.blocks.get(blockId);
154419
- for (const instr of block.instructions) {
154420
- if (
154421
- instr.value.kind === 'StoreLocal' &&
154422
- instr.value.lvalue.kind !== InstructionKind.Reassign
154423
- ) {
154424
- const value = instr.value;
154425
- if (value.lvalue.place.identifier.name !== null) {
154426
- const originalLVal = declarations.get(
154427
- value.lvalue.place.identifier.name.value
154428
- );
154429
- if (originalLVal === undefined) {
154430
- declarations.set(value.lvalue.place.identifier.name.value, {
154431
- lvalue: value.lvalue,
154432
- place: value.lvalue.place,
154433
- });
154434
- value.lvalue.kind = InstructionKind.Const;
154435
- }
154436
- }
154437
- }
154438
- }
154439
- switch (block.terminal.kind) {
154440
- case 'maybe-throw': {
154441
- queue.push(block.terminal.continuation);
154442
- break;
154443
- }
154444
- case 'goto': {
154445
- queue.push(block.terminal.block);
154446
- break;
154447
- }
154448
- case 'branch':
154449
- case 'logical':
154450
- case 'optional':
154451
- case 'ternary':
154452
- case 'label': {
154453
- for (const successor of eachTerminalSuccessor(block.terminal)) {
154454
- queue.push(successor);
154455
- }
154456
- break;
154457
- }
154458
- }
154459
- }
154460
- if (terminal.kind === 'for' && terminal.update !== null) {
154461
- const update = fn.body.blocks.get(terminal.update);
154462
- pushPhis(update);
154463
- }
154464
- }
154465
- for (const {phi: phi, block: phiBlock} of reassignmentPhis) {
154466
- for (const [, operand] of phi.operands) {
154467
- if (operand.mutableRange.start < terminal.id);
154468
- }
154469
- const isPhiMutatedAfterCreation =
154470
- phi.id.mutableRange.end >
154471
- ((_b =
154472
- (_a = phiBlock.instructions.at(0)) === null || _a === void 0
154473
- ? void 0
154474
- : _a.id) !== null && _b !== void 0
154475
- ? _b
154476
- : phiBlock.terminal.id);
154477
- CompilerError.invariant(phi.id.name != null, {
154478
- reason: 'Expected reassignment phis to have a name',
154479
- description: null,
154480
- loc: null,
154481
- suggestions: null,
154482
- });
154483
- const declaration = declarations.get(phi.id.name.value);
154484
- CompilerError.invariant(declaration != null, {
154485
- loc: null,
154486
- reason: 'Expected a declaration for all variables',
154487
- description: `${printIdentifier(phi.id)} in block bb${phiBlock.id}`,
154488
- suggestions: null,
154489
- });
154490
- if (isPhiMutatedAfterCreation) {
154491
- declaration.place.identifier.mutableRange.end = phi.id.mutableRange.end;
154492
- }
154493
- rewrites.set(phi.id, declaration.place.identifier);
154494
- }
154495
- for (const {phi: phi} of rewritePhis) {
154496
- let canonicalId = rewrites.get(phi.id);
154497
- if (canonicalId === undefined) {
154498
- canonicalId = phi.id;
154499
- for (const [, operand] of phi.operands) {
154500
- let canonicalOperand =
154501
- (_c = rewrites.get(operand)) !== null && _c !== void 0
154502
- ? _c
154503
- : operand;
154504
- if (canonicalOperand.id < canonicalId.id) {
154505
- canonicalId = canonicalOperand;
154506
- }
154507
- }
154508
- rewrites.set(phi.id, canonicalId);
154509
- if (canonicalId.name !== null) {
154510
- const declaration = declarations.get(canonicalId.name.value);
154511
- if (declaration !== undefined) {
154512
- declaration.lvalue.kind = InstructionKind.Let;
154513
- }
154514
- }
154515
- }
154516
- for (const [, operand] of phi.operands) {
154517
- rewrites.set(operand, canonicalId);
154518
- }
154519
- }
154520
- }
154521
- }
154522
- function rewritePlace(place, rewrites, declarations) {
154523
- const prevIdentifier = place.identifier;
154524
- const nextIdentifier = rewrites.get(prevIdentifier);
154525
- if (nextIdentifier !== undefined) {
154526
- if (nextIdentifier === prevIdentifier) return;
154527
- place.identifier = nextIdentifier;
154528
- } else if (prevIdentifier.name != null) {
154529
- const declaration = declarations.get(prevIdentifier.name.value);
154530
- if (declaration === undefined) return;
154531
- const originalIdentifier = declaration.place.identifier;
154532
- prevIdentifier.id = originalIdentifier.id;
154533
- }
154534
- }
154535
- function constantPropagation(fn) {
154536
- const constants = new Map();
154537
- constantPropagationImpl(fn, constants);
154538
- }
154539
- function constantPropagationImpl(fn, constants) {
154540
- while (true) {
154541
- const haveTerminalsChanged = applyConstantPropagation(fn, constants);
154542
- if (!haveTerminalsChanged) {
154543
- break;
154544
- }
154545
- reversePostorderBlocks(fn.body);
154546
- removeUnreachableForUpdates(fn.body);
154547
- removeDeadDoWhileStatements(fn.body);
154548
- removeUnnecessaryTryCatch(fn.body);
154549
- markInstructionIds(fn.body);
154550
- markPredecessors(fn.body);
154551
- for (const [, block] of fn.body.blocks) {
154552
- for (const phi of block.phis) {
154553
- for (const [predecessor] of phi.operands) {
154554
- if (!block.preds.has(predecessor)) {
154555
- phi.operands.delete(predecessor);
154556
- }
154430
+ reversePostorderBlocks(fn.body);
154431
+ removeUnreachableForUpdates(fn.body);
154432
+ removeDeadDoWhileStatements(fn.body);
154433
+ removeUnnecessaryTryCatch(fn.body);
154434
+ markInstructionIds(fn.body);
154435
+ markPredecessors(fn.body);
154436
+ for (const [, block] of fn.body.blocks) {
154437
+ for (const phi of block.phis) {
154438
+ for (const [predecessor] of phi.operands) {
154439
+ if (!block.preds.has(predecessor)) {
154440
+ phi.operands.delete(predecessor);
154441
+ }
154557
154442
  }
154558
154443
  }
154559
154444
  }
@@ -156825,12 +156710,7 @@ function visit$1(fn, fbtMacroTags, fbtValues) {
156825
156710
  }
156826
156711
  for (const operand of eachReactiveValueOperand(value)) {
156827
156712
  operand.identifier.scope = fbtScope;
156828
- fbtScope.range.start = makeInstructionId(
156829
- Math.min(
156830
- fbtScope.range.start,
156831
- operand.identifier.mutableRange.start
156832
- )
156833
- );
156713
+ expandFbtScopeRange(fbtScope.range, operand.identifier.mutableRange);
156834
156714
  fbtValues.add(operand.identifier.id);
156835
156715
  }
156836
156716
  } else if (
@@ -156843,12 +156723,7 @@ function visit$1(fn, fbtMacroTags, fbtValues) {
156843
156723
  }
156844
156724
  for (const operand of eachReactiveValueOperand(value)) {
156845
156725
  operand.identifier.scope = fbtScope;
156846
- fbtScope.range.start = makeInstructionId(
156847
- Math.min(
156848
- fbtScope.range.start,
156849
- operand.identifier.mutableRange.start
156850
- )
156851
- );
156726
+ expandFbtScopeRange(fbtScope.range, operand.identifier.mutableRange);
156852
156727
  fbtValues.add(operand.identifier.id);
156853
156728
  }
156854
156729
  } else if (fbtValues.has(lvalue.identifier.id)) {
@@ -156864,12 +156739,7 @@ function visit$1(fn, fbtMacroTags, fbtValues) {
156864
156739
  continue;
156865
156740
  }
156866
156741
  operand.identifier.scope = fbtScope;
156867
- fbtScope.range.start = makeInstructionId(
156868
- Math.min(
156869
- fbtScope.range.start,
156870
- operand.identifier.mutableRange.start
156871
- )
156872
- );
156742
+ expandFbtScopeRange(fbtScope.range, operand.identifier.mutableRange);
156873
156743
  }
156874
156744
  }
156875
156745
  }
@@ -156895,6 +156765,13 @@ function isFbtJsxChild(fbtValues, lvalue, value) {
156895
156765
  fbtValues.has(lvalue.identifier.id)
156896
156766
  );
156897
156767
  }
156768
+ function expandFbtScopeRange(fbtRange, extendWith) {
156769
+ if (extendWith.start !== 0) {
156770
+ fbtRange.start = makeInstructionId(
156771
+ Math.min(fbtRange.start, extendWith.start)
156772
+ );
156773
+ }
156774
+ }
156898
156775
  var _Context_nextCacheIndex, _Context_declarations$1;
156899
156776
  const MEMO_CACHE_SENTINEL = 'react.memo_cache_sentinel';
156900
156777
  const EARLY_RETURN_SENTINEL = 'react.early_return_sentinel';
@@ -157064,7 +156941,7 @@ function codegenFunction(
157064
156941
  } of cx.env.getOutlinedFunctions()) {
157065
156942
  const reactiveFunction = buildReactiveFunction(outlinedFunction);
157066
156943
  pruneUnusedLabels(reactiveFunction);
157067
- pruneTemporaryLValues(reactiveFunction);
156944
+ pruneUnusedLValues(reactiveFunction);
157068
156945
  pruneHoistedContexts(reactiveFunction);
157069
156946
  const identifiers = renameVariables(reactiveFunction);
157070
156947
  const codegen = codegenReactiveFunction(
@@ -157089,9 +156966,9 @@ function codegenFunction(
157089
156966
  function codegenReactiveFunction(cx, fn) {
157090
156967
  for (const param of fn.params) {
157091
156968
  if (param.kind === 'Identifier') {
157092
- cx.temp.set(param.identifier.id, null);
156969
+ cx.temp.set(param.identifier.declarationId, null);
157093
156970
  } else {
157094
- cx.temp.set(param.place.identifier.id, null);
156971
+ cx.temp.set(param.place.identifier.declarationId, null);
157095
156972
  }
157096
156973
  }
157097
156974
  const params = fn.params.map(param => convertParameter(param));
@@ -157183,12 +157060,12 @@ let Context$2 = class Context {
157183
157060
  }
157184
157061
  declare(identifier) {
157185
157062
  __classPrivateFieldGet(this, _Context_declarations$1, 'f').add(
157186
- identifier.id
157063
+ identifier.declarationId
157187
157064
  );
157188
157065
  }
157189
157066
  hasDeclared(identifier) {
157190
157067
  return __classPrivateFieldGet(this, _Context_declarations$1, 'f').has(
157191
- identifier.id
157068
+ identifier.declarationId
157192
157069
  );
157193
157070
  }
157194
157071
  synthesizeName(name) {
@@ -157884,7 +157761,7 @@ function codegenTerminal(cx, terminal) {
157884
157761
  let catchParam = null;
157885
157762
  if (terminal.handlerBinding !== null) {
157886
157763
  catchParam = convertIdentifier(terminal.handlerBinding.identifier);
157887
- cx.temp.set(terminal.handlerBinding.identifier.id, null);
157764
+ cx.temp.set(terminal.handlerBinding.identifier.declarationId, null);
157888
157765
  }
157889
157766
  return t__namespace.tryStatement(
157890
157767
  codegenBlock(cx, terminal.block),
@@ -157938,7 +157815,7 @@ function codegenInstructionNullable(cx, instr) {
157938
157815
  kind !== InstructionKind.Reassign &&
157939
157816
  place.identifier.name === null
157940
157817
  ) {
157941
- cx.temp.set(place.identifier.id, null);
157818
+ cx.temp.set(place.identifier.declarationId, null);
157942
157819
  }
157943
157820
  const isDeclared = cx.hasDeclared(place.identifier);
157944
157821
  hasReasign || (hasReasign = isDeclared);
@@ -157994,7 +157871,7 @@ function codegenInstructionNullable(cx, instr) {
157994
157871
  );
157995
157872
  if (instr.lvalue !== null) {
157996
157873
  if (instr.value.kind !== 'StoreContext') {
157997
- cx.temp.set(instr.lvalue.identifier.id, expr);
157874
+ cx.temp.set(instr.lvalue.identifier.declarationId, expr);
157998
157875
  return null;
157999
157876
  } else {
158000
157877
  const statement = codegenInstruction(cx, instr, expr);
@@ -158219,7 +158096,7 @@ function codegenInstruction(cx, instr, value) {
158219
158096
  return t__namespace.expressionStatement(convertValueToExpression(value));
158220
158097
  }
158221
158098
  if (instr.lvalue.identifier.name === null) {
158222
- cx.temp.set(instr.lvalue.identifier.id, value);
158099
+ cx.temp.set(instr.lvalue.identifier.declarationId, value);
158223
158100
  return t__namespace.emptyStatement();
158224
158101
  } else {
158225
158102
  const expressionValue = convertValueToExpression(value);
@@ -158449,7 +158326,7 @@ function codegenInstructionValue(cx, instrValue) {
158449
158326
  const loweredFunc = method.loweredFunc;
158450
158327
  const reactiveFunction = buildReactiveFunction(loweredFunc.func);
158451
158328
  pruneUnusedLabels(reactiveFunction);
158452
- pruneTemporaryLValues(reactiveFunction);
158329
+ pruneUnusedLValues(reactiveFunction);
158453
158330
  const fn = codegenReactiveFunction(
158454
158331
  new Context$2(
158455
158332
  cx.env,
@@ -158647,7 +158524,7 @@ function codegenInstructionValue(cx, instrValue) {
158647
158524
  const loweredFunc = instrValue.loweredFunc.func;
158648
158525
  const reactiveFunction = buildReactiveFunction(loweredFunc);
158649
158526
  pruneUnusedLabels(reactiveFunction);
158650
- pruneTemporaryLValues(reactiveFunction);
158527
+ pruneUnusedLValues(reactiveFunction);
158651
158528
  pruneHoistedContexts(reactiveFunction);
158652
158529
  const fn = codegenReactiveFunction(
158653
158530
  new Context$2(
@@ -158661,7 +158538,7 @@ function codegenInstructionValue(cx, instrValue) {
158661
158538
  ),
158662
158539
  reactiveFunction
158663
158540
  ).unwrap();
158664
- if (instrValue.expr.type === 'ArrowFunctionExpression') {
158541
+ if (instrValue.type === 'ArrowFunctionExpression') {
158665
158542
  let body = fn.body;
158666
158543
  if (body.body.length === 1 && loweredFunc.directives.length == 0) {
158667
158544
  const stmt = body.body[0];
@@ -159093,7 +158970,7 @@ function codegenPlaceToExpression(cx, place) {
159093
158970
  return convertValueToExpression(value);
159094
158971
  }
159095
158972
  function codegenPlace(cx, place) {
159096
- let tmp = cx.temp.get(place.identifier.id);
158973
+ let tmp = cx.temp.get(place.identifier.declarationId);
159097
158974
  if (tmp != null) {
159098
158975
  return tmp;
159099
158976
  }
@@ -159132,7 +159009,7 @@ let State$1 = class State {
159132
159009
  let Visitor$b = class Visitor extends ReactiveFunctionTransform {
159133
159010
  visitScope(scope, state) {
159134
159011
  for (const [, declaration] of scope.scope.declarations) {
159135
- state.declared.add(declaration.identifier.id);
159012
+ state.declared.add(declaration.identifier.declarationId);
159136
159013
  }
159137
159014
  this.traverseScope(scope, state);
159138
159015
  }
@@ -159161,7 +159038,7 @@ function transformDestructuring(state, instr, destructure) {
159161
159038
  let reassigned = new Set();
159162
159039
  let hasDeclaration = false;
159163
159040
  for (const place of eachPatternOperand(destructure.lvalue.pattern)) {
159164
- const isDeclared = state.declared.has(place.identifier.id);
159041
+ const isDeclared = state.declared.has(place.identifier.declarationId);
159165
159042
  if (isDeclared) {
159166
159043
  reassigned.add(place.identifier.id);
159167
159044
  }
@@ -159176,13 +159053,7 @@ function transformDestructuring(state, instr, destructure) {
159176
159053
  if (!reassigned.has(place.identifier.id)) {
159177
159054
  return place;
159178
159055
  }
159179
- const tempId = state.env.nextIdentifierId;
159180
- const temporary = Object.assign(Object.assign({}, place), {
159181
- identifier: Object.assign(Object.assign({}, place.identifier), {
159182
- id: tempId,
159183
- name: null,
159184
- }),
159185
- });
159056
+ const temporary = clonePlaceToTemporary(state.env, place);
159186
159057
  promoteTemporary(temporary.identifier);
159187
159058
  renamed.set(place, temporary);
159188
159059
  return temporary;
@@ -159445,12 +159316,12 @@ class FindLastUsageVisitor extends ReactiveFunctionVisitor {
159445
159316
  this.lastUsage = new Map();
159446
159317
  }
159447
159318
  visitPlace(id, place, _state) {
159448
- const previousUsage = this.lastUsage.get(place.identifier.id);
159319
+ const previousUsage = this.lastUsage.get(place.identifier.declarationId);
159449
159320
  const lastUsage =
159450
159321
  previousUsage !== undefined
159451
159322
  ? makeInstructionId(Math.max(previousUsage, id))
159452
159323
  : id;
159453
- this.lastUsage.set(place.identifier.id, lastUsage);
159324
+ this.lastUsage.set(place.identifier.declarationId, lastUsage);
159454
159325
  }
159455
159326
  }
159456
159327
  let Transform$4 = class Transform extends ReactiveFunctionTransform {
@@ -159519,7 +159390,9 @@ let Transform$4 = class Transform extends ReactiveFunctionTransform {
159519
159390
  case 'TemplateLiteral':
159520
159391
  case 'UnaryExpression': {
159521
159392
  if (current !== null && instr.instruction.lvalue !== null) {
159522
- current.lvalues.add(instr.instruction.lvalue.identifier.id);
159393
+ current.lvalues.add(
159394
+ instr.instruction.lvalue.identifier.declarationId
159395
+ );
159523
159396
  }
159524
159397
  break;
159525
159398
  }
@@ -159531,7 +159404,7 @@ let Transform$4 = class Transform extends ReactiveFunctionTransform {
159531
159404
  for (const lvalue of eachInstructionLValue(
159532
159405
  instr.instruction
159533
159406
  )) {
159534
- current.lvalues.add(lvalue.identifier.id);
159407
+ current.lvalues.add(lvalue.identifier.declarationId);
159535
159408
  }
159536
159409
  } else {
159537
159410
  log$1(
@@ -159656,10 +159529,10 @@ let Transform$4 = class Transform extends ReactiveFunctionTransform {
159656
159529
  }
159657
159530
  };
159658
159531
  function updateScopeDeclarations(scope, lastUsage) {
159659
- for (const [key] of scope.declarations) {
159660
- const lastUsedAt = lastUsage.get(key);
159532
+ for (const [id, decl] of scope.declarations) {
159533
+ const lastUsedAt = lastUsage.get(decl.identifier.declarationId);
159661
159534
  if (lastUsedAt < scope.range.end) {
159662
- scope.declarations.delete(key);
159535
+ scope.declarations.delete(id);
159663
159536
  }
159664
159537
  }
159665
159538
  }
@@ -159698,8 +159571,12 @@ function canMergeScopes(current, next) {
159698
159571
  (next.scope.dependencies.size !== 0 &&
159699
159572
  [...next.scope.dependencies].every(
159700
159573
  dep =>
159701
- current.scope.declarations.has(dep.identifier.id) &&
159702
- isAlwaysInvalidatingType(dep.identifier.type)
159574
+ isAlwaysInvalidatingType(dep.identifier.type) &&
159575
+ Iterable_some(
159576
+ current.scope.declarations.values(),
159577
+ decl =>
159578
+ decl.identifier.declarationId === dep.identifier.declarationId
159579
+ )
159703
159580
  ))
159704
159581
  ) {
159705
159582
  return true;
@@ -159729,7 +159606,7 @@ function areEqualDependencies(a, b) {
159729
159606
  let found = false;
159730
159607
  for (const bValue of b) {
159731
159608
  if (
159732
- aValue.identifier === bValue.identifier &&
159609
+ aValue.identifier.declarationId === bValue.identifier.declarationId &&
159733
159610
  areEqualPaths(aValue.path, bValue.path)
159734
159611
  ) {
159735
159612
  found = true;
@@ -159755,7 +159632,6 @@ function scopeIsEligibleForMerging(scopeBlock) {
159755
159632
  }
159756
159633
  let Visitor$9 = class Visitor extends ReactiveFunctionVisitor {
159757
159634
  visitScope(scopeBlock, state) {
159758
- this.traverseScope(scopeBlock, state);
159759
159635
  for (const dep of scopeBlock.scope.dependencies) {
159760
159636
  const {identifier: identifier} = dep;
159761
159637
  if (identifier.name == null) {
@@ -159767,21 +159643,22 @@ let Visitor$9 = class Visitor extends ReactiveFunctionVisitor {
159767
159643
  promoteIdentifier(declaration.identifier, state);
159768
159644
  }
159769
159645
  }
159646
+ this.traverseScope(scopeBlock, state);
159770
159647
  }
159771
159648
  visitPrunedScope(scopeBlock, state) {
159772
159649
  var _a;
159773
- this.traversePrunedScope(scopeBlock, state);
159774
159650
  for (const [, declaration] of scopeBlock.scope.declarations) {
159775
159651
  if (
159776
159652
  declaration.identifier.name == null &&
159777
- ((_a = state.pruned.get(declaration.identifier.id)) === null ||
159778
- _a === void 0
159653
+ ((_a = state.pruned.get(declaration.identifier.declarationId)) ===
159654
+ null || _a === void 0
159779
159655
  ? void 0
159780
159656
  : _a.usedOutsideScope) === true
159781
159657
  ) {
159782
159658
  promoteIdentifier(declaration.identifier, state);
159783
159659
  }
159784
159660
  }
159661
+ this.traversePrunedScope(scopeBlock, state);
159785
159662
  }
159786
159663
  visitParam(place, state) {
159787
159664
  if (place.identifier.name === null) {
@@ -159804,6 +159681,56 @@ let Visitor$9 = class Visitor extends ReactiveFunctionVisitor {
159804
159681
  visitReactiveFunction(fn, this, state);
159805
159682
  }
159806
159683
  };
159684
+ class Visitor2 extends ReactiveFunctionVisitor {
159685
+ visitPlace(_id, place, state) {
159686
+ if (
159687
+ place.identifier.name === null &&
159688
+ state.promoted.has(place.identifier.declarationId)
159689
+ ) {
159690
+ promoteIdentifier(place.identifier, state);
159691
+ }
159692
+ }
159693
+ visitLValue(_id, _lvalue, _state) {
159694
+ this.visitPlace(_id, _lvalue, _state);
159695
+ }
159696
+ traverseScopeIdentifiers(scope, state) {
159697
+ for (const [, decl] of scope.declarations) {
159698
+ if (
159699
+ decl.identifier.name === null &&
159700
+ state.promoted.has(decl.identifier.declarationId)
159701
+ ) {
159702
+ promoteIdentifier(decl.identifier, state);
159703
+ }
159704
+ }
159705
+ for (const dep of scope.dependencies) {
159706
+ if (
159707
+ dep.identifier.name === null &&
159708
+ state.promoted.has(dep.identifier.declarationId)
159709
+ ) {
159710
+ promoteIdentifier(dep.identifier, state);
159711
+ }
159712
+ }
159713
+ for (const reassignment of scope.reassignments) {
159714
+ if (
159715
+ reassignment.name === null &&
159716
+ state.promoted.has(reassignment.declarationId)
159717
+ ) {
159718
+ promoteIdentifier(reassignment, state);
159719
+ }
159720
+ }
159721
+ }
159722
+ visitScope(scope, state) {
159723
+ this.traverseScope(scope, state);
159724
+ this.traverseScopeIdentifiers(scope.scope, state);
159725
+ }
159726
+ visitPrunedScope(scopeBlock, state) {
159727
+ this.traversePrunedScope(scopeBlock, state);
159728
+ this.traverseScopeIdentifiers(scopeBlock.scope, state);
159729
+ }
159730
+ visitReactiveFunctionValue(_id, _dependencies, fn, state) {
159731
+ visitReactiveFunction(fn, this, state);
159732
+ }
159733
+ }
159807
159734
  class CollectPromotableTemporaries extends ReactiveFunctionVisitor {
159808
159735
  constructor() {
159809
159736
  super(...arguments);
@@ -159812,9 +159739,9 @@ class CollectPromotableTemporaries extends ReactiveFunctionVisitor {
159812
159739
  visitPlace(_id, place, state) {
159813
159740
  if (
159814
159741
  this.activeScopes.length !== 0 &&
159815
- state.pruned.has(place.identifier.id)
159742
+ state.pruned.has(place.identifier.declarationId)
159816
159743
  ) {
159817
- const prunedPlace = state.pruned.get(place.identifier.id);
159744
+ const prunedPlace = state.pruned.get(place.identifier.declarationId);
159818
159745
  if (prunedPlace.activeScopes.indexOf(this.activeScopes.at(-1)) === -1) {
159819
159746
  prunedPlace.usedOutsideScope = true;
159820
159747
  }
@@ -159823,16 +159750,17 @@ class CollectPromotableTemporaries extends ReactiveFunctionVisitor {
159823
159750
  visitValue(id, value, state) {
159824
159751
  this.traverseValue(id, value, state);
159825
159752
  if (value.kind === 'JsxExpression' && value.tag.kind === 'Identifier') {
159826
- state.tags.add(value.tag.identifier.id);
159753
+ state.tags.add(value.tag.identifier.declarationId);
159827
159754
  }
159828
159755
  }
159829
159756
  visitPrunedScope(scopeBlock, state) {
159830
- for (const [id] of scopeBlock.scope.declarations) {
159831
- state.pruned.set(id, {
159757
+ for (const [_id, decl] of scopeBlock.scope.declarations) {
159758
+ state.pruned.set(decl.identifier.declarationId, {
159832
159759
  activeScopes: [...this.activeScopes],
159833
159760
  usedOutsideScope: false,
159834
159761
  });
159835
159762
  }
159763
+ this.visitBlock(scopeBlock.instructions, state);
159836
159764
  }
159837
159765
  visitScope(scopeBlock, state) {
159838
159766
  this.activeScopes.push(scopeBlock.scope.id);
@@ -159841,7 +159769,7 @@ class CollectPromotableTemporaries extends ReactiveFunctionVisitor {
159841
159769
  }
159842
159770
  }
159843
159771
  function promoteUsedTemporaries(fn) {
159844
- const state = {tags: new Set(), pruned: new Map()};
159772
+ const state = {tags: new Set(), promoted: new Set(), pruned: new Map()};
159845
159773
  visitReactiveFunction(fn, new CollectPromotableTemporaries(), state);
159846
159774
  for (const operand of fn.params) {
159847
159775
  const place = operand.kind === 'Identifier' ? operand : operand.place;
@@ -159850,6 +159778,7 @@ function promoteUsedTemporaries(fn) {
159850
159778
  }
159851
159779
  }
159852
159780
  visitReactiveFunction(fn, new Visitor$9(), state);
159781
+ visitReactiveFunction(fn, new Visitor2(), state);
159853
159782
  }
159854
159783
  function promoteIdentifier(identifier, state) {
159855
159784
  CompilerError.invariant(identifier.name === null, {
@@ -159859,11 +159788,12 @@ function promoteIdentifier(identifier, state) {
159859
159788
  loc: GeneratedSource,
159860
159789
  suggestions: null,
159861
159790
  });
159862
- if (state.tags.has(identifier.id)) {
159791
+ if (state.tags.has(identifier.declarationId)) {
159863
159792
  promoteTemporaryJsxTag(identifier);
159864
159793
  } else {
159865
159794
  promoteTemporary(identifier);
159866
159795
  }
159796
+ state.promoted.add(identifier.declarationId);
159867
159797
  }
159868
159798
  function propagateEarlyReturns(fn) {
159869
159799
  visitReactiveFunction(fn, new Transform$3(fn.env), {
@@ -160542,18 +160472,23 @@ class FindPromotedTemporaries extends ReactiveFunctionVisitor {
160542
160472
  case 'LoadLocal':
160543
160473
  case 'LoadContext':
160544
160474
  case 'PropertyLoad': {
160545
- state.declarations.set(instruction.lvalue.identifier.id, scope);
160475
+ state.declarations.set(
160476
+ instruction.lvalue.identifier.declarationId,
160477
+ scope
160478
+ );
160546
160479
  break;
160547
160480
  }
160548
160481
  }
160549
160482
  }
160550
160483
  visitPlace(_id, place, state) {
160551
- const declaringScope = state.declarations.get(place.identifier.id);
160484
+ const declaringScope = state.declarations.get(
160485
+ place.identifier.declarationId
160486
+ );
160552
160487
  if (declaringScope === undefined) {
160553
160488
  return;
160554
160489
  }
160555
160490
  if (this.scopes.indexOf(declaringScope) === -1) {
160556
- state.usedOutsideDeclaringScope.add(place.identifier.id);
160491
+ state.usedOutsideDeclaringScope.add(place.identifier.declarationId);
160557
160492
  }
160558
160493
  }
160559
160494
  }
@@ -160797,7 +160732,7 @@ class Context {
160797
160732
  this,
160798
160733
  _Context_temporariesUsedOutsideScope,
160799
160734
  'f'
160800
- ).has(place.identifier.id);
160735
+ ).has(place.identifier.declarationId);
160801
160736
  }
160802
160737
  printDeps(includeAccesses = false) {
160803
160738
  return __classPrivateFieldGet(this, _Context_dependencies, 'f').printDeps(
@@ -160857,11 +160792,11 @@ class Context {
160857
160792
  declare(identifier, decl) {
160858
160793
  if (
160859
160794
  !__classPrivateFieldGet(this, _Context_declarations, 'f').has(
160860
- identifier.id
160795
+ identifier.declarationId
160861
160796
  )
160862
160797
  ) {
160863
160798
  __classPrivateFieldGet(this, _Context_declarations, 'f').set(
160864
- identifier.id,
160799
+ identifier.declarationId,
160865
160800
  decl
160866
160801
  );
160867
160802
  }
@@ -160935,7 +160870,7 @@ class Context {
160935
160870
  this,
160936
160871
  _Context_declarations,
160937
160872
  'f'
160938
- ).get(maybeDependency.identifier.id);
160873
+ ).get(maybeDependency.identifier.declarationId);
160939
160874
  if (
160940
160875
  originalDeclaration !== undefined &&
160941
160876
  originalDeclaration.scope.value !== null
@@ -160947,7 +160882,13 @@ class Context {
160947
160882
  _Context_instances,
160948
160883
  'm',
160949
160884
  _Context_isScopeActive
160950
- ).call(this, scope.value)
160885
+ ).call(this, scope.value) &&
160886
+ !Iterable_some(
160887
+ scope.value.declarations.values(),
160888
+ decl =>
160889
+ decl.identifier.declarationId ===
160890
+ maybeDependency.identifier.declarationId
160891
+ )
160951
160892
  ) {
160952
160893
  scope.value.declarations.set(maybeDependency.identifier.id, {
160953
160894
  identifier: maybeDependency.identifier,
@@ -160984,8 +160925,10 @@ class Context {
160984
160925
  : _a.value;
160985
160926
  if (
160986
160927
  currentScope != null &&
160987
- !Array.from(currentScope.reassignments).some(
160988
- identifier => identifier.id === place.identifier.id
160928
+ !Iterable_some(
160929
+ currentScope.reassignments,
160930
+ identifier =>
160931
+ identifier.declarationId === place.identifier.declarationId
160989
160932
  ) &&
160990
160933
  __classPrivateFieldGet(
160991
160934
  this,
@@ -161091,7 +161034,7 @@ class Context {
161091
161034
  )) !== null && _a !== void 0
161092
161035
  ? _a
161093
161036
  : __classPrivateFieldGet(this, _Context_declarations, 'f').get(
161094
- identifier.id
161037
+ identifier.declarationId
161095
161038
  );
161096
161039
  const currentScope =
161097
161040
  (_b = this.currentScope.value) === null || _b === void 0
@@ -161126,7 +161069,19 @@ class PropagationVisitor extends ReactiveFunctionVisitor {
161126
161069
  const scopeDependencies = context.enter(scope.scope, () => {
161127
161070
  this.visitBlock(scope.instructions, context);
161128
161071
  });
161129
- scope.scope.dependencies = scopeDependencies;
161072
+ for (const candidateDep of scopeDependencies) {
161073
+ if (
161074
+ !Iterable_some(
161075
+ scope.scope.dependencies,
161076
+ existingDep =>
161077
+ existingDep.identifier.declarationId ===
161078
+ candidateDep.identifier.declarationId &&
161079
+ areEqualPaths(existingDep.path, candidateDep.path)
161080
+ )
161081
+ ) {
161082
+ scope.scope.dependencies.add(candidateDep);
161083
+ }
161084
+ }
161130
161085
  }
161131
161086
  visitPrunedScope(scopeBlock, context) {
161132
161087
  context.enter(scopeBlock.scope, () => {
@@ -161438,12 +161393,12 @@ let Visitor$8 = class Visitor extends ReactiveFunctionTransform {
161438
161393
  instruction.value.kind === 'DeclareContext' &&
161439
161394
  instruction.value.lvalue.kind === 'HoistedConst'
161440
161395
  ) {
161441
- state.add(instruction.value.lvalue.place.identifier);
161396
+ state.add(instruction.value.lvalue.place.identifier.declarationId);
161442
161397
  return {kind: 'remove'};
161443
161398
  }
161444
161399
  if (
161445
161400
  instruction.value.kind === 'StoreContext' &&
161446
- state.has(instruction.value.lvalue.place.identifier)
161401
+ state.has(instruction.value.lvalue.place.identifier.declarationId)
161447
161402
  ) {
161448
161403
  return {
161449
161404
  kind: 'replace',
@@ -161465,69 +161420,6 @@ let Visitor$8 = class Visitor extends ReactiveFunctionTransform {
161465
161420
  return {kind: 'keep'};
161466
161421
  }
161467
161422
  };
161468
- function validateMemoizedEffectDependencies(fn) {
161469
- const errors = new CompilerError();
161470
- visitReactiveFunction(fn, new Visitor$7(), errors);
161471
- if (errors.hasErrors()) {
161472
- throw errors;
161473
- }
161474
- }
161475
- let Visitor$7 = class Visitor extends ReactiveFunctionVisitor {
161476
- constructor() {
161477
- super(...arguments);
161478
- this.scopes = new Set();
161479
- }
161480
- visitScope(scopeBlock, state) {
161481
- this.traverseScope(scopeBlock, state);
161482
- let areDependenciesMemoized = true;
161483
- for (const dep of scopeBlock.scope.dependencies) {
161484
- if (isUnmemoized$1(dep.identifier, this.scopes)) {
161485
- areDependenciesMemoized = false;
161486
- break;
161487
- }
161488
- }
161489
- if (areDependenciesMemoized) {
161490
- this.scopes.add(scopeBlock.scope.id);
161491
- for (const id of scopeBlock.scope.merged) {
161492
- this.scopes.add(id);
161493
- }
161494
- }
161495
- }
161496
- visitInstruction(instruction, state) {
161497
- this.traverseInstruction(instruction, state);
161498
- if (
161499
- instruction.value.kind === 'CallExpression' &&
161500
- isEffectHook(instruction.value.callee.identifier) &&
161501
- instruction.value.args.length >= 2
161502
- ) {
161503
- const deps = instruction.value.args[1];
161504
- if (
161505
- deps.kind === 'Identifier' &&
161506
- (isMutable(instruction, deps) ||
161507
- isUnmemoized$1(deps.identifier, this.scopes))
161508
- ) {
161509
- state.push({
161510
- reason:
161511
- 'React Compiler has skipped optimizing this component because the effect dependencies could not be memoized. Unmemoized effect dependencies can trigger an infinite loop or other unexpected behavior',
161512
- description: null,
161513
- severity: exports.ErrorSeverity.CannotPreserveMemoization,
161514
- loc: typeof instruction.loc !== 'symbol' ? instruction.loc : null,
161515
- suggestions: null,
161516
- });
161517
- }
161518
- }
161519
- }
161520
- };
161521
- function isUnmemoized$1(operand, scopes) {
161522
- return operand.scope != null && !scopes.has(operand.scope.id);
161523
- }
161524
- function isEffectHook(identifier) {
161525
- return (
161526
- isUseEffectHookType(identifier) ||
161527
- isUseLayoutEffectHookType(identifier) ||
161528
- isUseInsertionEffectHookType(identifier)
161529
- );
161530
- }
161531
161423
  var _InferenceState_env, _InferenceState_values, _InferenceState_variables;
161532
161424
  const UndefinedValue = {
161533
161425
  kind: 'Primitive',
@@ -162434,7 +162326,7 @@ function inferBlock(env, functionEffects, state, block) {
162434
162326
  );
162435
162327
  functionEffects.push(
162436
162328
  ...propEffects.filter(
162437
- propEffect => propEffect.kind !== 'GlobalMutation'
162329
+ effect => !isEffectSafeOutsideRender(effect)
162438
162330
  )
162439
162331
  );
162440
162332
  }
@@ -162584,7 +162476,7 @@ function inferBlock(env, functionEffects, state, block) {
162584
162476
  context: new Set(),
162585
162477
  };
162586
162478
  let hasCaptureArgument = false;
162587
- let isUseEffect = isEffectHook(instrValue.callee.identifier);
162479
+ let isHook = getHookKind(env, instrValue.callee.identifier) != null;
162588
162480
  for (let i = 0; i < instrValue.args.length; i++) {
162589
162481
  const argumentEffects = [];
162590
162482
  const arg = instrValue.args[i];
@@ -162606,8 +162498,7 @@ function inferBlock(env, functionEffects, state, block) {
162606
162498
  }
162607
162499
  functionEffects.push(
162608
162500
  ...argumentEffects.filter(
162609
- argEffect =>
162610
- !isUseEffect || i !== 0 || argEffect.kind !== 'GlobalMutation'
162501
+ argEffect => !isHook || !isEffectSafeOutsideRender(argEffect)
162611
162502
  )
162612
162503
  );
162613
162504
  hasCaptureArgument ||
@@ -162699,7 +162590,7 @@ function inferBlock(env, functionEffects, state, block) {
162699
162590
  const effects =
162700
162591
  signature !== null ? getFunctionEffects(instrValue, signature) : null;
162701
162592
  let hasCaptureArgument = false;
162702
- let isUseEffect = isEffectHook(instrValue.property.identifier);
162593
+ let isHook = getHookKind(env, instrValue.property.identifier) != null;
162703
162594
  for (let i = 0; i < instrValue.args.length; i++) {
162704
162595
  const argumentEffects = [];
162705
162596
  const arg = instrValue.args[i];
@@ -162721,8 +162612,7 @@ function inferBlock(env, functionEffects, state, block) {
162721
162612
  }
162722
162613
  functionEffects.push(
162723
162614
  ...argumentEffects.filter(
162724
- argEffect =>
162725
- !isUseEffect || i !== 0 || argEffect.kind !== 'GlobalMutation'
162615
+ argEffect => !isHook || !isEffectSafeOutsideRender(argEffect)
162726
162616
  )
162727
162617
  );
162728
162618
  hasCaptureArgument ||
@@ -163167,11 +163057,15 @@ function inferBlock(env, functionEffects, state, block) {
163167
163057
  } else {
163168
163058
  effect = exports.Effect.Read;
163169
163059
  }
163060
+ const propEffects = [];
163170
163061
  state.referenceAndRecordEffects(
163171
163062
  operand,
163172
163063
  effect,
163173
163064
  ValueReason.Other,
163174
- functionEffects
163065
+ propEffects
163066
+ );
163067
+ functionEffects.push(
163068
+ ...propEffects.filter(effect => !isEffectSafeOutsideRender(effect))
163175
163069
  );
163176
163070
  }
163177
163071
  }
@@ -163240,6 +163134,9 @@ function areArgumentsImmutableAndNonMutating(state, args) {
163240
163134
  }
163241
163135
  return true;
163242
163136
  }
163137
+ function isEffectSafeOutsideRender(effect) {
163138
+ return effect.kind === 'GlobalMutation';
163139
+ }
163243
163140
  function getWriteErrorReason(abstractValue) {
163244
163141
  if (abstractValue.reason.has(ValueReason.Global)) {
163245
163142
  return 'Writing to a variable defined outside a component or hook is not allowed. Consider using an effect';
@@ -163263,9 +163160,9 @@ function pruneNonEscapingScopes(fn) {
163263
163160
  const state = new State(fn.env);
163264
163161
  for (const param of fn.params) {
163265
163162
  if (param.kind === 'Identifier') {
163266
- state.declare(param.identifier.id);
163163
+ state.declare(param.identifier.declarationId);
163267
163164
  } else {
163268
- state.declare(param.place.identifier.id);
163165
+ state.declare(param.place.identifier.declarationId);
163269
163166
  }
163270
163167
  }
163271
163168
  visitReactiveFunction(fn, new CollectDependenciesVisitor(fn.env), state);
@@ -163322,7 +163219,9 @@ class State {
163322
163219
  let node = this.scopes.get(scope.id);
163323
163220
  if (node === undefined) {
163324
163221
  node = {
163325
- dependencies: [...scope.dependencies].map(dep => dep.identifier.id),
163222
+ dependencies: [...scope.dependencies].map(
163223
+ dep => dep.identifier.declarationId
163224
+ ),
163326
163225
  seen: false,
163327
163226
  };
163328
163227
  this.scopes.set(scope.id, node);
@@ -163766,18 +163665,18 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor {
163766
163665
  );
163767
163666
  for (const operand of aliasing.rvalues) {
163768
163667
  const operandId =
163769
- (_a = state.definitions.get(operand.identifier.id)) !== null &&
163770
- _a !== void 0
163668
+ (_a = state.definitions.get(operand.identifier.declarationId)) !==
163669
+ null && _a !== void 0
163771
163670
  ? _a
163772
- : operand.identifier.id;
163671
+ : operand.identifier.declarationId;
163773
163672
  state.visitOperand(instruction.id, operand, operandId);
163774
163673
  }
163775
163674
  for (const {place: lvalue, level: level} of aliasing.lvalues) {
163776
163675
  const lvalueId =
163777
- (_b = state.definitions.get(lvalue.identifier.id)) !== null &&
163778
- _b !== void 0
163676
+ (_b = state.definitions.get(lvalue.identifier.declarationId)) !==
163677
+ null && _b !== void 0
163779
163678
  ? _b
163780
- : lvalue.identifier.id;
163679
+ : lvalue.identifier.declarationId;
163781
163680
  let node = state.identifiers.get(lvalueId);
163782
163681
  if (node === undefined) {
163783
163682
  node = {
@@ -163792,10 +163691,10 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor {
163792
163691
  node.level = joinAliases(node.level, level);
163793
163692
  for (const operand of aliasing.rvalues) {
163794
163693
  const operandId =
163795
- (_c = state.definitions.get(operand.identifier.id)) !== null &&
163796
- _c !== void 0
163694
+ (_c = state.definitions.get(operand.identifier.declarationId)) !==
163695
+ null && _c !== void 0
163797
163696
  ? _c
163798
- : operand.identifier.id;
163697
+ : operand.identifier.declarationId;
163799
163698
  if (operandId === lvalueId) {
163800
163699
  continue;
163801
163700
  }
@@ -163805,8 +163704,8 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor {
163805
163704
  }
163806
163705
  if (instruction.value.kind === 'LoadLocal' && instruction.lvalue !== null) {
163807
163706
  state.definitions.set(
163808
- instruction.lvalue.identifier.id,
163809
- instruction.value.place.identifier.id
163707
+ instruction.lvalue.identifier.declarationId,
163708
+ instruction.value.place.identifier.declarationId
163810
163709
  );
163811
163710
  } else if (
163812
163711
  instruction.value.kind === 'CallExpression' ||
@@ -163826,7 +163725,7 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor {
163826
163725
  }
163827
163726
  for (const operand of instruction.value.args) {
163828
163727
  const place = operand.kind === 'Spread' ? operand.place : operand;
163829
- state.escapingValues.add(place.identifier.id);
163728
+ state.escapingValues.add(place.identifier.declarationId);
163830
163729
  }
163831
163730
  }
163832
163731
  }
@@ -163834,7 +163733,7 @@ class CollectDependenciesVisitor extends ReactiveFunctionVisitor {
163834
163733
  visitTerminal(stmt, state) {
163835
163734
  this.traverseTerminal(stmt, state);
163836
163735
  if (stmt.terminal.kind === 'return') {
163837
- state.escapingValues.add(stmt.terminal.value.identifier.id);
163736
+ state.escapingValues.add(stmt.terminal.value.identifier.declarationId);
163838
163737
  }
163839
163738
  }
163840
163739
  }
@@ -163853,11 +163752,11 @@ class PruneScopesTransform extends ReactiveFunctionTransform {
163853
163752
  return {kind: 'keep'};
163854
163753
  }
163855
163754
  const hasMemoizedOutput =
163856
- Array.from(scopeBlock.scope.declarations.keys()).some(id =>
163857
- state.has(id)
163755
+ Array.from(scopeBlock.scope.declarations.values()).some(decl =>
163756
+ state.has(decl.identifier.declarationId)
163858
163757
  ) ||
163859
163758
  Array.from(scopeBlock.scope.reassignments).some(identifier =>
163860
- state.has(identifier.id)
163759
+ state.has(identifier.declarationId)
163861
163760
  );
163862
163761
  if (hasMemoizedOutput) {
163863
163762
  return {kind: 'keep'};
@@ -163880,7 +163779,7 @@ class PruneScopesTransform extends ReactiveFunctionTransform {
163880
163779
  return {kind: 'keep'};
163881
163780
  }
163882
163781
  }
163883
- let Visitor$6 = class Visitor extends ReactiveFunctionVisitor {
163782
+ let Visitor$7 = class Visitor extends ReactiveFunctionVisitor {
163884
163783
  visitLValue(id, lvalue, state) {
163885
163784
  this.visitPlace(id, lvalue, state);
163886
163785
  }
@@ -163899,16 +163798,16 @@ let Visitor$6 = class Visitor extends ReactiveFunctionVisitor {
163899
163798
  }
163900
163799
  };
163901
163800
  function collectReactiveIdentifiers(fn) {
163902
- const visitor = new Visitor$6();
163801
+ const visitor = new Visitor$7();
163903
163802
  const state = new Set();
163904
163803
  visitReactiveFunction(fn, visitor, state);
163905
163804
  return state;
163906
163805
  }
163907
163806
  function pruneNonReactiveDependencies(fn) {
163908
163807
  const reactiveIdentifiers = collectReactiveIdentifiers(fn);
163909
- visitReactiveFunction(fn, new Visitor$5(), reactiveIdentifiers);
163808
+ visitReactiveFunction(fn, new Visitor$6(), reactiveIdentifiers);
163910
163809
  }
163911
- let Visitor$5 = class Visitor extends ReactiveFunctionVisitor {
163810
+ let Visitor$6 = class Visitor extends ReactiveFunctionVisitor {
163912
163811
  visitInstruction(instruction, state) {
163913
163812
  this.traverseInstruction(instruction, state);
163914
163813
  const {lvalue: lvalue, value: value} = instruction;
@@ -163982,16 +163881,16 @@ let Visitor$5 = class Visitor extends ReactiveFunctionVisitor {
163982
163881
  }
163983
163882
  }
163984
163883
  };
163985
- function pruneTemporaryLValues(fn) {
163884
+ function pruneUnusedLValues(fn) {
163986
163885
  const lvalues = new Map();
163987
- visitReactiveFunction(fn, new Visitor$4(), lvalues);
163886
+ visitReactiveFunction(fn, new Visitor$5(), lvalues);
163988
163887
  for (const [, instr] of lvalues) {
163989
163888
  instr.lvalue = null;
163990
163889
  }
163991
163890
  }
163992
- let Visitor$4 = class Visitor extends ReactiveFunctionVisitor {
163891
+ let Visitor$5 = class Visitor extends ReactiveFunctionVisitor {
163993
163892
  visitPlace(id, place, state) {
163994
- state.delete(place.identifier);
163893
+ state.delete(place.identifier.declarationId);
163995
163894
  }
163996
163895
  visitInstruction(instruction, state) {
163997
163896
  this.traverseInstruction(instruction, state);
@@ -163999,7 +163898,7 @@ let Visitor$4 = class Visitor extends ReactiveFunctionVisitor {
163999
163898
  instruction.lvalue !== null &&
164000
163899
  instruction.lvalue.identifier.name === null
164001
163900
  ) {
164002
- state.set(instruction.lvalue.identifier, instruction);
163901
+ state.set(instruction.lvalue.identifier.declarationId, instruction);
164003
163902
  }
164004
163903
  }
164005
163904
  };
@@ -164080,10 +163979,10 @@ function hasOwnDeclaration(block) {
164080
163979
  }
164081
163980
  function collectReferencedGlobals(fn) {
164082
163981
  const identifiers = new Set();
164083
- visitReactiveFunction(fn, new Visitor$3(), identifiers);
163982
+ visitReactiveFunction(fn, new Visitor$4(), identifiers);
164084
163983
  return identifiers;
164085
163984
  }
164086
- let Visitor$3 = class Visitor extends ReactiveFunctionVisitor {
163985
+ let Visitor$4 = class Visitor extends ReactiveFunctionVisitor {
164087
163986
  visitValue(id, value, state) {
164088
163987
  this.traverseValue(id, value, state);
164089
163988
  if (value.kind === 'FunctionExpression' || value.kind === 'ObjectMethod') {
@@ -164104,7 +164003,7 @@ var _Scopes_instances,
164104
164003
  function renameVariables(fn) {
164105
164004
  const globals = collectReferencedGlobals(fn);
164106
164005
  const scopes = new Scopes(globals);
164107
- renameVariablesImpl(fn, new Visitor$2(), scopes);
164006
+ renameVariablesImpl(fn, new Visitor$3(), scopes);
164108
164007
  return new Set([...scopes.names, ...globals]);
164109
164008
  }
164110
164009
  function renameVariablesImpl(fn, visitor, scopes) {
@@ -164119,7 +164018,7 @@ function renameVariablesImpl(fn, visitor, scopes) {
164119
164018
  visitReactiveFunction(fn, visitor, scopes);
164120
164019
  });
164121
164020
  }
164122
- let Visitor$2 = class Visitor extends ReactiveFunctionVisitor {
164021
+ let Visitor$3 = class Visitor extends ReactiveFunctionVisitor {
164123
164022
  visitParam(place, state) {
164124
164023
  state.visit(place.identifier);
164125
164024
  }
@@ -164168,7 +164067,7 @@ class Scopes {
164168
164067
  return;
164169
164068
  }
164170
164069
  const mappedName = __classPrivateFieldGet(this, _Scopes_seen, 'f').get(
164171
- identifier.id
164070
+ identifier.declarationId
164172
164071
  );
164173
164072
  if (mappedName !== undefined) {
164174
164073
  identifier.name = mappedName;
@@ -164199,12 +164098,12 @@ class Scopes {
164199
164098
  const identifierName = makeIdentifierName(name);
164200
164099
  identifier.name = identifierName;
164201
164100
  __classPrivateFieldGet(this, _Scopes_seen, 'f').set(
164202
- identifier.id,
164101
+ identifier.declarationId,
164203
164102
  identifierName
164204
164103
  );
164205
164104
  __classPrivateFieldGet(this, _Scopes_stack, 'f')
164206
164105
  .at(-1)
164207
- .set(identifierName.value, identifier.id);
164106
+ .set(identifierName.value, identifier.declarationId);
164208
164107
  this.names.add(identifierName.value);
164209
164108
  }
164210
164109
  enter(fn) {
@@ -164682,7 +164581,7 @@ function lower(func) {
164682
164581
  inferReferenceEffects(func, {isFunctionExpression: true});
164683
164582
  deadCodeElimination(func);
164684
164583
  inferMutableRanges(func);
164685
- leaveSSA(func);
164584
+ rewriteInstructionKindsBasedOnReassignment(func);
164686
164585
  inferReactiveScopeVariables(func);
164687
164586
  inferMutableContextVariables(func);
164688
164587
  }
@@ -164926,6 +164825,7 @@ function extractManualMemoizationArgs(instr, kind, sidemap) {
164926
164825
  function dropManualMemoization(func) {
164927
164826
  const isValidationEnabled =
164928
164827
  func.env.config.validatePreserveExistingMemoizationGuarantees ||
164828
+ func.env.config.validateNoSetStateInRender ||
164929
164829
  func.env.config.enablePreserveExistingMemoizationGuarantees;
164930
164830
  const sidemap = {
164931
164831
  functions: new Map(),
@@ -165360,20 +165260,7 @@ function rewriteBlock(env, block, returnTarget, returnValue) {
165360
165260
  block.instructions.push({
165361
165261
  id: makeInstructionId(0),
165362
165262
  loc: terminal.loc,
165363
- lvalue: {
165364
- effect: exports.Effect.Unknown,
165365
- identifier: {
165366
- id: env.nextIdentifierId,
165367
- mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
165368
- name: null,
165369
- scope: null,
165370
- type: makeType(),
165371
- loc: terminal.loc,
165372
- },
165373
- kind: 'Identifier',
165374
- reactive: false,
165375
- loc: terminal.loc,
165376
- },
165263
+ lvalue: createTemporaryPlace(env, terminal.loc),
165377
165264
  value: {
165378
165265
  kind: 'StoreLocal',
165379
165266
  lvalue: {
@@ -165397,20 +165284,7 @@ function declareTemporary(env, block, result) {
165397
165284
  block.instructions.push({
165398
165285
  id: makeInstructionId(0),
165399
165286
  loc: GeneratedSource,
165400
- lvalue: {
165401
- effect: exports.Effect.Unknown,
165402
- identifier: {
165403
- id: env.nextIdentifierId,
165404
- mutableRange: {start: makeInstructionId(0), end: makeInstructionId(0)},
165405
- name: null,
165406
- scope: null,
165407
- type: makeType(),
165408
- loc: result.loc,
165409
- },
165410
- kind: 'Identifier',
165411
- reactive: false,
165412
- loc: GeneratedSource,
165413
- },
165287
+ lvalue: createTemporaryPlace(env, result.loc),
165414
165288
  value: {
165415
165289
  kind: 'DeclareLocal',
165416
165290
  lvalue: {place: result, kind: InstructionKind.Let},
@@ -166073,7 +165947,7 @@ class Transform extends ReactiveFunctionTransform {
166073
165947
  return {kind: 'keep'};
166074
165948
  }
166075
165949
  }
166076
- let Visitor$1 = class Visitor extends ReactiveFunctionVisitor {
165950
+ let Visitor$2 = class Visitor extends ReactiveFunctionVisitor {
166077
165951
  constructor(env, aliases, paths) {
166078
165952
  super();
166079
165953
  this.map = new Map();
@@ -166215,7 +166089,7 @@ let Visitor$1 = class Visitor extends ReactiveFunctionVisitor {
166215
166089
  };
166216
166090
  function pruneInitializationDependencies(fn) {
166217
166091
  const [aliases, paths] = getAliases(fn);
166218
- visitReactiveFunction(fn, new Visitor$1(fn.env, aliases, paths), 'Update');
166092
+ visitReactiveFunction(fn, new Visitor$2(fn.env, aliases, paths), 'Update');
166219
166093
  }
166220
166094
  function update(map, key, path, value) {
166221
166095
  var _a;
@@ -167120,6 +166994,69 @@ function visitFunctionExpression(errors, fn) {
167120
166994
  }
167121
166995
  }
167122
166996
  }
166997
+ function validateMemoizedEffectDependencies(fn) {
166998
+ const errors = new CompilerError();
166999
+ visitReactiveFunction(fn, new Visitor$1(), errors);
167000
+ if (errors.hasErrors()) {
167001
+ throw errors;
167002
+ }
167003
+ }
167004
+ let Visitor$1 = class Visitor extends ReactiveFunctionVisitor {
167005
+ constructor() {
167006
+ super(...arguments);
167007
+ this.scopes = new Set();
167008
+ }
167009
+ visitScope(scopeBlock, state) {
167010
+ this.traverseScope(scopeBlock, state);
167011
+ let areDependenciesMemoized = true;
167012
+ for (const dep of scopeBlock.scope.dependencies) {
167013
+ if (isUnmemoized$1(dep.identifier, this.scopes)) {
167014
+ areDependenciesMemoized = false;
167015
+ break;
167016
+ }
167017
+ }
167018
+ if (areDependenciesMemoized) {
167019
+ this.scopes.add(scopeBlock.scope.id);
167020
+ for (const id of scopeBlock.scope.merged) {
167021
+ this.scopes.add(id);
167022
+ }
167023
+ }
167024
+ }
167025
+ visitInstruction(instruction, state) {
167026
+ this.traverseInstruction(instruction, state);
167027
+ if (
167028
+ instruction.value.kind === 'CallExpression' &&
167029
+ isEffectHook(instruction.value.callee.identifier) &&
167030
+ instruction.value.args.length >= 2
167031
+ ) {
167032
+ const deps = instruction.value.args[1];
167033
+ if (
167034
+ deps.kind === 'Identifier' &&
167035
+ (isMutable(instruction, deps) ||
167036
+ isUnmemoized$1(deps.identifier, this.scopes))
167037
+ ) {
167038
+ state.push({
167039
+ reason:
167040
+ 'React Compiler has skipped optimizing this component because the effect dependencies could not be memoized. Unmemoized effect dependencies can trigger an infinite loop or other unexpected behavior',
167041
+ description: null,
167042
+ severity: exports.ErrorSeverity.CannotPreserveMemoization,
167043
+ loc: typeof instruction.loc !== 'symbol' ? instruction.loc : null,
167044
+ suggestions: null,
167045
+ });
167046
+ }
167047
+ }
167048
+ }
167049
+ };
167050
+ function isUnmemoized$1(operand, scopes) {
167051
+ return operand.scope != null && !scopes.has(operand.scope.id);
167052
+ }
167053
+ function isEffectHook(identifier) {
167054
+ return (
167055
+ isUseEffectHookType(identifier) ||
167056
+ isUseLayoutEffectHookType(identifier) ||
167057
+ isUseInsertionEffectHookType(identifier)
167058
+ );
167059
+ }
167123
167060
  function validateNoCapitalizedCalls(fn) {
167124
167061
  var _a;
167125
167062
  const envConfig = fn.env.config;
@@ -167375,59 +167312,94 @@ function validateNoSetStateInRender(fn) {
167375
167312
  }
167376
167313
  function validateNoSetStateInRenderImpl(fn, unconditionalSetStateFunctions) {
167377
167314
  const unconditionalBlocks = computeUnconditionalBlocks(fn);
167315
+ let activeManualMemoId = null;
167378
167316
  const errors = new CompilerError();
167379
167317
  for (const [, block] of fn.body.blocks) {
167380
- if (unconditionalBlocks.has(block.id)) {
167381
- for (const instr of block.instructions) {
167382
- switch (instr.value.kind) {
167383
- case 'LoadLocal': {
167384
- if (
167385
- unconditionalSetStateFunctions.has(
167386
- instr.value.place.identifier.id
167387
- )
167388
- ) {
167389
- unconditionalSetStateFunctions.add(instr.lvalue.identifier.id);
167390
- }
167391
- break;
167318
+ for (const instr of block.instructions) {
167319
+ switch (instr.value.kind) {
167320
+ case 'LoadLocal': {
167321
+ if (
167322
+ unconditionalSetStateFunctions.has(instr.value.place.identifier.id)
167323
+ ) {
167324
+ unconditionalSetStateFunctions.add(instr.lvalue.identifier.id);
167392
167325
  }
167393
- case 'StoreLocal': {
167394
- if (
167395
- unconditionalSetStateFunctions.has(
167396
- instr.value.value.identifier.id
167397
- )
167398
- ) {
167399
- unconditionalSetStateFunctions.add(
167400
- instr.value.lvalue.place.identifier.id
167401
- );
167402
- unconditionalSetStateFunctions.add(instr.lvalue.identifier.id);
167403
- }
167404
- break;
167326
+ break;
167327
+ }
167328
+ case 'StoreLocal': {
167329
+ if (
167330
+ unconditionalSetStateFunctions.has(instr.value.value.identifier.id)
167331
+ ) {
167332
+ unconditionalSetStateFunctions.add(
167333
+ instr.value.lvalue.place.identifier.id
167334
+ );
167335
+ unconditionalSetStateFunctions.add(instr.lvalue.identifier.id);
167405
167336
  }
167406
- case 'ObjectMethod':
167407
- case 'FunctionExpression': {
167408
- if (
167409
- [...eachInstructionValueOperand(instr.value)].some(
167410
- operand =>
167411
- isSetStateType(operand.identifier) ||
167412
- unconditionalSetStateFunctions.has(operand.identifier.id)
167413
- ) &&
167414
- validateNoSetStateInRenderImpl(
167415
- instr.value.loweredFunc.func,
167416
- unconditionalSetStateFunctions
167417
- ).isErr()
167418
- ) {
167419
- unconditionalSetStateFunctions.add(instr.lvalue.identifier.id);
167420
- }
167421
- break;
167337
+ break;
167338
+ }
167339
+ case 'ObjectMethod':
167340
+ case 'FunctionExpression': {
167341
+ if (
167342
+ [...eachInstructionValueOperand(instr.value)].some(
167343
+ operand =>
167344
+ isSetStateType(operand.identifier) ||
167345
+ unconditionalSetStateFunctions.has(operand.identifier.id)
167346
+ ) &&
167347
+ validateNoSetStateInRenderImpl(
167348
+ instr.value.loweredFunc.func,
167349
+ unconditionalSetStateFunctions
167350
+ ).isErr()
167351
+ ) {
167352
+ unconditionalSetStateFunctions.add(instr.lvalue.identifier.id);
167422
167353
  }
167423
- case 'CallExpression': {
167424
- validateNonSetState(
167425
- errors,
167426
- unconditionalSetStateFunctions,
167427
- instr.value.callee
167428
- );
167429
- break;
167354
+ break;
167355
+ }
167356
+ case 'StartMemoize': {
167357
+ CompilerError.invariant(activeManualMemoId === null, {
167358
+ reason: 'Unexpected nested StartMemoize instructions',
167359
+ loc: instr.value.loc,
167360
+ });
167361
+ activeManualMemoId = instr.value.manualMemoId;
167362
+ break;
167363
+ }
167364
+ case 'FinishMemoize': {
167365
+ CompilerError.invariant(
167366
+ activeManualMemoId === instr.value.manualMemoId,
167367
+ {
167368
+ reason:
167369
+ 'Expected FinishMemoize to align with previous StartMemoize instruction',
167370
+ loc: instr.value.loc,
167371
+ }
167372
+ );
167373
+ activeManualMemoId = null;
167374
+ break;
167375
+ }
167376
+ case 'CallExpression': {
167377
+ const callee = instr.value.callee;
167378
+ if (
167379
+ isSetStateType(callee.identifier) ||
167380
+ unconditionalSetStateFunctions.has(callee.identifier.id)
167381
+ ) {
167382
+ if (activeManualMemoId !== null) {
167383
+ errors.push({
167384
+ reason:
167385
+ 'Calling setState from useMemo may trigger an infinite loop. (https://react.dev/reference/react/useState)',
167386
+ description: null,
167387
+ severity: exports.ErrorSeverity.InvalidReact,
167388
+ loc: callee.loc,
167389
+ suggestions: null,
167390
+ });
167391
+ } else if (unconditionalBlocks.has(block.id)) {
167392
+ errors.push({
167393
+ reason:
167394
+ 'This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)',
167395
+ description: null,
167396
+ severity: exports.ErrorSeverity.InvalidReact,
167397
+ loc: callee.loc,
167398
+ suggestions: null,
167399
+ });
167400
+ }
167430
167401
  }
167402
+ break;
167431
167403
  }
167432
167404
  }
167433
167405
  }
@@ -167438,21 +167410,6 @@ function validateNoSetStateInRenderImpl(fn, unconditionalSetStateFunctions) {
167438
167410
  return Ok(undefined);
167439
167411
  }
167440
167412
  }
167441
- function validateNonSetState(errors, unconditionalSetStateFunctions, operand) {
167442
- if (
167443
- isSetStateType(operand.identifier) ||
167444
- unconditionalSetStateFunctions.has(operand.identifier.id)
167445
- ) {
167446
- errors.push({
167447
- reason:
167448
- 'This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState)',
167449
- description: null,
167450
- severity: exports.ErrorSeverity.InvalidReact,
167451
- loc: typeof operand.loc !== 'symbol' ? operand.loc : null,
167452
- suggestions: null,
167453
- });
167454
- }
167455
- }
167456
167413
  function validatePreservedManualMemoization(fn) {
167457
167414
  const state = {errors: new CompilerError(), manualMemoState: null};
167458
167415
  visitReactiveFunction(fn, new Visitor(), state);
@@ -167557,7 +167514,7 @@ function validateInferredDep(
167557
167514
  for (const decl of declsWithinMemoBlock) {
167558
167515
  if (
167559
167516
  normalizedDep.root.kind === 'NamedLocal' &&
167560
- decl === normalizedDep.root.value.identifier.id
167517
+ decl === normalizedDep.root.value.identifier.declarationId
167561
167518
  ) {
167562
167519
  return;
167563
167520
  }
@@ -167622,7 +167579,7 @@ class Visitor extends ReactiveFunctionVisitor {
167622
167579
  const storeTarget = value.lvalue.place;
167623
167580
  (_a = state.manualMemoState) === null || _a === void 0
167624
167581
  ? void 0
167625
- : _a.decls.add(storeTarget.identifier.id);
167582
+ : _a.decls.add(storeTarget.identifier.declarationId);
167626
167583
  if (
167627
167584
  ((_b = storeTarget.identifier.name) === null || _b === void 0
167628
167585
  ? void 0
@@ -167642,24 +167599,23 @@ class Visitor extends ReactiveFunctionVisitor {
167642
167599
  }
167643
167600
  }
167644
167601
  recordTemporaries(instr, state) {
167645
- var _a, _b, _c;
167602
+ var _a;
167646
167603
  const temporaries = this.temporaries;
167647
- const {value: value} = instr;
167604
+ const {lvalue: lvalue, value: value} = instr;
167648
167605
  const lvalId =
167649
- (_a = instr.lvalue) === null || _a === void 0 ? void 0 : _a.identifier.id;
167606
+ lvalue === null || lvalue === void 0 ? void 0 : lvalue.identifier.id;
167650
167607
  if (lvalId != null && temporaries.has(lvalId)) {
167651
167608
  return;
167652
167609
  }
167653
167610
  const isNamedLocal =
167654
- lvalId != null &&
167655
- ((_c =
167656
- (_b = instr.lvalue) === null || _b === void 0
167611
+ ((_a =
167612
+ lvalue === null || lvalue === void 0
167657
167613
  ? void 0
167658
- : _b.identifier.name) === null || _c === void 0
167614
+ : lvalue.identifier.name) === null || _a === void 0
167659
167615
  ? void 0
167660
- : _c.kind) === 'named';
167661
- if (isNamedLocal && state.manualMemoState != null) {
167662
- state.manualMemoState.decls.add(lvalId);
167616
+ : _a.kind) === 'named';
167617
+ if (lvalue !== null && isNamedLocal && state.manualMemoState != null) {
167618
+ state.manualMemoState.decls.add(lvalue.identifier.declarationId);
167663
167619
  }
167664
167620
  const maybeDep = this.recordDepsInValue(value, state);
167665
167621
  if (lvalId != null) {
@@ -167945,7 +167901,33 @@ function getContextReassignment(
167945
167901
  break;
167946
167902
  }
167947
167903
  default: {
167948
- for (const operand of eachInstructionValueOperand(value)) {
167904
+ let operands = eachInstructionValueOperand(value);
167905
+ if (value.kind === 'CallExpression') {
167906
+ const signature = getFunctionCallSignature(
167907
+ fn.env,
167908
+ value.callee.identifier.type
167909
+ );
167910
+ if (
167911
+ signature === null || signature === void 0
167912
+ ? void 0
167913
+ : signature.noAlias
167914
+ ) {
167915
+ operands = [value.callee];
167916
+ }
167917
+ } else if (value.kind === 'MethodCall') {
167918
+ const signature = getFunctionCallSignature(
167919
+ fn.env,
167920
+ value.property.identifier.type
167921
+ );
167922
+ if (
167923
+ signature === null || signature === void 0
167924
+ ? void 0
167925
+ : signature.noAlias
167926
+ ) {
167927
+ operands = [value.receiver, value.property];
167928
+ }
167929
+ }
167930
+ for (const operand of operands) {
167949
167931
  CompilerError.invariant(operand.effect !== exports.Effect.Unknown, {
167950
167932
  reason: `Expected effects to be inferred prior to ValidateLocalsNotReassignedAfterRender`,
167951
167933
  loc: operand.loc,
@@ -167953,11 +167935,14 @@ function getContextReassignment(
167953
167935
  const reassignment = reassigningFunctions.get(
167954
167936
  operand.identifier.id
167955
167937
  );
167956
- if (
167957
- reassignment !== undefined &&
167958
- operand.effect === exports.Effect.Freeze
167959
- ) {
167960
- return reassignment;
167938
+ if (reassignment !== undefined) {
167939
+ if (operand.effect === exports.Effect.Freeze) {
167940
+ return reassignment;
167941
+ } else {
167942
+ for (const lval of eachInstructionLValue(instr)) {
167943
+ reassigningFunctions.set(lval.identifier.id, reassignment);
167944
+ }
167945
+ }
167961
167946
  }
167962
167947
  }
167963
167948
  break;
@@ -167973,21 +167958,22 @@ function getContextReassignment(
167973
167958
  }
167974
167959
  return null;
167975
167960
  }
167976
- function outlineFunctions(fn) {
167961
+ function outlineFunctions(fn, fbtOperands) {
167977
167962
  for (const [, block] of fn.body.blocks) {
167978
167963
  for (const instr of block.instructions) {
167979
- const {value: value} = instr;
167964
+ const {value: value, lvalue: lvalue} = instr;
167980
167965
  if (
167981
167966
  value.kind === 'FunctionExpression' ||
167982
167967
  value.kind === 'ObjectMethod'
167983
167968
  ) {
167984
- outlineFunctions(value.loweredFunc.func);
167969
+ outlineFunctions(value.loweredFunc.func, fbtOperands);
167985
167970
  }
167986
167971
  if (
167987
167972
  value.kind === 'FunctionExpression' &&
167988
167973
  value.loweredFunc.dependencies.length === 0 &&
167989
167974
  value.loweredFunc.func.context.length === 0 &&
167990
- value.loweredFunc.func.id === null
167975
+ value.loweredFunc.func.id === null &&
167976
+ !fbtOperands.has(lvalue.identifier.id)
167991
167977
  ) {
167992
167978
  const loweredFunc = value.loweredFunc.func;
167993
167979
  const id = fn.env.generateGloballyUniqueIdentifierName(loweredFunc.id);
@@ -168002,6 +167988,46 @@ function outlineFunctions(fn) {
168002
167988
  }
168003
167989
  }
168004
167990
  }
167991
+ function propagatePhiTypes(fn) {
167992
+ const propagated = new Set();
167993
+ for (const [, block] of fn.body.blocks) {
167994
+ for (const phi of block.phis) {
167995
+ if (phi.id.type.kind !== 'Type' || phi.id.name !== null) {
167996
+ continue;
167997
+ }
167998
+ let type = null;
167999
+ for (const [, operand] of phi.operands) {
168000
+ if (type === null) {
168001
+ type = operand.type;
168002
+ } else if (!typeEquals(type, operand.type)) {
168003
+ type = null;
168004
+ break;
168005
+ }
168006
+ }
168007
+ if (type !== null) {
168008
+ phi.id.type = type;
168009
+ phi.type = type;
168010
+ propagated.add(phi.id.id);
168011
+ }
168012
+ }
168013
+ for (const instr of block.instructions) {
168014
+ const {value: value} = instr;
168015
+ switch (value.kind) {
168016
+ case 'StoreLocal': {
168017
+ const lvalue = value.lvalue.place;
168018
+ if (
168019
+ propagated.has(value.value.identifier.id) &&
168020
+ lvalue.identifier.type.kind === 'Type' &&
168021
+ lvalue.identifier.name === null
168022
+ ) {
168023
+ lvalue.identifier.type = value.value.identifier.type;
168024
+ propagated.add(lvalue.identifier.id);
168025
+ }
168026
+ }
168027
+ }
168028
+ }
168029
+ }
168030
+ }
168005
168031
  function* run(
168006
168032
  func,
168007
168033
  config,
@@ -168022,11 +168048,11 @@ function* run(
168022
168048
  code,
168023
168049
  useMemoCacheIdentifier
168024
168050
  );
168025
- yield {
168051
+ yield log({
168026
168052
  kind: 'debug',
168027
168053
  name: 'EnvironmentConfig',
168028
168054
  value: prettyFormat$1(env.config),
168029
- };
168055
+ });
168030
168056
  const ast = yield* runWithEnvironment(func, env);
168031
168057
  return ast;
168032
168058
  }
@@ -168096,24 +168122,30 @@ function* runWithEnvironment(func, env) {
168096
168122
  }
168097
168123
  inferReactivePlaces(hir);
168098
168124
  yield log({kind: 'hir', name: 'InferReactivePlaces', value: hir});
168099
- leaveSSA(hir);
168100
- yield log({kind: 'hir', name: 'LeaveSSA', value: hir});
168125
+ rewriteInstructionKindsBasedOnReassignment(hir);
168126
+ yield log({
168127
+ kind: 'hir',
168128
+ name: 'RewriteInstructionKindsBasedOnReassignment',
168129
+ value: hir,
168130
+ });
168131
+ propagatePhiTypes(hir);
168132
+ yield log({kind: 'hir', name: 'PropagatePhiTypes', value: hir});
168101
168133
  inferReactiveScopeVariables(hir);
168102
168134
  yield log({kind: 'hir', name: 'InferReactiveScopeVariables', value: hir});
168135
+ const fbtOperands = memoizeFbtAndMacroOperandsInSameScope(hir);
168136
+ yield log({
168137
+ kind: 'hir',
168138
+ name: 'MemoizeFbtAndMacroOperandsInSameScope',
168139
+ value: hir,
168140
+ });
168103
168141
  if (env.config.enableFunctionOutlining) {
168104
- outlineFunctions(hir);
168142
+ outlineFunctions(hir, fbtOperands);
168105
168143
  yield log({kind: 'hir', name: 'OutlineFunctions', value: hir});
168106
168144
  }
168107
168145
  alignMethodCallScopes(hir);
168108
168146
  yield log({kind: 'hir', name: 'AlignMethodCallScopes', value: hir});
168109
168147
  alignObjectMethodScopes(hir);
168110
168148
  yield log({kind: 'hir', name: 'AlignObjectMethodScopes', value: hir});
168111
- const fbtOperands = memoizeFbtAndMacroOperandsInSameScope(hir);
168112
- yield log({
168113
- kind: 'hir',
168114
- name: 'MemoizeFbtAndMacroOperandsInSameScope',
168115
- value: hir,
168116
- });
168117
168149
  if (env.config.enableReactiveScopesInHIR) {
168118
168150
  pruneUnusedLabelsHIR(hir);
168119
168151
  yield log({kind: 'hir', name: 'PruneUnusedLabelsHIR', value: hir});
@@ -168250,7 +168282,7 @@ function* runWithEnvironment(func, env) {
168250
168282
  name: 'PromoteUsedTemporaries',
168251
168283
  value: reactiveFunction,
168252
168284
  });
168253
- pruneTemporaryLValues(reactiveFunction);
168285
+ pruneUnusedLValues(reactiveFunction);
168254
168286
  yield log({
168255
168287
  kind: 'reactive',
168256
168288
  name: 'PruneUnusedLValues',