[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
+};