From f850d3b26524db907f51592dcdf5d811e6aefc2e Mon Sep 17 00:00:00 2001 From: Lauren Tan Date: Wed, 28 Jun 2023 11:43:56 -0400 Subject: [PATCH] Improve remaining InvalidReact error messages --- .../src/HIR/BuildHIR.ts | 4 ++-- .../src/Inference/InferReferenceEffects.ts | 20 ++++++++--------- .../src/Validation/ValidateFrozenLambdas.ts | 9 ++++++-- .../Validation/ValidateNoRefAccesInRender.ts | 4 ++-- ...invalid-access-ref-during-render.expect.md | 2 +- .../error.invalid-array-push-frozen.expect.md | 2 +- ...valid-capture-func-passed-to-jsx.expect.md | 2 +- ...d-computed-store-to-frozen-value.expect.md | 2 +- ...omputed-property-of-frozen-value.expect.md | 2 +- ...-delete-property-of-frozen-value.expect.md | 2 +- ...destructure-assignment-to-global.expect.md | 2 +- ...ucture-to-local-global-variables.expect.md | 2 +- ...eze-conditionally-mutable-lambda.expect.md | 2 +- ...eeze-mutable-lambda-mutate-local.expect.md | 2 +- ...ze-mutable-lambda-reassign-local.expect.md | 2 +- ...pression-mutates-immutable-value.expect.md | 2 +- ...alid-mutate-after-aliased-freeze.expect.md | 2 +- ...rror.invalid-mutate-after-freeze.expect.md | 2 +- ...ror.invalid-pass-ref-to-function.expect.md | 2 +- ...d-property-store-to-frozen-value.expect.md | 2 +- ...n-callback-invoked-during-render.expect.md | 2 +- ...error.invalid-ref-value-as-props.expect.md | 2 +- ...d-set-and-read-ref-during-render.expect.md | 4 ++-- ...f-added-to-dep-without-type-info.expect.md | 2 +- .../error.reassignment-to-global.expect.md | 22 +++++++++++++++++++ .../compiler/error.reassignment-to-global.js | 5 +++++ .../compiler/error.todo-kitchensink.expect.md | 8 ------- .../compiler/error.todo-kitchensink.js | 4 ---- .../__tests__/ReactForgetDiagnostics-test.ts | 2 +- 29 files changed, 70 insertions(+), 50 deletions(-) create mode 100644 compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.reassignment-to-global.expect.md create mode 100644 compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.reassignment-to-global.js diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts index bc201d53d4..dcb36b25c0 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/HIR/BuildHIR.ts @@ -2551,9 +2551,9 @@ function lowerIdentifierForAssignment( if (kind === InstructionKind.Reassign) { // Trying to reassign a global is not allowed builder.errors.push({ - reason: `(BuildHIR::lowerAssignment) Assigning to an identifier defined outside the function scope is not supported.`, + reason: `This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure)`, severity: ErrorSeverity.InvalidReact, - loc: path.node.loc ?? null, + loc: path.parentPath.node.loc ?? null, suggestions: null, }); } else { diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts b/compiler/forget/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts index 7c1c67507a..4a66eb668b 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/Inference/InferReferenceEffects.ts @@ -25,11 +25,9 @@ import { } from "../HIR/HIR"; import { FunctionSignature } from "../HIR/ObjectShape"; import { - printIdentifier, printMixedHIR, printPlace, printSourceLocation, - printType, } from "../HIR/PrintHIR"; import { eachInstructionOperand, @@ -324,10 +322,11 @@ class InferenceState { effect = Effect.Mutate; } else { CompilerError.invalidReact({ - reason: `InferReferenceEffects: inferred mutation of known immutable value`, - description: `Found mutation of ${printIdentifier( - place.identifier - )}${printType(place.identifier.type)} (${valueKind})`, + reason: `This mutates a variable after it was passed to React, which means that React cannot observe changes to it`, + description: + place.identifier.name !== null + ? `Found mutation of ${place.identifier.name}` + : null, loc: place.loc, suggestions: null, }); @@ -340,10 +339,11 @@ class InferenceState { valueKind !== ValueKind.Context ) { CompilerError.invalidReact({ - reason: `InferReferenceEffects: inferred mutation of known immutable value`, - description: `Found mutation of ${printIdentifier( - place.identifier - )}${printType(place.identifier.type)} (${valueKind})`, + reason: `This mutates a variable after it was passed to React, which means that React cannot observe changes to it`, + description: + place.identifier.name !== null + ? `Found mutation of ${place.identifier.name}` + : null, loc: place.loc, suggestions: null, }); diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/Validation/ValidateFrozenLambdas.ts b/compiler/forget/packages/babel-plugin-react-forget/src/Validation/ValidateFrozenLambdas.ts index fe81cfa762..ca76e43fb0 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/Validation/ValidateFrozenLambdas.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/Validation/ValidateFrozenLambdas.ts @@ -132,11 +132,16 @@ function validateOperand( state.temporaries.get(operand.identifier.id) ?? operand.identifier.id; const lambda = state.lambdas.get(operandId); if (lambda !== undefined) { + // TODO: these seem to always be null, we should try to preserve original names from source + const description = + lambda.name !== null && operand.identifier.name !== null + ? `\`${lambda.name}\` is a function that may mutate \`${operand.identifier.name}\`. If you must mutate \`${operand.identifier.name}\` try using a React API like useState and use its setter function instead` + : null; return new CompilerErrorDetail({ - description: null, + description, loc: typeof operand.loc !== "symbol" ? operand.loc : null, reason: - "Cannot use a mutable function where an immutable value is expected", + "This mutates a variable that is managed by React, where an immutable value or a function was expected", severity: ErrorSeverity.InvalidReact, suggestions: null, }); diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/Validation/ValidateNoRefAccesInRender.ts b/compiler/forget/packages/babel-plugin-react-forget/src/Validation/ValidateNoRefAccesInRender.ts index da1f299bda..7bcdebb9f2 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/Validation/ValidateNoRefAccesInRender.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/Validation/ValidateNoRefAccesInRender.ts @@ -107,7 +107,7 @@ function validateNonRefValue(error: CompilerError, operand: Place): void { description: `Cannot access ref value at ${printPlace(operand)}`, loc: typeof operand.loc !== "symbol" ? operand.loc : null, reason: - "Ref values (the `current` property) may not be accessed during render", + "Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef)", severity: ErrorSeverity.InvalidReact, suggestions: null, }) @@ -123,7 +123,7 @@ function validateNonRefObject(error: CompilerError, operand: Place): void { description: `Cannot access ref object at ${printPlace(operand)}`, loc: typeof operand.loc !== "symbol" ? operand.loc : null, reason: - "Ref values may not be passed to functions because they could read the ref value (`current` property) during render", + "Ref values may not be passed to functions because they could read the ref value (`current` property) during render. (https://react.dev/reference/react/useRef)", severity: ErrorSeverity.InvalidReact, suggestions: null, }) diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md index b96122445f..b591fad42e 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md @@ -15,7 +15,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. Cannot access ref value at freeze $22:TObject (5:5) +[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at freeze $22:TObject (5:5) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-array-push-frozen.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-array-push-frozen.expect.md index c9de9f5de7..773acccb50 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-array-push-frozen.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-array-push-frozen.expect.md @@ -15,7 +15,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: InferReferenceEffects: inferred mutation of known immutable value. Found mutation of $19:TObject (frozen) (4:4) +[ReactForget] InvalidReact: This mutates a variable after it was passed to React, which means that React cannot observe changes to it (4:4) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.expect.md index 5b389053cf..b52e8f693e 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.expect.md @@ -20,7 +20,7 @@ function component(a, b) { ## Error ``` -[ReactForget] InvalidReact: Cannot use a mutable function where an immutable value is expected (8:8) +[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (8:8) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-computed-store-to-frozen-value.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-computed-store-to-frozen-value.expect.md index 69822f7548..1e4c4f712c 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-computed-store-to-frozen-value.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-computed-store-to-frozen-value.expect.md @@ -16,7 +16,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: InferReferenceEffects: inferred mutation of known immutable value. Found mutation of $21 (frozen) (5:5) +[ReactForget] InvalidReact: This mutates a variable after it was passed to React, which means that React cannot observe changes to it (5:5) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-delete-computed-property-of-frozen-value.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-delete-computed-property-of-frozen-value.expect.md index 99020154bb..f812dc758d 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-delete-computed-property-of-frozen-value.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-delete-computed-property-of-frozen-value.expect.md @@ -16,7 +16,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: InferReferenceEffects: inferred mutation of known immutable value. Found mutation of $19 (frozen) (5:5) +[ReactForget] InvalidReact: This mutates a variable after it was passed to React, which means that React cannot observe changes to it (5:5) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-delete-property-of-frozen-value.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-delete-property-of-frozen-value.expect.md index 7e0ad2b0db..7c8d25b08b 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-delete-property-of-frozen-value.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-delete-property-of-frozen-value.expect.md @@ -16,7 +16,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: InferReferenceEffects: inferred mutation of known immutable value. Found mutation of $18 (frozen) (5:5) +[ReactForget] InvalidReact: This mutates a variable after it was passed to React, which means that React cannot observe changes to it (5:5) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-destructure-assignment-to-global.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-destructure-assignment-to-global.expect.md index 42cc8702f8..8fb9d7ec4e 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-destructure-assignment-to-global.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-destructure-assignment-to-global.expect.md @@ -13,7 +13,7 @@ function useFoo(props) { ## Error ``` -[ReactForget] InvalidReact: (BuildHIR::lowerAssignment) Assigning to an identifier defined outside the function scope is not supported. (2:2) +[ReactForget] InvalidReact: This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure) (2:2) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-destructure-to-local-global-variables.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-destructure-to-local-global-variables.expect.md index acff85a2d7..e396c48b98 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-destructure-to-local-global-variables.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-destructure-to-local-global-variables.expect.md @@ -15,7 +15,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: (BuildHIR::lowerAssignment) Assigning to an identifier defined outside the function scope is not supported. (3:3) +[ReactForget] InvalidReact: This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure) (3:3) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.expect.md index d6e5385bd2..14b1666bde 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.expect.md @@ -25,7 +25,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: Cannot use a mutable function where an immutable value is expected (15:15) +[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (15:15) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.expect.md index dea675166b..cc5e8b7d2f 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.expect.md @@ -18,7 +18,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: Cannot use a mutable function where an immutable value is expected (8:8) +[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (8:8) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.expect.md index ed481f384b..6725c866e4 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.expect.md @@ -16,7 +16,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: Cannot use a mutable function where an immutable value is expected (6:6) +[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (6:6) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-function-expression-mutates-immutable-value.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-function-expression-mutates-immutable-value.expect.md index 519030a1fe..9b29b16cad 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-function-expression-mutates-immutable-value.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-function-expression-mutates-immutable-value.expect.md @@ -18,7 +18,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: InferReferenceEffects: inferred mutation of known immutable value. Found mutation of $39 (frozen) (5:5) +[ReactForget] InvalidReact: This mutates a variable after it was passed to React, which means that React cannot observe changes to it (5:5) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-mutate-after-aliased-freeze.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-mutate-after-aliased-freeze.expect.md index 2306135869..bdcccd4b50 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-mutate-after-aliased-freeze.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-mutate-after-aliased-freeze.expect.md @@ -25,7 +25,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: InferReferenceEffects: inferred mutation of known immutable value. Found mutation of $44:TObject (frozen) (13:13) +[ReactForget] InvalidReact: This mutates a variable after it was passed to React, which means that React cannot observe changes to it (13:13) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-mutate-after-freeze.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-mutate-after-freeze.expect.md index dc637053d5..cf5f6ff793 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-mutate-after-freeze.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-mutate-after-freeze.expect.md @@ -19,7 +19,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: InferReferenceEffects: inferred mutation of known immutable value. Found mutation of $26:TObject (frozen) (7:7) +[ReactForget] InvalidReact: This mutates a variable after it was passed to React, which means that React cannot observe changes to it (7:7) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.expect.md index 31a1b08f19..afd6b808f3 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.expect.md @@ -14,7 +14,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: Ref values may not be passed to functions because they could read the ref value (`current` property) during render. Cannot access ref object at mutate? $21[6:8]:TObject (3:3) +[ReactForget] InvalidReact: Ref values may not be passed to functions because they could read the ref value (`current` property) during render. (https://react.dev/reference/react/useRef). Cannot access ref object at mutate? $21[6:8]:TObject (3:3) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-property-store-to-frozen-value.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-property-store-to-frozen-value.expect.md index ca8e01e675..6dde3b3f53 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-property-store-to-frozen-value.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-property-store-to-frozen-value.expect.md @@ -16,7 +16,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: InferReferenceEffects: inferred mutation of known immutable value. Found mutation of $20 (frozen) (5:5) +[ReactForget] InvalidReact: This mutates a variable after it was passed to React, which means that React cannot observe changes to it (5:5) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md index a148fbf6e5..28e47ba6c4 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md @@ -18,7 +18,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. Cannot access ref value at capture $42[6:16]:TObject (5:5) +[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at capture $42[6:16]:TObject (5:5) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.expect.md index 6d02d60096..b9aa2f0489 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.expect.md @@ -13,7 +13,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. Cannot access ref value at freeze $19:TObject (3:3) +[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at freeze $19:TObject (3:3) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.expect.md index 5421762d56..727d52707d 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.expect.md @@ -14,9 +14,9 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: Ref values may not be passed to functions because they could read the ref value (`current` property) during render. Cannot access ref object at store $21[7:9]:TObject (3:3) +[ReactForget] InvalidReact: Ref values may not be passed to functions because they could read the ref value (`current` property) during render. (https://react.dev/reference/react/useRef). Cannot access ref object at store $21[7:9]:TObject (3:3) -[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. Cannot access ref value at freeze $24:TObject (4:4) +[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at freeze $24:TObject (4:4) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md index a7540dae62..e189cb7d4a 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md @@ -21,7 +21,7 @@ function Foo({ a }) { ## Error ``` -[ReactForget] InvalidReact: Ref values may not be passed to functions because they could read the ref value (`current` property) during render. Cannot access ref object at capture $29:TObject (4:4) +[ReactForget] InvalidReact: Ref values may not be passed to functions because they could read the ref value (`current` property) during render. (https://react.dev/reference/react/useRef). Cannot access ref object at capture $29:TObject (4:4) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.reassignment-to-global.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.reassignment-to-global.expect.md new file mode 100644 index 0000000000..5174ee5ca9 --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.reassignment-to-global.expect.md @@ -0,0 +1,22 @@ + +## Input + +```javascript +function Component() { + // Cannot assign to globals + someUnknownGlobal = true; + moduleLocal = true; +} + +``` + + +## Error + +``` +[ReactForget] InvalidReact: This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure) (3:3) + +[ReactForget] InvalidReact: This reassigns a variable which was not defined inside of the component. Components should be pure and side-effect free. If this variable is used in rendering, use useState instead. (https://react.dev/learn/keeping-components-pure) (4:4) +``` + + \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.reassignment-to-global.js b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.reassignment-to-global.js new file mode 100644 index 0000000000..d0509a3d52 --- /dev/null +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.reassignment-to-global.js @@ -0,0 +1,5 @@ +function Component() { + // Cannot assign to globals + someUnknownGlobal = true; + moduleLocal = true; +} diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.expect.md index 68cb36f844..c5d4fb46a9 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.expect.md @@ -64,10 +64,6 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) { } } - // Cannot assign to globals - someUnknownGlobal = true; - moduleLocal = true; - function component(a) { // Add support for function declarations once we support `var` hoisting. function t() {} @@ -126,10 +122,6 @@ let moduleLocal = false; [ReactForget] Todo: (BuildHIR::node.lowerReorderableExpression) Expression type 'CallExpression' cannot be safely reordered (55:55) [ReactForget] Todo: (BuildHIR::node.lowerReorderableExpression) Expression type 'BinaryExpression' cannot be safely reordered (53:53) - -[ReactForget] InvalidReact: (BuildHIR::lowerAssignment) Assigning to an identifier defined outside the function scope is not supported. (64:64) - -[ReactForget] InvalidReact: (BuildHIR::lowerAssignment) Assigning to an identifier defined outside the function scope is not supported. (65:65) ``` \ No newline at end of file diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.js b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.js index 32250ac273..111f9b25b1 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.js +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-kitchensink.js @@ -60,10 +60,6 @@ function foo([a, b], { c, d, e = "e" }, f = "f", ...args) { } } - // Cannot assign to globals - someUnknownGlobal = true; - moduleLocal = true; - function component(a) { // Add support for function declarations once we support `var` hoisting. function t() {} diff --git a/compiler/forget/packages/eslint-plugin-react-forget/__tests__/ReactForgetDiagnostics-test.ts b/compiler/forget/packages/eslint-plugin-react-forget/__tests__/ReactForgetDiagnostics-test.ts index 04a075990a..e207a35736 100644 --- a/compiler/forget/packages/eslint-plugin-react-forget/__tests__/ReactForgetDiagnostics-test.ts +++ b/compiler/forget/packages/eslint-plugin-react-forget/__tests__/ReactForgetDiagnostics-test.ts @@ -72,7 +72,7 @@ const tests: ForgetTestCases = { errors: [ { message: - "[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. Cannot access ref value at freeze $22:TObject (6:6)", + "[ReactForget] InvalidReact: Ref values (the `current` property) may not be accessed during render. (https://react.dev/reference/react/useRef). Cannot access ref value at freeze $22:TObject (6:6)", line: 6, column: 10, endColumn: 15,