@samitouri / QOS-React / commits / 8d74e8c73a

[compiler] Patch error reporting for blocklisted imports

ghstack-source-id: 614c1e9c04828bfa2da13a6abaeff7ce3e67cb9b Pull Request resolved: https://github.com/facebook/react/pull/30652

Mofei Zhang committed Aug 9, 2024 at 13:43 UTC 8d74e8c73a5cc5e461bb1413a74c6b058c6be134
2 files changed +27 -5
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Imports.ts
+11 -4
@@ -7,25 +7,27 @@
7
8 import {NodePath} from '@babel/core';
9 import * as t from '@babel/types';
10 -import {CompilerError} from '../CompilerError';
10 +import {CompilerError, ErrorSeverity} from '../CompilerError';
11 import {EnvironmentConfig, ExternalFunction, GeneratedSource} from '../HIR';
12 import {getOrInsertDefault} from '../Utils/utils';
13
14 export function validateRestrictedImports(
15 path: NodePath<t.Program>,
16 {validateBlocklistedImports}: EnvironmentConfig,
17 -): void {
17 +): CompilerError | null {
18 if (
19 validateBlocklistedImports == null ||
20 validateBlocklistedImports.length === 0
21 ) {
22 - return;
22 + return null;
23 }
24 + const error = new CompilerError();
25 const restrictedImports = new Set(validateBlocklistedImports);
26 path.traverse({
27 ImportDeclaration(importDeclPath) {
28 if (restrictedImports.has(importDeclPath.node.source.value)) {
28 - CompilerError.throwTodo({
29 + error.push({
30 + severity: ErrorSeverity.Todo,
31 reason: 'Bailing out due to blocklisted import',
32 description: `Import from module ${importDeclPath.node.source.value}`,
33 loc: importDeclPath.node.loc ?? null,
@@ -33,6 +35,11 @@ export function validateRestrictedImports(
35 }
36 },
37 });
38 + if (error.hasErrors()) {
39 + return error;
40 + } else {
41 + return null;
42 + }
43 }
44
45 export function addImportsToProgram(
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts
+16 -1
@@ -277,6 +277,17 @@ function isFilePartOfSources(
277 return false;
278 }
279
280 +/**
281 + * `compileProgram` is directly invoked by the react-compiler babel plugin, so
282 + * exceptions thrown by this function will fail the babel build.
283 + * - call `handleError` if your error is recoverable.
284 + * Unless the error is a warning / info diagnostic, compilation of a function
285 + * / entire file should also be skipped.
286 + * - throw an exception if the error is fatal / not recoverable.
287 + * Examples of this are invalid compiler configs or failure to codegen outlined
288 + * functions *after* already emitting optimized components / hooks that invoke
289 + * the outlined functions.
290 + */
291 export function compileProgram(
292 program: NodePath<t.Program>,
293 pass: CompilerPass,
@@ -300,7 +311,11 @@ export function compileProgram(
311 });
312 }
313 const environment = environmentResult.unwrap();
303 - validateRestrictedImports(program, environment);
314 + const restrictedImportsErr = validateRestrictedImports(program, environment);
315 + if (restrictedImportsErr) {
316 + handleError(restrictedImportsErr, pass, null);
317 + return;
318 + }
319 const useMemoCacheIdentifier = program.scope.generateUidIdentifier('c');
320 const moduleName = pass.opts.runtimeModule ?? 'react/compiler-runtime';
321