Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b658717e9 |
@@ -59,6 +59,7 @@ type ProgramContextOptions = {
|
|||||||
opts: PluginOptions;
|
opts: PluginOptions;
|
||||||
filename: string | null;
|
filename: string | null;
|
||||||
code: string | null;
|
code: string | null;
|
||||||
|
hasModuleScopeOptOut: boolean;
|
||||||
};
|
};
|
||||||
export class ProgramContext {
|
export class ProgramContext {
|
||||||
/**
|
/**
|
||||||
@@ -70,6 +71,7 @@ export class ProgramContext {
|
|||||||
code: string | null;
|
code: string | null;
|
||||||
reactRuntimeModule: string;
|
reactRuntimeModule: string;
|
||||||
suppressions: Array<SuppressionRange>;
|
suppressions: Array<SuppressionRange>;
|
||||||
|
hasModuleScopeOptOut: boolean;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is a hack to work around what seems to be a Babel bug. Babel doesn't
|
* This is a hack to work around what seems to be a Babel bug. Babel doesn't
|
||||||
@@ -94,6 +96,7 @@ export class ProgramContext {
|
|||||||
opts,
|
opts,
|
||||||
filename,
|
filename,
|
||||||
code,
|
code,
|
||||||
|
hasModuleScopeOptOut,
|
||||||
}: ProgramContextOptions) {
|
}: ProgramContextOptions) {
|
||||||
this.scope = program.scope;
|
this.scope = program.scope;
|
||||||
this.opts = opts;
|
this.opts = opts;
|
||||||
@@ -101,6 +104,7 @@ export class ProgramContext {
|
|||||||
this.code = code;
|
this.code = code;
|
||||||
this.reactRuntimeModule = getReactCompilerRuntimeModule(opts.target);
|
this.reactRuntimeModule = getReactCompilerRuntimeModule(opts.target);
|
||||||
this.suppressions = suppressions;
|
this.suppressions = suppressions;
|
||||||
|
this.hasModuleScopeOptOut = hasModuleScopeOptOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
isHookName(name: string): boolean {
|
isHookName(name: string): boolean {
|
||||||
|
|||||||
@@ -325,6 +325,8 @@ export function compileProgram(
|
|||||||
filename: pass.filename,
|
filename: pass.filename,
|
||||||
code: pass.code,
|
code: pass.code,
|
||||||
suppressions,
|
suppressions,
|
||||||
|
hasModuleScopeOptOut:
|
||||||
|
findDirectiveDisablingMemoization(program.node.directives) != null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const queue: Array<CompileSource> = findFunctionsToCompile(
|
const queue: Array<CompileSource> = findFunctionsToCompile(
|
||||||
@@ -368,7 +370,19 @@ export function compileProgram(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Avoid modifying the program if we find a program level opt-out
|
// Avoid modifying the program if we find a program level opt-out
|
||||||
if (findDirectiveDisablingMemoization(program.node.directives) != null) {
|
if (programContext.hasModuleScopeOptOut) {
|
||||||
|
if (compiledFns.length > 0) {
|
||||||
|
const error = new CompilerError();
|
||||||
|
error.pushErrorDetail(
|
||||||
|
new CompilerErrorDetail({
|
||||||
|
reason:
|
||||||
|
'Unexpected compiled functions when module scope opt-out is present',
|
||||||
|
severity: ErrorSeverity.Invariant,
|
||||||
|
loc: null,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
handleError(error, programContext, null);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,9 +505,10 @@ function processFn(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Otherwise if 'use no forget/memo' is present, we still run the code through the compiler
|
* If 'use no forget/memo' is present and we still ran the code through the
|
||||||
* for validation but we don't mutate the babel AST. This allows us to flag if there is an
|
* compiler for validation, log a skip event and don't mutate the babel AST.
|
||||||
* unused 'use no forget/memo' directive.
|
* This allows us to flag if there is an unused 'use no forget/memo'
|
||||||
|
* directive.
|
||||||
*/
|
*/
|
||||||
if (
|
if (
|
||||||
programContext.opts.ignoreUseNoForget === false &&
|
programContext.opts.ignoreUseNoForget === false &&
|
||||||
@@ -518,16 +533,7 @@ function processFn(
|
|||||||
prunedMemoValues: compiledFn.prunedMemoValues,
|
prunedMemoValues: compiledFn.prunedMemoValues,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
if (programContext.hasModuleScopeOptOut) {
|
||||||
* Always compile functions with opt in directives.
|
|
||||||
*/
|
|
||||||
if (directives.optIn != null) {
|
|
||||||
return compiledFn;
|
|
||||||
} else if (programContext.opts.compilationMode === 'annotation') {
|
|
||||||
/**
|
|
||||||
* If no opt-in directive is found and the compiler is configured in
|
|
||||||
* annotation mode, don't insert the compiled function.
|
|
||||||
*/
|
|
||||||
return null;
|
return null;
|
||||||
} else if (programContext.opts.noEmit) {
|
} else if (programContext.opts.noEmit) {
|
||||||
/**
|
/**
|
||||||
@@ -541,6 +547,15 @@ function processFn(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
} else if (
|
||||||
|
programContext.opts.compilationMode === 'annotation' &&
|
||||||
|
directives.optIn == null
|
||||||
|
) {
|
||||||
|
/**
|
||||||
|
* If no opt-in directive is found and the compiler is configured in
|
||||||
|
* annotation mode, don't insert the compiled function.
|
||||||
|
*/
|
||||||
|
return null;
|
||||||
} else {
|
} else {
|
||||||
return compiledFn;
|
return compiledFn;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,16 +33,15 @@ export const FIXTURE_ENTRYPOINT = {
|
|||||||
import { print } from "shared-runtime";
|
import { print } from "shared-runtime";
|
||||||
import useEffectWrapper from "useEffectWrapper";
|
import useEffectWrapper from "useEffectWrapper";
|
||||||
|
|
||||||
function Foo(t0) {
|
function Foo({ propVal }) {
|
||||||
"use memo";
|
"use memo";
|
||||||
const { propVal } = t0;
|
|
||||||
|
|
||||||
const arr = [propVal];
|
const arr = [propVal];
|
||||||
useEffectWrapper(() => print(arr), [arr]);
|
useEffectWrapper(() => print(arr));
|
||||||
|
|
||||||
const arr2 = [];
|
const arr2 = [];
|
||||||
useEffectWrapper(() => arr2.push(propVal), [arr2, propVal]);
|
useEffectWrapper(() => arr2.push(propVal));
|
||||||
arr2.push(2);
|
arr2.push(2);
|
||||||
|
|
||||||
return { arr, arr2 };
|
return { arr, arr2 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ function Foo() {
|
|||||||
function Foo() {
|
function Foo() {
|
||||||
return <button onClick={() => alert("hello!")}>Click me!</button>;
|
return <button onClick={() => alert("hello!")}>Click me!</button>;
|
||||||
}
|
}
|
||||||
function _temp() {
|
|
||||||
return alert("hello!");
|
|
||||||
}
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -19,22 +19,11 @@ export const FIXTURE_ENTRYPOINT = {
|
|||||||
## Code
|
## Code
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
import { c as _c } from "react/compiler-runtime"; // @noEmit
|
// @noEmit
|
||||||
|
|
||||||
function Foo() {
|
function Foo() {
|
||||||
"use memo";
|
"use memo";
|
||||||
const $ = _c(1);
|
return <button onClick={() => alert("hello!")}>Click me!</button>;
|
||||||
let t0;
|
|
||||||
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
|
|
||||||
t0 = <button onClick={_temp}>Click me!</button>;
|
|
||||||
$[0] = t0;
|
|
||||||
} else {
|
|
||||||
t0 = $[0];
|
|
||||||
}
|
|
||||||
return t0;
|
|
||||||
}
|
|
||||||
function _temp() {
|
|
||||||
return alert("hello!");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const FIXTURE_ENTRYPOINT = {
|
export const FIXTURE_ENTRYPOINT = {
|
||||||
|
|||||||
Reference in New Issue
Block a user