diff --git a/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts b/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts index ee0d0f74c5f..2055b25c0c9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/CompilerError.ts @@ -58,11 +58,15 @@ export type CompilerDiagnosticDetail = /** * A/the source of the error */ - { - kind: 'error'; - loc: SourceLocation | null; - message: string; - }; + | { + kind: 'error'; + loc: SourceLocation | null; + message: string; + } + | { + kind: 'hint'; + message: string; + }; export enum CompilerSuggestionOperation { InsertBefore, @@ -134,7 +138,12 @@ export class CompilerDiagnostic { } primaryLocation(): SourceLocation | null { - return this.options.details.filter(d => d.kind === 'error')[0]?.loc ?? null; + const firstErrorDetail = this.options.details.filter( + d => d.kind === 'error', + )[0]; + return firstErrorDetail != null && firstErrorDetail.kind === 'error' + ? firstErrorDetail.loc + : null; } printErrorMessage(source: string, options: PrintErrorMessageOptions): string { @@ -167,9 +176,14 @@ export class CompilerDiagnostic { buffer.push(codeFrame); break; } + case 'hint': { + buffer.push('\n\n'); + buffer.push(detail.message); + break; + } default: { assertExhaustive( - detail.kind, + detail, `Unexpected detail kind ${(detail as any).kind}`, ); } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts index 44bbaa463d6..871c8296c35 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts @@ -471,8 +471,7 @@ function applySignature( effect.reason?.kind === 'AssignCurrentProperty' ) { diagnostic.withDetail({ - kind: 'error', - loc: effect.value.loc, + kind: 'hint', message: `Hint: If this value is a Ref (value returned by \`useRef()\`), rename the variable to end in "Ref".`, }); } @@ -1096,8 +1095,7 @@ function applyEffect( effect.reason?.kind === 'AssignCurrentProperty' ) { diagnostic.withDetail({ - kind: 'error', - loc: effect.value.loc, + kind: 'hint', message: `Hint: If this value is a Ref (value returned by \`useRef()\`), rename the variable to end in "Ref".`, }); } diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-assing-to-ref-current-in-render.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-assing-to-ref-current-in-render.expect.md index af94ba06973..aef40d34cb5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-assing-to-ref-current-in-render.expect.md +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.invalid-assing-to-ref-current-in-render.expect.md @@ -30,13 +30,7 @@ Modifying a value returned from a hook is not allowed. Consider moving the modif 7 | } 8 | - 3 | component Foo() { - 4 | const foo = useFoo(); -> 5 | foo.current = true; - | ^^^ Hint: If this value is a Ref (value returned by `useRef()`), rename the variable to end in "Ref". - 6 | return
; - 7 | } - 8 | +Hint: If this value is a Ref (value returned by `useRef()`), rename the variable to end in "Ref". ``` \ No newline at end of file