Skip to content

Commit f8312e0

Browse files
committed
[compiler] Errors in earlier functions dont stop subsequent compilation
Errors in an earlier component/hook shouldn't stop later components from compiling. ghstack-source-id: 55363fd Pull Request resolved: #30844
1 parent c741d2d commit f8312e0

6 files changed

+133
-22
lines changed

compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,6 @@ export function compileProgram(
310310
pass.opts.eslintSuppressionRules ?? DEFAULT_ESLINT_SUPPRESSIONS,
311311
pass.opts.flowSuppressions,
312312
);
313-
const lintError = suppressionsToCompilerError(suppressions);
314-
let hasCriticalError = lintError != null;
315313
const queue: Array<{
316314
kind: 'original' | 'outlined';
317315
fn: BabelFn;
@@ -385,22 +383,24 @@ export function compileProgram(
385383
);
386384
}
387385

388-
if (lintError != null) {
389-
/**
390-
* Note that Babel does not attach comment nodes to nodes; they are dangling off of the
391-
* Program node itself. We need to figure out whether an eslint suppression range
392-
* applies to this function first.
393-
*/
394-
const suppressionsInFunction = filterSuppressionsThatAffectFunction(
395-
suppressions,
396-
fn,
397-
);
398-
if (suppressionsInFunction.length > 0) {
399-
if (optOutDirectives.length > 0) {
400-
logError(lintError, pass, fn.node.loc ?? null);
401-
} else {
402-
handleError(lintError, pass, fn.node.loc ?? null);
403-
}
386+
/**
387+
* Note that Babel does not attach comment nodes to nodes; they are dangling off of the
388+
* Program node itself. We need to figure out whether an eslint suppression range
389+
* applies to this function first.
390+
*/
391+
const suppressionsInFunction = filterSuppressionsThatAffectFunction(
392+
suppressions,
393+
fn,
394+
);
395+
if (suppressionsInFunction.length > 0) {
396+
const lintError = suppressionsToCompilerError(suppressionsInFunction);
397+
if (optOutDirectives.length > 0) {
398+
logError(lintError, pass, fn.node.loc ?? null);
399+
} else {
400+
handleError(lintError, pass, fn.node.loc ?? null);
401+
}
402+
if (isCriticalError(lintError)) {
403+
return null;
404404
}
405405
}
406406

@@ -436,7 +436,6 @@ export function compileProgram(
436436
return null;
437437
}
438438
}
439-
hasCriticalError ||= isCriticalError(err);
440439
handleError(err, pass, fn.node.loc ?? null);
441440
return null;
442441
}
@@ -470,7 +469,7 @@ export function compileProgram(
470469
return null;
471470
}
472471

473-
if (!pass.opts.noEmit && !hasCriticalError) {
472+
if (!pass.opts.noEmit) {
474473
return compiledFn;
475474
}
476475
return null;

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-unclosed-eslint-suppression.expect.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,6 @@ function CrimesAgainstReact() {
3939
1 | // Note: Everything below this is sketchy
4040
> 2 | /* eslint-disable react-hooks/rules-of-hooks */
4141
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InvalidReact: React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. eslint-disable react-hooks/rules-of-hooks (2:2)
42-
43-
InvalidReact: React Compiler has skipped optimizing this component because one or more React ESLint rules were disabled. React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. eslint-disable-next-line react-hooks/rules-of-hooks (25:25)
4442
3 | function lowercasecomponent() {
4543
4 | 'use forget';
4644
5 | const x = [];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @panicThreshold(none)
6+
import {useHook} from 'shared-runtime';
7+
8+
function InvalidComponent(props) {
9+
if (props.cond) {
10+
useHook();
11+
}
12+
return <div>Hello World!</div>;
13+
}
14+
15+
function ValidComponent(props) {
16+
return <div>{props.greeting}</div>;
17+
}
18+
19+
```
20+
21+
## Code
22+
23+
```javascript
24+
import { c as _c } from "react/compiler-runtime"; // @panicThreshold(none)
25+
import { useHook } from "shared-runtime";
26+
27+
function InvalidComponent(props) {
28+
if (props.cond) {
29+
useHook();
30+
}
31+
return <div>Hello World!</div>;
32+
}
33+
34+
function ValidComponent(props) {
35+
const $ = _c(2);
36+
let t0;
37+
if ($[0] !== props.greeting) {
38+
t0 = <div>{props.greeting}</div>;
39+
$[0] = props.greeting;
40+
$[1] = t0;
41+
} else {
42+
t0 = $[1];
43+
}
44+
return t0;
45+
}
46+
47+
```
48+
49+
### Eval output
50+
(kind: exception) Fixture not implemented
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// @panicThreshold(none)
2+
import {useHook} from 'shared-runtime';
3+
4+
function InvalidComponent(props) {
5+
if (props.cond) {
6+
useHook();
7+
}
8+
return <div>Hello World!</div>;
9+
}
10+
11+
function ValidComponent(props) {
12+
return <div>{props.greeting}</div>;
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
2+
## Input
3+
4+
```javascript
5+
// @panicThreshold(none)
6+
7+
// unclosed disable rule should affect all components
8+
/* eslint-disable react-hooks/rules-of-hooks */
9+
10+
function ValidComponent1(props) {
11+
return <div>Hello World!</div>;
12+
}
13+
14+
function ValidComponent2(props) {
15+
return <div>{props.greeting}</div>;
16+
}
17+
18+
```
19+
20+
## Code
21+
22+
```javascript
23+
// @panicThreshold(none)
24+
25+
// unclosed disable rule should affect all components
26+
/* eslint-disable react-hooks/rules-of-hooks */
27+
28+
function ValidComponent1(props) {
29+
return <div>Hello World!</div>;
30+
}
31+
32+
function ValidComponent2(props) {
33+
return <div>{props.greeting}</div>;
34+
}
35+
36+
```
37+
38+
### Eval output
39+
(kind: exception) Fixture not implemented
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// @panicThreshold(none)
2+
3+
// unclosed disable rule should affect all components
4+
/* eslint-disable react-hooks/rules-of-hooks */
5+
6+
function ValidComponent1(props) {
7+
return <div>Hello World!</div>;
8+
}
9+
10+
function ValidComponent2(props) {
11+
return <div>{props.greeting}</div>;
12+
}

0 commit comments

Comments
 (0)