Skip to content

Commit e247982

Browse files
committed
[compiler][entrypoint] Fix edgecases for noEmit and opt-outs
Title
1 parent 1c521f5 commit e247982

File tree

5 files changed

+39
-35
lines changed

5 files changed

+39
-35
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type ProgramContextOptions = {
5959
opts: PluginOptions;
6060
filename: string | null;
6161
code: string | null;
62+
hasModuleScopeOptOut: boolean;
6263
};
6364
export class ProgramContext {
6465
/**
@@ -70,6 +71,7 @@ export class ProgramContext {
7071
code: string | null;
7172
reactRuntimeModule: string;
7273
suppressions: Array<SuppressionRange>;
74+
hasModuleScopeOptOut: boolean;
7375

7476
/*
7577
* This is a hack to work around what seems to be a Babel bug. Babel doesn't
@@ -94,13 +96,15 @@ export class ProgramContext {
9496
opts,
9597
filename,
9698
code,
99+
hasModuleScopeOptOut,
97100
}: ProgramContextOptions) {
98101
this.scope = program.scope;
99102
this.opts = opts;
100103
this.filename = filename;
101104
this.code = code;
102105
this.reactRuntimeModule = getReactCompilerRuntimeModule(opts.target);
103106
this.suppressions = suppressions;
107+
this.hasModuleScopeOptOut = hasModuleScopeOptOut;
104108
}
105109

106110
isHookName(name: string): boolean {

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

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,8 @@ export function compileProgram(
325325
filename: pass.filename,
326326
code: pass.code,
327327
suppressions,
328+
hasModuleScopeOptOut:
329+
findDirectiveDisablingMemoization(program.node.directives) != null,
328330
});
329331

330332
const queue: Array<CompileSource> = findFunctionsToCompile(
@@ -368,7 +370,19 @@ export function compileProgram(
368370
}
369371

370372
// Avoid modifying the program if we find a program level opt-out
371-
if (findDirectiveDisablingMemoization(program.node.directives) != null) {
373+
if (programContext.hasModuleScopeOptOut) {
374+
if (compiledFns.length > 0) {
375+
const error = new CompilerError();
376+
error.pushErrorDetail(
377+
new CompilerErrorDetail({
378+
reason:
379+
'Unexpected compiled functions when module scope opt-out is present',
380+
severity: ErrorSeverity.Invariant,
381+
loc: null,
382+
}),
383+
);
384+
handleError(error, programContext, null);
385+
}
372386
return null;
373387
}
374388

@@ -491,9 +505,10 @@ function processFn(
491505
}
492506

493507
/**
494-
* Otherwise if 'use no forget/memo' is present, we still run the code through the compiler
495-
* for validation but we don't mutate the babel AST. This allows us to flag if there is an
496-
* unused 'use no forget/memo' directive.
508+
* If 'use no forget/memo' is present and we still ran the code through the
509+
* compiler for validation, log a skip event and don't mutate the babel AST.
510+
* This allows us to flag if there is an unused 'use no forget/memo'
511+
* directive.
497512
*/
498513
if (
499514
programContext.opts.ignoreUseNoForget === false &&
@@ -518,16 +533,7 @@ function processFn(
518533
prunedMemoValues: compiledFn.prunedMemoValues,
519534
});
520535

521-
/**
522-
* Always compile functions with opt in directives.
523-
*/
524-
if (directives.optIn != null) {
525-
return compiledFn;
526-
} else if (programContext.opts.compilationMode === 'annotation') {
527-
/**
528-
* If no opt-in directive is found and the compiler is configured in
529-
* annotation mode, don't insert the compiled function.
530-
*/
536+
if (programContext.hasModuleScopeOptOut) {
531537
return null;
532538
} else if (programContext.opts.noEmit) {
533539
/**
@@ -541,6 +547,15 @@ function processFn(
541547
}
542548
}
543549
return null;
550+
} else if (
551+
programContext.opts.compilationMode === 'annotation' &&
552+
directives.optIn == null
553+
) {
554+
/**
555+
* If no opt-in directive is found and the compiler is configured in
556+
* annotation mode, don't insert the compiled function.
557+
*/
558+
return null;
544559
} else {
545560
return compiledFn;
546561
}

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/infer-effect-dependencies/no-emit/retry-opt-in--no-emit.expect.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,15 @@ export const FIXTURE_ENTRYPOINT = {
3333
import { print } from "shared-runtime";
3434
import useEffectWrapper from "useEffectWrapper";
3535

36-
function Foo(t0) {
36+
function Foo({ propVal }) {
3737
"use memo";
38-
const { propVal } = t0;
39-
4038
const arr = [propVal];
41-
useEffectWrapper(() => print(arr), [arr]);
39+
useEffectWrapper(() => print(arr));
4240

4341
const arr2 = [];
44-
useEffectWrapper(() => arr2.push(propVal), [arr2, propVal]);
42+
useEffectWrapper(() => arr2.push(propVal));
4543
arr2.push(2);
44+
4645
return { arr, arr2 };
4746
}
4847

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-bailout-nopanic-shouldnt-outline.expect.md

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ function Foo() {
2020
function Foo() {
2121
return <button onClick={() => alert("hello!")}>Click me!</button>;
2222
}
23-
function _temp() {
24-
return alert("hello!");
25-
}
2623

2724
```
2825

compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/use-memo-noemit.expect.md

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,11 @@ export const FIXTURE_ENTRYPOINT = {
1919
## Code
2020

2121
```javascript
22-
import { c as _c } from "react/compiler-runtime"; // @noEmit
22+
// @noEmit
2323

2424
function Foo() {
2525
"use memo";
26-
const $ = _c(1);
27-
let t0;
28-
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
29-
t0 = <button onClick={_temp}>Click me!</button>;
30-
$[0] = t0;
31-
} else {
32-
t0 = $[0];
33-
}
34-
return t0;
35-
}
36-
function _temp() {
37-
return alert("hello!");
26+
return <button onClick={() => alert("hello!")}>Click me!</button>;
3827
}
3928

4029
export const FIXTURE_ENTRYPOINT = {

0 commit comments

Comments
 (0)