diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts index 72fa101260df5..4faa35d18f747 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts @@ -451,6 +451,12 @@ export function compileProgram( pass.code, ), }; + if ( + !compileResult.compiledFn.hasFireRewrite && + !compileResult.compiledFn.hasLoweredContextAccess + ) { + return null; + } } catch (err) { // TODO: we might want to log error here, but this will also result in duplicate logging if (err instanceof CompilerError) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts index f8a2bc4989c12..ce535a9b38667 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -14,7 +14,7 @@ import { renameVariables, } from '.'; import {CompilerError, ErrorSeverity} from '../CompilerError'; -import {Environment, EnvironmentConfig, ExternalFunction} from '../HIR'; +import {Environment, ExternalFunction} from '../HIR'; import { ArrayPattern, BlockId, @@ -156,7 +156,7 @@ export function codegenFunction( const compiled = compileResult.unwrap(); const hookGuard = fn.env.config.enableEmitHookGuards; - if (hookGuard != null) { + if (hookGuard != null && fn.env.isInferredMemoEnabled) { compiled.body = t.blockStatement([ createHookGuard( hookGuard, @@ -250,7 +250,11 @@ export function codegenFunction( } const emitInstrumentForget = fn.env.config.enableEmitInstrumentForget; - if (emitInstrumentForget != null && fn.id != null) { + if ( + emitInstrumentForget != null && + fn.id != null && + fn.env.isInferredMemoEnabled + ) { /* * Technically, this is a conditional hook call. However, we expect * __DEV__ and gating identifier to be runtime constants @@ -548,7 +552,7 @@ function codegenBlockNoReset( } function wrapCacheDep(cx: Context, value: t.Expression): t.Expression { - if (cx.env.config.enableEmitFreeze != null) { + if (cx.env.config.enableEmitFreeze != null && cx.env.isInferredMemoEnabled) { // The import declaration for emitFreeze is inserted in the Babel plugin return t.conditionalExpression( t.identifier('__DEV__'), @@ -1553,7 +1557,7 @@ function createHookGuard( * ``` */ function createCallExpression( - config: EnvironmentConfig, + env: Environment, callee: t.Expression, args: Array, loc: SourceLocation | null, @@ -1564,8 +1568,8 @@ function createCallExpression( callExpr.loc = loc; } - const hookGuard = config.enableEmitHookGuards; - if (hookGuard != null && isHook) { + const hookGuard = env.config.enableEmitHookGuards; + if (hookGuard != null && isHook && env.isInferredMemoEnabled) { const iife = t.functionExpression( null, [], @@ -1701,7 +1705,7 @@ function codegenInstructionValue( const callee = codegenPlaceToExpression(cx, instrValue.callee); const args = instrValue.args.map(arg => codegenArgument(cx, arg)); value = createCallExpression( - cx.env.config, + cx.env, callee, args, instrValue.loc, @@ -1791,7 +1795,7 @@ function codegenInstructionValue( ); const args = instrValue.args.map(arg => codegenArgument(cx, arg)); value = createCallExpression( - cx.env.config, + cx.env, memberExpr, args, instrValue.loc, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dont-add-hook-guards-on-retry.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dont-add-hook-guards-on-retry.expect.md new file mode 100644 index 0000000000000..6477654d3d0ea --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dont-add-hook-guards-on-retry.expect.md @@ -0,0 +1,27 @@ + +## Input + +```javascript +// @flow @enableEmitHookGuards @panicThreshold(none) @enableFire + +component Foo(useDynamicHook) { + useDynamicHook(); + return
hello world
; +} + +``` + +## Code + +```javascript +function Foo({ + useDynamicHook, +}: $ReadOnly<{ useDynamicHook: any }>): React.Node { + useDynamicHook(); + return
hello world
; +} + +``` + +### Eval output +(kind: exception) Fixture not implemented \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dont-add-hook-guards-on-retry.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dont-add-hook-guards-on-retry.js new file mode 100644 index 0000000000000..d0313aa42fdb4 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dont-add-hook-guards-on-retry.js @@ -0,0 +1,6 @@ +// @flow @enableEmitHookGuards @panicThreshold(none) @enableFire + +component Foo(useDynamicHook) { + useDynamicHook(); + return
hello world
; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/repro-dont-add-hook-guards-on-retry.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/repro-dont-add-hook-guards-on-retry.expect.md new file mode 100644 index 0000000000000..5a27845f079e3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/repro-dont-add-hook-guards-on-retry.expect.md @@ -0,0 +1,49 @@ + +## Input + +```javascript +// @flow @enableEmitHookGuards @panicThreshold(none) @enableFire +import {useEffect, fire} from 'react'; + +function Component(props, useDynamicHook) { + 'use memo'; + useDynamicHook(); + const foo = props => { + console.log(props); + }; + useEffect(() => { + fire(foo(props)); + }); + + return
hello world
; +} + +``` + +## Code + +```javascript +import { $dispatcherGuard } from "react-compiler-runtime"; +import { useFire } from "react/compiler-runtime"; +import { useEffect, fire } from "react"; + +function Component(props, useDynamicHook) { + "use memo"; + + useDynamicHook(); + const foo = _temp; + const t0 = useFire(foo); + + useEffect(() => { + t0(props); + }); + return
hello world
; +} +function _temp(props_0) { + console.log(props_0); +} + +``` + +### Eval output +(kind: exception) Fixture not implemented \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/repro-dont-add-hook-guards-on-retry.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/repro-dont-add-hook-guards-on-retry.js new file mode 100644 index 0000000000000..077982e8d48fd --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/transform-fire/repro-dont-add-hook-guards-on-retry.js @@ -0,0 +1,15 @@ +// @flow @enableEmitHookGuards @panicThreshold(none) @enableFire +import {useEffect, fire} from 'react'; + +function Component(props, useDynamicHook) { + 'use memo'; + useDynamicHook(); + const foo = props => { + console.log(props); + }; + useEffect(() => { + fire(foo(props)); + }); + + return
hello world
; +}