babel-plugin-react-compiler 0.0.0-experimental-f980e29-20250522 → 0.0.0-experimental-a550a97-20250527

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ import * as BabelCore from '@babel/core';
2
2
  import { NodePath as NodePath$1 } from '@babel/core';
3
3
  import * as t from '@babel/types';
4
4
  import { z } from 'zod';
5
- import { Scope, NodePath } from '@babel/traverse';
5
+ import { NodePath, Scope } from '@babel/traverse';
6
6
 
7
7
  interface Result<T, E> {
8
8
  map<U>(fn: (val: T) => U): Result<U, E>;
@@ -546,7 +546,8 @@ declare class Environment {
546
546
  hasFireRewrite: boolean;
547
547
  hasInferredEffect: boolean;
548
548
  inferredEffectLocations: Set<SourceLocation>;
549
- constructor(scope: Scope, fnType: ReactFunctionType, compilerMode: CompilerMode, config: EnvironmentConfig, contextIdentifiers: Set<t.Identifier>, logger: Logger | null, filename: string | null, code: string | null, programContext: ProgramContext);
549
+ parentFunction: NodePath<t.Function>;
550
+ constructor(scope: Scope, fnType: ReactFunctionType, compilerMode: CompilerMode, config: EnvironmentConfig, contextIdentifiers: Set<t.Identifier>, parentFunction: NodePath<t.Function>, logger: Logger | null, filename: string | null, code: string | null, programContext: ProgramContext);
550
551
  get isInferredMemoEnabled(): boolean;
551
552
  get nextIdentifierId(): IdentifierId;
552
553
  get nextBlockId(): BlockId;
@@ -1412,6 +1413,7 @@ type DependencyPathEntry = {
1412
1413
  type DependencyPath = Array<DependencyPathEntry>;
1413
1414
  type ReactiveScopeDependency = {
1414
1415
  identifier: Identifier;
1416
+ reactive: boolean;
1415
1417
  path: DependencyPath;
1416
1418
  };
1417
1419
  declare const opaqueBlockId: unique symbol;
@@ -1556,6 +1558,8 @@ declare const DynamicGatingOptionsSchema: z.ZodObject<{
1556
1558
  source: string;
1557
1559
  }>;
1558
1560
  type DynamicGatingOptions = z.infer<typeof DynamicGatingOptionsSchema>;
1561
+ declare const CustomOptOutDirectiveSchema: z.ZodDefault<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
1562
+ type CustomOptOutDirective = z.infer<typeof CustomOptOutDirectiveSchema>;
1559
1563
  type PluginOptions = {
1560
1564
  environment: EnvironmentConfig;
1561
1565
  logger: Logger | null;
@@ -1567,6 +1571,7 @@ type PluginOptions = {
1567
1571
  eslintSuppressionRules: Array<string> | null | undefined;
1568
1572
  flowSuppressions: boolean;
1569
1573
  ignoreUseNoForget: boolean;
1574
+ customOptOutDirectives: CustomOptOutDirective;
1570
1575
  sources: Array<string> | ((filename: string) => boolean) | null;
1571
1576
  enableReanimatedCheck: boolean;
1572
1577
  target: CompilerReactTarget;
@@ -1645,7 +1650,7 @@ type CompilerPass = {
1645
1650
  declare const OPT_IN_DIRECTIVES: Set<string>;
1646
1651
  declare const OPT_OUT_DIRECTIVES: Set<string>;
1647
1652
  declare function tryFindDirectiveEnablingMemoization(directives: Array<t.Directive>, opts: PluginOptions): Result<t.Directive | null, CompilerError>;
1648
- declare function findDirectiveDisablingMemoization(directives: Array<t.Directive>): t.Directive | null;
1653
+ declare function findDirectiveDisablingMemoization(directives: Array<t.Directive>, { customOptOutDirectives }: PluginOptions): t.Directive | null;
1649
1654
  type BabelFn = NodePath$1<t.FunctionDeclaration> | NodePath$1<t.FunctionExpression> | NodePath$1<t.ArrowFunctionExpression>;
1650
1655
  type CompileProgramMetadata = {
1651
1656
  retryErrors: Array<{
package/dist/index.js CHANGED
@@ -5855,7 +5855,7 @@ var require_parentheses = __commonJS({
5855
5855
  exports2.DoExpression = DoExpression;
5856
5856
  exports2.FunctionExpression = FunctionExpression7;
5857
5857
  exports2.FunctionTypeAnnotation = FunctionTypeAnnotation;
5858
- exports2.Identifier = Identifier28;
5858
+ exports2.Identifier = Identifier29;
5859
5859
  exports2.LogicalExpression = LogicalExpression;
5860
5860
  exports2.NullableTypeAnnotation = NullableTypeAnnotation;
5861
5861
  exports2.ObjectExpression = ObjectExpression;
@@ -6070,7 +6070,7 @@ var require_parentheses = __commonJS({
6070
6070
  return parent.operator !== "??";
6071
6071
  }
6072
6072
  }
6073
- function Identifier28(node, parent, tokenContext, _inForInit, getRawIdentifier) {
6073
+ function Identifier29(node, parent, tokenContext, _inForInit, getRawIdentifier) {
6074
6074
  var _node$extra;
6075
6075
  const parentType = parent.type;
6076
6076
  if ((_node$extra = node.extra) != null && _node$extra.parenthesized && parentType === "AssignmentExpression" && parent.left === node) {
@@ -8040,7 +8040,7 @@ var require_types = __commonJS({
8040
8040
  exports2.ArrayPattern = exports2.ArrayExpression = ArrayExpression5;
8041
8041
  exports2.BigIntLiteral = BigIntLiteral;
8042
8042
  exports2.BooleanLiteral = BooleanLiteral;
8043
- exports2.Identifier = Identifier28;
8043
+ exports2.Identifier = Identifier29;
8044
8044
  exports2.NullLiteral = NullLiteral;
8045
8045
  exports2.NumericLiteral = NumericLiteral;
8046
8046
  exports2.ObjectPattern = exports2.ObjectExpression = ObjectExpression;
@@ -8077,7 +8077,7 @@ var require_types = __commonJS({
8077
8077
  }
8078
8078
  return lastRawIdentResult = node.name;
8079
8079
  }
8080
- function Identifier28(node) {
8080
+ function Identifier29(node) {
8081
8081
  var _node$loc;
8082
8082
  this.sourceIdentifierName(((_node$loc = node.loc) == null ? void 0 : _node$loc.identifierName) || node.name);
8083
8083
  this.word(this.tokenMap ? this._getRawIdentifier(node) : node.name);
@@ -34766,7 +34766,7 @@ var require_parentheses2 = __commonJS({
34766
34766
  exports2.DoExpression = DoExpression;
34767
34767
  exports2.FunctionExpression = FunctionExpression7;
34768
34768
  exports2.FunctionTypeAnnotation = FunctionTypeAnnotation;
34769
- exports2.Identifier = Identifier28;
34769
+ exports2.Identifier = Identifier29;
34770
34770
  exports2.LogicalExpression = LogicalExpression;
34771
34771
  exports2.NullableTypeAnnotation = NullableTypeAnnotation;
34772
34772
  exports2.ObjectExpression = ObjectExpression;
@@ -34981,7 +34981,7 @@ var require_parentheses2 = __commonJS({
34981
34981
  return parent.operator !== "??";
34982
34982
  }
34983
34983
  }
34984
- function Identifier28(node, parent, tokenContext, _inForInit, getRawIdentifier) {
34984
+ function Identifier29(node, parent, tokenContext, _inForInit, getRawIdentifier) {
34985
34985
  var _node$extra;
34986
34986
  const parentType = parent.type;
34987
34987
  if ((_node$extra = node.extra) != null && _node$extra.parenthesized && parentType === "AssignmentExpression" && parent.left === node) {
@@ -36951,7 +36951,7 @@ var require_types2 = __commonJS({
36951
36951
  exports2.ArrayPattern = exports2.ArrayExpression = ArrayExpression5;
36952
36952
  exports2.BigIntLiteral = BigIntLiteral;
36953
36953
  exports2.BooleanLiteral = BooleanLiteral;
36954
- exports2.Identifier = Identifier28;
36954
+ exports2.Identifier = Identifier29;
36955
36955
  exports2.NullLiteral = NullLiteral;
36956
36956
  exports2.NumericLiteral = NumericLiteral;
36957
36957
  exports2.ObjectPattern = exports2.ObjectExpression = ObjectExpression;
@@ -36988,7 +36988,7 @@ var require_types2 = __commonJS({
36988
36988
  }
36989
36989
  return lastRawIdentResult = node.name;
36990
36990
  }
36991
- function Identifier28(node) {
36991
+ function Identifier29(node) {
36992
36992
  var _node$loc;
36993
36993
  this.sourceIdentifierName(((_node$loc = node.loc) == null ? void 0 : _node$loc.identifierName) || node.name);
36994
36994
  this.word(this.tokenMap ? this._getRawIdentifier(node) : node.name);
@@ -59070,7 +59070,7 @@ var require_types3 = __commonJS({
59070
59070
  Object.defineProperty(exports2, "__esModule", {
59071
59071
  value: true
59072
59072
  });
59073
- exports2.Identifier = Identifier28;
59073
+ exports2.Identifier = Identifier29;
59074
59074
  exports2.SpreadElement = exports2.RestElement = RestElement;
59075
59075
  exports2.ObjectPattern = exports2.ObjectExpression = ObjectExpression;
59076
59076
  exports2.ObjectMethod = ObjectMethod3;
@@ -59120,7 +59120,7 @@ var require_types3 = __commonJS({
59120
59120
  return newObj;
59121
59121
  }
59122
59122
  }
59123
- function Identifier28(node) {
59123
+ function Identifier29(node) {
59124
59124
  this.exactSource(node.loc, () => {
59125
59125
  this.word(node.name);
59126
59126
  });
@@ -71106,7 +71106,7 @@ function newBlock(id, kind) {
71106
71106
  }
71107
71107
  var _completed, _current, _entry, _scopes, _context, _bindings, _env, _exceptionHandlerStack, _HIRBuilder_instances, resolveBabelBinding_fn;
71108
71108
  var HIRBuilder = class {
71109
- constructor(env, parentFunction, bindings = null, context = null) {
71109
+ constructor(env, options) {
71110
71110
  __privateAdd(this, _HIRBuilder_instances);
71111
71111
  __privateAdd(this, _completed, /* @__PURE__ */ new Map());
71112
71112
  __privateAdd(this, _current);
@@ -71122,12 +71122,12 @@ var HIRBuilder = class {
71122
71122
  * of the current babel node.
71123
71123
  */
71124
71124
  this.fbtDepth = 0;
71125
+ var _a, _b, _c;
71125
71126
  __privateSet(this, _env, env);
71126
- __privateSet(this, _bindings, bindings != null ? bindings : /* @__PURE__ */ new Map());
71127
- this.parentFunction = parentFunction;
71128
- __privateSet(this, _context, context != null ? context : []);
71127
+ __privateSet(this, _bindings, (_a = options == null ? void 0 : options.bindings) != null ? _a : /* @__PURE__ */ new Map());
71128
+ __privateSet(this, _context, (_b = options == null ? void 0 : options.context) != null ? _b : []);
71129
71129
  __privateSet(this, _entry, makeBlockId(env.nextBlockId));
71130
- __privateSet(this, _current, newBlock(__privateGet(this, _entry), "block"));
71130
+ __privateSet(this, _current, newBlock(__privateGet(this, _entry), (_c = options == null ? void 0 : options.entryBlockKind) != null ? _c : "block"));
71131
71131
  }
71132
71132
  get nextIdentifierId() {
71133
71133
  return __privateGet(this, _env).nextIdentifierId;
@@ -71211,7 +71211,7 @@ var HIRBuilder = class {
71211
71211
  if (babelBinding == null) {
71212
71212
  return { kind: "Global", name: originalName };
71213
71213
  }
71214
- const outerBinding = this.parentFunction.scope.parent.getBinding(originalName);
71214
+ const outerBinding = __privateGet(this, _env).parentFunction.scope.parent.getBinding(originalName);
71215
71215
  if (babelBinding === outerBinding) {
71216
71216
  const path2 = babelBinding.path;
71217
71217
  if (path2.isImportDefaultSpecifier()) {
@@ -71256,7 +71256,7 @@ var HIRBuilder = class {
71256
71256
  isContextIdentifier(path) {
71257
71257
  const binding = __privateMethod(this, _HIRBuilder_instances, resolveBabelBinding_fn).call(this, path);
71258
71258
  if (binding) {
71259
- const outerBinding = this.parentFunction.scope.parent.getBinding(
71259
+ const outerBinding = __privateGet(this, _env).parentFunction.scope.parent.getBinding(
71260
71260
  path.node.name
71261
71261
  );
71262
71262
  if (binding === outerBinding) {
@@ -71347,6 +71347,7 @@ var HIRBuilder = class {
71347
71347
  const nextId = __privateGet(this, _env).nextBlockId;
71348
71348
  __privateSet(this, _current, newBlock(nextId, nextBlockKind));
71349
71349
  }
71350
+ return blockId;
71350
71351
  }
71351
71352
  /*
71352
71353
  * Terminate the current block w the given terminal, and set the previously
@@ -71588,6 +71589,11 @@ function getReversePostorderedBlocks(func) {
71588
71589
  return;
71589
71590
  }
71590
71591
  const block = func.blocks.get(blockId);
71592
+ CompilerError.invariant(block != null, {
71593
+ reason: "[HIRBuilder] Unexpected null block",
71594
+ description: `expected block ${blockId} to exist`,
71595
+ loc: GeneratedSource
71596
+ });
71591
71597
  const successors = [...eachTerminalSuccessor(block.terminal)].reverse();
71592
71598
  const fallthrough = terminalFallthrough(block.terminal);
71593
71599
  if (fallthrough != null) {
@@ -72696,9 +72702,12 @@ var DefaultNonmutatingHook = addHook(
72696
72702
  );
72697
72703
 
72698
72704
  // src/HIR/BuildHIR.ts
72699
- function lower(func, env, bindings = null, capturedRefs = [], parent = null) {
72705
+ function lower(func, env, bindings = null, capturedRefs = []) {
72700
72706
  var _a, _b, _c;
72701
- const builder = new HIRBuilder(env, parent != null ? parent : func, bindings, capturedRefs);
72707
+ const builder = new HIRBuilder(env, {
72708
+ bindings,
72709
+ context: capturedRefs
72710
+ });
72702
72711
  const context = [];
72703
72712
  for (const ref of capturedRefs != null ? capturedRefs : []) {
72704
72713
  context.push({
@@ -72827,7 +72836,7 @@ function lower(func, env, bindings = null, capturedRefs = [], parent = null) {
72827
72836
  return Ok({
72828
72837
  id,
72829
72838
  params,
72830
- fnType: parent == null ? env.fnType : "Other",
72839
+ fnType: bindings == null ? env.fnType : "Other",
72831
72840
  returnTypeAnnotation: null,
72832
72841
  // TODO: extract the actual return type node if present
72833
72842
  returnType: makeType(),
@@ -75620,15 +75629,12 @@ function lowerFunctionToValue(builder, expr) {
75620
75629
  };
75621
75630
  }
75622
75631
  function lowerFunction(builder, expr) {
75623
- const componentScope = builder.parentFunction.scope;
75632
+ const componentScope = builder.environment.parentFunction.scope;
75624
75633
  const capturedContext = gatherCapturedContext(expr, componentScope);
75625
- const lowering = lower(
75626
- expr,
75627
- builder.environment,
75628
- builder.bindings,
75629
- [...builder.context, ...capturedContext],
75630
- builder.parentFunction
75631
- );
75634
+ const lowering = lower(expr, builder.environment, builder.bindings, [
75635
+ ...builder.context,
75636
+ ...capturedContext
75637
+ ]);
75632
75638
  let loweredFunc;
75633
75639
  if (lowering.isErr()) {
75634
75640
  lowering.unwrapErr().details.forEach((detail) => builder.errors.pushErrorDetail(detail));
@@ -78179,7 +78185,7 @@ var EnvironmentConfigSchema = z.object({
78179
78185
  });
78180
78186
  var _globals, _shapes, _moduleTypes, _nextIdentifer, _nextBlock, _nextScope, _scope, _outlinedFunctions, _contextIdentifiers, _hoistedIdentifiers, _Environment_instances, resolveModuleType_fn, isKnownReactModule_fn, getCustomHookType_fn;
78181
78187
  var Environment = class {
78182
- constructor(scope, fnType, compilerMode, config, contextIdentifiers, logger, filename, code, programContext) {
78188
+ constructor(scope, fnType, compilerMode, config, contextIdentifiers, parentFunction, logger, filename, code, programContext) {
78183
78189
  __privateAdd(this, _Environment_instances);
78184
78190
  __privateAdd(this, _globals);
78185
78191
  __privateAdd(this, _shapes);
@@ -78236,6 +78242,7 @@ var Environment = class {
78236
78242
  const reanimatedModuleType = getReanimatedModuleType(__privateGet(this, _shapes));
78237
78243
  __privateGet(this, _moduleTypes).set(REANIMATED_MODULE_NAME, reanimatedModuleType);
78238
78244
  }
78245
+ this.parentFunction = parentFunction;
78239
78246
  __privateSet(this, _contextIdentifiers, contextIdentifiers);
78240
78247
  __privateSet(this, _hoistedIdentifiers, /* @__PURE__ */ new Set());
78241
78248
  }
@@ -85690,6 +85697,7 @@ function canMergeScopes(current, next) {
85690
85697
  new Set(
85691
85698
  [...current.scope.declarations.values()].map((declaration) => ({
85692
85699
  identifier: declaration.identifier,
85700
+ reactive: true,
85693
85701
  path: []
85694
85702
  }))
85695
85703
  ),
@@ -90193,6 +90201,29 @@ function inferReactivePlaces(fn) {
90193
90201
  }
90194
90202
  }
90195
90203
  } while (reactiveIdentifiers.snapshot());
90204
+ function propagateReactivityToInnerFunctions(fn2, isOutermost) {
90205
+ for (const [, block] of fn2.body.blocks) {
90206
+ for (const instr of block.instructions) {
90207
+ if (!isOutermost) {
90208
+ for (const operand of eachInstructionOperand(instr)) {
90209
+ reactiveIdentifiers.isReactive(operand);
90210
+ }
90211
+ }
90212
+ if (instr.value.kind === "ObjectMethod" || instr.value.kind === "FunctionExpression") {
90213
+ propagateReactivityToInnerFunctions(
90214
+ instr.value.loweredFunc.func,
90215
+ false
90216
+ );
90217
+ }
90218
+ }
90219
+ if (!isOutermost) {
90220
+ for (const operand of eachTerminalOperand(block.terminal)) {
90221
+ reactiveIdentifiers.isReactive(operand);
90222
+ }
90223
+ }
90224
+ }
90225
+ }
90226
+ propagateReactivityToInnerFunctions(fn, true);
90196
90227
  }
90197
90228
  function postDominatorFrontier(fn, postDominators, targetId) {
90198
90229
  const visited = /* @__PURE__ */ new Set();
@@ -90452,7 +90483,7 @@ var PropertyPathRegistry = class _PropertyPathRegistry {
90452
90483
  constructor() {
90453
90484
  this.roots = /* @__PURE__ */ new Map();
90454
90485
  }
90455
- getOrCreateIdentifier(identifier4) {
90486
+ getOrCreateIdentifier(identifier4, reactive) {
90456
90487
  let rootNode = this.roots.get(identifier4.id);
90457
90488
  if (rootNode === void 0) {
90458
90489
  rootNode = {
@@ -90461,12 +90492,18 @@ var PropertyPathRegistry = class _PropertyPathRegistry {
90461
90492
  optionalProperties: /* @__PURE__ */ new Map(),
90462
90493
  fullPath: {
90463
90494
  identifier: identifier4,
90495
+ reactive,
90464
90496
  path: []
90465
90497
  },
90466
90498
  hasOptional: false,
90467
90499
  parent: null
90468
90500
  };
90469
90501
  this.roots.set(identifier4.id, rootNode);
90502
+ } else {
90503
+ CompilerError.invariant(reactive === rootNode.fullPath.reactive, {
90504
+ reason: "[HoistablePropertyLoads] Found inconsistencies in `reactive` flag when deduping identifier reads within the same scope",
90505
+ loc: identifier4.loc
90506
+ });
90470
90507
  }
90471
90508
  return rootNode;
90472
90509
  }
@@ -90480,6 +90517,7 @@ var PropertyPathRegistry = class _PropertyPathRegistry {
90480
90517
  parent,
90481
90518
  fullPath: {
90482
90519
  identifier: parent.fullPath.identifier,
90520
+ reactive: parent.fullPath.reactive,
90483
90521
  path: parent.fullPath.path.concat(entry)
90484
90522
  },
90485
90523
  hasOptional: parent.hasOptional || entry.optional
@@ -90489,7 +90527,7 @@ var PropertyPathRegistry = class _PropertyPathRegistry {
90489
90527
  return child;
90490
90528
  }
90491
90529
  getOrCreateProperty(n) {
90492
- let currNode = this.getOrCreateIdentifier(n.identifier);
90530
+ let currNode = this.getOrCreateIdentifier(n.identifier, n.reactive);
90493
90531
  if (n.path.length === 0) {
90494
90532
  return currNode;
90495
90533
  }
@@ -90511,6 +90549,7 @@ function getMaybeNonNullInInstruction(instr, context) {
90511
90549
  if (instr.kind === "PropertyLoad") {
90512
90550
  path = (_a = context.temporaries.get(instr.object.identifier.id)) != null ? _a : {
90513
90551
  identifier: instr.object.identifier,
90552
+ reactive: instr.object.reactive,
90514
90553
  path: []
90515
90554
  };
90516
90555
  } else if (instr.kind === "Destructure") {
@@ -90539,7 +90578,7 @@ function collectNonNullsInBlocks(fn, context) {
90539
90578
  if (fn.fnType === "Component" && fn.params.length > 0 && fn.params[0].kind === "Identifier") {
90540
90579
  const identifier4 = fn.params[0].identifier;
90541
90580
  knownNonNullIdentifiers.add(
90542
- context.registry.getOrCreateIdentifier(identifier4)
90581
+ context.registry.getOrCreateIdentifier(identifier4, true)
90543
90582
  );
90544
90583
  }
90545
90584
  const nodes = /* @__PURE__ */ new Map();
@@ -90684,8 +90723,11 @@ function reduceMaybeOptionalChains(nodes, registry) {
90684
90723
  do {
90685
90724
  changed = false;
90686
90725
  for (const original of optionalChainNodes) {
90687
- let { identifier: identifier4, path: origPath } = original.fullPath;
90688
- let currNode = registry.getOrCreateIdentifier(identifier4);
90726
+ let { identifier: identifier4, path: origPath, reactive } = original.fullPath;
90727
+ let currNode = registry.getOrCreateIdentifier(
90728
+ identifier4,
90729
+ reactive
90730
+ );
90689
90731
  for (let i = 0; i < origPath.length; i++) {
90690
90732
  const entry = origPath[i];
90691
90733
  const nextEntry = entry.optional && nodes.has(currNode) ? { property: entry.property, optional: false } : entry;
@@ -90905,6 +90947,7 @@ function traverseOptionalBlock(optional, context, outerAlternate) {
90905
90947
  );
90906
90948
  baseObject = {
90907
90949
  identifier: maybeTest.instructions[0].value.place.identifier,
90950
+ reactive: maybeTest.instructions[0].value.place.reactive,
90908
90951
  path
90909
90952
  };
90910
90953
  test = maybeTest.terminal;
@@ -90960,6 +91003,7 @@ function traverseOptionalBlock(optional, context, outerAlternate) {
90960
91003
  );
90961
91004
  const load = {
90962
91005
  identifier: baseObject.identifier,
91006
+ reactive: baseObject.reactive,
90963
91007
  path: [
90964
91008
  ...baseObject.path,
90965
91009
  {
@@ -90996,8 +91040,8 @@ var _ReactiveScopeDependencyTreeHIR = class _ReactiveScopeDependencyTreeHIR {
90996
91040
  __privateAdd(this, _hoistableObjects, /* @__PURE__ */ new Map());
90997
91041
  __privateAdd(this, _deps, /* @__PURE__ */ new Map());
90998
91042
  var _a, _b;
90999
- for (const { path, identifier: identifier4 } of hoistableObjects) {
91000
- let currNode = __privateMethod(_a = _ReactiveScopeDependencyTreeHIR, _ReactiveScopeDependencyTreeHIR_static, getOrCreateRoot_fn).call(_a, identifier4, __privateGet(this, _hoistableObjects), path.length > 0 && path[0].optional ? "Optional" : "NonNull");
91043
+ for (const { path, identifier: identifier4, reactive } of hoistableObjects) {
91044
+ let currNode = __privateMethod(_a = _ReactiveScopeDependencyTreeHIR, _ReactiveScopeDependencyTreeHIR_static, getOrCreateRoot_fn).call(_a, identifier4, reactive, __privateGet(this, _hoistableObjects), path.length > 0 && path[0].optional ? "Optional" : "NonNull");
91001
91045
  for (let i = 0; i < path.length; i++) {
91002
91046
  const prevAccessType = (_b = currNode.properties.get(
91003
91047
  path[i].property
@@ -91029,8 +91073,8 @@ var _ReactiveScopeDependencyTreeHIR = class _ReactiveScopeDependencyTreeHIR {
91029
91073
  */
91030
91074
  addDependency(dep) {
91031
91075
  var _a;
91032
- const { identifier: identifier4, path } = dep;
91033
- let depCursor = __privateMethod(_a = _ReactiveScopeDependencyTreeHIR, _ReactiveScopeDependencyTreeHIR_static, getOrCreateRoot_fn).call(_a, identifier4, __privateGet(this, _deps), "UnconditionalAccess" /* UnconditionalAccess */);
91076
+ const { identifier: identifier4, reactive, path } = dep;
91077
+ let depCursor = __privateMethod(_a = _ReactiveScopeDependencyTreeHIR, _ReactiveScopeDependencyTreeHIR_static, getOrCreateRoot_fn).call(_a, identifier4, reactive, __privateGet(this, _deps), "UnconditionalAccess" /* UnconditionalAccess */);
91034
91078
  let hoistableCursor = __privateGet(this, _hoistableObjects).get(identifier4);
91035
91079
  for (const entry of path) {
91036
91080
  let nextHoistableCursor;
@@ -91071,7 +91115,13 @@ var _ReactiveScopeDependencyTreeHIR = class _ReactiveScopeDependencyTreeHIR {
91071
91115
  deriveMinimalDependencies() {
91072
91116
  const results = /* @__PURE__ */ new Set();
91073
91117
  for (const [rootId, rootNode] of __privateGet(this, _deps).entries()) {
91074
- collectMinimalDependenciesInSubtree(rootNode, rootId, [], results);
91118
+ collectMinimalDependenciesInSubtree(
91119
+ rootNode,
91120
+ rootNode.reactive,
91121
+ rootId,
91122
+ [],
91123
+ results
91124
+ );
91075
91125
  }
91076
91126
  return results;
91077
91127
  }
@@ -91103,14 +91153,21 @@ var _ReactiveScopeDependencyTreeHIR = class _ReactiveScopeDependencyTreeHIR {
91103
91153
  _hoistableObjects = new WeakMap();
91104
91154
  _deps = new WeakMap();
91105
91155
  _ReactiveScopeDependencyTreeHIR_static = new WeakSet();
91106
- getOrCreateRoot_fn = function(identifier4, roots, defaultAccessType) {
91156
+ getOrCreateRoot_fn = function(identifier4, reactive, roots, defaultAccessType) {
91107
91157
  let rootNode = roots.get(identifier4);
91108
91158
  if (rootNode === void 0) {
91109
91159
  rootNode = {
91110
91160
  properties: /* @__PURE__ */ new Map(),
91161
+ reactive,
91111
91162
  accessType: defaultAccessType
91112
91163
  };
91113
91164
  roots.set(identifier4, rootNode);
91165
+ } else {
91166
+ CompilerError.invariant(reactive === rootNode.reactive, {
91167
+ reason: "[DeriveMinimalDependenciesHIR] Conflicting reactive root flag",
91168
+ description: `Identifier ${printIdentifier(identifier4)}`,
91169
+ loc: GeneratedSource
91170
+ });
91114
91171
  }
91115
91172
  return rootNode;
91116
91173
  };
@@ -91145,13 +91202,14 @@ function merge(access1, access2) {
91145
91202
  }
91146
91203
  }
91147
91204
  }
91148
- function collectMinimalDependenciesInSubtree(node, rootIdentifier, path, results) {
91205
+ function collectMinimalDependenciesInSubtree(node, reactive, rootIdentifier, path, results) {
91149
91206
  if (isDependency(node.accessType)) {
91150
- results.add({ identifier: rootIdentifier, path });
91207
+ results.add({ identifier: rootIdentifier, reactive, path });
91151
91208
  } else {
91152
91209
  for (const [childName, childNode] of node.properties) {
91153
91210
  collectMinimalDependenciesInSubtree(
91154
91211
  childNode,
91212
+ reactive,
91155
91213
  rootIdentifier,
91156
91214
  [
91157
91215
  ...path,
@@ -91319,6 +91377,7 @@ function collectTemporariesSidemapImpl(fn, usedOutsideDeclaringScope, temporarie
91319
91377
  )) {
91320
91378
  temporaries.set(lvalue.identifier.id, {
91321
91379
  identifier: value.place.identifier,
91380
+ reactive: value.place.reactive,
91322
91381
  path: []
91323
91382
  });
91324
91383
  }
@@ -91339,11 +91398,13 @@ function getProperty(object, propertyName, optional, temporaries) {
91339
91398
  if (resolvedDependency == null) {
91340
91399
  property = {
91341
91400
  identifier: object.identifier,
91401
+ reactive: object.reactive,
91342
91402
  path: [{ property: propertyName, optional }]
91343
91403
  };
91344
91404
  } else {
91345
91405
  property = {
91346
91406
  identifier: resolvedDependency.identifier,
91407
+ reactive: resolvedDependency.reactive,
91347
91408
  path: [...resolvedDependency.path, { property: propertyName, optional }]
91348
91409
  };
91349
91410
  }
@@ -91432,6 +91493,7 @@ var DependencyCollectionContext = class {
91432
91493
  this.visitDependency(
91433
91494
  (_a = __privateGet(this, _temporaries).get(place.identifier.id)) != null ? _a : {
91434
91495
  identifier: place.identifier,
91496
+ reactive: place.reactive,
91435
91497
  path: []
91436
91498
  }
91437
91499
  );
@@ -91466,6 +91528,7 @@ var DependencyCollectionContext = class {
91466
91528
  if (isUseRefType(maybeDependency.identifier) && ((_a = maybeDependency.path.at(0)) == null ? void 0 : _a.property) === "current") {
91467
91529
  maybeDependency = {
91468
91530
  identifier: maybeDependency.identifier,
91531
+ reactive: maybeDependency.reactive,
91469
91532
  path: []
91470
91533
  };
91471
91534
  }
@@ -91482,7 +91545,11 @@ var DependencyCollectionContext = class {
91482
91545
  if (currentScope != null && !Iterable_some(
91483
91546
  currentScope.reassignments,
91484
91547
  (identifier4) => identifier4.declarationId === place.identifier.declarationId
91485
- ) && __privateMethod(this, _DependencyCollectionContext_instances, checkValidDependency_fn).call(this, { identifier: place.identifier, path: [] })) {
91548
+ ) && __privateMethod(this, _DependencyCollectionContext_instances, checkValidDependency_fn).call(this, {
91549
+ identifier: place.identifier,
91550
+ reactive: place.reactive,
91551
+ path: []
91552
+ })) {
91486
91553
  currentScope.reassignments.add(place.identifier);
91487
91554
  }
91488
91555
  }
@@ -91654,10 +91721,215 @@ function collectDependencies(fn, usedOutsideDeclaringScope, temporaries, process
91654
91721
  return context.deps;
91655
91722
  }
91656
91723
 
91724
+ // src/HIR/ScopeDependencyUtils.ts
91725
+ function buildDependencyInstructions(dep, env) {
91726
+ const builder = new HIRBuilder(env, {
91727
+ entryBlockKind: "value"
91728
+ });
91729
+ let dependencyValue;
91730
+ if (dep.path.every((path) => !path.optional)) {
91731
+ dependencyValue = writeNonOptionalDependency(dep, env, builder);
91732
+ } else {
91733
+ dependencyValue = writeOptionalDependency(dep, builder, null);
91734
+ }
91735
+ const exitBlockId = builder.terminate(
91736
+ {
91737
+ kind: "unsupported",
91738
+ loc: GeneratedSource,
91739
+ id: makeInstructionId(0)
91740
+ },
91741
+ null
91742
+ );
91743
+ return {
91744
+ place: {
91745
+ kind: "Identifier",
91746
+ identifier: dependencyValue,
91747
+ effect: "freeze" /* Freeze */,
91748
+ reactive: dep.reactive,
91749
+ loc: GeneratedSource
91750
+ },
91751
+ value: builder.build(),
91752
+ exitBlockId
91753
+ };
91754
+ }
91755
+ function writeNonOptionalDependency(dep, env, builder) {
91756
+ const loc = dep.identifier.loc;
91757
+ let curr = makeTemporaryIdentifier(env.nextIdentifierId, loc);
91758
+ builder.push({
91759
+ lvalue: {
91760
+ identifier: curr,
91761
+ kind: "Identifier",
91762
+ effect: "mutate" /* Mutate */,
91763
+ reactive: dep.reactive,
91764
+ loc
91765
+ },
91766
+ value: {
91767
+ kind: "LoadLocal",
91768
+ place: {
91769
+ identifier: dep.identifier,
91770
+ kind: "Identifier",
91771
+ effect: "freeze" /* Freeze */,
91772
+ reactive: dep.reactive,
91773
+ loc
91774
+ },
91775
+ loc
91776
+ },
91777
+ id: makeInstructionId(1),
91778
+ loc
91779
+ });
91780
+ for (const path of dep.path) {
91781
+ const next = makeTemporaryIdentifier(env.nextIdentifierId, loc);
91782
+ builder.push({
91783
+ lvalue: {
91784
+ identifier: next,
91785
+ kind: "Identifier",
91786
+ effect: "mutate" /* Mutate */,
91787
+ reactive: dep.reactive,
91788
+ loc
91789
+ },
91790
+ value: {
91791
+ kind: "PropertyLoad",
91792
+ object: {
91793
+ identifier: curr,
91794
+ kind: "Identifier",
91795
+ effect: "freeze" /* Freeze */,
91796
+ reactive: dep.reactive,
91797
+ loc
91798
+ },
91799
+ property: path.property,
91800
+ loc
91801
+ },
91802
+ id: makeInstructionId(1),
91803
+ loc
91804
+ });
91805
+ curr = next;
91806
+ }
91807
+ return curr;
91808
+ }
91809
+ function writeOptionalDependency(dep, builder, parentAlternate) {
91810
+ const env = builder.environment;
91811
+ const dependencyValue = {
91812
+ kind: "Identifier",
91813
+ identifier: makeTemporaryIdentifier(env.nextIdentifierId, GeneratedSource),
91814
+ effect: "mutate" /* Mutate */,
91815
+ reactive: dep.reactive,
91816
+ loc: GeneratedSource
91817
+ };
91818
+ const continuationBlock = builder.reserve(builder.currentBlockKind());
91819
+ let alternate;
91820
+ if (parentAlternate != null) {
91821
+ alternate = parentAlternate;
91822
+ } else {
91823
+ alternate = builder.enter("value", () => {
91824
+ const temp = lowerValueToTemporary(builder, {
91825
+ kind: "Primitive",
91826
+ value: void 0,
91827
+ loc: GeneratedSource
91828
+ });
91829
+ lowerValueToTemporary(builder, {
91830
+ kind: "StoreLocal",
91831
+ lvalue: { kind: "Const" /* Const */, place: __spreadValues({}, dependencyValue) },
91832
+ value: __spreadValues({}, temp),
91833
+ type: null,
91834
+ loc: GeneratedSource
91835
+ });
91836
+ return {
91837
+ kind: "goto",
91838
+ variant: "Break" /* Break */,
91839
+ block: continuationBlock.id,
91840
+ id: makeInstructionId(0),
91841
+ loc: GeneratedSource
91842
+ };
91843
+ });
91844
+ }
91845
+ const consequent = builder.reserve("value");
91846
+ let testIdentifier = null;
91847
+ const testBlock = builder.enter("value", () => {
91848
+ const testDependency = __spreadProps(__spreadValues({}, dep), {
91849
+ path: dep.path.slice(0, dep.path.length - 1)
91850
+ });
91851
+ const firstOptional = dep.path.findIndex((path) => path.optional);
91852
+ CompilerError.invariant(firstOptional !== -1, {
91853
+ reason: "[ScopeDependencyUtils] Internal invariant broken: expected optional path",
91854
+ loc: dep.identifier.loc,
91855
+ description: null,
91856
+ suggestions: null
91857
+ });
91858
+ if (firstOptional === dep.path.length - 1) {
91859
+ testIdentifier = writeNonOptionalDependency(testDependency, env, builder);
91860
+ } else {
91861
+ testIdentifier = writeOptionalDependency(
91862
+ testDependency,
91863
+ builder,
91864
+ alternate
91865
+ );
91866
+ }
91867
+ return {
91868
+ kind: "branch",
91869
+ test: {
91870
+ identifier: testIdentifier,
91871
+ effect: "freeze" /* Freeze */,
91872
+ kind: "Identifier",
91873
+ loc: GeneratedSource,
91874
+ reactive: dep.reactive
91875
+ },
91876
+ consequent: consequent.id,
91877
+ alternate,
91878
+ id: makeInstructionId(0),
91879
+ loc: GeneratedSource,
91880
+ fallthrough: continuationBlock.id
91881
+ };
91882
+ });
91883
+ builder.enterReserved(consequent, () => {
91884
+ CompilerError.invariant(testIdentifier !== null, {
91885
+ reason: "Satisfy type checker",
91886
+ description: null,
91887
+ loc: null,
91888
+ suggestions: null
91889
+ });
91890
+ lowerValueToTemporary(builder, {
91891
+ kind: "StoreLocal",
91892
+ lvalue: { kind: "Const" /* Const */, place: __spreadValues({}, dependencyValue) },
91893
+ value: lowerValueToTemporary(builder, {
91894
+ kind: "PropertyLoad",
91895
+ object: {
91896
+ identifier: testIdentifier,
91897
+ kind: "Identifier",
91898
+ effect: "freeze" /* Freeze */,
91899
+ reactive: dep.reactive,
91900
+ loc: GeneratedSource
91901
+ },
91902
+ property: dep.path.at(-1).property,
91903
+ loc: GeneratedSource
91904
+ }),
91905
+ type: null,
91906
+ loc: GeneratedSource
91907
+ });
91908
+ return {
91909
+ kind: "goto",
91910
+ variant: "Break" /* Break */,
91911
+ block: continuationBlock.id,
91912
+ id: makeInstructionId(0),
91913
+ loc: GeneratedSource
91914
+ };
91915
+ });
91916
+ builder.terminateWithContinuation(
91917
+ {
91918
+ kind: "optional",
91919
+ optional: dep.path.at(-1).optional,
91920
+ test: testBlock,
91921
+ fallthrough: continuationBlock.id,
91922
+ id: makeInstructionId(0),
91923
+ loc: GeneratedSource
91924
+ },
91925
+ continuationBlock
91926
+ );
91927
+ return dependencyValue.identifier;
91928
+ }
91929
+
91657
91930
  // src/Inference/InferEffectDependencies.ts
91658
91931
  function inferEffectDependencies(fn) {
91659
91932
  var _a, _b;
91660
- let hasRewrite = false;
91661
91933
  const fnExpressions = /* @__PURE__ */ new Map();
91662
91934
  const autodepFnConfigs = /* @__PURE__ */ new Map();
91663
91935
  for (const effectTarget of fn.env.config.inferEffectDependencies) {
@@ -91676,6 +91948,7 @@ function inferEffectDependencies(fn) {
91676
91948
  const scopeInfos = /* @__PURE__ */ new Map();
91677
91949
  const loadGlobals = /* @__PURE__ */ new Set();
91678
91950
  const reactiveIds = inferReactiveIdentifiers(fn);
91951
+ const rewriteBlocks = [];
91679
91952
  for (const [, block] of fn.body.blocks) {
91680
91953
  if (block.terminal.kind === "scope") {
91681
91954
  const scopeBlock = fn.body.blocks.get(block.terminal.block);
@@ -91686,7 +91959,7 @@ function inferEffectDependencies(fn) {
91686
91959
  );
91687
91960
  }
91688
91961
  }
91689
- const rewriteInstrs = /* @__PURE__ */ new Map();
91962
+ const rewriteInstrs = [];
91690
91963
  for (const instr of block.instructions) {
91691
91964
  const { value, lvalue } = instr;
91692
91965
  if (value.kind === "FunctionExpression") {
@@ -91727,7 +92000,6 @@ function inferEffectDependencies(fn) {
91727
92000
  const callee = value.kind === "CallExpression" ? value.callee : value.property;
91728
92001
  if (value.args.length === autodepFnLoads.get(callee.identifier.id) && value.args[0].kind === "Identifier") {
91729
92002
  const effectDeps = [];
91730
- const newInstructions = [];
91731
92003
  const deps = {
91732
92004
  kind: "ArrayExpression",
91733
92005
  elements: effectDeps,
@@ -91745,17 +92017,21 @@ function inferEffectDependencies(fn) {
91745
92017
  minimalDeps = inferMinimalDependencies(fnExpr);
91746
92018
  }
91747
92019
  const usedDeps = [];
91748
- for (const dep of minimalDeps) {
91749
- if ((isUseRefType(dep.identifier) || isSetStateType(dep.identifier)) && !reactiveIds.has(dep.identifier.id) || isFireFunctionType(dep.identifier)) {
92020
+ for (const maybeDep of minimalDeps) {
92021
+ if ((isUseRefType(maybeDep.identifier) || isSetStateType(maybeDep.identifier)) && !reactiveIds.has(maybeDep.identifier.id) || isFireFunctionType(maybeDep.identifier)) {
91750
92022
  continue;
91751
92023
  }
91752
- const { place, instructions } = writeDependencyToInstructions(
92024
+ const dep = truncateDepAtCurrent(maybeDep);
92025
+ const { place, value: value2, exitBlockId } = buildDependencyInstructions(
91753
92026
  dep,
91754
- reactiveIds.has(dep.identifier.id),
91755
- fn.env,
91756
- fnExpr.loc
92027
+ fn.env
91757
92028
  );
91758
- newInstructions.push(...instructions);
92029
+ rewriteInstrs.push({
92030
+ kind: "block",
92031
+ location: instr.id,
92032
+ value: value2,
92033
+ exitBlockId
92034
+ });
91759
92035
  effectDeps.push(place);
91760
92036
  usedDeps.push(dep);
91761
92037
  }
@@ -91773,24 +92049,30 @@ function inferEffectDependencies(fn) {
91773
92049
  decorations
91774
92050
  });
91775
92051
  }
91776
- newInstructions.push({
91777
- id: makeInstructionId(0),
91778
- loc: GeneratedSource,
91779
- lvalue: __spreadProps(__spreadValues({}, depsPlace), { effect: "mutate" /* Mutate */ }),
91780
- value: deps
92052
+ rewriteInstrs.push({
92053
+ kind: "instr",
92054
+ location: instr.id,
92055
+ value: {
92056
+ id: makeInstructionId(0),
92057
+ loc: GeneratedSource,
92058
+ lvalue: __spreadProps(__spreadValues({}, depsPlace), { effect: "mutate" /* Mutate */ }),
92059
+ value: deps
92060
+ }
91781
92061
  });
91782
92062
  value.args.push(__spreadProps(__spreadValues({}, depsPlace), { effect: "freeze" /* Freeze */ }));
91783
- rewriteInstrs.set(instr.id, newInstructions);
91784
92063
  fn.env.inferredEffectLocations.add(callee.loc);
91785
92064
  } else if (loadGlobals.has(value.args[0].identifier.id)) {
91786
- newInstructions.push({
91787
- id: makeInstructionId(0),
91788
- loc: GeneratedSource,
91789
- lvalue: __spreadProps(__spreadValues({}, depsPlace), { effect: "mutate" /* Mutate */ }),
91790
- value: deps
92065
+ rewriteInstrs.push({
92066
+ kind: "instr",
92067
+ location: instr.id,
92068
+ value: {
92069
+ id: makeInstructionId(0),
92070
+ loc: GeneratedSource,
92071
+ lvalue: __spreadProps(__spreadValues({}, depsPlace), { effect: "mutate" /* Mutate */ }),
92072
+ value: deps
92073
+ }
91791
92074
  });
91792
92075
  value.args.push(__spreadProps(__spreadValues({}, depsPlace), { effect: "freeze" /* Freeze */ }));
91793
- rewriteInstrs.set(instr.id, newInstructions);
91794
92076
  fn.env.inferredEffectLocations.add(callee.loc);
91795
92077
  }
91796
92078
  } else if (value.args.length >= 2 && value.args.length - 1 === autodepFnLoads.get(callee.identifier.id) && value.args[0] != null && value.args[0].kind === "Identifier") {
@@ -91809,70 +92091,81 @@ function inferEffectDependencies(fn) {
91809
92091
  }
91810
92092
  }
91811
92093
  }
91812
- if (rewriteInstrs.size > 0) {
91813
- hasRewrite = true;
91814
- const newInstrs = [];
91815
- for (const instr of block.instructions) {
91816
- const newInstr = rewriteInstrs.get(instr.id);
91817
- if (newInstr != null) {
91818
- newInstrs.push(...newInstr, instr);
91819
- } else {
91820
- newInstrs.push(instr);
91821
- }
91822
- }
91823
- block.instructions = newInstrs;
91824
- }
92094
+ rewriteSplices(block, rewriteInstrs, rewriteBlocks);
91825
92095
  }
91826
- if (hasRewrite) {
92096
+ if (rewriteBlocks.length > 0) {
92097
+ for (const block of rewriteBlocks) {
92098
+ fn.body.blocks.set(block.id, block);
92099
+ }
92100
+ reversePostorderBlocks(fn.body);
92101
+ markPredecessors(fn.body);
91827
92102
  markInstructionIds(fn.body);
91828
92103
  fixScopeAndIdentifierRanges(fn.body);
91829
92104
  fn.env.hasInferredEffect = true;
91830
92105
  }
91831
92106
  }
91832
- function writeDependencyToInstructions(dep, reactive, env, loc) {
91833
- const instructions = [];
91834
- let currValue = createTemporaryPlace(env, GeneratedSource);
91835
- currValue.reactive = reactive;
91836
- instructions.push({
91837
- id: makeInstructionId(0),
91838
- loc: GeneratedSource,
91839
- lvalue: __spreadProps(__spreadValues({}, currValue), { effect: "mutate" /* Mutate */ }),
91840
- value: {
91841
- kind: "LoadLocal",
91842
- place: {
91843
- kind: "Identifier",
91844
- identifier: dep.identifier,
91845
- effect: "capture" /* Capture */,
91846
- reactive,
91847
- loc
91848
- },
91849
- loc
91850
- }
91851
- });
91852
- for (const path of dep.path) {
91853
- if (path.optional) {
91854
- break;
91855
- }
91856
- if (path.property === "current") {
91857
- break;
92107
+ function truncateDepAtCurrent(dep) {
92108
+ const idx = dep.path.findIndex((path) => path.property === "current");
92109
+ if (idx === -1) {
92110
+ return dep;
92111
+ } else {
92112
+ return __spreadProps(__spreadValues({}, dep), { path: dep.path.slice(0, idx) });
92113
+ }
92114
+ }
92115
+ function rewriteSplices(originalBlock, splices, rewriteBlocks) {
92116
+ if (splices.length === 0) {
92117
+ return;
92118
+ }
92119
+ const originalInstrs = originalBlock.instructions;
92120
+ let currBlock = __spreadProps(__spreadValues({}, originalBlock), { instructions: [] });
92121
+ rewriteBlocks.push(currBlock);
92122
+ let cursor = 0;
92123
+ for (const rewrite of splices) {
92124
+ while (originalInstrs[cursor].id < rewrite.location) {
92125
+ CompilerError.invariant(
92126
+ originalInstrs[cursor].id < originalInstrs[cursor + 1].id,
92127
+ {
92128
+ reason: "[InferEffectDependencies] Internal invariant broken: expected block instructions to be sorted",
92129
+ loc: originalInstrs[cursor].loc
92130
+ }
92131
+ );
92132
+ currBlock.instructions.push(originalInstrs[cursor]);
92133
+ cursor++;
91858
92134
  }
91859
- const nextValue = createTemporaryPlace(env, GeneratedSource);
91860
- nextValue.reactive = reactive;
91861
- instructions.push({
91862
- id: makeInstructionId(0),
91863
- loc: GeneratedSource,
91864
- lvalue: __spreadProps(__spreadValues({}, nextValue), { effect: "mutate" /* Mutate */ }),
91865
- value: {
91866
- kind: "PropertyLoad",
91867
- object: __spreadProps(__spreadValues({}, currValue), { effect: "capture" /* Capture */ }),
91868
- property: path.property,
91869
- loc
91870
- }
92135
+ CompilerError.invariant(originalInstrs[cursor].id === rewrite.location, {
92136
+ reason: "[InferEffectDependencies] Internal invariant broken: splice location not found",
92137
+ loc: originalInstrs[cursor].loc
91871
92138
  });
91872
- currValue = nextValue;
92139
+ if (rewrite.kind === "instr") {
92140
+ currBlock.instructions.push(rewrite.value);
92141
+ } else {
92142
+ const { entry, blocks } = rewrite.value;
92143
+ const entryBlock = blocks.get(entry);
92144
+ currBlock.instructions.push(...entryBlock.instructions);
92145
+ if (blocks.size > 1) {
92146
+ CompilerError.invariant(
92147
+ terminalFallthrough(entryBlock.terminal) === rewrite.exitBlockId,
92148
+ {
92149
+ reason: "[InferEffectDependencies] Internal invariant broken: expected entry block to have a fallthrough",
92150
+ loc: entryBlock.terminal.loc
92151
+ }
92152
+ );
92153
+ const originalTerminal = currBlock.terminal;
92154
+ currBlock.terminal = entryBlock.terminal;
92155
+ for (const [id, block] of blocks) {
92156
+ if (id === entry) {
92157
+ continue;
92158
+ }
92159
+ if (id === rewrite.exitBlockId) {
92160
+ block.terminal = originalTerminal;
92161
+ currBlock = block;
92162
+ }
92163
+ rewriteBlocks.push(block);
92164
+ }
92165
+ }
92166
+ }
91873
92167
  }
91874
- currValue.effect = "freeze" /* Freeze */;
91875
- return { place: currValue, instructions };
92168
+ currBlock.instructions.push(...originalInstrs.slice(cursor));
91876
92169
  }
91877
92170
  function inferReactiveIdentifiers(fn) {
91878
92171
  const reactiveIds = /* @__PURE__ */ new Set();
@@ -96587,6 +96880,7 @@ function run(func, config, fnType, mode, programContext, logger, filename, code)
96587
96880
  mode,
96588
96881
  config,
96589
96882
  contextIdentifiers,
96883
+ func,
96590
96884
  logger,
96591
96885
  filename,
96592
96886
  code,
@@ -97068,11 +97362,16 @@ function tryFindDirectiveEnablingMemoization(directives, opts) {
97068
97362
  return Err(dynamicGating.unwrapErr());
97069
97363
  }
97070
97364
  }
97071
- function findDirectiveDisablingMemoization(directives) {
97072
- var _a;
97073
- return (_a = directives.find(
97365
+ function findDirectiveDisablingMemoization(directives, { customOptOutDirectives }) {
97366
+ var _a, _b;
97367
+ if (customOptOutDirectives != null) {
97368
+ return (_a = directives.find(
97369
+ (directive2) => customOptOutDirectives.indexOf(directive2.value.value) !== -1
97370
+ )) != null ? _a : null;
97371
+ }
97372
+ return (_b = directives.find(
97074
97373
  (directive2) => OPT_OUT_DIRECTIVES.has(directive2.value.value)
97075
- )) != null ? _a : null;
97374
+ )) != null ? _b : null;
97076
97375
  }
97077
97376
  function findDirectivesDynamicGating(directives, opts) {
97078
97377
  var _a, _b;
@@ -97299,7 +97598,7 @@ function compileProgram(program, pass) {
97299
97598
  filename: pass.filename,
97300
97599
  code: pass.code,
97301
97600
  suppressions,
97302
- hasModuleScopeOptOut: findDirectiveDisablingMemoization(program.node.directives) != null
97601
+ hasModuleScopeOptOut: findDirectiveDisablingMemoization(program.node.directives, pass.opts) != null
97303
97602
  });
97304
97603
  const queue = findFunctionsToCompile(
97305
97604
  program,
@@ -97408,7 +97707,10 @@ function processFn(fn, fnType, programContext) {
97408
97707
  }
97409
97708
  directives = {
97410
97709
  optIn: optIn.unwrapOr(null),
97411
- optOut: findDirectiveDisablingMemoization(fn.node.body.directives)
97710
+ optOut: findDirectiveDisablingMemoization(
97711
+ fn.node.body.directives,
97712
+ programContext.opts
97713
+ )
97412
97714
  };
97413
97715
  }
97414
97716
  let compiledFn;
@@ -98114,6 +98416,7 @@ var PanicThresholdOptionsSchema = z.enum([
98114
98416
  var DynamicGatingOptionsSchema = z.object({
98115
98417
  source: z.string()
98116
98418
  });
98419
+ var CustomOptOutDirectiveSchema = z.nullable(z.array(z.string())).default(null);
98117
98420
  var CompilerReactTargetSchema = z.union([
98118
98421
  z.literal("17"),
98119
98422
  z.literal("18"),
@@ -98164,6 +98467,7 @@ var defaultOptions = {
98164
98467
  return filename.indexOf("node_modules") === -1;
98165
98468
  },
98166
98469
  enableReanimatedCheck: true,
98470
+ customOptOutDirectives: null,
98167
98471
  target: "19"
98168
98472
  };
98169
98473
  function parsePluginOptions(obj) {
@@ -98220,6 +98524,20 @@ function parsePluginOptions(obj) {
98220
98524
  }
98221
98525
  break;
98222
98526
  }
98527
+ case "customOptOutDirectives": {
98528
+ const result = CustomOptOutDirectiveSchema.safeParse(value);
98529
+ if (result.success) {
98530
+ parsedOptions[key2] = result.data;
98531
+ } else {
98532
+ CompilerError.throwInvalidConfig({
98533
+ reason: "Could not parse custom opt out directives. Update React Compiler config to fix the error",
98534
+ description: `${fromZodError(result.error)}`,
98535
+ loc: null,
98536
+ suggestions: null
98537
+ });
98538
+ }
98539
+ break;
98540
+ }
98223
98541
  default: {
98224
98542
  parsedOptions[key2] = value;
98225
98543
  }
@@ -98633,20 +98951,24 @@ var testComplexConfigDefaults = {
98633
98951
  }
98634
98952
  ]
98635
98953
  };
98954
+ function* splitPragma(pragma) {
98955
+ for (const entry of pragma.split("@")) {
98956
+ const keyVal = entry.trim();
98957
+ const valIdx = keyVal.indexOf(":");
98958
+ if (valIdx === -1) {
98959
+ yield { key: keyVal.split(" ", 1)[0], value: null };
98960
+ } else {
98961
+ yield { key: keyVal.slice(0, valIdx), value: keyVal.slice(valIdx + 1) };
98962
+ }
98963
+ }
98964
+ }
98636
98965
  function parseConfigPragmaEnvironmentForTest(pragma) {
98637
98966
  const maybeConfig = {};
98638
- for (const token2 of pragma.split(" ")) {
98639
- if (!token2.startsWith("@")) {
98640
- continue;
98641
- }
98642
- const keyVal = token2.slice(1);
98643
- const valIdx = keyVal.indexOf(":");
98644
- const key2 = valIdx === -1 ? keyVal : keyVal.slice(0, valIdx);
98645
- const val = valIdx === -1 ? void 0 : keyVal.slice(valIdx + 1);
98646
- const isSet = val === void 0 || val === "true";
98967
+ for (const { key: key2, value: val } of splitPragma(pragma)) {
98647
98968
  if (!hasOwnProperty2(EnvironmentConfigSchema.shape, key2)) {
98648
98969
  continue;
98649
98970
  }
98971
+ const isSet = val == null || val === "true";
98650
98972
  if (isSet && key2 in testComplexConfigDefaults) {
98651
98973
  maybeConfig[key2] = testComplexConfigDefaults[key2];
98652
98974
  } else if (isSet) {
@@ -98698,18 +99020,11 @@ function parseConfigPragmaForTests(pragma, defaults) {
98698
99020
  compilationMode: defaults.compilationMode,
98699
99021
  environment
98700
99022
  });
98701
- for (const token2 of pragma.split(" ")) {
98702
- if (!token2.startsWith("@")) {
98703
- continue;
98704
- }
98705
- const keyVal = token2.slice(1);
98706
- const idx = keyVal.indexOf(":");
98707
- const key2 = idx === -1 ? keyVal : keyVal.slice(0, idx);
98708
- const val = idx === -1 ? void 0 : keyVal.slice(idx + 1);
99023
+ for (const { key: key2, value: val } of splitPragma(pragma)) {
98709
99024
  if (!hasOwnProperty2(defaultOptions, key2)) {
98710
99025
  continue;
98711
99026
  }
98712
- const isSet = val === void 0 || val === "true";
99027
+ const isSet = val == null || val === "true";
98713
99028
  if (isSet && key2 in testComplexPluginOptionDefaults) {
98714
99029
  options[key2] = testComplexPluginOptionDefaults[key2];
98715
99030
  } else if (isSet) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "babel-plugin-react-compiler",
3
- "version": "0.0.0-experimental-f980e29-20250522",
3
+ "version": "0.0.0-experimental-a550a97-20250527",
4
4
  "description": "Babel plugin for React Compiler.",
5
5
  "main": "dist/index.js",
6
6
  "license": "MIT",