From ed9ea81e4a73b02bf138508b4c4ec6acf71b9676 Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Thu, 5 Oct 2023 10:57:20 -0700 Subject: [PATCH] Snap/sprout use new pragma parser and compiler defaults Updates Snap and Sprout to use the new pragma parser, which also means they will always use the same default flags as the compiler itself sets. A side benefit of this is that you no longer need to rebuild snap/sprout to update their flags, since they will take flags from the version of the compiler being executed. --- .../disable-jsx-memoization.expect.md | 4 +- .../compiler/disable-jsx-memoization.js | 2 +- ...mutable-range-extensions-are-bad.expect.md | 3 +- ...ot-all-mutable-range-extensions-are-bad.js | 1 + ...invalid-access-ref-during-render.expect.md | 2 +- .../error.invalid-access-ref-during-render.js | 2 +- ...valid-capture-func-passed-to-jsx.expect.md | 3 +- ...rror.invalid-capture-func-passed-to-jsx.js | 1 + ...eze-conditionally-mutable-lambda.expect.md | 3 +- ...lid-freeze-conditionally-mutable-lambda.js | 1 + ...eeze-mutable-lambda-mutate-local.expect.md | 3 +- ...alid-freeze-mutable-lambda-mutate-local.js | 1 + ...ze-mutable-lambda-reassign-local.expect.md | 3 +- ...id-freeze-mutable-lambda-reassign-local.js | 1 + ...ror.invalid-pass-ref-to-function.expect.md | 3 +- .../error.invalid-pass-ref-to-function.js | 1 + ...n-callback-invoked-during-render.expect.md | 2 +- ...d-ref-in-callback-invoked-during-render.js | 2 +- ...error.invalid-ref-value-as-props.expect.md | 3 +- .../error.invalid-ref-value-as-props.js | 1 + ...d-set-and-read-ref-during-render.expect.md | 5 +- ....invalid-set-and-read-ref-during-render.js | 1 + ...nconditional-set-state-in-render.expect.md | 5 +- ...valid-unconditional-set-state-in-render.js | 1 + ...f-added-to-dep-without-type-info.expect.md | 3 +- ...-use-ref-added-to-dep-without-type-info.js | 1 + ...o-unconditional-set-state-lambda.expect.md | 3 +- ...ror.todo-unconditional-set-state-lambda.js | 1 + ...rrent-aliased-not-added-to-dep-2.expect.md | 3 +- .../ref-current-aliased-not-added-to-dep-2.js | 1 - .../ref-current-not-added-to-dep-2.expect.md | 3 +- .../ref-current-not-added-to-dep-2.js | 1 - .../fixture-test-utils/src/compiler-utils.ts | 46 ++----------------- .../fixture-test-utils/src/constants.ts | 6 +++ compiler/packages/snap/src/compiler-worker.ts | 8 +++- compiler/packages/snap/src/runner.ts | 13 ++++-- compiler/packages/sprout/src/runner-worker.ts | 15 ++++-- 37 files changed, 80 insertions(+), 78 deletions(-) diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/disable-jsx-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/disable-jsx-memoization.expect.md index 223445d433..f08ff9d676 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/disable-jsx-memoization.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/disable-jsx-memoization.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @memoizeJsxElements false +// @memoizeJsxElements:false function Component(props) { const [name, setName] = useState(null); const onChange = function (e) { @@ -26,7 +26,7 @@ export const FIXTURE_ENTRYPOINT = { ## Code ```javascript -import { unstable_useMemoCache as useMemoCache } from "react"; // @memoizeJsxElements false +import { unstable_useMemoCache as useMemoCache } from "react"; // @memoizeJsxElements:false function Component(props) { const $ = useMemoCache(1); const [name, setName] = useState(null); diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/disable-jsx-memoization.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/disable-jsx-memoization.js index ef97791265..3cb4d05041 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/disable-jsx-memoization.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/disable-jsx-memoization.js @@ -1,4 +1,4 @@ -// @memoizeJsxElements false +// @memoizeJsxElements:false function Component(props) { const [name, setName] = useState(null); const onChange = function (e) { diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.expect.md index e23580622d..60eea597fb 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateNoSetStateInRender function Component(props) { const logEvent = useLogging(props.appId); const [currentStep, setCurrentStep] = useState(0); @@ -33,7 +34,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState) (11:11) +[ReactForget] InvalidReact: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState) (12:12) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.js index e8301cfd6e..2a4ce055cd 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.bug-validate-no-set-state-not-all-mutable-range-extensions-are-bad.js @@ -1,3 +1,4 @@ +// @validateNoSetStateInRender function Component(props) { const logEvent = useLogging(props.appId); const [currentStep, setCurrentStep] = useState(0); diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md index b591fad42e..1e36f7c902 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @debug +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); const value = ref.current; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.js index 0be1f1047a..4269fe4b86 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-access-ref-during-render.js @@ -1,4 +1,4 @@ -// @debug +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); const value = ref.current; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.expect.md index b52e8f693e..85a7e7f672 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateFrozenLambdas function component(a, b) { let y = { b }; let z = { a }; @@ -20,7 +21,7 @@ function component(a, b) { ## Error ``` -[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (8:8) +[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (9:9) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.js index 35357391f9..13841d6307 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-capture-func-passed-to-jsx.js @@ -1,3 +1,4 @@ +// @validateFrozenLambdas function component(a, b) { let y = { b }; let z = { a }; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.expect.md index 14b1666bde..6f62e04264 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateFrozenLambdas function Component(props) { const x = {}; let fn; @@ -25,7 +26,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (15:15) +[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (16:16) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.js index 0ffb689787..076e9cd6cf 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-conditionally-mutable-lambda.js @@ -1,3 +1,4 @@ +// @validateFrozenLambdas function Component(props) { const x = {}; let fn; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.expect.md index cc5e8b7d2f..a991205cf0 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateFrozenLambdas function Component(props) { const x = {}; const onChange = (e) => { @@ -18,7 +19,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (8:8) +[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (9:9) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.js index 846b9df81a..9c830542c0 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-mutate-local.js @@ -1,3 +1,4 @@ +// @validateFrozenLambdas function Component(props) { const x = {}; const onChange = (e) => { diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.expect.md index 6725c866e4..1404800c4b 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateFrozenLambdas function Component(props) { let x = ""; const onChange = (e) => { @@ -16,7 +17,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (6:6) +[ReactForget] InvalidReact: This mutates a variable that is managed by React, where an immutable value or a function was expected (7:7) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.js index b13ea05c67..f71882f091 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-freeze-mutable-lambda-reassign-local.js @@ -1,3 +1,4 @@ +// @validateFrozenLambdas function Component(props) { let x = ""; const onChange = (e) => { diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.expect.md index afd6b808f3..a2c7181cbc 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); const x = foo(ref); @@ -14,7 +15,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. (https://react.dev/reference/react/useRef). 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 (4:4) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.js index ce93fc174c..bba228dfa4 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-pass-ref-to-function.js @@ -1,3 +1,4 @@ +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); const x = foo(ref); diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md index 28e47ba6c4..f8d25f7b51 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.expect.md @@ -2,7 +2,7 @@ ## Input ```javascript -// @debug +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); const renderItem = (item) => { diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.js index f400b30286..df786b271a 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-in-callback-invoked-during-render.js @@ -1,4 +1,4 @@ -// @debug +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); const renderItem = (item) => { diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.expect.md index b9aa2f0489..ad1e7a7ca0 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); return ; @@ -13,7 +14,7 @@ function Component(props) { ## Error ``` -[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) +[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 (4:4) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.js index 3cf0b2aaf8..0c8c1e65c8 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-ref-value-as-props.js @@ -1,3 +1,4 @@ +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); return ; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.expect.md index 727d52707d..c728ae32de 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); ref.current = props.value; @@ -14,9 +15,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. (https://react.dev/reference/react/useRef). 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 (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) +[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 (5:5) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.js index 97ce6931db..ef485e9005 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-set-and-read-ref-during-render.js @@ -1,3 +1,4 @@ +// @validateRefAccessDuringRender function Component(props) { const ref = useRef(null); ref.current = props.value; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-unconditional-set-state-in-render.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-unconditional-set-state-in-render.expect.md index d17de1bd11..17428d98d5 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-unconditional-set-state-in-render.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-unconditional-set-state-in-render.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateNoSetStateInRender function Component(props) { const [x, setX] = useState(0); const aliased = setX; @@ -18,9 +19,9 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState) (5:5) - [ReactForget] InvalidReact: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState) (6:6) + +[ReactForget] InvalidReact: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState) (7:7) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-unconditional-set-state-in-render.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-unconditional-set-state-in-render.js index afef24308b..7e08cbe532 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-unconditional-set-state-in-render.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-unconditional-set-state-in-render.js @@ -1,3 +1,4 @@ +// @validateNoSetStateInRender function Component(props) { const [x, setX] = useState(0); const aliased = setX; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md index e189cb7d4a..6b40cae910 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateRefAccessDuringRender function Foo({ a }) { const ref = useRef(); // type information is lost here as we don't track types of fields @@ -21,7 +22,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. (https://react.dev/reference/react/useRef). 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 (5:5) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.js index bbf5facc4a..c6c9228f9e 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.invalid-use-ref-added-to-dep-without-type-info.js @@ -1,3 +1,4 @@ +// @validateRefAccessDuringRender function Foo({ a }) { const ref = useRef(); // type information is lost here as we don't track types of fields diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-unconditional-set-state-lambda.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-unconditional-set-state-lambda.expect.md index 3159b7a33a..8d1e2600a6 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-unconditional-set-state-lambda.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-unconditional-set-state-lambda.expect.md @@ -2,6 +2,7 @@ ## Input ```javascript +// @validateNoSetStateInRender function Component(props) { let y = 0; const [x, setX] = useState(0); @@ -21,7 +22,7 @@ function Component(props) { ## Error ``` -[ReactForget] InvalidReact: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState) (6:6) +[ReactForget] InvalidReact: This is an unconditional set state during render, which will trigger an infinite loop. (https://react.dev/reference/react/useState) (7:7) ``` \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-unconditional-set-state-lambda.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-unconditional-set-state-lambda.js index 8a89c2cbb1..8e7069b7c2 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-unconditional-set-state-lambda.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-unconditional-set-state-lambda.js @@ -1,3 +1,4 @@ +// @validateNoSetStateInRender function Component(props) { let y = 0; const [x, setX] = useState(0); diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.expect.md index 7054f3d815..caf1faa54f 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.expect.md @@ -2,7 +2,6 @@ ## Input ```javascript -// @validateRefAccessDuringRender false function Foo({ a }) { const ref = useRef(); const val = ref.current; @@ -16,7 +15,7 @@ function Foo({ a }) { ## Code ```javascript -import { unstable_useMemoCache as useMemoCache } from "react"; // @validateRefAccessDuringRender false +import { unstable_useMemoCache as useMemoCache } from "react"; function Foo(t20) { const $ = useMemoCache(4); const { a } = t20; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.js index 92d7decf20..1bdd040c67 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-aliased-not-added-to-dep-2.js @@ -1,4 +1,3 @@ -// @validateRefAccessDuringRender false function Foo({ a }) { const ref = useRef(); const val = ref.current; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.expect.md index 83da9c0bed..5074bc6bd6 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.expect.md @@ -2,7 +2,6 @@ ## Input ```javascript -// @validateRefAccessDuringRender false function Foo({ a }) { const ref = useRef(); const x = { a, val: ref.current }; @@ -15,7 +14,7 @@ function Foo({ a }) { ## Code ```javascript -import { unstable_useMemoCache as useMemoCache } from "react"; // @validateRefAccessDuringRender false +import { unstable_useMemoCache as useMemoCache } from "react"; function Foo(t17) { const $ = useMemoCache(4); const { a } = t17; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.js index a31a11fd3e..80ced49a9d 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.js +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/ref-current-not-added-to-dep-2.js @@ -1,4 +1,3 @@ -// @validateRefAccessDuringRender false function Foo({ a }) { const ref = useRef(); const x = { a, val: ref.current }; diff --git a/compiler/packages/fixture-test-utils/src/compiler-utils.ts b/compiler/packages/fixture-test-utils/src/compiler-utils.ts index e42ab8eced..618f974e8e 100644 --- a/compiler/packages/fixture-test-utils/src/compiler-utils.ts +++ b/compiler/packages/fixture-test-utils/src/compiler-utils.ts @@ -2,6 +2,7 @@ import assert from "assert"; import type { runReactForgetBabelPlugin as RunReactForgetBabelPlugin } from "babel-plugin-react-forget/src/Babel/RunReactForgetBabelPlugin"; import { CompilationMode } from "babel-plugin-react-forget/src/Entrypoint"; import type { Effect, ValueKind } from "babel-plugin-react-forget/src/HIR"; +import type { parseConfigPragma as ParseConfigPragma } from "babel-plugin-react-forget/src/HIR/Environment"; export function parseLanguage(source: string): "flow" | "typescript" { return source.indexOf("@flow") !== -1 ? "flow" : "typescript"; @@ -11,6 +12,7 @@ export function transformFixtureInput( input: string, basename: string, pluginFn: typeof RunReactForgetBabelPlugin, + parseConfigPragmaFn: typeof ParseConfigPragma, includeAst: boolean = false ) { // Extract the first line to quickly check for custom test directives @@ -19,16 +21,8 @@ export function transformFixtureInput( let language = parseLanguage(firstLine); let gating = null; let instrumentForget = null; - let memoizeJsxElements = true; - let enableAssumeHooksFollowRulesOfReact = false; - let disableAllMemoization = false; - let validateRefAccessDuringRender = true; - let validateNoSetStateInRender = true; let enableEmitFreeze = null; let compilationMode: CompilationMode = "all"; - let enableForest = false; - let enableMergeConsecutiveScopes = false; - let bailoutOnHoleyArrays = false; if (firstLine.indexOf("@compilationMode(annotation)") !== -1) { assert( @@ -57,37 +51,13 @@ export function transformFixtureInput( importSpecifierName: "useRenderCounter", }; } - if (firstLine.includes("@memoizeJsxElements false")) { - memoizeJsxElements = false; - } - if (firstLine.includes("@enableAssumeHooksFollowRulesOfReact true")) { - enableAssumeHooksFollowRulesOfReact = true; - } - if (firstLine.includes("@disableAllMemoization true")) { - disableAllMemoization = true; - } - if (firstLine.includes("@validateRefAccessDuringRender false")) { - validateRefAccessDuringRender = false; - } - if (firstLine.includes("@validateNoSetStateInRender false")) { - validateNoSetStateInRender = false; - } if (firstLine.includes("@enableEmitFreeze")) { enableEmitFreeze = { source: "react-forget-runtime", importSpecifierName: "makeReadOnly", }; } - if (firstLine.includes("@enableForest true")) { - enableForest = true; - } - if (firstLine.includes("@bailoutOnHoleyArrays")) { - bailoutOnHoleyArrays = true; - } - - if (firstLine.includes("@enableMergeConsecutiveScopes")) { - enableMergeConsecutiveScopes = true; - } + const config = parseConfigPragmaFn(firstLine); return pluginFn( input, @@ -95,6 +65,7 @@ export function transformFixtureInput( language, { environment: { + ...config, customHooks: new Map([ [ "useFreeze", @@ -124,17 +95,8 @@ export function transformFixtureInput( }, ], ]), - enableAssumeHooksFollowRulesOfReact, - disableAllMemoization, - memoizeJsxElements, - validateRefAccessDuringRender, - validateFrozenLambdas: true, - validateNoSetStateInRender, enableEmitFreeze, - enableMergeConsecutiveScopes, assertValidMutableRanges: true, - bailoutOnHoleyArrays, - enableForest, }, compilationMode, logger: null, diff --git a/compiler/packages/fixture-test-utils/src/constants.ts b/compiler/packages/fixture-test-utils/src/constants.ts index a55c2f1b23..36091aee78 100644 --- a/compiler/packages/fixture-test-utils/src/constants.ts +++ b/compiler/packages/fixture-test-utils/src/constants.ts @@ -13,6 +13,12 @@ export const LOGGER_PATH = path.join( "Utils", "logger.js" ); +export const PARSE_CONFIG_PRAGMA_PATH = path.join( + process.cwd(), + "dist", + "HIR", + "Environment.js" +); export const FIXTURES_PATH = path.join( process.cwd(), "src", diff --git a/compiler/packages/snap/src/compiler-worker.ts b/compiler/packages/snap/src/compiler-worker.ts index 5308bba0d5..81412ca108 100644 --- a/compiler/packages/snap/src/compiler-worker.ts +++ b/compiler/packages/snap/src/compiler-worker.ts @@ -6,6 +6,7 @@ */ import type { runReactForgetBabelPlugin as RunReactForgetBabelPlugin } from "babel-plugin-react-forget/src/Babel/RunReactForgetBabelPlugin"; +import type { parseConfigPragma as ParseConfigPragma } from "babel-plugin-react-forget/src/HIR/Environment"; import { TestFixture, transformFixtureInput, @@ -39,6 +40,7 @@ export type TestResult = { export async function compile( compilerPath: string, loggerPath: string, + parseConfigPragmaPath: string, fixture: TestFixture, compilerVersion: number, implicitDebugMode: boolean, @@ -78,6 +80,9 @@ export async function compile( runReactForgetBabelPlugin: typeof RunReactForgetBabelPlugin; }; const { toggleLogging } = require(loggerPath); + const { parseConfigPragma } = require(parseConfigPragmaPath) as { + parseConfigPragma: typeof ParseConfigPragma; + }; // only try logging if we filtered out all but one fixture, // since console log order is non-deterministic @@ -86,7 +91,8 @@ export async function compile( code = transformFixtureInput( input, basename, - runReactForgetBabelPlugin + runReactForgetBabelPlugin, + parseConfigPragma ).code; } catch (e) { e.message = e.message.replace(/\u001b[^m]*m/g, ""); diff --git a/compiler/packages/snap/src/runner.ts b/compiler/packages/snap/src/runner.ts index 1f95966ef5..7575c7b702 100644 --- a/compiler/packages/snap/src/runner.ts +++ b/compiler/packages/snap/src/runner.ts @@ -9,12 +9,14 @@ import watcher from "@parcel/watcher"; import chalk from "chalk"; import { COMPILER_PATH, - LOGGER_PATH, - FIXTURES_PATH, FILTER_FILENAME, FILTER_PATH, - readTestFilter, + FIXTURES_PATH, + LOGGER_PATH, + PARSE_CONFIG_PRAGMA_PATH, TestFilter, + getFixtures, + readTestFilter, } from "fixture-test-utils"; import fs from "fs"; import invariant from "invariant"; @@ -26,9 +28,8 @@ import * as readline from "readline"; import ts from "typescript"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; -import { TestResult } from "./compiler-worker"; import * as compiler from "./compiler-worker"; -import { getFixtures } from "fixture-test-utils"; +import { TestResult } from "./compiler-worker"; const WORKER_PATH = require.resolve("./compiler-worker.js"); @@ -126,6 +127,7 @@ async function run( .compile( COMPILER_PATH, LOGGER_PATH, + PARSE_CONFIG_PRAGMA_PATH, fixture, compilerVersion, filter?.debug ?? false, @@ -142,6 +144,7 @@ async function run( let output = await compiler.compile( COMPILER_PATH, LOGGER_PATH, + PARSE_CONFIG_PRAGMA_PATH, fixture, compilerVersion, filter?.debug ?? false, diff --git a/compiler/packages/sprout/src/runner-worker.ts b/compiler/packages/sprout/src/runner-worker.ts index 4585d047e5..1c1f2f504e 100644 --- a/compiler/packages/sprout/src/runner-worker.ts +++ b/compiler/packages/sprout/src/runner-worker.ts @@ -5,24 +5,30 @@ * LICENSE file in the root directory of this source tree. */ +import { NodePath, PluginItem, transformFromAstSync } from "@babel/core"; +import * as parser from "@babel/parser"; +import * as t from "@babel/types"; import type { runReactForgetBabelPlugin as RunReactForgetBabelPlugin } from "babel-plugin-react-forget/src/Babel/RunReactForgetBabelPlugin"; +import type { parseConfigPragma as ParseConfigPragma } from "babel-plugin-react-forget/src/HIR/Environment"; import { COMPILER_PATH, + PARSE_CONFIG_PRAGMA_PATH, parseLanguage, TestFixture, transformFixtureInput, } from "fixture-test-utils"; -import { NodePath, PluginItem, transformFromAstSync } from "@babel/core"; import fs from "fs/promises"; -import * as parser from "@babel/parser"; -import * as t from "@babel/types"; -import { doEval, EvaluatorResult } from "./runner-evaluator"; import path from "path"; +import { doEval, EvaluatorResult } from "./runner-evaluator"; const { runReactForgetBabelPlugin } = require(COMPILER_PATH) as { runReactForgetBabelPlugin: typeof RunReactForgetBabelPlugin; }; +const { parseConfigPragma } = require(PARSE_CONFIG_PRAGMA_PATH) as { + parseConfigPragma: typeof ParseConfigPragma; +}; + // TODO: save output in .sprout.md files export type TestResult = | { @@ -118,6 +124,7 @@ function transformFixtureForget( input, filename, runReactForgetBabelPlugin, + parseConfigPragma, true );