@samitouri / QOS-React / commits / 3f2a42a5de

[compiler] Handle empty list of eslint suppression rules (#34323)

--- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/facebook/react/pull/34323). * #34276 * __->__ #34323

Joseph Savona committed Sep 8, 2025 at 10:33 UTC 3f2a42a5decc88551d34c96f3d031c316ac34f6a
4 files changed +92 -8
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Options.ts
+5
@@ -135,7 +135,12 @@ export type PluginOptions = {
135 */
136 eslintSuppressionRules: Array<string> | null | undefined;
137
138 + /**
139 + * Whether to report "suppression" errors for Flow suppressions. If false, suppression errors
140 + * are only emitted for ESLint suppressions
141 + */
142 flowSuppressions: boolean;
143 +
144 /*
145 * Ignore 'use no forget' annotations. Helpful during testing but should not be used in production.
146 */
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Suppression.ts
+19 -8
@@ -86,12 +86,18 @@ export function findProgramSuppressions(
86 let enableComment: t.Comment | null = null;
87 let source: SuppressionSource | null = null;
88
89 - const rulePattern = `(${ruleNames.join('|')})`;
90 - const disableNextLinePattern = new RegExp(
91 - `eslint-disable-next-line ${rulePattern}`,
92 - );
93 - const disablePattern = new RegExp(`eslint-disable ${rulePattern}`);
94 - const enablePattern = new RegExp(`eslint-enable ${rulePattern}`);
89 + let disableNextLinePattern: RegExp | null = null;
90 + let disablePattern: RegExp | null = null;
91 + let enablePattern: RegExp | null = null;
92 + if (ruleNames.length !== 0) {
93 + const rulePattern = `(${ruleNames.join('|')})`;
94 + disableNextLinePattern = new RegExp(
95 + `eslint-disable-next-line ${rulePattern}`,
96 + );
97 + disablePattern = new RegExp(`eslint-disable ${rulePattern}`);
98 + enablePattern = new RegExp(`eslint-enable ${rulePattern}`);
99 + }
100 +
101 const flowSuppressionPattern = new RegExp(
102 '\\$(FlowFixMe\\w*|FlowExpectedError|FlowIssue)\\[react\\-rule',
103 );
@@ -107,6 +113,7 @@ export function findProgramSuppressions(
113 * CommentLine within the block.
114 */
115 disableComment == null &&
116 + disableNextLinePattern != null &&
117 disableNextLinePattern.test(comment.value)
118 ) {
119 disableComment = comment;
@@ -124,12 +131,16 @@ export function findProgramSuppressions(
131 source = 'Flow';
132 }
133
127 - if (disablePattern.test(comment.value)) {
134 + if (disablePattern != null && disablePattern.test(comment.value)) {
135 disableComment = comment;
136 source = 'Eslint';
137 }
138
132 - if (enablePattern.test(comment.value) && source === 'Eslint') {
139 + if (
140 + enablePattern != null &&
141 + enablePattern.test(comment.value) &&
142 + source === 'Eslint'
143 + ) {
144 enableComment = comment;
145 }
146
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/empty-eslint-suppressions-config.expect.md new
+53
@@ -0,0 +1,53 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +// @eslintSuppressionRules:[]
6 +
7 +// The suppression here shouldn't cause compilation to get skipped
8 +// Previously we had a bug where an empty list of suppressions would
9 +// create a regexp that matched any suppression
10 +function Component(props) {
11 + 'use forget';
12 + // eslint-disable-next-line foo/not-react-related
13 + return <div>{props.text}</div>;
14 +}
15 +
16 +export const FIXTURE_ENTRYPOINT = {
17 + fn: Component,
18 + params: [{text: 'Hello'}],
19 +};
20 +
21 +```
22 +
23 +## Code
24 +
25 +```javascript
26 +import { c as _c } from "react/compiler-runtime"; // @eslintSuppressionRules:[]
27 +
28 +// The suppression here shouldn't cause compilation to get skipped
29 +// Previously we had a bug where an empty list of suppressions would
30 +// create a regexp that matched any suppression
31 +function Component(props) {
32 + "use forget";
33 + const $ = _c(2);
34 + let t0;
35 + if ($[0] !== props.text) {
36 + t0 = <div>{props.text}</div>;
37 + $[0] = props.text;
38 + $[1] = t0;
39 + } else {
40 + t0 = $[1];
41 + }
42 + return t0;
43 +}
44 +
45 +export const FIXTURE_ENTRYPOINT = {
46 + fn: Component,
47 + params: [{ text: "Hello" }],
48 +};
49 +
50 +```
51 +
52 +### Eval output
53 +(kind: ok) <div>Hello</div>
\ No newline at end of file
compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/empty-eslint-suppressions-config.js new
+15
@@ -0,0 +1,15 @@
1 +// @eslintSuppressionRules:[]
2 +
3 +// The suppression here shouldn't cause compilation to get skipped
4 +// Previously we had a bug where an empty list of suppressions would
5 +// create a regexp that matched any suppression
6 +function Component(props) {
7 + 'use forget';
8 + // eslint-disable-next-line foo/not-react-related
9 + return <div>{props.text}</div>;
10 +}
11 +
12 +export const FIXTURE_ENTRYPOINT = {
13 + fn: Component,
14 + params: [{text: 'Hello'}],
15 +};