babel-plugin-react-compiler 0.0.0-experimental-23b8160-20240916 → 0.0.0-experimental-24ec0eb-20240918

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
@@ -139601,6 +139601,8 @@ var InstructionKind;
139601
139601
  InstructionKind['Catch'] = 'Catch';
139602
139602
  InstructionKind['HoistedConst'] = 'HoistedConst';
139603
139603
  InstructionKind['HoistedLet'] = 'HoistedLet';
139604
+ InstructionKind['HoistedFunction'] = 'HoistedFunction';
139605
+ InstructionKind['Function'] = 'Function';
139604
139606
  })(InstructionKind || (InstructionKind = {}));
139605
139607
  function makeTemporaryIdentifier(id, loc) {
139606
139608
  return {
@@ -143160,6 +143162,24 @@ function clonePlaceToTemporary(env, place) {
143160
143162
  temp.reactive = place.reactive;
143161
143163
  return temp;
143162
143164
  }
143165
+ function fixScopeAndIdentifierRanges(func) {
143166
+ var _a, _b;
143167
+ for (const [, block] of func.blocks) {
143168
+ const terminal = block.terminal;
143169
+ if (terminal.kind === 'scope' || terminal.kind === 'pruned-scope') {
143170
+ const fallthroughBlock = func.blocks.get(terminal.fallthrough);
143171
+ const firstId =
143172
+ (_b =
143173
+ (_a = fallthroughBlock.instructions[0]) === null || _a === void 0
143174
+ ? void 0
143175
+ : _a.id) !== null && _b !== void 0
143176
+ ? _b
143177
+ : fallthroughBlock.terminal.id;
143178
+ terminal.scope.range.start = terminal.id;
143179
+ terminal.scope.range.end = firstId;
143180
+ }
143181
+ }
143182
+ }
143163
143183
  const PRIMITIVE_TYPE = {kind: 'Primitive'};
143164
143184
  let nextAnonId = 0;
143165
143185
  function createAnonId() {
@@ -144017,7 +144037,14 @@ function lowerStatement(builder, stmtPath, label = null) {
144017
144037
  if (builder.environment.isHoistedIdentifier(binding.identifier)) {
144018
144038
  continue;
144019
144039
  }
144020
- if (!binding.path.isVariableDeclarator()) {
144040
+ let kind;
144041
+ if (binding.kind === 'const' || binding.kind === 'var') {
144042
+ kind = InstructionKind.HoistedConst;
144043
+ } else if (binding.kind === 'let') {
144044
+ kind = InstructionKind.HoistedLet;
144045
+ } else if (binding.path.isFunctionDeclaration()) {
144046
+ kind = InstructionKind.HoistedFunction;
144047
+ } else if (!binding.path.isVariableDeclarator()) {
144021
144048
  builder.errors.push({
144022
144049
  severity: exports.ErrorSeverity.Todo,
144023
144050
  reason: 'Unsupported declaration type for hoisting',
@@ -144029,11 +144056,7 @@ function lowerStatement(builder, stmtPath, label = null) {
144029
144056
  : GeneratedSource,
144030
144057
  });
144031
144058
  continue;
144032
- } else if (
144033
- binding.kind !== 'const' &&
144034
- binding.kind !== 'var' &&
144035
- binding.kind !== 'let'
144036
- ) {
144059
+ } else {
144037
144060
  builder.errors.push({
144038
144061
  severity: exports.ErrorSeverity.Todo,
144039
144062
  reason: 'Handle non-const declarations for hoisting',
@@ -144065,12 +144088,6 @@ function lowerStatement(builder, stmtPath, label = null) {
144065
144088
  ? _j
144066
144089
  : GeneratedSource,
144067
144090
  };
144068
- const kind =
144069
- binding.kind === 'const' || binding.kind === 'var'
144070
- ? InstructionKind.HoistedConst
144071
- : binding.kind === 'let'
144072
- ? InstructionKind.HoistedLet
144073
- : assertExhaustive(binding.kind, 'Unexpected binding kind');
144074
144091
  lowerValueToTemporary(builder, {
144075
144092
  kind: 'DeclareContext',
144076
144093
  lvalue: {kind: kind, place: place},
@@ -144615,7 +144632,7 @@ function lowerStatement(builder, stmtPath, label = null) {
144615
144632
  (_10 = stmt.node.loc) !== null && _10 !== void 0
144616
144633
  ? _10
144617
144634
  : GeneratedSource,
144618
- InstructionKind.Let,
144635
+ InstructionKind.Function,
144619
144636
  id,
144620
144637
  fn,
144621
144638
  'Assignment'
@@ -147765,7 +147782,6 @@ function lowerType(node) {
147765
147782
  }
147766
147783
  }
147767
147784
  function buildReactiveScopeTerminalsHIR(fn) {
147768
- var _a, _b;
147769
147785
  const queuedRewrites = [];
147770
147786
  recursivelyTraverseItems(
147771
147787
  [...getScopes(fn)],
@@ -147831,21 +147847,7 @@ function buildReactiveScopeTerminalsHIR(fn) {
147831
147847
  reversePostorderBlocks(fn.body);
147832
147848
  markPredecessors(fn.body);
147833
147849
  markInstructionIds(fn.body);
147834
- for (const [, block] of fn.body.blocks) {
147835
- const terminal = block.terminal;
147836
- if (terminal.kind === 'scope' || terminal.kind === 'pruned-scope') {
147837
- const fallthroughBlock = fn.body.blocks.get(terminal.fallthrough);
147838
- const firstId =
147839
- (_b =
147840
- (_a = fallthroughBlock.instructions[0]) === null || _a === void 0
147841
- ? void 0
147842
- : _a.id) !== null && _b !== void 0
147843
- ? _b
147844
- : fallthroughBlock.terminal.id;
147845
- terminal.scope.range.start = terminal.id;
147846
- terminal.scope.range.end = firstId;
147847
- }
147848
- }
147850
+ fixScopeAndIdentifierRanges(fn.body);
147849
147851
  }
147850
147852
  function pushStartScopeTerminal(scope, context) {
147851
147853
  const blockId = context.env.nextBlockId;
@@ -150159,6 +150161,17 @@ const REACT_APIS = [
150159
150161
  returnValueKind: exports.ValueKind.Mutable,
150160
150162
  }),
150161
150163
  ],
150164
+ [
150165
+ 'useImperativeHandle',
150166
+ addHook(DEFAULT_SHAPES, {
150167
+ positionalParams: [],
150168
+ restParam: exports.Effect.Freeze,
150169
+ returnType: {kind: 'Primitive'},
150170
+ calleeEffect: exports.Effect.Read,
150171
+ hookKind: 'useImperativeHandle',
150172
+ returnValueKind: exports.ValueKind.Frozen,
150173
+ }),
150174
+ ],
150162
150175
  [
150163
150176
  'useMemo',
150164
150177
  addHook(DEFAULT_SHAPES, {
@@ -150600,6 +150613,7 @@ const EnvironmentConfigSchema = z.object({
150600
150613
  enableUseTypeAnnotations: z.boolean().default(false),
150601
150614
  enablePropagateDepsInHIR: z.boolean().default(false),
150602
150615
  enableOptionalDependencies: z.boolean().default(true),
150616
+ enableInlineJsxTransform: z.boolean().default(false),
150603
150617
  validateHooksUsage: z.boolean().default(true),
150604
150618
  validateRefAccessDuringRender: z.boolean().default(true),
150605
150619
  validateNoSetStateInRender: z.boolean().default(true),
@@ -155087,6 +155101,380 @@ function instructionMayThrow(instr) {
155087
155101
  }
155088
155102
  }
155089
155103
  }
155104
+ function createSymbolProperty(
155105
+ fn,
155106
+ instr,
155107
+ nextInstructions,
155108
+ propertyName,
155109
+ symbolName
155110
+ ) {
155111
+ const symbolPlace = createTemporaryPlace(fn.env, instr.value.loc);
155112
+ const symbolInstruction = {
155113
+ id: makeInstructionId(0),
155114
+ lvalue: Object.assign(Object.assign({}, symbolPlace), {
155115
+ effect: exports.Effect.Mutate,
155116
+ }),
155117
+ value: {
155118
+ kind: 'LoadGlobal',
155119
+ binding: {kind: 'Global', name: 'Symbol'},
155120
+ loc: instr.value.loc,
155121
+ },
155122
+ loc: instr.loc,
155123
+ };
155124
+ nextInstructions.push(symbolInstruction);
155125
+ const symbolForPlace = createTemporaryPlace(fn.env, instr.value.loc);
155126
+ const symbolForInstruction = {
155127
+ id: makeInstructionId(0),
155128
+ lvalue: Object.assign(Object.assign({}, symbolForPlace), {
155129
+ effect: exports.Effect.Read,
155130
+ }),
155131
+ value: {
155132
+ kind: 'PropertyLoad',
155133
+ object: Object.assign({}, symbolInstruction.lvalue),
155134
+ property: 'for',
155135
+ loc: instr.value.loc,
155136
+ },
155137
+ loc: instr.loc,
155138
+ };
155139
+ nextInstructions.push(symbolForInstruction);
155140
+ const symbolValuePlace = createTemporaryPlace(fn.env, instr.value.loc);
155141
+ const symbolValueInstruction = {
155142
+ id: makeInstructionId(0),
155143
+ lvalue: Object.assign(Object.assign({}, symbolValuePlace), {
155144
+ effect: exports.Effect.Mutate,
155145
+ }),
155146
+ value: {kind: 'Primitive', value: symbolName, loc: instr.value.loc},
155147
+ loc: instr.loc,
155148
+ };
155149
+ nextInstructions.push(symbolValueInstruction);
155150
+ const $$typeofPlace = createTemporaryPlace(fn.env, instr.value.loc);
155151
+ const $$typeofInstruction = {
155152
+ id: makeInstructionId(0),
155153
+ lvalue: Object.assign(Object.assign({}, $$typeofPlace), {
155154
+ effect: exports.Effect.Mutate,
155155
+ }),
155156
+ value: {
155157
+ kind: 'MethodCall',
155158
+ receiver: symbolInstruction.lvalue,
155159
+ property: symbolForInstruction.lvalue,
155160
+ args: [symbolValueInstruction.lvalue],
155161
+ loc: instr.value.loc,
155162
+ },
155163
+ loc: instr.loc,
155164
+ };
155165
+ const $$typeofProperty = {
155166
+ kind: 'ObjectProperty',
155167
+ key: {name: propertyName, kind: 'string'},
155168
+ type: 'property',
155169
+ place: Object.assign(Object.assign({}, $$typeofPlace), {
155170
+ effect: exports.Effect.Capture,
155171
+ }),
155172
+ };
155173
+ nextInstructions.push($$typeofInstruction);
155174
+ return $$typeofProperty;
155175
+ }
155176
+ function createTagProperty(fn, instr, nextInstructions, componentTag) {
155177
+ let tagProperty;
155178
+ switch (componentTag.kind) {
155179
+ case 'BuiltinTag': {
155180
+ const tagPropertyPlace = createTemporaryPlace(fn.env, instr.value.loc);
155181
+ const tagInstruction = {
155182
+ id: makeInstructionId(0),
155183
+ lvalue: Object.assign(Object.assign({}, tagPropertyPlace), {
155184
+ effect: exports.Effect.Mutate,
155185
+ }),
155186
+ value: {
155187
+ kind: 'Primitive',
155188
+ value: componentTag.name,
155189
+ loc: instr.value.loc,
155190
+ },
155191
+ loc: instr.loc,
155192
+ };
155193
+ tagProperty = {
155194
+ kind: 'ObjectProperty',
155195
+ key: {name: 'type', kind: 'string'},
155196
+ type: 'property',
155197
+ place: Object.assign(Object.assign({}, tagPropertyPlace), {
155198
+ effect: exports.Effect.Capture,
155199
+ }),
155200
+ };
155201
+ nextInstructions.push(tagInstruction);
155202
+ break;
155203
+ }
155204
+ case 'Identifier': {
155205
+ tagProperty = {
155206
+ kind: 'ObjectProperty',
155207
+ key: {name: 'type', kind: 'string'},
155208
+ type: 'property',
155209
+ place: Object.assign(Object.assign({}, componentTag), {
155210
+ effect: exports.Effect.Capture,
155211
+ }),
155212
+ };
155213
+ break;
155214
+ }
155215
+ }
155216
+ return tagProperty;
155217
+ }
155218
+ function createPropsProperties(
155219
+ fn,
155220
+ instr,
155221
+ nextInstructions,
155222
+ propAttributes,
155223
+ children
155224
+ ) {
155225
+ let refProperty;
155226
+ let keyProperty;
155227
+ const props = [];
155228
+ propAttributes.forEach(prop => {
155229
+ switch (prop.kind) {
155230
+ case 'JsxAttribute': {
155231
+ if (prop.name === 'ref') {
155232
+ refProperty = {
155233
+ kind: 'ObjectProperty',
155234
+ key: {name: 'ref', kind: 'string'},
155235
+ type: 'property',
155236
+ place: Object.assign({}, prop.place),
155237
+ };
155238
+ } else if (prop.name === 'key') {
155239
+ keyProperty = {
155240
+ kind: 'ObjectProperty',
155241
+ key: {name: 'key', kind: 'string'},
155242
+ type: 'property',
155243
+ place: Object.assign({}, prop.place),
155244
+ };
155245
+ } else {
155246
+ const attributeProperty = {
155247
+ kind: 'ObjectProperty',
155248
+ key: {name: prop.name, kind: 'string'},
155249
+ type: 'property',
155250
+ place: Object.assign({}, prop.place),
155251
+ };
155252
+ props.push(attributeProperty);
155253
+ }
155254
+ break;
155255
+ }
155256
+ case 'JsxSpreadAttribute': {
155257
+ props.push({kind: 'Spread', place: Object.assign({}, prop.argument)});
155258
+ break;
155259
+ }
155260
+ }
155261
+ });
155262
+ const propsPropertyPlace = createTemporaryPlace(fn.env, instr.value.loc);
155263
+ if (children) {
155264
+ let childrenPropProperty;
155265
+ if (children.length === 1) {
155266
+ childrenPropProperty = {
155267
+ kind: 'ObjectProperty',
155268
+ key: {name: 'children', kind: 'string'},
155269
+ type: 'property',
155270
+ place: Object.assign(Object.assign({}, children[0]), {
155271
+ effect: exports.Effect.Capture,
155272
+ }),
155273
+ };
155274
+ } else {
155275
+ const childrenPropPropertyPlace = createTemporaryPlace(
155276
+ fn.env,
155277
+ instr.value.loc
155278
+ );
155279
+ const childrenPropInstruction = {
155280
+ id: makeInstructionId(0),
155281
+ lvalue: Object.assign(Object.assign({}, childrenPropPropertyPlace), {
155282
+ effect: exports.Effect.Mutate,
155283
+ }),
155284
+ value: {
155285
+ kind: 'ArrayExpression',
155286
+ elements: [...children],
155287
+ loc: instr.value.loc,
155288
+ },
155289
+ loc: instr.loc,
155290
+ };
155291
+ nextInstructions.push(childrenPropInstruction);
155292
+ childrenPropProperty = {
155293
+ kind: 'ObjectProperty',
155294
+ key: {name: 'children', kind: 'string'},
155295
+ type: 'property',
155296
+ place: Object.assign(Object.assign({}, childrenPropPropertyPlace), {
155297
+ effect: exports.Effect.Capture,
155298
+ }),
155299
+ };
155300
+ }
155301
+ props.push(childrenPropProperty);
155302
+ }
155303
+ if (refProperty == null) {
155304
+ const refPropertyPlace = createTemporaryPlace(fn.env, instr.value.loc);
155305
+ const refInstruction = {
155306
+ id: makeInstructionId(0),
155307
+ lvalue: Object.assign(Object.assign({}, refPropertyPlace), {
155308
+ effect: exports.Effect.Mutate,
155309
+ }),
155310
+ value: {kind: 'Primitive', value: null, loc: instr.value.loc},
155311
+ loc: instr.loc,
155312
+ };
155313
+ refProperty = {
155314
+ kind: 'ObjectProperty',
155315
+ key: {name: 'ref', kind: 'string'},
155316
+ type: 'property',
155317
+ place: Object.assign(Object.assign({}, refPropertyPlace), {
155318
+ effect: exports.Effect.Capture,
155319
+ }),
155320
+ };
155321
+ nextInstructions.push(refInstruction);
155322
+ }
155323
+ if (keyProperty == null) {
155324
+ const keyPropertyPlace = createTemporaryPlace(fn.env, instr.value.loc);
155325
+ const keyInstruction = {
155326
+ id: makeInstructionId(0),
155327
+ lvalue: Object.assign(Object.assign({}, keyPropertyPlace), {
155328
+ effect: exports.Effect.Mutate,
155329
+ }),
155330
+ value: {kind: 'Primitive', value: null, loc: instr.value.loc},
155331
+ loc: instr.loc,
155332
+ };
155333
+ keyProperty = {
155334
+ kind: 'ObjectProperty',
155335
+ key: {name: 'key', kind: 'string'},
155336
+ type: 'property',
155337
+ place: Object.assign(Object.assign({}, keyPropertyPlace), {
155338
+ effect: exports.Effect.Capture,
155339
+ }),
155340
+ };
155341
+ nextInstructions.push(keyInstruction);
155342
+ }
155343
+ const propsInstruction = {
155344
+ id: makeInstructionId(0),
155345
+ lvalue: Object.assign(Object.assign({}, propsPropertyPlace), {
155346
+ effect: exports.Effect.Mutate,
155347
+ }),
155348
+ value: {kind: 'ObjectExpression', properties: props, loc: instr.value.loc},
155349
+ loc: instr.loc,
155350
+ };
155351
+ const propsProperty = {
155352
+ kind: 'ObjectProperty',
155353
+ key: {name: 'props', kind: 'string'},
155354
+ type: 'property',
155355
+ place: Object.assign(Object.assign({}, propsPropertyPlace), {
155356
+ effect: exports.Effect.Capture,
155357
+ }),
155358
+ };
155359
+ nextInstructions.push(propsInstruction);
155360
+ return {
155361
+ refProperty: refProperty,
155362
+ keyProperty: keyProperty,
155363
+ propsProperty: propsProperty,
155364
+ };
155365
+ }
155366
+ function inlineJsxTransform(fn) {
155367
+ for (const [, block] of fn.body.blocks) {
155368
+ let nextInstructions = null;
155369
+ for (let i = 0; i < block.instructions.length; i++) {
155370
+ const instr = block.instructions[i];
155371
+ switch (instr.value.kind) {
155372
+ case 'JsxExpression': {
155373
+ nextInstructions !== null && nextInstructions !== void 0
155374
+ ? nextInstructions
155375
+ : (nextInstructions = block.instructions.slice(0, i));
155376
+ const {
155377
+ refProperty: refProperty,
155378
+ keyProperty: keyProperty,
155379
+ propsProperty: propsProperty,
155380
+ } = createPropsProperties(
155381
+ fn,
155382
+ instr,
155383
+ nextInstructions,
155384
+ instr.value.props,
155385
+ instr.value.children
155386
+ );
155387
+ const reactElementInstruction = {
155388
+ id: makeInstructionId(0),
155389
+ lvalue: Object.assign(Object.assign({}, instr.lvalue), {
155390
+ effect: exports.Effect.Store,
155391
+ }),
155392
+ value: {
155393
+ kind: 'ObjectExpression',
155394
+ properties: [
155395
+ createSymbolProperty(
155396
+ fn,
155397
+ instr,
155398
+ nextInstructions,
155399
+ '$$typeof',
155400
+ 'react.transitional.element'
155401
+ ),
155402
+ createTagProperty(fn, instr, nextInstructions, instr.value.tag),
155403
+ refProperty,
155404
+ keyProperty,
155405
+ propsProperty,
155406
+ ],
155407
+ loc: instr.value.loc,
155408
+ },
155409
+ loc: instr.loc,
155410
+ };
155411
+ nextInstructions.push(reactElementInstruction);
155412
+ break;
155413
+ }
155414
+ case 'JsxFragment': {
155415
+ nextInstructions !== null && nextInstructions !== void 0
155416
+ ? nextInstructions
155417
+ : (nextInstructions = block.instructions.slice(0, i));
155418
+ const {
155419
+ refProperty: refProperty,
155420
+ keyProperty: keyProperty,
155421
+ propsProperty: propsProperty,
155422
+ } = createPropsProperties(
155423
+ fn,
155424
+ instr,
155425
+ nextInstructions,
155426
+ [],
155427
+ instr.value.children
155428
+ );
155429
+ const reactElementInstruction = {
155430
+ id: makeInstructionId(0),
155431
+ lvalue: Object.assign(Object.assign({}, instr.lvalue), {
155432
+ effect: exports.Effect.Store,
155433
+ }),
155434
+ value: {
155435
+ kind: 'ObjectExpression',
155436
+ properties: [
155437
+ createSymbolProperty(
155438
+ fn,
155439
+ instr,
155440
+ nextInstructions,
155441
+ '$$typeof',
155442
+ 'react.transitional.element'
155443
+ ),
155444
+ createSymbolProperty(
155445
+ fn,
155446
+ instr,
155447
+ nextInstructions,
155448
+ 'type',
155449
+ 'react.fragment'
155450
+ ),
155451
+ refProperty,
155452
+ keyProperty,
155453
+ propsProperty,
155454
+ ],
155455
+ loc: instr.value.loc,
155456
+ },
155457
+ loc: instr.loc,
155458
+ };
155459
+ nextInstructions.push(reactElementInstruction);
155460
+ break;
155461
+ }
155462
+ default: {
155463
+ if (nextInstructions !== null) {
155464
+ nextInstructions.push(instr);
155465
+ }
155466
+ }
155467
+ }
155468
+ }
155469
+ if (nextInstructions !== null) {
155470
+ block.instructions = nextInstructions;
155471
+ }
155472
+ }
155473
+ reversePostorderBlocks(fn.body);
155474
+ markPredecessors(fn.body);
155475
+ markInstructionIds(fn.body);
155476
+ fixScopeAndIdentifierRanges(fn.body);
155477
+ }
155090
155478
  function findScopesToMerge(fn) {
155091
155479
  const objectMethodDecls = new Set();
155092
155480
  const mergeScopesBuilder = new DisjointSet();
@@ -157991,22 +158379,12 @@ function codegenTerminal(cx, terminal) {
157991
158379
  suggestions: null,
157992
158380
  });
157993
158381
  case InstructionKind.Catch:
157994
- CompilerError.invariant(false, {
157995
- reason: 'Unexpected catch variable as for..in collection',
157996
- description: null,
157997
- loc: iterableItem.loc,
157998
- suggestions: null,
157999
- });
158000
158382
  case InstructionKind.HoistedConst:
158001
- CompilerError.invariant(false, {
158002
- reason: 'Unexpected HoistedConst variable in for..in collection',
158003
- description: null,
158004
- loc: iterableItem.loc,
158005
- suggestions: null,
158006
- });
158007
158383
  case InstructionKind.HoistedLet:
158384
+ case InstructionKind.HoistedFunction:
158385
+ case InstructionKind.Function:
158008
158386
  CompilerError.invariant(false, {
158009
- reason: 'Unexpected HoistedLet variable in for..in collection',
158387
+ reason: `Unexpected ${iterableItem.value.lvalue.kind} variable in for..in collection`,
158010
158388
  description: null,
158011
158389
  loc: iterableItem.loc,
158012
158390
  suggestions: null,
@@ -158080,30 +158458,13 @@ function codegenTerminal(cx, terminal) {
158080
158458
  varDeclKind = 'let';
158081
158459
  break;
158082
158460
  case InstructionKind.Reassign:
158083
- CompilerError.invariant(false, {
158084
- reason:
158085
- 'Destructure should never be Reassign as it would be an Object/ArrayPattern',
158086
- description: null,
158087
- loc: iterableItem.loc,
158088
- suggestions: null,
158089
- });
158090
158461
  case InstructionKind.Catch:
158091
- CompilerError.invariant(false, {
158092
- reason: 'Unexpected catch variable as for..of collection',
158093
- description: null,
158094
- loc: iterableItem.loc,
158095
- suggestions: null,
158096
- });
158097
158462
  case InstructionKind.HoistedConst:
158098
- CompilerError.invariant(false, {
158099
- reason: 'Unexpected HoistedConst variable in for..of collection',
158100
- description: null,
158101
- loc: iterableItem.loc,
158102
- suggestions: null,
158103
- });
158104
158463
  case InstructionKind.HoistedLet:
158464
+ case InstructionKind.HoistedFunction:
158465
+ case InstructionKind.Function:
158105
158466
  CompilerError.invariant(false, {
158106
- reason: 'Unexpected HoistedLet variable in for..of collection',
158467
+ reason: `Unexpected ${iterableItem.value.lvalue.kind} variable in for..of collection`,
158107
158468
  description: null,
158108
158469
  loc: iterableItem.loc,
158109
158470
  suggestions: null,
@@ -158262,6 +158623,39 @@ function codegenInstructionNullable(cx, instr) {
158262
158623
  t__namespace.variableDeclarator(codegenLValue(cx, lvalue), value),
158263
158624
  ]);
158264
158625
  }
158626
+ case InstructionKind.Function: {
158627
+ CompilerError.invariant(instr.lvalue === null, {
158628
+ reason: `Function declaration cannot be referenced as an expression`,
158629
+ description: null,
158630
+ loc: instr.value.loc,
158631
+ suggestions: null,
158632
+ });
158633
+ const genLvalue = codegenLValue(cx, lvalue);
158634
+ CompilerError.invariant(genLvalue.type === 'Identifier', {
158635
+ reason: 'Expected an identifier as a function declaration lvalue',
158636
+ description: null,
158637
+ loc: instr.value.loc,
158638
+ suggestions: null,
158639
+ });
158640
+ CompilerError.invariant(
158641
+ (value === null || value === void 0 ? void 0 : value.type) ===
158642
+ 'FunctionExpression',
158643
+ {
158644
+ reason: 'Expected a function as a function declaration value',
158645
+ description: null,
158646
+ loc: instr.value.loc,
158647
+ suggestions: null,
158648
+ }
158649
+ );
158650
+ return createFunctionDeclaration(
158651
+ instr.loc,
158652
+ genLvalue,
158653
+ value.params,
158654
+ value.body,
158655
+ value.generator,
158656
+ value.async
158657
+ );
158658
+ }
158265
158659
  case InstructionKind.Let: {
158266
158660
  CompilerError.invariant(instr.lvalue === null, {
158267
158661
  reason: `Const declaration cannot be referenced as an expression`,
@@ -158303,19 +158697,11 @@ function codegenInstructionNullable(cx, instr) {
158303
158697
  case InstructionKind.Catch: {
158304
158698
  return t__namespace.emptyStatement();
158305
158699
  }
158306
- case InstructionKind.HoistedLet: {
158700
+ case InstructionKind.HoistedLet:
158701
+ case InstructionKind.HoistedConst:
158702
+ case InstructionKind.HoistedFunction: {
158307
158703
  CompilerError.invariant(false, {
158308
- reason:
158309
- 'Expected HoistedLet to have been pruned in PruneHoistedContexts',
158310
- description: null,
158311
- loc: instr.loc,
158312
- suggestions: null,
158313
- });
158314
- }
158315
- case InstructionKind.HoistedConst: {
158316
- CompilerError.invariant(false, {
158317
- reason:
158318
- 'Expected HoistedConsts to have been pruned in PruneHoistedContexts',
158704
+ reason: `Expected ${kind} to have been pruned in PruneHoistedContexts`,
158319
158705
  description: null,
158320
158706
  loc: instr.loc,
158321
158707
  suggestions: null,
@@ -158463,6 +158849,7 @@ function withLoc(fn) {
158463
158849
  const createBinaryExpression = withLoc(t__namespace.binaryExpression);
158464
158850
  const createExpressionStatement = withLoc(t__namespace.expressionStatement);
158465
158851
  const createVariableDeclaration = withLoc(t__namespace.variableDeclaration);
158852
+ const createFunctionDeclaration = withLoc(t__namespace.functionDeclaration);
158466
158853
  const createTaggedTemplateExpression = withLoc(
158467
158854
  t__namespace.taggedTemplateExpression
158468
158855
  );
@@ -162063,6 +162450,16 @@ let Visitor$8 = class Visitor extends ReactiveFunctionTransform {
162063
162450
  );
162064
162451
  return {kind: 'remove'};
162065
162452
  }
162453
+ if (
162454
+ instruction.value.kind === 'DeclareContext' &&
162455
+ instruction.value.lvalue.kind === 'HoistedFunction'
162456
+ ) {
162457
+ state.set(
162458
+ instruction.value.lvalue.place.identifier.declarationId,
162459
+ InstructionKind.Function
162460
+ );
162461
+ return {kind: 'remove'};
162462
+ }
162066
162463
  if (
162067
162464
  instruction.value.kind === 'StoreContext' &&
162068
162465
  state.has(instruction.value.lvalue.place.identifier.declarationId)
@@ -167172,7 +167569,7 @@ function equation(left, right) {
167172
167569
  return {left: left, right: right};
167173
167570
  }
167174
167571
  function* generate(func) {
167175
- if (func.env.fnType === 'Component') {
167572
+ if (func.fnType === 'Component') {
167176
167573
  const [props, ref] = func.params;
167177
167574
  if (props && props.kind === 'Identifier') {
167178
167575
  yield equation(props.identifier.type, {
@@ -168204,16 +168601,131 @@ function validateNoCapitalizedCalls(fn) {
168204
168601
  }
168205
168602
  }
168206
168603
  }
168604
+ var _Env_changed;
168605
+ class Env extends Map {
168606
+ constructor() {
168607
+ super(...arguments);
168608
+ _Env_changed.set(this, false);
168609
+ }
168610
+ resetChanged() {
168611
+ __classPrivateFieldSet(this, _Env_changed, false, 'f');
168612
+ }
168613
+ hasChanged() {
168614
+ return __classPrivateFieldGet(this, _Env_changed, 'f');
168615
+ }
168616
+ set(key, value) {
168617
+ const cur = this.get(key);
168618
+ const widenedValue = joinRefAccessTypes(
168619
+ value,
168620
+ cur !== null && cur !== void 0 ? cur : {kind: 'None'}
168621
+ );
168622
+ if (
168623
+ !(cur == null && widenedValue.kind === 'None') &&
168624
+ (cur == null || !tyEqual(cur, widenedValue))
168625
+ ) {
168626
+ __classPrivateFieldSet(this, _Env_changed, true, 'f');
168627
+ }
168628
+ return super.set(key, widenedValue);
168629
+ }
168630
+ }
168631
+ _Env_changed = new WeakMap();
168207
168632
  function validateNoRefAccessInRender(fn) {
168208
- const state = {
168209
- refs: new Set(),
168210
- refValues: new Map(),
168211
- refAccessingFunctions: new Set(),
168212
- };
168213
- validateNoRefAccessInRenderImpl(fn, state).unwrap();
168633
+ const env = new Env();
168634
+ validateNoRefAccessInRenderImpl(fn, env).unwrap();
168635
+ }
168636
+ function refTypeOfType(identifier) {
168637
+ if (isRefValueType(identifier)) {
168638
+ return {kind: 'RefValue'};
168639
+ } else if (isUseRefType(identifier)) {
168640
+ return {kind: 'Ref'};
168641
+ } else {
168642
+ return {kind: 'None'};
168643
+ }
168214
168644
  }
168215
- function validateNoRefAccessInRenderImpl(fn, state) {
168216
- var _a, _b;
168645
+ function tyEqual(a, b) {
168646
+ if (a.kind !== b.kind) {
168647
+ return false;
168648
+ }
168649
+ switch (a.kind) {
168650
+ case 'None':
168651
+ return true;
168652
+ case 'Ref':
168653
+ return true;
168654
+ case 'RefValue':
168655
+ CompilerError.invariant(b.kind === 'RefValue', {
168656
+ reason: 'Expected ref value',
168657
+ loc: null,
168658
+ });
168659
+ return a.loc == b.loc;
168660
+ case 'Structure': {
168661
+ CompilerError.invariant(b.kind === 'Structure', {
168662
+ reason: 'Expected structure',
168663
+ loc: null,
168664
+ });
168665
+ const fnTypesEqual =
168666
+ (a.fn === null && b.fn === null) ||
168667
+ (a.fn !== null &&
168668
+ b.fn !== null &&
168669
+ a.fn.readRefEffect === b.fn.readRefEffect &&
168670
+ tyEqual(a.fn.returnType, b.fn.returnType));
168671
+ return (
168672
+ fnTypesEqual &&
168673
+ (a.value === b.value ||
168674
+ (a.value !== null && b.value !== null && tyEqual(a.value, b.value)))
168675
+ );
168676
+ }
168677
+ }
168678
+ }
168679
+ function joinRefAccessTypes(...types) {
168680
+ function joinRefAccessRefTypes(a, b) {
168681
+ if (a.kind === 'RefValue') {
168682
+ return a;
168683
+ } else if (b.kind === 'RefValue') {
168684
+ return b;
168685
+ } else if (a.kind === 'Ref' || b.kind === 'Ref') {
168686
+ return {kind: 'Ref'};
168687
+ } else {
168688
+ CompilerError.invariant(
168689
+ a.kind === 'Structure' && b.kind === 'Structure',
168690
+ {reason: 'Expected structure', loc: null}
168691
+ );
168692
+ const fn =
168693
+ a.fn === null
168694
+ ? b.fn
168695
+ : b.fn === null
168696
+ ? a.fn
168697
+ : {
168698
+ readRefEffect: a.fn.readRefEffect || b.fn.readRefEffect,
168699
+ returnType: joinRefAccessTypes(
168700
+ a.fn.returnType,
168701
+ b.fn.returnType
168702
+ ),
168703
+ };
168704
+ const value =
168705
+ a.value === null
168706
+ ? b.value
168707
+ : b.value === null
168708
+ ? a.value
168709
+ : joinRefAccessRefTypes(a.value, b.value);
168710
+ return {kind: 'Structure', fn: fn, value: value};
168711
+ }
168712
+ }
168713
+ return types.reduce(
168714
+ (a, b) => {
168715
+ if (a.kind === 'None') {
168716
+ return b;
168717
+ } else if (b.kind === 'None') {
168718
+ return a;
168719
+ } else {
168720
+ return joinRefAccessRefTypes(a, b);
168721
+ }
168722
+ },
168723
+ {kind: 'None'}
168724
+ );
168725
+ }
168726
+ function validateNoRefAccessInRenderImpl(fn, env) {
168727
+ var _a, _b, _c, _d, _e, _f;
168728
+ let returnValues = [];
168217
168729
  let place;
168218
168730
  for (const param of fn.params) {
168219
168731
  if (param.kind === 'Identifier') {
@@ -168221,291 +168733,293 @@ function validateNoRefAccessInRenderImpl(fn, state) {
168221
168733
  } else {
168222
168734
  place = param.place;
168223
168735
  }
168224
- if (isRefValueType(place.identifier)) {
168225
- state.refValues.set(place.identifier.id, null);
168226
- }
168227
- if (isUseRefType(place.identifier)) {
168228
- state.refs.add(place.identifier.id);
168229
- }
168736
+ const type = refTypeOfType(place.identifier);
168737
+ env.set(place.identifier.id, type);
168230
168738
  }
168231
- const errors = new CompilerError();
168232
- for (const [, block] of fn.body.blocks) {
168233
- for (const phi of block.phis) {
168234
- phi.operands.forEach(operand => {
168235
- var _a;
168236
- if (state.refs.has(operand.id) || isUseRefType(phi.id)) {
168237
- state.refs.add(phi.id.id);
168238
- }
168239
- const refValue = state.refValues.get(operand.id);
168240
- if (refValue !== undefined || isRefValueType(operand)) {
168241
- state.refValues.set(
168242
- phi.id.id,
168243
- (_a =
168244
- refValue !== null && refValue !== void 0
168245
- ? refValue
168246
- : state.refValues.get(phi.id.id)) !== null && _a !== void 0
168247
- ? _a
168248
- : null
168249
- );
168250
- }
168251
- if (state.refAccessingFunctions.has(operand.id)) {
168252
- state.refAccessingFunctions.add(phi.id.id);
168253
- }
168254
- });
168255
- }
168256
- for (const instr of block.instructions) {
168257
- for (const operand of eachInstructionValueOperand(instr.value)) {
168258
- if (isRefValueType(operand.identifier)) {
168259
- CompilerError.invariant(state.refValues.has(operand.identifier.id), {
168260
- reason: 'Expected ref value to be in state',
168261
- loc: operand.loc,
168262
- });
168263
- }
168264
- if (isUseRefType(operand.identifier)) {
168265
- CompilerError.invariant(state.refs.has(operand.identifier.id), {
168266
- reason: 'Expected ref to be in state',
168267
- loc: operand.loc,
168268
- });
168269
- }
168739
+ for (let i = 0; (i == 0 || env.hasChanged()) && i < 10; i++) {
168740
+ env.resetChanged();
168741
+ returnValues = [];
168742
+ const errors = new CompilerError();
168743
+ for (const [, block] of fn.body.blocks) {
168744
+ for (const phi of block.phis) {
168745
+ env.set(
168746
+ phi.id.id,
168747
+ joinRefAccessTypes(
168748
+ ...Array(...phi.operands.values()).map(operand => {
168749
+ var _a;
168750
+ return (_a = env.get(operand.id)) !== null && _a !== void 0
168751
+ ? _a
168752
+ : {kind: 'None'};
168753
+ })
168754
+ )
168755
+ );
168270
168756
  }
168271
- switch (instr.value.kind) {
168272
- case 'JsxExpression':
168273
- case 'JsxFragment': {
168274
- for (const operand of eachInstructionValueOperand(instr.value)) {
168275
- validateNoDirectRefValueAccess(errors, operand, state);
168276
- }
168277
- break;
168278
- }
168279
- case 'ComputedLoad':
168280
- case 'PropertyLoad': {
168281
- if (typeof instr.value.property !== 'string') {
168282
- validateNoRefValueAccess(errors, state, instr.value.property);
168283
- }
168284
- if (
168285
- state.refAccessingFunctions.has(instr.value.object.identifier.id)
168286
- ) {
168287
- state.refAccessingFunctions.add(instr.lvalue.identifier.id);
168288
- }
168289
- if (state.refs.has(instr.value.object.identifier.id)) {
168290
- state.refs.add(instr.lvalue.identifier.id);
168291
- state.refValues.set(instr.lvalue.identifier.id, instr.loc);
168292
- }
168293
- break;
168294
- }
168295
- case 'LoadContext':
168296
- case 'LoadLocal': {
168297
- if (
168298
- state.refAccessingFunctions.has(instr.value.place.identifier.id)
168299
- ) {
168300
- state.refAccessingFunctions.add(instr.lvalue.identifier.id);
168301
- }
168302
- const refValue = state.refValues.get(instr.value.place.identifier.id);
168303
- if (refValue !== undefined) {
168304
- state.refValues.set(instr.lvalue.identifier.id, refValue);
168757
+ for (const instr of block.instructions) {
168758
+ switch (instr.value.kind) {
168759
+ case 'JsxExpression':
168760
+ case 'JsxFragment': {
168761
+ for (const operand of eachInstructionValueOperand(instr.value)) {
168762
+ validateNoDirectRefValueAccess(errors, operand, env);
168763
+ }
168764
+ break;
168305
168765
  }
168306
- if (state.refs.has(instr.value.place.identifier.id)) {
168307
- state.refs.add(instr.lvalue.identifier.id);
168766
+ case 'ComputedLoad':
168767
+ case 'PropertyLoad': {
168768
+ if (typeof instr.value.property !== 'string') {
168769
+ validateNoDirectRefValueAccess(errors, instr.value.property, env);
168770
+ }
168771
+ const objType = env.get(instr.value.object.identifier.id);
168772
+ let lookupType = null;
168773
+ if (
168774
+ (objType === null || objType === void 0
168775
+ ? void 0
168776
+ : objType.kind) === 'Structure'
168777
+ ) {
168778
+ lookupType = objType.value;
168779
+ } else if (
168780
+ (objType === null || objType === void 0
168781
+ ? void 0
168782
+ : objType.kind) === 'Ref'
168783
+ ) {
168784
+ lookupType = {kind: 'RefValue', loc: instr.loc};
168785
+ }
168786
+ env.set(
168787
+ instr.lvalue.identifier.id,
168788
+ lookupType !== null && lookupType !== void 0
168789
+ ? lookupType
168790
+ : refTypeOfType(instr.lvalue.identifier)
168791
+ );
168792
+ break;
168308
168793
  }
168309
- break;
168310
- }
168311
- case 'StoreContext':
168312
- case 'StoreLocal': {
168313
- if (
168314
- state.refAccessingFunctions.has(instr.value.value.identifier.id)
168315
- ) {
168316
- state.refAccessingFunctions.add(
168317
- instr.value.lvalue.place.identifier.id
168794
+ case 'LoadContext':
168795
+ case 'LoadLocal': {
168796
+ env.set(
168797
+ instr.lvalue.identifier.id,
168798
+ (_a = env.get(instr.value.place.identifier.id)) !== null &&
168799
+ _a !== void 0
168800
+ ? _a
168801
+ : refTypeOfType(instr.lvalue.identifier)
168318
168802
  );
168319
- state.refAccessingFunctions.add(instr.lvalue.identifier.id);
168803
+ break;
168320
168804
  }
168321
- const refValue = state.refValues.get(instr.value.value.identifier.id);
168322
- if (
168323
- refValue !== undefined ||
168324
- isRefValueType(instr.value.lvalue.place.identifier)
168325
- ) {
168326
- state.refValues.set(
168805
+ case 'StoreContext':
168806
+ case 'StoreLocal': {
168807
+ env.set(
168327
168808
  instr.value.lvalue.place.identifier.id,
168328
- refValue !== null && refValue !== void 0 ? refValue : null
168809
+ (_b = env.get(instr.value.value.identifier.id)) !== null &&
168810
+ _b !== void 0
168811
+ ? _b
168812
+ : refTypeOfType(instr.value.lvalue.place.identifier)
168329
168813
  );
168330
- state.refValues.set(
168814
+ env.set(
168331
168815
  instr.lvalue.identifier.id,
168332
- refValue !== null && refValue !== void 0 ? refValue : null
168816
+ (_c = env.get(instr.value.value.identifier.id)) !== null &&
168817
+ _c !== void 0
168818
+ ? _c
168819
+ : refTypeOfType(instr.lvalue.identifier)
168333
168820
  );
168821
+ break;
168334
168822
  }
168335
- if (state.refs.has(instr.value.value.identifier.id)) {
168336
- state.refs.add(instr.value.lvalue.place.identifier.id);
168337
- state.refs.add(instr.lvalue.identifier.id);
168338
- }
168339
- break;
168340
- }
168341
- case 'Destructure': {
168342
- const destructuredFunction = state.refAccessingFunctions.has(
168343
- instr.value.value.identifier.id
168344
- );
168345
- const destructuredRef = state.refs.has(
168346
- instr.value.value.identifier.id
168347
- );
168348
- for (const lval of eachPatternOperand(instr.value.lvalue.pattern)) {
168349
- if (isUseRefType(lval.identifier)) {
168350
- state.refs.add(lval.identifier.id);
168351
- }
168352
- if (destructuredRef || isRefValueType(lval.identifier)) {
168353
- state.refs.add(lval.identifier.id);
168354
- state.refValues.set(lval.identifier.id, null);
168823
+ case 'Destructure': {
168824
+ const objType = env.get(instr.value.value.identifier.id);
168825
+ let lookupType = null;
168826
+ if (
168827
+ (objType === null || objType === void 0
168828
+ ? void 0
168829
+ : objType.kind) === 'Structure'
168830
+ ) {
168831
+ lookupType = objType.value;
168355
168832
  }
168356
- if (destructuredFunction) {
168357
- state.refAccessingFunctions.add(lval.identifier.id);
168833
+ env.set(
168834
+ instr.lvalue.identifier.id,
168835
+ lookupType !== null && lookupType !== void 0
168836
+ ? lookupType
168837
+ : refTypeOfType(instr.lvalue.identifier)
168838
+ );
168839
+ for (const lval of eachPatternOperand(instr.value.lvalue.pattern)) {
168840
+ env.set(
168841
+ lval.identifier.id,
168842
+ lookupType !== null && lookupType !== void 0
168843
+ ? lookupType
168844
+ : refTypeOfType(lval.identifier)
168845
+ );
168358
168846
  }
168847
+ break;
168359
168848
  }
168360
- break;
168361
- }
168362
- case 'ObjectMethod':
168363
- case 'FunctionExpression': {
168364
- if (
168365
- [...eachInstructionValueOperand(instr.value)].some(
168366
- operand =>
168367
- state.refValues.has(operand.identifier.id) ||
168368
- state.refAccessingFunctions.has(operand.identifier.id)
168369
- ) ||
168370
- ([...eachInstructionValueOperand(instr.value)].some(operand =>
168371
- state.refs.has(operand.identifier.id)
168372
- ) &&
168373
- validateNoRefAccessInRenderImpl(
168374
- instr.value.loweredFunc.func,
168375
- state
168376
- ).isErr())
168377
- ) {
168378
- state.refAccessingFunctions.add(instr.lvalue.identifier.id);
168849
+ case 'ObjectMethod':
168850
+ case 'FunctionExpression': {
168851
+ let returnType = {kind: 'None'};
168852
+ let readRefEffect = false;
168853
+ const result = validateNoRefAccessInRenderImpl(
168854
+ instr.value.loweredFunc.func,
168855
+ env
168856
+ );
168857
+ if (result.isOk()) {
168858
+ returnType = result.unwrap();
168859
+ } else if (result.isErr()) {
168860
+ readRefEffect = true;
168861
+ }
168862
+ env.set(instr.lvalue.identifier.id, {
168863
+ kind: 'Structure',
168864
+ fn: {readRefEffect: readRefEffect, returnType: returnType},
168865
+ value: null,
168866
+ });
168867
+ break;
168379
168868
  }
168380
- break;
168381
- }
168382
- case 'MethodCall': {
168383
- if (!isEffectHook(instr.value.property.identifier)) {
168869
+ case 'MethodCall':
168870
+ case 'CallExpression': {
168871
+ const callee =
168872
+ instr.value.kind === 'CallExpression'
168873
+ ? instr.value.callee
168874
+ : instr.value.property;
168875
+ const hookKind = getHookKindForType(fn.env, callee.identifier.type);
168876
+ let returnType = {kind: 'None'};
168877
+ const fnType = env.get(callee.identifier.id);
168878
+ if (
168879
+ (fnType === null || fnType === void 0 ? void 0 : fnType.kind) ===
168880
+ 'Structure' &&
168881
+ fnType.fn !== null
168882
+ ) {
168883
+ returnType = fnType.fn.returnType;
168884
+ if (fnType.fn.readRefEffect) {
168885
+ errors.push({
168886
+ severity: exports.ErrorSeverity.InvalidReact,
168887
+ reason:
168888
+ 'This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)',
168889
+ loc: callee.loc,
168890
+ description:
168891
+ callee.identifier.name !== null &&
168892
+ callee.identifier.name.kind === 'named'
168893
+ ? `Function \`${callee.identifier.name.value}\` accesses a ref`
168894
+ : null,
168895
+ suggestions: null,
168896
+ });
168897
+ }
168898
+ }
168384
168899
  for (const operand of eachInstructionValueOperand(instr.value)) {
168385
- validateNoRefAccess(errors, state, operand, operand.loc);
168900
+ if (hookKind != null) {
168901
+ validateNoDirectRefValueAccess(errors, operand, env);
168902
+ } else {
168903
+ validateNoRefAccess(errors, env, operand, operand.loc);
168904
+ }
168386
168905
  }
168906
+ env.set(instr.lvalue.identifier.id, returnType);
168907
+ break;
168387
168908
  }
168388
- break;
168389
- }
168390
- case 'CallExpression': {
168391
- const callee = instr.value.callee;
168392
- const isUseEffect = isEffectHook(callee.identifier);
168393
- if (!isUseEffect) {
168394
- if (state.refAccessingFunctions.has(callee.identifier.id)) {
168395
- errors.push({
168396
- severity: exports.ErrorSeverity.InvalidReact,
168397
- reason:
168398
- 'This function accesses a ref value (the `current` property), which may not be accessed during render. (https://react.dev/reference/react/useRef)',
168399
- loc: callee.loc,
168400
- description:
168401
- callee.identifier.name !== null &&
168402
- callee.identifier.name.kind === 'named'
168403
- ? `Function \`${callee.identifier.name.value}\` accesses a ref`
168404
- : null,
168405
- suggestions: null,
168406
- });
168407
- }
168909
+ case 'ObjectExpression':
168910
+ case 'ArrayExpression': {
168911
+ const types = [];
168408
168912
  for (const operand of eachInstructionValueOperand(instr.value)) {
168409
- validateNoRefAccess(
168410
- errors,
168411
- state,
168412
- operand,
168413
- (_a = state.refValues.get(operand.identifier.id)) !== null &&
168414
- _a !== void 0
168415
- ? _a
168416
- : operand.loc
168913
+ validateNoDirectRefValueAccess(errors, operand, env);
168914
+ types.push(
168915
+ (_d = env.get(operand.identifier.id)) !== null && _d !== void 0
168916
+ ? _d
168917
+ : {kind: 'None'}
168417
168918
  );
168418
168919
  }
168419
- }
168420
- break;
168421
- }
168422
- case 'ObjectExpression':
168423
- case 'ArrayExpression': {
168424
- for (const operand of eachInstructionValueOperand(instr.value)) {
168425
- validateNoDirectRefValueAccess(errors, operand, state);
168426
- if (state.refAccessingFunctions.has(operand.identifier.id)) {
168427
- state.refAccessingFunctions.add(instr.lvalue.identifier.id);
168920
+ const value = joinRefAccessTypes(...types);
168921
+ if (value.kind === 'None') {
168922
+ env.set(instr.lvalue.identifier.id, {kind: 'None'});
168923
+ } else {
168924
+ env.set(instr.lvalue.identifier.id, {
168925
+ kind: 'Structure',
168926
+ value: value,
168927
+ fn: null,
168928
+ });
168428
168929
  }
168429
- if (state.refs.has(operand.identifier.id)) {
168430
- state.refs.add(instr.lvalue.identifier.id);
168930
+ break;
168931
+ }
168932
+ case 'PropertyDelete':
168933
+ case 'PropertyStore':
168934
+ case 'ComputedDelete':
168935
+ case 'ComputedStore': {
168936
+ validateNoRefAccess(errors, env, instr.value.object, instr.loc);
168937
+ for (const operand of eachInstructionValueOperand(instr.value)) {
168938
+ if (operand === instr.value.object) {
168939
+ continue;
168940
+ }
168941
+ validateNoRefValueAccess(errors, env, operand);
168431
168942
  }
168432
- const refValue = state.refValues.get(operand.identifier.id);
168433
- if (refValue !== undefined) {
168434
- state.refValues.set(instr.lvalue.identifier.id, refValue);
168943
+ break;
168944
+ }
168945
+ case 'StartMemoize':
168946
+ case 'FinishMemoize':
168947
+ break;
168948
+ default: {
168949
+ for (const operand of eachInstructionValueOperand(instr.value)) {
168950
+ validateNoRefValueAccess(errors, env, operand);
168435
168951
  }
168952
+ break;
168436
168953
  }
168437
- break;
168438
168954
  }
168439
- case 'PropertyDelete':
168440
- case 'PropertyStore':
168441
- case 'ComputedDelete':
168442
- case 'ComputedStore': {
168443
- validateNoRefAccess(
168444
- errors,
168445
- state,
168446
- instr.value.object,
168447
- (_b = state.refValues.get(instr.value.object.identifier.id)) !==
168448
- null && _b !== void 0
168449
- ? _b
168450
- : instr.loc
168955
+ if (isUseRefType(instr.lvalue.identifier)) {
168956
+ env.set(
168957
+ instr.lvalue.identifier.id,
168958
+ joinRefAccessTypes(
168959
+ (_e = env.get(instr.lvalue.identifier.id)) !== null &&
168960
+ _e !== void 0
168961
+ ? _e
168962
+ : {kind: 'None'},
168963
+ {kind: 'Ref'}
168964
+ )
168451
168965
  );
168452
- for (const operand of eachInstructionValueOperand(instr.value)) {
168453
- if (operand === instr.value.object) {
168454
- continue;
168455
- }
168456
- validateNoRefValueAccess(errors, state, operand);
168457
- }
168458
- break;
168459
168966
  }
168460
- case 'StartMemoize':
168461
- case 'FinishMemoize':
168462
- break;
168463
- default: {
168464
- for (const operand of eachInstructionValueOperand(instr.value)) {
168465
- validateNoRefValueAccess(errors, state, operand);
168466
- }
168467
- break;
168967
+ if (isRefValueType(instr.lvalue.identifier)) {
168968
+ env.set(
168969
+ instr.lvalue.identifier.id,
168970
+ joinRefAccessTypes(
168971
+ (_f = env.get(instr.lvalue.identifier.id)) !== null &&
168972
+ _f !== void 0
168973
+ ? _f
168974
+ : {kind: 'None'},
168975
+ {kind: 'RefValue', loc: instr.loc}
168976
+ )
168977
+ );
168468
168978
  }
168469
168979
  }
168470
- if (isUseRefType(instr.lvalue.identifier)) {
168471
- state.refs.add(instr.lvalue.identifier.id);
168472
- }
168473
- if (
168474
- isRefValueType(instr.lvalue.identifier) &&
168475
- !state.refValues.has(instr.lvalue.identifier.id)
168476
- ) {
168477
- state.refValues.set(instr.lvalue.identifier.id, instr.loc);
168980
+ for (const operand of eachTerminalOperand(block.terminal)) {
168981
+ if (block.terminal.kind !== 'return') {
168982
+ validateNoRefValueAccess(errors, env, operand);
168983
+ } else {
168984
+ validateNoDirectRefValueAccess(errors, operand, env);
168985
+ returnValues.push(env.get(operand.identifier.id));
168986
+ }
168478
168987
  }
168479
168988
  }
168480
- for (const operand of eachTerminalOperand(block.terminal)) {
168481
- if (block.terminal.kind !== 'return') {
168482
- validateNoRefValueAccess(errors, state, operand);
168483
- } else {
168484
- validateNoDirectRefValueAccess(errors, operand, state);
168485
- }
168989
+ if (errors.hasErrors()) {
168990
+ return Err(errors);
168486
168991
  }
168487
168992
  }
168488
- if (errors.hasErrors()) {
168489
- return Err(errors);
168490
- } else {
168491
- return Ok(undefined);
168993
+ CompilerError.invariant(!env.hasChanged(), {
168994
+ reason: 'Ref type environment did not converge',
168995
+ loc: null,
168996
+ });
168997
+ return Ok(
168998
+ joinRefAccessTypes(...returnValues.filter(env => env !== undefined))
168999
+ );
169000
+ }
169001
+ function destructure(type) {
169002
+ if (
169003
+ (type === null || type === void 0 ? void 0 : type.kind) === 'Structure' &&
169004
+ type.value !== null
169005
+ ) {
169006
+ return destructure(type.value);
168492
169007
  }
169008
+ return type;
168493
169009
  }
168494
- function validateNoRefValueAccess(errors, state, operand) {
169010
+ function validateNoRefValueAccess(errors, env, operand) {
168495
169011
  var _a;
169012
+ const type = destructure(env.get(operand.identifier.id));
168496
169013
  if (
168497
- state.refValues.has(operand.identifier.id) ||
168498
- state.refAccessingFunctions.has(operand.identifier.id)
169014
+ (type === null || type === void 0 ? void 0 : type.kind) === 'RefValue' ||
169015
+ ((type === null || type === void 0 ? void 0 : type.kind) === 'Structure' &&
169016
+ ((_a = type.fn) === null || _a === void 0 ? void 0 : _a.readRefEffect))
168499
169017
  ) {
168500
169018
  errors.push({
168501
169019
  severity: exports.ErrorSeverity.InvalidReact,
168502
169020
  reason:
168503
169021
  'Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)',
168504
- loc:
168505
- (_a = state.refValues.get(operand.identifier.id)) !== null &&
168506
- _a !== void 0
168507
- ? _a
168508
- : operand.loc,
169022
+ loc: (type.kind === 'RefValue' && type.loc) || operand.loc,
168509
169023
  description:
168510
169024
  operand.identifier.name !== null &&
168511
169025
  operand.identifier.name.kind === 'named'
@@ -168515,17 +169029,20 @@ function validateNoRefValueAccess(errors, state, operand) {
168515
169029
  });
168516
169030
  }
168517
169031
  }
168518
- function validateNoRefAccess(errors, state, operand, loc) {
169032
+ function validateNoRefAccess(errors, env, operand, loc) {
169033
+ var _a;
169034
+ const type = destructure(env.get(operand.identifier.id));
168519
169035
  if (
168520
- state.refs.has(operand.identifier.id) ||
168521
- state.refValues.has(operand.identifier.id) ||
168522
- state.refAccessingFunctions.has(operand.identifier.id)
169036
+ (type === null || type === void 0 ? void 0 : type.kind) === 'Ref' ||
169037
+ (type === null || type === void 0 ? void 0 : type.kind) === 'RefValue' ||
169038
+ ((type === null || type === void 0 ? void 0 : type.kind) === 'Structure' &&
169039
+ ((_a = type.fn) === null || _a === void 0 ? void 0 : _a.readRefEffect))
168523
169040
  ) {
168524
169041
  errors.push({
168525
169042
  severity: exports.ErrorSeverity.InvalidReact,
168526
169043
  reason:
168527
169044
  'Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)',
168528
- loc: loc,
169045
+ loc: (type.kind === 'RefValue' && type.loc) || loc,
168529
169046
  description:
168530
169047
  operand.identifier.name !== null &&
168531
169048
  operand.identifier.name.kind === 'named'
@@ -168535,18 +169052,15 @@ function validateNoRefAccess(errors, state, operand, loc) {
168535
169052
  });
168536
169053
  }
168537
169054
  }
168538
- function validateNoDirectRefValueAccess(errors, operand, state) {
169055
+ function validateNoDirectRefValueAccess(errors, operand, env) {
168539
169056
  var _a;
168540
- if (state.refValues.has(operand.identifier.id)) {
169057
+ const type = destructure(env.get(operand.identifier.id));
169058
+ if ((type === null || type === void 0 ? void 0 : type.kind) === 'RefValue') {
168541
169059
  errors.push({
168542
169060
  severity: exports.ErrorSeverity.InvalidReact,
168543
169061
  reason:
168544
169062
  'Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)',
168545
- loc:
168546
- (_a = state.refValues.get(operand.identifier.id)) !== null &&
168547
- _a !== void 0
168548
- ? _a
168549
- : operand.loc,
169063
+ loc: (_a = type.loc) !== null && _a !== void 0 ? _a : operand.loc,
168550
169064
  description:
168551
169065
  operand.identifier.name !== null &&
168552
169066
  operand.identifier.name.kind === 'named'
@@ -170760,6 +171274,10 @@ function* runWithEnvironment(func, env) {
170760
171274
  propagateScopeDependenciesHIR(hir);
170761
171275
  yield log({kind: 'hir', name: 'PropagateScopeDependenciesHIR', value: hir});
170762
171276
  }
171277
+ if (env.config.enableInlineJsxTransform) {
171278
+ inlineJsxTransform(hir);
171279
+ yield log({kind: 'hir', name: 'inlineJsxTransform', value: hir});
171280
+ }
170763
171281
  const reactiveFunction = buildReactiveFunction(hir);
170764
171282
  yield log({
170765
171283
  kind: 'reactive',
@@ -170933,6 +171451,10 @@ function log(value) {
170933
171451
  }
170934
171452
  return value;
170935
171453
  }
171454
+ function* runPlayground(func, config, fnType) {
171455
+ const ast = yield* run(func, config, fnType, '_c', null, null, null);
171456
+ return ast;
171457
+ }
170936
171458
  function isComponentDeclaration(node) {
170937
171459
  return Object.prototype.hasOwnProperty.call(node, '__componentDeclaration');
170938
171460
  }
@@ -171999,4 +172521,5 @@ exports.printHIR = printHIR;
171999
172521
  exports.printReactiveFunction = printReactiveFunction;
172000
172522
  exports.run = run;
172001
172523
  exports.runBabelPluginReactCompiler = runBabelPluginReactCompiler;
172524
+ exports.runPlayground = runPlayground;
172002
172525
  exports.validateEnvironmentConfig = validateEnvironmentConfig;