Skip to content

Commit 3871fda

Browse files
committed
[compiler][be] Clean up compilation skipping logic in Program
ghstack-source-id: fe2c81d Pull Request resolved: facebook#30642
1 parent 0fb03c4 commit 3871fda

File tree

1 file changed

+85
-73
lines changed
  • compiler/packages/babel-plugin-react-compiler/src/Entrypoint

1 file changed

+85
-73
lines changed

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

Lines changed: 85 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
ErrorSeverity,
1414
} from '../CompilerError';
1515
import {
16+
EnvironmentConfig,
1617
ExternalFunction,
1718
ReactFunctionType,
1819
parseEnvironmentConfig,
@@ -276,41 +277,27 @@ export function compileProgram(
276277
program: NodePath<t.Program>,
277278
pass: CompilerPass,
278279
): void {
279-
if (pass.opts.sources) {
280-
if (pass.filename === null) {
281-
const error = new CompilerError();
282-
error.pushErrorDetail(
283-
new CompilerErrorDetail({
284-
reason: `Expected a filename but found none.`,
285-
description:
286-
"When the 'sources' config options is specified, the React compiler will only compile files with a name",
287-
severity: ErrorSeverity.InvalidConfig,
288-
loc: null,
289-
}),
290-
);
291-
handleError(error, pass, null);
292-
return;
293-
}
294-
295-
if (!isFilePartOfSources(pass.opts.sources, pass.filename)) {
296-
return;
297-
}
298-
}
299-
300-
// Top level "use no forget", skip this file entirely
301-
if (
302-
findDirectiveDisablingMemoization(program.node.directives, pass.opts) !=
303-
null
304-
) {
280+
if (shouldSkipCompilation(program, pass)) {
305281
return;
306282
}
307283

308-
const environment = parseEnvironmentConfig(pass.opts.environment ?? {});
284+
/*
285+
* TODO(lauren): Remove pass.opts.environment nullcheck once PluginOptions
286+
* is validated
287+
*/
288+
const environmentResult = parseEnvironmentConfig(pass.opts.environment ?? {});
289+
if (environmentResult.isErr()) {
290+
CompilerError.throwInvalidConfig({
291+
reason:
292+
'Error in validating environment config. This is an advanced setting and not meant to be used directly',
293+
description: environmentResult.unwrapErr().toString(),
294+
suggestions: null,
295+
loc: null,
296+
});
297+
}
298+
const environment = environmentResult.unwrap();
309299
const useMemoCacheIdentifier = program.scope.generateUidIdentifier('c');
310300
const moduleName = pass.opts.runtimeModule ?? 'react/compiler-runtime';
311-
if (hasMemoCacheFunctionImport(program, moduleName)) {
312-
return;
313-
}
314301

315302
/*
316303
* Record lint errors and critical errors as depending on Forget's config,
@@ -332,7 +319,7 @@ export function compileProgram(
332319
const compiledFns: Array<CompileResult> = [];
333320

334321
const traverseFunction = (fn: BabelFn, pass: CompilerPass): void => {
335-
const fnType = getReactFunctionType(fn, pass);
322+
const fnType = getReactFunctionType(fn, pass, environment);
336323
if (fnType === null || ALREADY_COMPILED.has(fn.node)) {
337324
return;
338325
}
@@ -403,24 +390,9 @@ export function compileProgram(
403390

404391
let compiledFn: CodegenFunction;
405392
try {
406-
/*
407-
* TODO(lauren): Remove pass.opts.environment nullcheck once PluginOptions
408-
* is validated
409-
*/
410-
if (environment.isErr()) {
411-
CompilerError.throwInvalidConfig({
412-
reason:
413-
'Error in validating environment config. This is an advanced setting and not meant to be used directly',
414-
description: environment.unwrapErr().toString(),
415-
suggestions: null,
416-
loc: null,
417-
});
418-
}
419-
const config = environment.unwrap();
420-
421393
compiledFn = compileFn(
422394
fn,
423-
config,
395+
environment,
424396
fnType,
425397
useMemoCacheIdentifier.name,
426398
pass.opts.logger,
@@ -514,43 +486,29 @@ export function compileProgram(
514486
externalFunctions.push(gating);
515487
}
516488

517-
const lowerContextAccess = pass.opts.environment?.lowerContextAccess;
489+
const lowerContextAccess = environment.lowerContextAccess;
518490
if (lowerContextAccess && hasLoweredContextAccess) {
519-
externalFunctions.push(tryParseExternalFunction(lowerContextAccess));
491+
externalFunctions.push(lowerContextAccess);
520492
}
521493

522-
const enableEmitInstrumentForget =
523-
pass.opts.environment?.enableEmitInstrumentForget;
494+
const enableEmitInstrumentForget = environment.enableEmitInstrumentForget;
524495
if (enableEmitInstrumentForget != null) {
525-
externalFunctions.push(
526-
tryParseExternalFunction(enableEmitInstrumentForget.fn),
527-
);
496+
externalFunctions.push(enableEmitInstrumentForget.fn);
528497
if (enableEmitInstrumentForget.gating != null) {
529-
externalFunctions.push(
530-
tryParseExternalFunction(enableEmitInstrumentForget.gating),
531-
);
498+
externalFunctions.push(enableEmitInstrumentForget.gating);
532499
}
533500
}
534501

535-
if (pass.opts.environment?.enableEmitFreeze != null) {
536-
const enableEmitFreeze = tryParseExternalFunction(
537-
pass.opts.environment.enableEmitFreeze,
538-
);
539-
externalFunctions.push(enableEmitFreeze);
502+
if (environment.enableEmitFreeze != null) {
503+
externalFunctions.push(environment.enableEmitFreeze);
540504
}
541505

542-
if (pass.opts.environment?.enableEmitHookGuards != null) {
543-
const enableEmitHookGuards = tryParseExternalFunction(
544-
pass.opts.environment.enableEmitHookGuards,
545-
);
546-
externalFunctions.push(enableEmitHookGuards);
506+
if (environment.enableEmitHookGuards != null) {
507+
externalFunctions.push(environment.enableEmitHookGuards);
547508
}
548509

549-
if (pass.opts.environment?.enableChangeDetectionForDebugging != null) {
550-
const enableChangeDetectionForDebugging = tryParseExternalFunction(
551-
pass.opts.environment.enableChangeDetectionForDebugging,
552-
);
553-
externalFunctions.push(enableChangeDetectionForDebugging);
510+
if (environment.enableChangeDetectionForDebugging != null) {
511+
externalFunctions.push(environment.enableChangeDetectionForDebugging);
554512
}
555513
} catch (err) {
556514
handleError(err, pass, null);
@@ -593,11 +551,65 @@ export function compileProgram(
593551
}
594552
}
595553

554+
function shouldSkipCompilation(
555+
program: NodePath<t.Program>,
556+
pass: CompilerPass,
557+
): boolean {
558+
if (pass.opts.sources) {
559+
if (pass.filename === null) {
560+
const error = new CompilerError();
561+
error.pushErrorDetail(
562+
new CompilerErrorDetail({
563+
reason: `Expected a filename but found none.`,
564+
description:
565+
"When the 'sources' config options is specified, the React compiler will only compile files with a name",
566+
severity: ErrorSeverity.InvalidConfig,
567+
loc: null,
568+
}),
569+
);
570+
handleError(error, pass, null);
571+
return true;
572+
}
573+
574+
if (!isFilePartOfSources(pass.opts.sources, pass.filename)) {
575+
return true;
576+
}
577+
}
578+
579+
// Top level "use no forget", skip this file entirely
580+
const useNoForget = findDirectiveDisablingMemoization(
581+
program.node.directives,
582+
pass.opts,
583+
);
584+
if (useNoForget != null) {
585+
pass.opts.logger?.logEvent(pass.filename, {
586+
kind: 'CompileError',
587+
fnLoc: null,
588+
detail: {
589+
severity: ErrorSeverity.Todo,
590+
reason: 'Skipped due to "use no forget" directive.',
591+
loc: useNoForget.loc ?? null,
592+
suggestions: null,
593+
},
594+
});
595+
return true;
596+
}
597+
const moduleName = pass.opts.runtimeModule ?? 'react/compiler-runtime';
598+
if (hasMemoCacheFunctionImport(program, moduleName)) {
599+
return true;
600+
}
601+
return false;
602+
}
603+
596604
function getReactFunctionType(
597605
fn: BabelFn,
598606
pass: CompilerPass,
607+
/**
608+
* TODO(mofeiZ): remove once we validate PluginOptions with Zod
609+
*/
610+
environment: EnvironmentConfig,
599611
): ReactFunctionType | null {
600-
const hookPattern = pass.opts.environment?.hookPattern ?? null;
612+
const hookPattern = environment.hookPattern;
601613
if (fn.node.body.type === 'BlockStatement') {
602614
// Opt-outs disable compilation regardless of mode
603615
const useNoForget = findDirectiveDisablingMemoization(

0 commit comments

Comments
 (0)