@samitouri / QOS-React / commits / f39dd1b82f

InferReferenceEffects s/reference/referenceAndRecordEffects/

ghstack-source-id: 4d7439e7ada77e65991869593aa6a5d88d5ad600 Pull Request resolved: https://github.com/facebook/react-forget/pull/2882

Joe Savona committed Apr 20, 2024 at 12:18 UTC f39dd1b82f71e5390f9dbca2b9b10824a4958f72
1 file changed +138 -128
compiler/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts
+138 -128
@@ -374,11 +374,11 @@ class InferenceState {
374 * Similarly, a freeze reference is converted to readonly if the
375 * value is already frozen or is immutable.
376 */
377 - reference(
377 + referenceAndRecordEffects(
378 place: Place,
379 - functionEffects: Array<FunctionEffect>,
379 effectKind: Effect,
381 - reason: ValueReason
380 + reason: ValueReason,
381 + functionEffects: Array<FunctionEffect>
382 ): void {
383 const values = this.#variables.get(place.identifier.id);
384 if (values === undefined) {
@@ -407,11 +407,11 @@ class InferenceState {
407 } else {
408 for (const place of effect.places) {
409 if (this.isDefined(place)) {
410 - this.reference(
410 + this.referenceAndRecordEffects(
411 { ...place, loc: effect.loc },
412 - functionEffects,
412 effect.effect,
414 - reason
413 + reason,
414 + functionEffects
415 );
416 }
417 }
@@ -448,11 +448,11 @@ class InferenceState {
448 ) {
449 if (value.kind === "FunctionExpression") {
450 for (const operand of eachInstructionValueOperand(value)) {
451 - this.reference(
451 + this.referenceAndRecordEffects(
452 operand,
453 - functionEffects,
453 Effect.Freeze,
455 - ValueReason.Other
454 + ValueReason.Other,
455 + functionEffects
456 );
457 }
458 }
@@ -928,19 +928,19 @@ function inferBlock(
928 reason: new Set([ValueReason.Other]),
929 context: new Set(),
930 };
931 - state.reference(
931 + state.referenceAndRecordEffects(
932 instrValue.callee,
933 - functionEffects,
933 Effect.Read,
935 - ValueReason.Other
934 + ValueReason.Other,
935 + functionEffects
936 );
937
938 for (const operand of eachCallArgument(instrValue.args)) {
939 - state.reference(
939 + state.referenceAndRecordEffects(
940 operand,
941 - functionEffects,
941 Effect.ConditionallyMutate,
943 - ValueReason.Other
942 + ValueReason.Other,
943 + functionEffects
944 );
945 }
946
@@ -967,29 +967,29 @@ function inferBlock(
967 case "ObjectProperty": {
968 if (property.key.kind === "computed") {
969 // Object keys must be primitives, so we know they're frozen at this point
970 - state.reference(
970 + state.referenceAndRecordEffects(
971 property.key.name,
972 - functionEffects,
972 Effect.Freeze,
974 - ValueReason.Other
973 + ValueReason.Other,
974 + functionEffects
975 );
976 }
977 // Object construction captures but does not modify the key/property values
978 - state.reference(
978 + state.referenceAndRecordEffects(
979 property.place,
980 - functionEffects,
980 Effect.Capture,
982 - ValueReason.Other
981 + ValueReason.Other,
982 + functionEffects
983 );
984 break;
985 }
986 case "Spread": {
987 // Object construction captures but does not modify the key/property values
988 - state.reference(
988 + state.referenceAndRecordEffects(
989 property.place,
990 - functionEffects,
990 Effect.Capture,
992 - ValueReason.Other
991 + ValueReason.Other,
992 + functionEffects
993 );
994 break;
995 }
@@ -1105,11 +1105,11 @@ function inferBlock(
1105 case "FunctionExpression": {
1106 let hasMutableOperand = false;
1107 for (const operand of eachInstructionOperand(instr)) {
1108 - state.reference(
1108 + state.referenceAndRecordEffects(
1109 operand,
1110 - [],
1110 operand.effect === Effect.Unknown ? Effect.Read : operand.effect,
1112 - ValueReason.Other
1111 + ValueReason.Other,
1112 + []
1113 );
1114 hasMutableOperand ||= isMutableEffect(operand.effect, operand.loc);
1115 }
@@ -1156,18 +1156,18 @@ function inferBlock(
1156 const arg = instrValue.args[i];
1157 const place = arg.kind === "Identifier" ? arg : arg.place;
1158 if (effects !== null) {
1159 - state.reference(
1159 + state.referenceAndRecordEffects(
1160 place,
1161 - argumentEffects,
1161 effects[i],
1163 - ValueReason.Other
1162 + ValueReason.Other,
1163 + argumentEffects
1164 );
1165 } else {
1166 - state.reference(
1166 + state.referenceAndRecordEffects(
1167 place,
1168 - argumentEffects,
1168 Effect.ConditionallyMutate,
1170 - ValueReason.Other
1169 + ValueReason.Other,
1170 + argumentEffects
1171 );
1172 }
1173 /*
@@ -1183,18 +1183,18 @@ function inferBlock(
1183 hasCaptureArgument ||= place.effect === Effect.Capture;
1184 }
1185 if (signature !== null) {
1186 - state.reference(
1186 + state.referenceAndRecordEffects(
1187 instrValue.callee,
1188 - functionEffects,
1188 signature.calleeEffect,
1190 - ValueReason.Other
1189 + ValueReason.Other,
1190 + functionEffects
1191 );
1192 } else {
1193 - state.reference(
1193 + state.referenceAndRecordEffects(
1194 instrValue.callee,
1195 - functionEffects,
1195 Effect.ConditionallyMutate,
1197 - ValueReason.Other
1196 + ValueReason.Other,
1197 + functionEffects
1198 );
1199 }
1200 hasCaptureArgument ||= instrValue.callee.effect === Effect.Capture;
@@ -1214,11 +1214,11 @@ function inferBlock(
1214 loc: instrValue.loc,
1215 suggestions: null,
1216 });
1217 - state.reference(
1217 + state.referenceAndRecordEffects(
1218 instrValue.property,
1219 - functionEffects,
1219 Effect.Read,
1221 - ValueReason.Other
1220 + ValueReason.Other,
1221 + functionEffects
1222 );
1223
1224 const signature = getFunctionCallSignature(
@@ -1250,18 +1250,18 @@ function inferBlock(
1250 */
1251 for (const arg of instrValue.args) {
1252 const place = arg.kind === "Identifier" ? arg : arg.place;
1253 - state.reference(
1253 + state.referenceAndRecordEffects(
1254 place,
1255 - functionEffects,
1255 Effect.Read,
1257 - ValueReason.Other
1256 + ValueReason.Other,
1257 + functionEffects
1258 );
1259 }
1260 - state.reference(
1260 + state.referenceAndRecordEffects(
1261 instrValue.receiver,
1262 - functionEffects,
1262 Effect.Capture,
1264 - ValueReason.Other
1263 + ValueReason.Other,
1264 + functionEffects
1265 );
1266 state.initialize(instrValue, returnValueKind);
1267 state.define(instr.lvalue, instrValue);
@@ -1285,18 +1285,18 @@ function inferBlock(
1285 * If effects are inferred for an argument, we should fail invalid
1286 * mutating effects
1287 */
1288 - state.reference(
1288 + state.referenceAndRecordEffects(
1289 place,
1290 - argumentEffects,
1290 effects[i],
1292 - ValueReason.Other
1291 + ValueReason.Other,
1292 + argumentEffects
1293 );
1294 } else {
1295 - state.reference(
1295 + state.referenceAndRecordEffects(
1296 place,
1297 - argumentEffects,
1297 Effect.ConditionallyMutate,
1299 - ValueReason.Other
1298 + ValueReason.Other,
1299 + argumentEffects
1300 );
1301 }
1302 /*
@@ -1312,18 +1312,18 @@ function inferBlock(
1312 hasCaptureArgument ||= place.effect === Effect.Capture;
1313 }
1314 if (signature !== null) {
1315 - state.reference(
1315 + state.referenceAndRecordEffects(
1316 instrValue.receiver,
1317 - functionEffects,
1317 signature.calleeEffect,
1319 - ValueReason.Other
1318 + ValueReason.Other,
1319 + functionEffects
1320 );
1321 } else {
1322 - state.reference(
1322 + state.referenceAndRecordEffects(
1323 instrValue.receiver,
1324 - functionEffects,
1324 Effect.ConditionallyMutate,
1326 - ValueReason.Other
1325 + ValueReason.Other,
1326 + functionEffects
1327 );
1328 }
1329 hasCaptureArgument ||= instrValue.receiver.effect === Effect.Capture;
@@ -1340,17 +1340,17 @@ function inferBlock(
1340 state.kind(instrValue.object).kind === ValueKind.Context
1341 ? Effect.ConditionallyMutate
1342 : Effect.Capture;
1343 - state.reference(
1343 + state.referenceAndRecordEffects(
1344 instrValue.value,
1345 - functionEffects,
1345 effect,
1347 - ValueReason.Other
1346 + ValueReason.Other,
1347 + functionEffects
1348 );
1349 - state.reference(
1349 + state.referenceAndRecordEffects(
1350 instrValue.object,
1351 - functionEffects,
1351 Effect.Store,
1353 - ValueReason.Other
1352 + ValueReason.Other,
1353 + functionEffects
1354 );
1355
1356 const lvalue = instr.lvalue;
@@ -1369,11 +1369,11 @@ function inferBlock(
1369 break;
1370 }
1371 case "PropertyLoad": {
1372 - state.reference(
1372 + state.referenceAndRecordEffects(
1373 instrValue.object,
1374 - functionEffects,
1374 Effect.Read,
1376 - ValueReason.Other
1375 + ValueReason.Other,
1376 + functionEffects
1377 );
1378 const lvalue = instr.lvalue;
1379 lvalue.effect = Effect.ConditionallyMutate;
@@ -1386,23 +1386,23 @@ function inferBlock(
1386 state.kind(instrValue.object).kind === ValueKind.Context
1387 ? Effect.ConditionallyMutate
1388 : Effect.Capture;
1389 - state.reference(
1389 + state.referenceAndRecordEffects(
1390 instrValue.value,
1391 - functionEffects,
1391 effect,
1393 - ValueReason.Other
1392 + ValueReason.Other,
1393 + functionEffects
1394 );
1395 - state.reference(
1395 + state.referenceAndRecordEffects(
1396 instrValue.property,
1397 - functionEffects,
1397 Effect.Capture,
1399 - ValueReason.Other
1398 + ValueReason.Other,
1399 + functionEffects
1400 );
1401 - state.reference(
1401 + state.referenceAndRecordEffects(
1402 instrValue.object,
1403 - functionEffects,
1403 Effect.Store,
1405 - ValueReason.Other
1404 + ValueReason.Other,
1405 + functionEffects
1406 );
1407
1408 const lvalue = instr.lvalue;
@@ -1411,17 +1411,17 @@ function inferBlock(
1411 continue;
1412 }
1413 case "ComputedDelete": {
1414 - state.reference(
1414 + state.referenceAndRecordEffects(
1415 instrValue.object,
1416 - functionEffects,
1416 Effect.Mutate,
1418 - ValueReason.Other
1417 + ValueReason.Other,
1418 + functionEffects
1419 );
1420 - state.reference(
1420 + state.referenceAndRecordEffects(
1421 instrValue.property,
1422 - functionEffects,
1422 Effect.Read,
1424 - ValueReason.Other
1423 + ValueReason.Other,
1424 + functionEffects
1425 );
1426 state.initialize(instrValue, {
1427 kind: ValueKind.Immutable,
@@ -1433,17 +1433,17 @@ function inferBlock(
1433 continue;
1434 }
1435 case "ComputedLoad": {
1436 - state.reference(
1436 + state.referenceAndRecordEffects(
1437 instrValue.object,
1438 - functionEffects,
1438 Effect.Read,
1440 - ValueReason.Other
1439 + ValueReason.Other,
1440 + functionEffects
1441 );
1442 - state.reference(
1442 + state.referenceAndRecordEffects(
1443 instrValue.property,
1444 - functionEffects,
1444 Effect.Read,
1446 - ValueReason.Other
1445 + ValueReason.Other,
1446 + functionEffects
1447 );
1448 const lvalue = instr.lvalue;
1449 lvalue.effect = Effect.ConditionallyMutate;
@@ -1458,11 +1458,11 @@ function inferBlock(
1458 * It also means that any side-effects which would occur as part of the promise evaluation
1459 * will occur.
1460 */
1461 - state.reference(
1461 + state.referenceAndRecordEffects(
1462 instrValue.value,
1463 - functionEffects,
1463 Effect.ConditionallyMutate,
1465 - ValueReason.Other
1464 + ValueReason.Other,
1465 + functionEffects
1466 );
1467 const lvalue = instr.lvalue;
1468 lvalue.effect = Effect.ConditionallyMutate;
@@ -1479,11 +1479,11 @@ function inferBlock(
1479 * ```
1480 */
1481 state.initialize(instrValue, state.kind(instrValue.value));
1482 - state.reference(
1482 + state.referenceAndRecordEffects(
1483 instrValue.value,
1484 - functionEffects,
1484 Effect.Read,
1486 - ValueReason.Other
1485 + ValueReason.Other,
1486 + functionEffects
1487 );
1488 const lvalue = instr.lvalue;
1489 lvalue.effect = Effect.ConditionallyMutate;
@@ -1494,18 +1494,18 @@ function inferBlock(
1494 case "FinishMemoize": {
1495 for (const val of eachInstructionValueOperand(instrValue)) {
1496 if (env.config.enablePreserveExistingMemoizationGuarantees) {
1497 - state.reference(
1497 + state.referenceAndRecordEffects(
1498 val,
1499 - functionEffects,
1499 Effect.Freeze,
1501 - ValueReason.Other
1500 + ValueReason.Other,
1501 + functionEffects
1502 );
1503 } else {
1504 - state.reference(
1504 + state.referenceAndRecordEffects(
1505 val,
1506 - functionEffects,
1506 Effect.Read,
1508 - ValueReason.Other
1507 + ValueReason.Other,
1508 + functionEffects
1509 );
1510 }
1511 }
@@ -1526,11 +1526,11 @@ function inferBlock(
1526 state.kind(lvalue).kind === ValueKind.Context
1527 ? Effect.ConditionallyMutate
1528 : Effect.Capture;
1529 - state.reference(
1529 + state.referenceAndRecordEffects(
1530 instrValue.place,
1531 - functionEffects,
1531 effect,
1533 - ValueReason.Other
1532 + ValueReason.Other,
1533 + functionEffects
1534 );
1535 lvalue.effect = Effect.ConditionallyMutate;
1536 // direct aliasing: `a = b`;
@@ -1538,11 +1538,11 @@ function inferBlock(
1538 continue;
1539 }
1540 case "LoadContext": {
1541 - state.reference(
1541 + state.referenceAndRecordEffects(
1542 instrValue.place,
1543 - functionEffects,
1543 Effect.Capture,
1545 - ValueReason.Other
1544 + ValueReason.Other,
1545 + functionEffects
1546 );
1547 const lvalue = instr.lvalue;
1548 lvalue.effect = Effect.ConditionallyMutate;
@@ -1598,11 +1598,11 @@ function inferBlock(
1598 state.kind(instrValue.lvalue).kind === ValueKind.Context
1599 ? Effect.ConditionallyMutate
1600 : Effect.Capture;
1601 - state.reference(
1601 + state.referenceAndRecordEffects(
1602 instrValue.value,
1603 - functionEffects,
1603 effect,
1605 - ValueReason.Other
1604 + ValueReason.Other,
1605 + functionEffects
1606 );
1607
1608 const lvalue = instr.lvalue;
@@ -1624,11 +1624,11 @@ function inferBlock(
1624 state.kind(instrValue.lvalue.place).kind === ValueKind.Context
1625 ? Effect.ConditionallyMutate
1626 : Effect.Capture;
1627 - state.reference(
1627 + state.referenceAndRecordEffects(
1628 instrValue.value,
1629 - functionEffects,
1629 effect,
1631 - ValueReason.Other
1630 + ValueReason.Other,
1631 + functionEffects
1632 );
1633
1634 const lvalue = instr.lvalue;
@@ -1645,17 +1645,17 @@ function inferBlock(
1645 continue;
1646 }
1647 case "StoreContext": {
1648 - state.reference(
1648 + state.referenceAndRecordEffects(
1649 instrValue.value,
1650 - functionEffects,
1650 Effect.ConditionallyMutate,
1652 - ValueReason.Other
1651 + ValueReason.Other,
1652 + functionEffects
1653 );
1654 - state.reference(
1654 + state.referenceAndRecordEffects(
1655 instrValue.lvalue.place,
1656 - functionEffects,
1656 Effect.Mutate,
1658 - ValueReason.Other
1657 + ValueReason.Other,
1658 + functionEffects
1659 );
1660
1661 const lvalue = instr.lvalue;
@@ -1664,11 +1664,11 @@ function inferBlock(
1664 continue;
1665 }
1666 case "StoreGlobal": {
1667 - state.reference(
1667 + state.referenceAndRecordEffects(
1668 instrValue.value,
1669 - functionEffects,
1669 Effect.Capture,
1671 - ValueReason.Other
1670 + ValueReason.Other,
1671 + functionEffects
1672 );
1673 const lvalue = instr.lvalue;
1674 lvalue.effect = Effect.Store;
@@ -1696,11 +1696,11 @@ function inferBlock(
1696 break;
1697 }
1698 }
1699 - state.reference(
1699 + state.referenceAndRecordEffects(
1700 instrValue.value,
1701 - functionEffects,
1701 effect,
1703 - ValueReason.Other
1702 + ValueReason.Other,
1703 + functionEffects
1704 );
1705
1706 const lvalue = instr.lvalue;
@@ -1750,7 +1750,12 @@ function inferBlock(
1750 loc: instrValue.loc,
1751 suggestions: null,
1752 });
1753 - state.reference(operand, functionEffects, effect.kind, effect.reason);
1753 + state.referenceAndRecordEffects(
1754 + operand,
1755 + effect.kind,
1756 + effect.reason,
1757 + functionEffects
1758 + );
1759 }
1760
1761 state.initialize(instrValue, valueKind);
@@ -1772,7 +1777,12 @@ function inferBlock(
1777 } else {
1778 effect = Effect.Read;
1779 }
1775 - state.reference(operand, functionEffects, effect, ValueReason.Other);
1780 + state.referenceAndRecordEffects(
1781 + operand,
1782 + effect,
1783 + ValueReason.Other,
1784 + functionEffects
1785 + );
1786 }
1787 }
1788