@samitouri / QOS-React-1 / commits / 6a3d6a4382

[compiler] Allow type cast expressions with refs (#31871)

We report a false positive for the combination of a ref-accessing function placed inside an array which is they type-cast. Here we teach ref validation about type casts. I also tried other variants like `return ref as const` but those already worked. Closes #31864

Joseph Savona committed Dec 20, 2024 at 08:56 UTC 6a3d6a4382cdafc1260483a6fc5f76593fc038e4
3 files changed +85
compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoRefAccesInRender.ts
+8
@@ -305,6 +305,14 @@ function validateNoRefAccessInRenderImpl(
305 );
306 break;
307 }
308 + case 'TypeCastExpression': {
309 + env.set(
310 + instr.lvalue.identifier.id,
311 + env.get(instr.value.value.identifier.id) ??
312 + refTypeOfType(instr.lvalue),
313 + );
314 + break;
315 + }
316 case 'LoadContext':
317 case 'LoadLocal': {
318 env.set(
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-type-cast-in-render.expect.md new
+60
@@ -0,0 +1,60 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +import {useRef} from 'react';
6 +
7 +function useArrayOfRef() {
8 + const ref = useRef(null);
9 + const callback = value => {
10 + ref.current = value;
11 + };
12 + return [callback] as const;
13 +}
14 +
15 +export const FIXTURE_ENTRYPOINT = {
16 + fn: () => {
17 + useArrayOfRef();
18 + return 'ok';
19 + },
20 + params: [{}],
21 +};
22 +
23 +```
24 +
25 +## Code
26 +
27 +```javascript
28 +import { c as _c } from "react/compiler-runtime";
29 +import { useRef } from "react";
30 +
31 +function useArrayOfRef() {
32 + const $ = _c(1);
33 + const ref = useRef(null);
34 + let t0;
35 + if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
36 + const callback = (value) => {
37 + ref.current = value;
38 + };
39 +
40 + t0 = [callback];
41 + $[0] = t0;
42 + } else {
43 + t0 = $[0];
44 + }
45 + return t0 as const;
46 +}
47 +
48 +export const FIXTURE_ENTRYPOINT = {
49 + fn: () => {
50 + useArrayOfRef();
51 + return "ok";
52 + },
53 +
54 + params: [{}],
55 +};
56 +
57 +```
58 +
59 +### Eval output
60 +(kind: ok) "ok"
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/allow-ref-type-cast-in-render.js new
+17
@@ -0,0 +1,17 @@
1 +import {useRef} from 'react';
2 +
3 +function useArrayOfRef() {
4 + const ref = useRef(null);
5 + const callback = value => {
6 + ref.current = value;
7 + };
8 + return [callback] as const;
9 +}
10 +
11 +export const FIXTURE_ENTRYPOINT = {
12 + fn: () => {
13 + useArrayOfRef();
14 + return 'ok';
15 + },
16 + params: [{}],
17 +};