@samitouri / QOS-React-1 / commits / 130b809ac2

Allow property loads from hook

Looking up certain properties on a hook is a common pattern for logging. It's non-ideal but it's not a bug to do this. This updates Forget to not error on this pattern.

Sathya Gunasekaran committed Feb 28, 2024 at 16:19 UTC 130b809ac2006ebfb381244bfa4bf3828304ea67
5 files changed +104 -2
compiler/packages/babel-plugin-react-forget/src/Validation/ValidateHooksUsage.ts
+1 -2
@@ -233,7 +233,6 @@ export function validateHooksUsage(fn: HIRFunction): void {
233 break;
234 }
235 case "PropertyLoad": {
236 - visitPlace(instr.value.object);
236 const objectKind = getKindForPlace(instr.value.object);
237 const isHookProperty = isHookName(instr.value.property);
238 let kind: Kind;
@@ -249,7 +248,7 @@ export function validateHooksUsage(fn: HIRFunction): void {
248 * let x = useFoo.useBar; // useFoo is KnownHook, any property from it inherits KnownHook
249 * }
250 */
252 - kind = Kind.KnownHook;
251 + kind = isHookProperty ? Kind.KnownHook : Kind.Local;
252 break;
253 }
254 case Kind.PotentialHook: {
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.hook-property-load-local-hook.expect.md new
+37
@@ -0,0 +1,37 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function useFoo() {}
6 +useFoo.useBar = function () {
7 + return "foo";
8 +};
9 +
10 +function Foo() {
11 + let bar = useFoo.useBar;
12 + return bar();
13 +}
14 +
15 +export const FIXTURE_ENTRYPOINT = {
16 + fn: Foo,
17 + params: [],
18 +};
19 +
20 +```
21 +
22 +
23 +## Error
24 +
25 +```
26 + 5 |
27 + 6 | function Foo() {
28 +> 7 | let bar = useFoo.useBar;
29 + | ^^^^^^^^^^^^^ [ReactForget] InvalidReact: Hooks may not be referenced as normal values, they must be called. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (7:7)
30 +
31 +[ReactForget] InvalidReact: Hooks may not be referenced as normal values, they must be called. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (8:8)
32 + 8 | return bar();
33 + 9 | }
34 + 10 |
35 +```
36 +
37 +
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.hook-property-load-local-hook.js new
+14
@@ -0,0 +1,14 @@
1 +function useFoo() {}
2 +useFoo.useBar = function () {
3 + return "foo";
4 +};
5 +
6 +function Foo() {
7 + let bar = useFoo.useBar;
8 + return bar();
9 +}
10 +
11 +export const FIXTURE_ENTRYPOINT = {
12 + fn: Foo,
13 + params: [],
14 +};
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/hook-property-load-local.expect.md new
+40
@@ -0,0 +1,40 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function useFoo() {}
6 +
7 +function Foo() {
8 + let name = useFoo.name;
9 + console.log(name);
10 + return name;
11 +}
12 +
13 +export const FIXTURE_ENTRYPOINT = {
14 + fn: Foo,
15 + params: [],
16 +};
17 +
18 +```
19 +
20 +## Code
21 +
22 +```javascript
23 +function useFoo() {}
24 +
25 +function Foo() {
26 + const name = useFoo.name;
27 + console.log(name);
28 + return name;
29 +}
30 +
31 +export const FIXTURE_ENTRYPOINT = {
32 + fn: Foo,
33 + params: [],
34 +};
35 +
36 +```
37 +
38 +### Eval output
39 +(kind: ok) "useFoo"
40 +logs: ['useFoo']
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/hook-property-load-local.js new
+12
@@ -0,0 +1,12 @@
1 +function useFoo() {}
2 +
3 +function Foo() {
4 + let name = useFoo.name;
5 + console.log(name);
6 + return name;
7 +}
8 +
9 +export const FIXTURE_ENTRYPOINT = {
10 + fn: Foo,
11 + params: [],
12 +};