Skip to content

Commit 02d4dda

Browse files
committed
[compiler] Deprecate noEmit, add outputMode (#35112)
This deprecates the `noEmit: boolean` flag and adds `outputMode: 'client' | 'client-no-memo' | 'ssr' | 'lint'` as the replacement. OutputMode defaults to null and takes precedence if specified, otherwise we use 'client' mode for noEmit=false and 'lint' mode for noEmit=true. Key points: * Retrying failed compilation switches from 'client' mode to 'client-no-memo' * Validations are enabled behind Environment.proto.shouldEnableValidations, enabled for all modes except 'client-no-memo'. Similar for dropping manual memoization. * OptimizeSSR is now gated by the outputMode==='ssr', not a feature flag * Creation of reactive scopes, and related codegen logic, is now gated by outputMode==='client' DiffTrain build for [50e7ec8](50e7ec8)
1 parent a088349 commit 02d4dda

35 files changed

+178
-123
lines changed

compiled/eslint-plugin-react-hooks/index.js

Lines changed: 92 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32266,10 +32266,9 @@ const EnvironmentConfigSchema = v4.z.object({
3226632266
validateNoDynamicallyCreatedComponentsOrHooks: v4.z.boolean().default(false),
3226732267
enableAllowSetStateFromRefsInEffects: v4.z.boolean().default(true),
3226832268
enableInferEventHandlers: v4.z.boolean().default(false),
32269-
enableOptimizeForSSR: v4.z.boolean().default(false),
3227032269
});
3227132270
class Environment {
32272-
constructor(scope, fnType, compilerMode, config, contextIdentifiers, parentFunction, logger, filename, code, programContext) {
32271+
constructor(scope, fnType, outputMode, config, contextIdentifiers, parentFunction, logger, filename, code, programContext) {
3227332272
_Environment_instances.add(this);
3227432273
_Environment_globals.set(this, void 0);
3227532274
_Environment_shapes.set(this, void 0);
@@ -32285,7 +32284,7 @@ class Environment {
3228532284
_Environment_flowTypeEnvironment.set(this, void 0);
3228632285
__classPrivateFieldSet(this, _Environment_scope, scope, "f");
3228732286
this.fnType = fnType;
32288-
this.compilerMode = compilerMode;
32287+
this.outputMode = outputMode;
3228932288
this.config = config;
3229032289
this.filename = filename;
3229132290
this.code = code;
@@ -32369,8 +32368,52 @@ class Environment {
3236932368
});
3237032369
return __classPrivateFieldGet(this, _Environment_flowTypeEnvironment, "f");
3237132370
}
32372-
get isInferredMemoEnabled() {
32373-
return this.compilerMode !== 'no_inferred_memo';
32371+
get enableDropManualMemoization() {
32372+
switch (this.outputMode) {
32373+
case 'lint': {
32374+
return true;
32375+
}
32376+
case 'client':
32377+
case 'ssr': {
32378+
return true;
32379+
}
32380+
case 'client-no-memo': {
32381+
return false;
32382+
}
32383+
default: {
32384+
assertExhaustive$1(this.outputMode, `Unexpected output mode '${this.outputMode}'`);
32385+
}
32386+
}
32387+
}
32388+
get enableMemoization() {
32389+
switch (this.outputMode) {
32390+
case 'client':
32391+
case 'lint': {
32392+
return true;
32393+
}
32394+
case 'ssr':
32395+
case 'client-no-memo': {
32396+
return false;
32397+
}
32398+
default: {
32399+
assertExhaustive$1(this.outputMode, `Unexpected output mode '${this.outputMode}'`);
32400+
}
32401+
}
32402+
}
32403+
get enableValidations() {
32404+
switch (this.outputMode) {
32405+
case 'client':
32406+
case 'lint':
32407+
case 'ssr': {
32408+
return true;
32409+
}
32410+
case 'client-no-memo': {
32411+
return false;
32412+
}
32413+
default: {
32414+
assertExhaustive$1(this.outputMode, `Unexpected output mode '${this.outputMode}'`);
32415+
}
32416+
}
3237432417
}
3237532418
get nextIdentifierId() {
3237632419
var _a, _b;
@@ -34657,7 +34700,7 @@ function pruneableValue(value, state) {
3465734700
}
3465834701
case 'CallExpression':
3465934702
case 'MethodCall': {
34660-
if (state.env.config.enableOptimizeForSSR) {
34703+
if (state.env.outputMode === 'ssr') {
3466134704
const calleee = value.kind === 'CallExpression' ? value.callee : value.property;
3466234705
const hookKind = getHookKind(state.env, calleee.identifier);
3466334706
switch (hookKind) {
@@ -37468,7 +37511,7 @@ function codegenFunction(fn, { uniqueIdentifiers, fbtOperands, }) {
3746837511
}
3746937512
const compiled = compileResult.unwrap();
3747037513
const hookGuard = fn.env.config.enableEmitHookGuards;
37471-
if (hookGuard != null && fn.env.isInferredMemoEnabled) {
37514+
if (hookGuard != null && fn.env.outputMode === 'client') {
3747237515
compiled.body = libExports$1.blockStatement([
3747337516
createHookGuard(hookGuard, fn.env.programContext, compiled.body.body, GuardKind.PushHookGuard, GuardKind.PopHookGuard),
3747437517
]);
@@ -37498,7 +37541,7 @@ function codegenFunction(fn, { uniqueIdentifiers, fbtOperands, }) {
3749837541
const emitInstrumentForget = fn.env.config.enableEmitInstrumentForget;
3749937542
if (emitInstrumentForget != null &&
3750037543
fn.id != null &&
37501-
fn.env.isInferredMemoEnabled) {
37544+
fn.env.outputMode === 'client') {
3750237545
const gating = emitInstrumentForget.gating != null
3750337546
? libExports$1.identifier(fn.env.programContext.addImportSpecifier(emitInstrumentForget.gating).name)
3750437547
: null;
@@ -37736,7 +37779,8 @@ function codegenBlockNoReset(cx, block) {
3773637779
return libExports$1.blockStatement(statements);
3773737780
}
3773837781
function wrapCacheDep(cx, value) {
37739-
if (cx.env.config.enableEmitFreeze != null && cx.env.isInferredMemoEnabled) {
37782+
if (cx.env.config.enableEmitFreeze != null &&
37783+
cx.env.outputMode === 'client') {
3774037784
const emitFreezeIdentifier = cx.env.programContext.addImportSpecifier(cx.env.config.enableEmitFreeze).name;
3774137785
cx.env.programContext
3774237786
.assertGlobalBinding(EMIT_FREEZE_GLOBAL_GATING, cx.env.scope)
@@ -38582,7 +38626,7 @@ function createCallExpression(env, callee, args, loc, isHook) {
3858238626
callExpr.loc = loc;
3858338627
}
3858438628
const hookGuard = env.config.enableEmitHookGuards;
38585-
if (hookGuard != null && isHook && env.isInferredMemoEnabled) {
38629+
if (hookGuard != null && isHook && env.outputMode === 'client') {
3858638630
const iife = libExports$1.functionExpression(null, [], libExports$1.blockStatement([
3858738631
createHookGuard(hookGuard, env.programContext, [libExports$1.returnStatement(callExpr)], GuardKind.AllowHook, GuardKind.DisallowHook),
3858838632
]));
@@ -42280,7 +42324,7 @@ function computeEffectsForLegacySignature(state, signature, lvalue, receiver, ar
4228042324
}),
4228142325
});
4228242326
}
42283-
if (signature.knownIncompatible != null && state.env.isInferredMemoEnabled) {
42327+
if (signature.knownIncompatible != null && state.env.enableValidations) {
4228442328
const errors = new CompilerError();
4228542329
errors.pushDiagnostic(CompilerDiagnostic.create({
4228642330
category: ErrorCategory.IncompatibleLibrary,
@@ -53412,7 +53456,7 @@ function runWithEnvironment(func, env) {
5341253456
log({ kind: 'hir', name: 'PruneMaybeThrows', value: hir });
5341353457
validateContextVariableLValues(hir);
5341453458
validateUseMemo(hir).unwrap();
53415-
if (env.isInferredMemoEnabled &&
53459+
if (env.enableDropManualMemoization &&
5341653460
!env.config.enablePreserveExistingManualUseMemo &&
5341753461
!env.config.disableMemoizationForDebugging &&
5341853462
!env.config.enableChangeDetectionForDebugging) {
@@ -53438,7 +53482,7 @@ function runWithEnvironment(func, env) {
5343853482
log({ kind: 'hir', name: 'ConstantPropagation', value: hir });
5343953483
inferTypes(hir);
5344053484
log({ kind: 'hir', name: 'InferTypes', value: hir });
53441-
if (env.isInferredMemoEnabled) {
53485+
if (env.enableValidations) {
5344253486
if (env.config.validateHooksUsage) {
5344353487
validateHooksUsage(hir).unwrap();
5344453488
}
@@ -53459,12 +53503,12 @@ function runWithEnvironment(func, env) {
5345953503
log({ kind: 'hir', name: 'AnalyseFunctions', value: hir });
5346053504
const mutabilityAliasingErrors = inferMutationAliasingEffects(hir);
5346153505
log({ kind: 'hir', name: 'InferMutationAliasingEffects', value: hir });
53462-
if (env.isInferredMemoEnabled) {
53506+
if (env.enableValidations) {
5346353507
if (mutabilityAliasingErrors.isErr()) {
5346453508
throw mutabilityAliasingErrors.unwrapErr();
5346553509
}
5346653510
}
53467-
if (env.config.enableOptimizeForSSR) {
53511+
if (env.outputMode === 'ssr') {
5346853512
optimizeForSSR(hir);
5346953513
log({ kind: 'hir', name: 'OptimizeForSSR', value: hir });
5347053514
}
@@ -53480,13 +53524,13 @@ function runWithEnvironment(func, env) {
5348053524
isFunctionExpression: false,
5348153525
});
5348253526
log({ kind: 'hir', name: 'InferMutationAliasingRanges', value: hir });
53483-
if (env.isInferredMemoEnabled) {
53527+
if (env.enableValidations) {
5348453528
if (mutabilityAliasingRangeErrors.isErr()) {
5348553529
throw mutabilityAliasingRangeErrors.unwrapErr();
5348653530
}
5348753531
validateLocalsNotReassignedAfterRender(hir);
5348853532
}
53489-
if (env.isInferredMemoEnabled) {
53533+
if (env.enableValidations) {
5349053534
if (env.config.assertValidMutableRanges) {
5349153535
assertValidMutableRanges(hir);
5349253536
}
@@ -53521,14 +53565,12 @@ function runWithEnvironment(func, env) {
5352153565
name: 'RewriteInstructionKindsBasedOnReassignment',
5352253566
value: hir,
5352353567
});
53524-
if (env.isInferredMemoEnabled) {
53525-
if (env.config.validateStaticComponents) {
53526-
env.logErrors(validateStaticComponents(hir));
53527-
}
53528-
if (!env.config.enableOptimizeForSSR) {
53529-
inferReactiveScopeVariables(hir);
53530-
log({ kind: 'hir', name: 'InferReactiveScopeVariables', value: hir });
53531-
}
53568+
if (env.enableValidations && env.config.validateStaticComponents) {
53569+
env.logErrors(validateStaticComponents(hir));
53570+
}
53571+
if (env.enableMemoization) {
53572+
inferReactiveScopeVariables(hir);
53573+
log({ kind: 'hir', name: 'InferReactiveScopeVariables', value: hir });
5353253574
}
5353353575
const fbtOperands = memoizeFbtAndMacroOperandsInSameScope(hir);
5353453576
log({
@@ -54106,7 +54148,7 @@ function isFilePartOfSources(sources, filename) {
5410654148
return false;
5410754149
}
5410854150
function compileProgram(program, pass) {
54109-
var _a;
54151+
var _a, _b;
5411054152
if (shouldSkipCompilation(program, pass)) {
5411154153
return null;
5411254154
}
@@ -54127,9 +54169,10 @@ function compileProgram(program, pass) {
5412754169
});
5412854170
const queue = findFunctionsToCompile(program, pass, programContext);
5412954171
const compiledFns = [];
54172+
const outputMode = (_b = pass.opts.outputMode) !== null && _b !== void 0 ? _b : (pass.opts.noEmit ? 'lint' : 'client');
5413054173
while (queue.length !== 0) {
5413154174
const current = queue.shift();
54132-
const compiled = processFn(current.fn, current.fnType, programContext);
54175+
const compiled = processFn(current.fn, current.fnType, programContext, outputMode);
5413354176
if (compiled != null) {
5413454177
for (const outlined of compiled.outlined) {
5413554178
CompilerError.invariant(outlined.fn.outlined.length === 0, {
@@ -54211,7 +54254,7 @@ function findFunctionsToCompile(program, pass, programContext) {
5421154254
}, Object.assign(Object.assign({}, pass), { opts: Object.assign(Object.assign({}, pass.opts), pass.opts), filename: (_a = pass.filename) !== null && _a !== void 0 ? _a : null }));
5421254255
return queue;
5421354256
}
54214-
function processFn(fn, fnType, programContext) {
54257+
function processFn(fn, fnType, programContext, outputMode) {
5421554258
var _a, _b, _c, _d, _e, _f, _g, _h;
5421654259
let directives;
5421754260
if (fn.node.body.type !== 'BlockStatement') {
@@ -54232,19 +54275,24 @@ function processFn(fn, fnType, programContext) {
5423254275
};
5423354276
}
5423454277
let compiledFn;
54235-
const compileResult = tryCompileFunction(fn, fnType, programContext);
54278+
const compileResult = tryCompileFunction(fn, fnType, programContext, outputMode);
5423654279
if (compileResult.kind === 'error') {
5423754280
if (directives.optOut != null) {
5423854281
logError(compileResult.error, programContext, (_b = fn.node.loc) !== null && _b !== void 0 ? _b : null);
5423954282
}
5424054283
else {
5424154284
handleError(compileResult.error, programContext, (_c = fn.node.loc) !== null && _c !== void 0 ? _c : null);
5424254285
}
54243-
const retryResult = retryCompileFunction(fn, fnType, programContext);
54244-
if (retryResult == null) {
54286+
if (outputMode === 'client') {
54287+
const retryResult = retryCompileFunction(fn, fnType, programContext);
54288+
if (retryResult == null) {
54289+
return null;
54290+
}
54291+
compiledFn = retryResult;
54292+
}
54293+
else {
5424554294
return null;
5424654295
}
54247-
compiledFn = retryResult;
5424854296
}
5424954297
else {
5425054298
compiledFn = compileResult.compiledFn;
@@ -54272,7 +54320,7 @@ function processFn(fn, fnType, programContext) {
5427254320
if (programContext.hasModuleScopeOptOut) {
5427354321
return null;
5427454322
}
54275-
else if (programContext.opts.noEmit) {
54323+
else if (programContext.opts.outputMode === 'lint') {
5427654324
for (const loc of compiledFn.inferredEffectLocations) {
5427754325
if (loc !== GeneratedSource) {
5427854326
programContext.inferredEffectLocations.add(loc);
@@ -54288,7 +54336,7 @@ function processFn(fn, fnType, programContext) {
5428854336
return compiledFn;
5428954337
}
5429054338
}
54291-
function tryCompileFunction(fn, fnType, programContext) {
54339+
function tryCompileFunction(fn, fnType, programContext, outputMode) {
5429254340
const suppressionsInFunction = filterSuppressionsThatAffectFunction(programContext.suppressions, fn);
5429354341
if (suppressionsInFunction.length > 0) {
5429454342
return {
@@ -54299,7 +54347,7 @@ function tryCompileFunction(fn, fnType, programContext) {
5429954347
try {
5430054348
return {
5430154349
kind: 'compile',
54302-
compiledFn: compileFn(fn, programContext.opts.environment, fnType, 'all_features', programContext, programContext.opts.logger, programContext.filename, programContext.code),
54350+
compiledFn: compileFn(fn, programContext.opts.environment, fnType, outputMode, programContext, programContext.opts.logger, programContext.filename, programContext.code),
5430354351
};
5430454352
}
5430554353
catch (err) {
@@ -54312,7 +54360,7 @@ function retryCompileFunction(fn, fnType, programContext) {
5431254360
return null;
5431354361
}
5431454362
try {
54315-
const retryResult = compileFn(fn, environment, fnType, 'no_inferred_memo', programContext, programContext.opts.logger, programContext.filename, programContext.code);
54363+
const retryResult = compileFn(fn, environment, fnType, 'client-no-memo', programContext, programContext.opts.logger, programContext.filename, programContext.code);
5431654364
if (!retryResult.hasFireRewrite && !retryResult.hasInferredEffect) {
5431754365
return null;
5431854366
}
@@ -54988,13 +55036,20 @@ v4.z.enum([
5498855036
'annotation',
5498955037
'all',
5499055038
]);
55039+
v4.z.enum([
55040+
'ssr',
55041+
'client',
55042+
'client-no-memo',
55043+
'lint',
55044+
]);
5499155045
const defaultOptions = {
5499255046
compilationMode: 'infer',
5499355047
panicThreshold: 'none',
5499455048
environment: parseEnvironmentConfig({}).unwrap(),
5499555049
logger: null,
5499655050
gating: null,
5499755051
noEmit: false,
55052+
outputMode: null,
5499855053
dynamicGating: null,
5499955054
eslintSuppressionRules: null,
5500055055
flowSuppressions: true,
@@ -55413,7 +55468,7 @@ function BabelPluginReactCompiler(_babel) {
5541355468

5541455469
var _LRUCache_values, _LRUCache_headIdx;
5541555470
const COMPILER_OPTIONS = {
55416-
noEmit: true,
55471+
outputMode: 'lint',
5541755472
panicThreshold: 'none',
5541855473
flowSuppressions: false,
5541955474
environment: {

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4cf770d7e1a52c66401b42c7d135f40b7dc23981
1+
50e7ec8a694072fd6fcd52182df8a75211bf084d
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
4cf770d7e1a52c66401b42c7d135f40b7dc23981
1+
50e7ec8a694072fd6fcd52182df8a75211bf084d

compiled/facebook-www/React-dev.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@ __DEV__ &&
14991499
exports.useTransition = function () {
15001500
return resolveDispatcher().useTransition();
15011501
};
1502-
exports.version = "19.3.0-www-classic-4cf770d7-20251120";
1502+
exports.version = "19.3.0-www-classic-50e7ec8a-20251120";
15031503
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
15041504
"function" ===
15051505
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-dev.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@ __DEV__ &&
14991499
exports.useTransition = function () {
15001500
return resolveDispatcher().useTransition();
15011501
};
1502-
exports.version = "19.3.0-www-modern-4cf770d7-20251120";
1502+
exports.version = "19.3.0-www-modern-50e7ec8a-20251120";
15031503
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
15041504
"function" ===
15051505
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-prod.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,4 +606,4 @@ exports.useSyncExternalStore = function (
606606
exports.useTransition = function () {
607607
return ReactSharedInternals.H.useTransition();
608608
};
609-
exports.version = "19.3.0-www-classic-4cf770d7-20251120";
609+
exports.version = "19.3.0-www-classic-50e7ec8a-20251120";

compiled/facebook-www/React-prod.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -606,4 +606,4 @@ exports.useSyncExternalStore = function (
606606
exports.useTransition = function () {
607607
return ReactSharedInternals.H.useTransition();
608608
};
609-
exports.version = "19.3.0-www-modern-4cf770d7-20251120";
609+
exports.version = "19.3.0-www-modern-50e7ec8a-20251120";

compiled/facebook-www/React-profiling.classic.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ exports.useSyncExternalStore = function (
610610
exports.useTransition = function () {
611611
return ReactSharedInternals.H.useTransition();
612612
};
613-
exports.version = "19.3.0-www-classic-4cf770d7-20251120";
613+
exports.version = "19.3.0-www-classic-50e7ec8a-20251120";
614614
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
615615
"function" ===
616616
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

compiled/facebook-www/React-profiling.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ exports.useSyncExternalStore = function (
610610
exports.useTransition = function () {
611611
return ReactSharedInternals.H.useTransition();
612612
};
613-
exports.version = "19.3.0-www-modern-4cf770d7-20251120";
613+
exports.version = "19.3.0-www-modern-50e7ec8a-20251120";
614614
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
615615
"function" ===
616616
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

0 commit comments

Comments
 (0)