@samitouri / QOS-React / commits / 530231712f

[be] Extract hooks helpers to separate file

This is a precursor to allowing the set of custom hooks (and their behavior) to be configurable.

Joe Savona committed Feb 16, 2023 at 10:38 UTC 530231712fdb60044285c3b0eee9e665433f86d6
5 files changed +85 -76
compiler/forget/src/HIR/Hooks.ts new
+81
@@ -0,0 +1,81 @@
1 +/**
2 + * Copyright (c) Facebook, Inc. and its affiliates.
3 + *
4 + * This source code is licensed under the MIT license found in the
5 + * LICENSE file in the root directory of this source tree.
6 + */
7 +
8 +import { Effect, Place, ValueKind } from "./HIR";
9 +
10 +export const HOOKS: Map<string, Hook> = new Map([
11 + [
12 + "useState",
13 + {
14 + kind: "State",
15 + name: "useState",
16 + effectKind: Effect.Freeze,
17 + valueKind: ValueKind.Frozen,
18 + },
19 + ],
20 + [
21 + "useRef",
22 + {
23 + kind: "Ref",
24 + name: "useRef",
25 + effectKind: Effect.Capture,
26 + valueKind: ValueKind.Mutable,
27 + },
28 + ],
29 + [
30 + "useFreeze",
31 + {
32 + kind: "Ref",
33 + name: "useFreeze",
34 + effectKind: Effect.Freeze,
35 + valueKind: ValueKind.Frozen,
36 + },
37 + ],
38 + [
39 + "useMemo",
40 + {
41 + kind: "Memo",
42 + name: "useMemo",
43 + effectKind: Effect.Freeze,
44 + valueKind: ValueKind.Frozen,
45 + },
46 + ],
47 + [
48 + "useCallback",
49 + {
50 + kind: "Memo",
51 + name: "useCallback",
52 + effectKind: Effect.Freeze,
53 + valueKind: ValueKind.Frozen,
54 + },
55 + ],
56 +]);
57 +
58 +export type HookKind = "State" | "Ref" | "Custom" | "Memo";
59 +export type Hook = {
60 + kind: HookKind;
61 + name: string;
62 + effectKind: Effect;
63 + valueKind: ValueKind;
64 +};
65 +
66 +export function parseHookCall(place: Place): Hook | null {
67 + const name = place.identifier.name;
68 + if (name === null || !name.match(/^_?use/)) {
69 + return null;
70 + }
71 + const hook = HOOKS.get(name);
72 + if (hook != null) {
73 + return hook;
74 + }
75 + return {
76 + kind: "Custom",
77 + name: place.identifier.name ?? "",
78 + effectKind: Effect.Mutate,
79 + valueKind: ValueKind.Mutable,
80 + };
81 +}
compiler/forget/src/Inference/InferReferenceEffects.ts
+1 -73
@@ -19,6 +19,7 @@ import {
19 Place,
20 ValueKind,
21 } from "../HIR/HIR";
22 +import { parseHookCall } from "../HIR/Hooks";
23 import {
24 printMixedHIR,
25 printPlace,
@@ -810,79 +811,6 @@ function inferBlock(env: Environment, block: BasicBlock) {
811 }
812 }
813
813 -const HOOKS: Map<string, Hook> = new Map([
814 - [
815 - "useState",
816 - {
817 - kind: "State",
818 - name: "useState",
819 - effectKind: Effect.Freeze,
820 - valueKind: ValueKind.Frozen,
821 - },
822 - ],
823 - [
824 - "useRef",
825 - {
826 - kind: "Ref",
827 - name: "useRef",
828 - effectKind: Effect.Capture,
829 - valueKind: ValueKind.Mutable,
830 - },
831 - ],
832 - [
833 - "useFreeze",
834 - {
835 - kind: "Ref",
836 - name: "useFreeze",
837 - effectKind: Effect.Freeze,
838 - valueKind: ValueKind.Frozen,
839 - },
840 - ],
841 - [
842 - "useMemo",
843 - {
844 - kind: "Memo",
845 - name: "useMemo",
846 - effectKind: Effect.Freeze,
847 - valueKind: ValueKind.Frozen,
848 - },
849 - ],
850 - [
851 - "useCallback",
852 - {
853 - kind: "Memo",
854 - name: "useCallback",
855 - effectKind: Effect.Freeze,
856 - valueKind: ValueKind.Frozen,
857 - },
858 - ],
859 -]);
860 -
861 -type HookKind = "State" | "Ref" | "Custom" | "Memo";
862 -type Hook = {
863 - kind: HookKind;
864 - name: string;
865 - effectKind: Effect;
866 - valueKind: ValueKind;
867 -};
868 -
869 -export function parseHookCall(place: Place): Hook | null {
870 - const name = place.identifier.name;
871 - if (name === null || !name.match(/^_?use/)) {
872 - return null;
873 - }
874 - const hook = HOOKS.get(name);
875 - if (hook != null) {
876 - return hook;
877 - }
878 - return {
879 - kind: "Custom",
880 - name: place.identifier.name ?? "",
881 - effectKind: Effect.Mutate,
882 - valueKind: ValueKind.Mutable,
883 - };
884 -}
885 -
814 function hasContextRefOperand(env: Environment, instrValue: InstructionValue) {
815 for (const place of eachInstructionValueOperand(instrValue)) {
816 if (env.isDefined(place) && env.kind(place) === ValueKind.Context) {
compiler/forget/src/ReactiveScopes/FlattenScopesWithHooks.ts
+1 -1
@@ -12,7 +12,7 @@ import {
12 ReactiveStatement,
13 ReactiveValue,
14 } from "../HIR";
15 -import { parseHookCall } from "../Inference/InferReferenceEffects";
15 +import { parseHookCall } from "../HIR/Hooks";
16 import {
17 ReactiveFunctionTransform,
18 Transformed,
compiler/forget/src/ReactiveScopes/InferReactiveIdentifiers.ts
+1 -1
@@ -12,7 +12,7 @@ import {
12 ReactiveFunction,
13 ReactiveInstruction,
14 } from "../HIR/HIR";
15 -import { parseHookCall } from "../Inference/InferReferenceEffects";
15 +import { parseHookCall } from "../HIR/Hooks";
16 import { assertExhaustive } from "../Utils/utils";
17 import {
18 eachReactiveValueOperand,
compiler/forget/src/TypeInference/InferTypes.ts
+1 -1
@@ -8,8 +8,8 @@ import {
8 TypeId,
9 TypeVar,
10 } from "../HIR/HIR";
11 +import { parseHookCall } from "../HIR/Hooks";
12 import { eachInstructionOperand } from "../HIR/visitors";
12 -import { parseHookCall } from "../Inference/InferReferenceEffects";
13
14 function isPrimitiveBinaryOp(op: t.BinaryExpression["operator"]) {
15 switch (op) {