From d59b8408c3fe0e5eb0d1bd8e3f743451ae6bbee3 Mon Sep 17 00:00:00 2001 From: Lauren Tan Date: Thu, 24 Apr 2025 13:13:19 -0400 Subject: [PATCH 1/3] [forgive] Don't look up user babel configs Projects with existing babel config files may confuse the LSP, so explictly opt out of looking them up. --- compiler/packages/react-forgive/server/src/compiler/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/packages/react-forgive/server/src/compiler/index.ts b/compiler/packages/react-forgive/server/src/compiler/index.ts index 3723785cfbebd..fe192c62132b6 100644 --- a/compiler/packages/react-forgive/server/src/compiler/index.ts +++ b/compiler/packages/react-forgive/server/src/compiler/index.ts @@ -33,6 +33,8 @@ export async function compile({ plugins: ['typescript', 'jsx'], }, sourceType: 'module', + configFile: false, + babelrc: false, }); if (ast == null) { return null; @@ -48,6 +50,8 @@ export async function compile({ plugins, sourceType: 'module', sourceFileName: file, + configFile: false, + babelrc: false, }); if (result?.code == null) { throw new Error( From b53e74ad1d8dc397c245095b8246fb842847d70f Mon Sep 17 00:00:00 2001 From: Lauren Tan Date: Thu, 24 Apr 2025 13:14:17 -0400 Subject: [PATCH 2/3] [forgive][ez] Tweak logging Summary: Test Plan: Reviewers: Subscribers: Tasks: Tags: --- compiler/packages/react-forgive/server/src/index.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/compiler/packages/react-forgive/server/src/index.ts b/compiler/packages/react-forgive/server/src/index.ts index 0b43e9fcd2945..fd4ffd99886c9 100644 --- a/compiler/packages/react-forgive/server/src/index.ts +++ b/compiler/packages/react-forgive/server/src/index.ts @@ -132,7 +132,7 @@ connection.onInitialized(() => { }); documents.onDidChangeContent(async event => { - connection.console.info(`Changed: ${event.document.uri}`); + connection.console.info(`Compiling: ${event.document.uri}`); resetState(); if (SUPPORTED_LANGUAGE_IDS.has(event.document.languageId)) { const text = event.document.getText(); @@ -143,8 +143,11 @@ documents.onDidChangeContent(async event => { options: compilerOptions, }); } catch (err) { + connection.console.error('Failed to compile'); if (err instanceof Error) { - connection.console.error(err.stack ?? ''); + connection.console.error(err.stack ?? err.message); + } else { + connection.console.error(JSON.stringify(err, null, 2)); } } } @@ -192,7 +195,6 @@ connection.onCodeLensResolve(lens => { }); connection.onCodeAction(params => { - connection.console.log('onCodeAction'); const codeActions: Array = []; for (const codeActionEvent of codeActionEvents) { if ( @@ -242,6 +244,7 @@ connection.onRequest(AutoDepsDecorationsRequest.type, async params => { }); function resetState() { + connection.console.debug('Clearing state'); compiledFns.clear(); autoDepsDecorations = []; codeActionEvents = []; From 4fa7b8e9e0cc8041b6f1b45e599573ff9b5ce8cd Mon Sep 17 00:00:00 2001 From: Lauren Tan Date: Thu, 24 Apr 2025 13:14:27 -0400 Subject: [PATCH 3/3] [compiler] Emit CompileSkip before CompileSuccess event Previously the CompileSuccess event would emit first before CompileSkip, so the lsp's codelens would incorrectly flag skipped components/hooks (via 'use no memo') as being optimized. --- .../src/Entrypoint/Program.ts | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) 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 622b7f72dad9b..34347f10b8fdf 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Program.ts @@ -469,6 +469,23 @@ export function compileProgram( } } + /** + * Otherwise if 'use no forget/memo' is present, we still run the code through the compiler + * for validation but we don't mutate the babel AST. This allows us to flag if there is an + * unused 'use no forget/memo' directive. + */ + if (pass.opts.ignoreUseNoForget === false && optOutDirectives.length > 0) { + for (const directive of optOutDirectives) { + pass.opts.logger?.logEvent(pass.filename, { + kind: 'CompileSkip', + fnLoc: fn.node.body.loc ?? null, + reason: `Skipped due to '${directive.value.value}' directive.`, + loc: directive.loc ?? null, + }); + } + return null; + } + pass.opts.logger?.logEvent(pass.filename, { kind: 'CompileSuccess', fnLoc: fn.node.loc ?? null, @@ -492,23 +509,6 @@ export function compileProgram( return null; } - /** - * Otherwise if 'use no forget/memo' is present, we still run the code through the compiler - * for validation but we don't mutate the babel AST. This allows us to flag if there is an - * unused 'use no forget/memo' directive. - */ - if (pass.opts.ignoreUseNoForget === false && optOutDirectives.length > 0) { - for (const directive of optOutDirectives) { - pass.opts.logger?.logEvent(pass.filename, { - kind: 'CompileSkip', - fnLoc: fn.node.body.loc ?? null, - reason: `Skipped due to '${directive.value.value}' directive.`, - loc: directive.loc ?? null, - }); - } - return null; - } - if (!pass.opts.noEmit) { return compileResult.compiledFn; }