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.
This commit is contained in:
Sathya Gunasekaran
2024-02-28 16:19:43 -08:00
parent 8879a2dd49
commit 130b809ac2
5 changed files with 104 additions and 2 deletions
@@ -233,7 +233,6 @@ export function validateHooksUsage(fn: HIRFunction): void {
break;
}
case "PropertyLoad": {
visitPlace(instr.value.object);
const objectKind = getKindForPlace(instr.value.object);
const isHookProperty = isHookName(instr.value.property);
let kind: Kind;
@@ -249,7 +248,7 @@ export function validateHooksUsage(fn: HIRFunction): void {
* let x = useFoo.useBar; // useFoo is KnownHook, any property from it inherits KnownHook
* }
*/
kind = Kind.KnownHook;
kind = isHookProperty ? Kind.KnownHook : Kind.Local;
break;
}
case Kind.PotentialHook: {
@@ -0,0 +1,37 @@
## Input
```javascript
function useFoo() {}
useFoo.useBar = function () {
return "foo";
};
function Foo() {
let bar = useFoo.useBar;
return bar();
}
export const FIXTURE_ENTRYPOINT = {
fn: Foo,
params: [],
};
```
## Error
```
5 |
6 | function Foo() {
> 7 | let bar = useFoo.useBar;
| ^^^^^^^^^^^^^ [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)
[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)
8 | return bar();
9 | }
10 |
```
@@ -0,0 +1,14 @@
function useFoo() {}
useFoo.useBar = function () {
return "foo";
};
function Foo() {
let bar = useFoo.useBar;
return bar();
}
export const FIXTURE_ENTRYPOINT = {
fn: Foo,
params: [],
};
@@ -0,0 +1,40 @@
## Input
```javascript
function useFoo() {}
function Foo() {
let name = useFoo.name;
console.log(name);
return name;
}
export const FIXTURE_ENTRYPOINT = {
fn: Foo,
params: [],
};
```
## Code
```javascript
function useFoo() {}
function Foo() {
const name = useFoo.name;
console.log(name);
return name;
}
export const FIXTURE_ENTRYPOINT = {
fn: Foo,
params: [],
};
```
### Eval output
(kind: ok) "useFoo"
logs: ['useFoo']
@@ -0,0 +1,12 @@
function useFoo() {}
function Foo() {
let name = useFoo.name;
console.log(name);
return name;
}
export const FIXTURE_ENTRYPOINT = {
fn: Foo,
params: [],
};