diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-279ac76f53af.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-279ac76f53af.expect.md new file mode 100644 index 0000000000..300fe4c181 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-279ac76f53af.expect.md @@ -0,0 +1,29 @@ + +## Input + +```javascript +// @skip +// Unsupported input + +// Valid -- this is a regression test. +jest.useFakeTimers(); +beforeEach(() => { + jest.useRealTimers(); +}); + +``` + +## Code + +```javascript +// @skip +// Unsupported input + +// Valid -- this is a regression test. +jest.useFakeTimers(); +beforeEach(() => { + jest.useRealTimers(); +}); + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-28a78701970c.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-28a78701970c.expect.md new file mode 100644 index 0000000000..9c80a890ab --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-28a78701970c.expect.md @@ -0,0 +1,40 @@ + +## Input + +```javascript +// @skip +// Unsupported input + +// Valid because hooks can be used in anonymous function arguments to +// React.memo. +const MemoizedFunction = React.memo((props) => { + useHook(); + return ; +}); + +``` + + +## Error + +``` +[ReactForget] InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (8:8) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-8566f9a360e2.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-8566f9a360e2.expect.md new file mode 100644 index 0000000000..97c2d87316 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-8566f9a360e2.expect.md @@ -0,0 +1,26 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +const MemoizedButton = memo(function (props) { + if (props.fancy) { + useCustomHook(); + } + return ; +}); + +``` + + +## Error + +``` +[ReactForget] InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (8:8) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-a0058f0b446d.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-a0058f0b446d.expect.md new file mode 100644 index 0000000000..cf5f00f894 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-a0058f0b446d.expect.md @@ -0,0 +1,25 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +function ComponentWithConditionalHook() { + if (cond) { + Namespace.useConditionalHook(); + } +} + +``` + + +## Error + +``` +[ReactForget] InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (8:8) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2.expect.md new file mode 100644 index 0000000000..88fa4fbdcb --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2.expect.md @@ -0,0 +1,26 @@ + +## Input + +```javascript +// @skip +// Unsupported input + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +const FancyButton = React.forwardRef((props, ref) => { + if (props.fancy) { + useCustomHook(); + } + return ; +}); + +``` + + +## Error + +``` +[ReactForget] InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (8:8) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-27c18dc8dad2.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-27c18dc8dad2.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-27c18dc8dad2.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-69521d94fa03.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-69521d94fa03.expect.md new file mode 100644 index 0000000000..c7626edd61 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-69521d94fa03.expect.md @@ -0,0 +1,28 @@ + +## Input + +```javascript +// @skip +// Unsupported input + +// Valid because the neither the condition nor the loop affect the hook call. +function App(props) { + const someObject = { propA: true }; + for (const propName in someObject) { + if (propName === true) { + } else { + } + } + const [myState, setMyState] = useState(null); +} + +``` + + +## Error + +``` +[ReactForget] InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (12:12) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-69521d94fa03.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-69521d94fa03.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-69521d94fa03.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-69521d94fa03.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-93dc5d5e538a.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-93dc5d5e538a.expect.md new file mode 100644 index 0000000000..c6ba4426d0 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-93dc5d5e538a.expect.md @@ -0,0 +1,27 @@ + +## Input + +```javascript +// @skip +// Unsupported input + +// Valid because the loop doesn't change the order of hooks calls. +function RegressionTest() { + const res = []; + const additionalCond = true; + for (let i = 0; i !== 10 && additionalCond; ++i) { + res.push(i); + } + React.useLayoutEffect(() => {}); +} + +``` + + +## Error + +``` +[ReactForget] InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (11:11) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-93dc5d5e538a.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-93dc5d5e538a.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-93dc5d5e538a.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-93dc5d5e538a.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42.expect.md new file mode 100644 index 0000000000..406fb8ace0 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42.expect.md @@ -0,0 +1,25 @@ + +## Input + +```javascript +// @skip +// Unsupported input + +// This is valid because "use"-prefixed functions called in +// unnamed function arguments are not assumed to be hooks. +React.unknownFunction((foo, bar) => { + if (foo) { + useNotAHook(bar); + } +}); + +``` + + +## Error + +``` +[ReactForget] InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (8:8) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-d0935abedc42.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-d0935abedc42.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-d0935abedc42.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913.expect.md new file mode 100644 index 0000000000..83274b52ec --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913.expect.md @@ -0,0 +1,26 @@ + +## Input + +```javascript +// @skip +// Unsupported input + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +function useHook() { + try { + f(); + useState(); + } catch {} +} + +``` + + +## Error + +``` +[ReactForget] InvalidReact: Hooks must always be called in a consistent order, and may not be called conditionally. See the Rules of Hooks (https://react.dev/warnings/invalid-hook-call-warning) (9:9) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-e29c874aa913.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.bail.rules-of-hooks-e29c874aa913.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.rules-of-hooks-e29c874aa913.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0a1dbff27ba0.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0a1dbff27ba0.expect.md new file mode 100644 index 0000000000..1d1a58e602 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0a1dbff27ba0.expect.md @@ -0,0 +1,45 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +function createHook() { + return function useHookWithConditionalHook() { + if (cond) { + useConditionalHook(); + } + }; +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; // @skip +// Passed but should have failed + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +function createHook() { + const $ = useMemoCache(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = function useHookWithConditionalHook() { + if (cond) { + useConditionalHook(); + } + }; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-0a1dbff27ba0.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0a1dbff27ba0.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-0a1dbff27ba0.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0a1dbff27ba0.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0de1224ce64b.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0de1224ce64b.expect.md new file mode 100644 index 0000000000..0f8c4eef1b --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0de1224ce64b.expect.md @@ -0,0 +1,45 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's a common misunderstanding. +// We *could* make it valid but the runtime error could be confusing. +function createComponent() { + return function ComponentWithHookInsideCallback() { + useEffect(() => { + useHookInsideCallback(); + }); + }; +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; // @skip +// Passed but should have failed + +// Invalid because it's a common misunderstanding. +// We *could* make it valid but the runtime error could be confusing. +function createComponent() { + const $ = useMemoCache(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = function ComponentWithHookInsideCallback() { + useEffect(() => { + useHookInsideCallback(); + }); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-0de1224ce64b.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0de1224ce64b.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-0de1224ce64b.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0de1224ce64b.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-191029ac48c8.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-191029ac48c8.expect.md new file mode 100644 index 0000000000..2ec80a9fc9 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-191029ac48c8.expect.md @@ -0,0 +1,41 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's dangerous. +// Normally, this would crash, but not if you use inline requires. +// This *must* be invalid. +// It's expected to have some false positives, but arguably +// they are confusing anyway due to the use*() convention +// already being associated with Hooks. +useState(); +if (foo) { + const foo = React.useCallback(() => {}); +} +useCustomHook(); + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's dangerous. +// Normally, this would crash, but not if you use inline requires. +// This *must* be invalid. +// It's expected to have some false positives, but arguably +// they are confusing anyway due to the use*() convention +// already being associated with Hooks. +useState(); +if (foo) { + const foo = React.useCallback(() => {}); +} +useCustomHook(); + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-191029ac48c8.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-191029ac48c8.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-191029ac48c8.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-191029ac48c8.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-206e2811c87c.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-206e2811c87c.expect.md new file mode 100644 index 0000000000..ebc33e5ccf --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-206e2811c87c.expect.md @@ -0,0 +1,37 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// This is a false positive (it's valid) that unfortunately +// we cannot avoid. Prefer to rename it to not start with "use" +class Foo extends Component { + render() { + if (cond) { + FooStore.useFeatureFlag(); + } + } +} + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +// This is a false positive (it's valid) that unfortunately +// we cannot avoid. Prefer to rename it to not start with "use" +class Foo extends Component { + render() { + if (cond) { + FooStore.useFeatureFlag(); + } + } +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-206e2811c87c.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-206e2811c87c.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-206e2811c87c.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-206e2811c87c.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-28a7111f56a7.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-28a7111f56a7.expect.md new file mode 100644 index 0000000000..c68c6e8ba0 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-28a7111f56a7.expect.md @@ -0,0 +1,43 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Technically this is a false positive. +// We *could* make it valid (and it used to be). +// +// However, top-level Hook-like calls can be very dangerous +// in environments with inline requires because they can mask +// the runtime error by accident. +// So we prefer to disallow it despite the false positive. + +const { createHistory, useBasename } = require("history-2.1.2"); +const browserHistory = useBasename(createHistory)({ + basename: "/", +}); + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +// Technically this is a false positive. +// We *could* make it valid (and it used to be). +// +// However, top-level Hook-like calls can be very dangerous +// in environments with inline requires because they can mask +// the runtime error by accident. +// So we prefer to disallow it despite the false positive. + +const { createHistory, useBasename } = require("history-2.1.2"); +const browserHistory = useBasename(createHistory)({ + basename: "/", +}); + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-28a7111f56a7.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-28a7111f56a7.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-28a7111f56a7.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-28a7111f56a7.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-2c51251df67a.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-2c51251df67a.expect.md new file mode 100644 index 0000000000..c0649482d8 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-2c51251df67a.expect.md @@ -0,0 +1,29 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +(class { + useHook() { + useState(); + } +}); + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +(class { + useHook() { + useState(); + } +}); + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-2c51251df67a.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-2c51251df67a.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-2c51251df67a.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-2c51251df67a.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-449a37146a83.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-449a37146a83.expect.md new file mode 100644 index 0000000000..1cb7604edf --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-449a37146a83.expect.md @@ -0,0 +1,41 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's a common misunderstanding. +// We *could* make it valid but the runtime error could be confusing. +function createComponent() { + return function ComponentWithHookInsideCallback() { + function handleClick() { + useState(); + } + }; +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; // @skip +// Passed but should have failed + +// Invalid because it's a common misunderstanding. +// We *could* make it valid but the runtime error could be confusing. +function createComponent() { + const $ = useMemoCache(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = function ComponentWithHookInsideCallback() {}; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-449a37146a83.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-449a37146a83.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-449a37146a83.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-449a37146a83.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-5a7ac9a6e8fa.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-5a7ac9a6e8fa.expect.md new file mode 100644 index 0000000000..2f576bb961 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-5a7ac9a6e8fa.expect.md @@ -0,0 +1,34 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// These are neither functions nor hooks. +function _normalFunctionWithHook() { + useHookInsideNormalFunction(); +} +function _useNotAHook() { + useHookInsideNormalFunction(); +} + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +// These are neither functions nor hooks. +function _normalFunctionWithHook() { + useHookInsideNormalFunction(); +} + +function _useNotAHook() { + useHookInsideNormalFunction(); +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-5a7ac9a6e8fa.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-5a7ac9a6e8fa.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-5a7ac9a6e8fa.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-5a7ac9a6e8fa.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-76a74b4666e9.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-76a74b4666e9.expect.md new file mode 100644 index 0000000000..54cd30c3cc --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-76a74b4666e9.expect.md @@ -0,0 +1,29 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's a common misunderstanding. +// We *could* make it valid but the runtime error could be confusing. +function ComponentWithHookInsideCallback() { + function handleClick() { + useState(); + } +} + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's a common misunderstanding. +// We *could* make it valid but the runtime error could be confusing. +function ComponentWithHookInsideCallback() {} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-76a74b4666e9.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-76a74b4666e9.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-76a74b4666e9.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-76a74b4666e9.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-8303403b8e4c.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-8303403b8e4c.expect.md new file mode 100644 index 0000000000..26c4a63175 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-8303403b8e4c.expect.md @@ -0,0 +1,29 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +class ClassComponentWithHook extends React.Component { + render() { + React.useState(); + } +} + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +class ClassComponentWithHook extends React.Component { + render() { + React.useState(); + } +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-8303403b8e4c.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-8303403b8e4c.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-8303403b8e4c.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-8303403b8e4c.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-99b5c750d1d1.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-99b5c750d1d1.expect.md new file mode 100644 index 0000000000..fdba1ca765 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-99b5c750d1d1.expect.md @@ -0,0 +1,33 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +class ClassComponentWithFeatureFlag extends React.Component { + render() { + if (foo) { + useFeatureFlag(); + } + } +} + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +class ClassComponentWithFeatureFlag extends React.Component { + render() { + if (foo) { + useFeatureFlag(); + } + } +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-99b5c750d1d1.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-99b5c750d1d1.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-99b5c750d1d1.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-99b5c750d1d1.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-9c79feec4b9b.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-9c79feec4b9b.expect.md new file mode 100644 index 0000000000..ecdca8a2a8 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-9c79feec4b9b.expect.md @@ -0,0 +1,29 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +(class { + h = () => { + useState(); + }; +}); + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +(class { + h = () => { + useState(); + }; +}); + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-9c79feec4b9b.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-9c79feec4b9b.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-9c79feec4b9b.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-9c79feec4b9b.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-a63fd4f9dcc0.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-a63fd4f9dcc0.expect.md new file mode 100644 index 0000000000..403e200dd6 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-a63fd4f9dcc0.expect.md @@ -0,0 +1,29 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// This is invalid because "use"-prefixed functions used in named +// functions are assumed to be hooks. +React.unknownFunction(function notAComponent(foo, bar) { + useProbablyAHook(bar); +}); + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +// This is invalid because "use"-prefixed functions used in named +// functions are assumed to be hooks. +React.unknownFunction(function notAComponent(foo, bar) { + useProbablyAHook(bar); +}); + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-a63fd4f9dcc0.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-a63fd4f9dcc0.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-a63fd4f9dcc0.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-a63fd4f9dcc0.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-acb56658fe7e.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-acb56658fe7e.expect.md new file mode 100644 index 0000000000..20b1fd657b --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-acb56658fe7e.expect.md @@ -0,0 +1,31 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +class C { + m() { + This.useHook(); + Super.useHook(); + } +} + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +class C { + m() { + This.useHook(); + Super.useHook(); + } +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-acb56658fe7e.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-acb56658fe7e.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-acb56658fe7e.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-acb56658fe7e.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-c59788ef5676.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-c59788ef5676.expect.md new file mode 100644 index 0000000000..d9eaea7004 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-c59788ef5676.expect.md @@ -0,0 +1,33 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Currently invalid because it violates the convention and removes the "taint" +// from a hook. We *could* make it valid to avoid some false positives but let's +// ensure that we don't break the "renderItem" and "normalFunctionWithConditionalHook" +// cases which must remain invalid. +function normalFunctionWithHook() { + useHookInsideNormalFunction(); +} + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +// Currently invalid because it violates the convention and removes the "taint" +// from a hook. We *could* make it valid to avoid some false positives but let's +// ensure that we don't break the "renderItem" and "normalFunctionWithConditionalHook" +// cases which must remain invalid. +function normalFunctionWithHook() { + useHookInsideNormalFunction(); +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-c59788ef5676.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-c59788ef5676.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-c59788ef5676.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-c59788ef5676.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d842d36db450.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d842d36db450.expect.md new file mode 100644 index 0000000000..d597564eb3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d842d36db450.expect.md @@ -0,0 +1,45 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +function createComponent() { + return function ComponentWithConditionalHook() { + if (cond) { + useConditionalHook(); + } + }; +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; // @skip +// Passed but should have failed + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +function createComponent() { + const $ = useMemoCache(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = function ComponentWithConditionalHook() { + if (cond) { + useConditionalHook(); + } + }; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-d842d36db450.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d842d36db450.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-d842d36db450.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d842d36db450.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d952b82c2597.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d952b82c2597.expect.md new file mode 100644 index 0000000000..215bfbed28 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d952b82c2597.expect.md @@ -0,0 +1,41 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's a common misunderstanding. +// We *could* make it valid but the runtime error could be confusing. +function ComponentWithHookInsideCallback() { + useEffect(() => { + useHookInsideCallback(); + }); +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; // @skip +// Passed but should have failed + +// Invalid because it's a common misunderstanding. +// We *could* make it valid but the runtime error could be confusing. +function ComponentWithHookInsideCallback() { + const $ = useMemoCache(1); + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 = () => { + useHookInsideCallback(); + }; + $[0] = t0; + } else { + t0 = $[0]; + } + useEffect(t0); +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-d952b82c2597.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d952b82c2597.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-d952b82c2597.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d952b82c2597.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-ddeca9708b63.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-ddeca9708b63.expect.md new file mode 100644 index 0000000000..10080ab54f --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-ddeca9708b63.expect.md @@ -0,0 +1,29 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +(class { + i() { + useState(); + } +}); + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +(class { + i() { + useState(); + } +}); + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-ddeca9708b63.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-ddeca9708b63.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-ddeca9708b63.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-ddeca9708b63.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e675f0a672d8.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e675f0a672d8.expect.md new file mode 100644 index 0000000000..8bb65427e0 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e675f0a672d8.expect.md @@ -0,0 +1,46 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +function renderItem() { + useState(); +} + +function List(props) { + return props.items.map(renderItem); +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; // @skip +// Passed but should have failed + +// Invalid because it's dangerous and might not warn otherwise. +// This *must* be invalid. +function renderItem() { + useState(); +} + +function List(props) { + const $ = useMemoCache(2); + let t0; + if ($[0] !== props.items) { + t0 = props.items.map(renderItem); + $[0] = props.items; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-e675f0a672d8.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e675f0a672d8.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-e675f0a672d8.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e675f0a672d8.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e69ffce323c3.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e69ffce323c3.expect.md new file mode 100644 index 0000000000..3b57c7a398 --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e69ffce323c3.expect.md @@ -0,0 +1,29 @@ + +## Input + +```javascript +// @skip +// Passed but should have failed + +(class { + useHook = () => { + useState(); + }; +}); + +``` + +## Code + +```javascript +// @skip +// Passed but should have failed + +(class { + useHook = () => { + useState(); + }; +}); + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-e69ffce323c3.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e69ffce323c3.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-e69ffce323c3.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e69ffce323c3.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-f6f37b63b2d4.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-f6f37b63b2d4 similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.error.invalid-rules-of-hooks-f6f37b63b2d4.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rules-of-hooks/todo.invalid.invalid-rules-of-hooks-f6f37b63b2d4 diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.error.object-pattern-computed-key.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.error.object-pattern-computed-key.expect.md new file mode 100644 index 0000000000..be645aa92d --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.error.object-pattern-computed-key.expect.md @@ -0,0 +1,27 @@ + +## Input + +```javascript +import { identity } from "shared-runtime"; + +const SCALE = 2; +function Component(props) { + const { [props.name]: value } = props; + return value; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ name: "Sathya" }], +}; + +``` + + +## Error + +``` +[ReactForget] Todo: (BuildHIR::lowerAssignment) Handle computed properties in ObjectPattern (5:5) +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.object-pattern-computed-key.js b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.error.object-pattern-computed-key.js similarity index 100% rename from compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.object-pattern-computed-key.js rename to compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.error.object-pattern-computed-key.js diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.unnecessary-lambda-memoization.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.unnecessary-lambda-memoization.expect.md index fa5f784072..ab141a1d6d 100644 --- a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.unnecessary-lambda-memoization.expect.md +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.unnecessary-lambda-memoization.expect.md @@ -26,9 +26,8 @@ import { unstable_useMemoCache as useMemoCache } from "react"; function Component(props) { const $ = useMemoCache(5); const data = useFreeze(); - const c_0 = $[0] !== data.items; let t1; - if (c_0) { + if ($[0] !== data.items) { let t0; if ($[2] === Symbol.for("react.memo_cache_sentinel")) { t0 = (item) => ; @@ -43,9 +42,8 @@ function Component(props) { t1 = $[1]; } const items = t1; - const c_3 = $[3] !== items; let t2; - if (c_3) { + if ($[3] !== items) { t2 =
{items}
; $[3] = items; $[4] = t2; diff --git a/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.useContext-mutate-context-in-callback.expect.md b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.useContext-mutate-context-in-callback.expect.md new file mode 100644 index 0000000000..4dcc0da17b --- /dev/null +++ b/compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/todo.useContext-mutate-context-in-callback.expect.md @@ -0,0 +1,46 @@ + +## Input + +```javascript +function Component(props) { + const FooContext = useContext(Foo); + // This function should be memoized, but its mutable range is entangled + // with the useContext call. We can't memoize hooks, therefore the + // reactive scope around the hook + callback is pruned and we're left + // w no memoization of the callback. + // + // Ideally we'd determine that this isn't called during render and can + // therefore be considered "immutable" or otherwise safe to memoize + // independently + const onClick = () => { + FooContext.current = true; + }; + return
; +} + +``` + +## Code + +```javascript +import { unstable_useMemoCache as useMemoCache } from "react"; +function Component(props) { + const $ = useMemoCache(2); + const FooContext = useContext(Foo); + + const onClick = () => { + FooContext.current = true; + }; + let t0; + if ($[0] !== onClick) { + t0 =
; + $[0] = onClick; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/fixture-test-utils/src/fixture-utils.ts b/compiler/packages/fixture-test-utils/src/fixture-utils.ts index 87f5b75cbc..112027c2e6 100644 --- a/compiler/packages/fixture-test-utils/src/fixture-utils.ts +++ b/compiler/packages/fixture-test-utils/src/fixture-utils.ts @@ -42,11 +42,7 @@ function stripExtension(filename: string, extensions: Array): string { return filename; } -function shouldSkip( - filter: TestFilter | null, - filterId: string, - filename: string -) { +function shouldSkip(filter: TestFilter | null, filterId: string) { if (filter) { if (filter.kind === "only" && filter.paths.indexOf(filterId) === -1) { return true; @@ -56,8 +52,6 @@ function shouldSkip( ) { return true; } - } else if (filename.startsWith("todo.")) { - return true; } return false; } @@ -117,10 +111,9 @@ export function getFixtures( }); const fixtures: Map = new Map(); for (const filePath of inputFiles) { - const filename = path.basename(filePath); // Do not include extensions in unique identifier for fixture const partialPath = stripExtension(filePath, INPUT_EXTENSIONS); - if (shouldSkip(filter, partialPath, filename)) { + if (shouldSkip(filter, partialPath)) { continue; } @@ -145,10 +138,9 @@ export function getFixtures( cwd: FIXTURES_PATH, }); for (const filePath of outputFiles) { - const filename = path.basename(filePath); // Do not include extensions in unique identifier for fixture const partialPath = stripExtension(filePath, [OUTPUT_EXTENSION]); - if (shouldSkip(filter, partialPath, filename)) { + if (shouldSkip(filter, partialPath)) { continue; } diff --git a/compiler/packages/snap/src/compiler-worker.ts b/compiler/packages/snap/src/compiler-worker.ts index 488e6b7596..0159b53bc1 100644 --- a/compiler/packages/snap/src/compiler-worker.ts +++ b/compiler/packages/snap/src/compiler-worker.ts @@ -53,8 +53,7 @@ export async function compile( clearRequireCache(); } version = compilerVersion; - const { inputPath, outputPath, outputExists, basename } = - fixture; + const { inputPath, outputPath, outputExists, basename } = fixture; const input = inputPath != null ? await fs.readFile(inputPath, "utf8") : null; const expected = outputExists ? await fs.readFile(outputPath, "utf8") : null; @@ -109,7 +108,8 @@ export async function compile( } const output = writeOutputToString(input, code, error); - const expectError = basename.startsWith("error."); + const expectError = + basename.startsWith("error.") || basename.startsWith("todo.error"); let unexpectedError: string | null = null; if (expectError) { if (error === null) { diff --git a/compiler/packages/sprout/src/SproutTodoFilter.ts b/compiler/packages/sprout/src/SproutTodoFilter.ts index df438f14a0..fd66cbc773 100644 --- a/compiler/packages/sprout/src/SproutTodoFilter.ts +++ b/compiler/packages/sprout/src/SproutTodoFilter.ts @@ -477,6 +477,37 @@ const skipFilter = new Set([ // nothing to compile/run "repro-no-gating-import-without-compiled-functions", + + // TODOs + "rules-of-hooks/todo.bail.rules-of-hooks-279ac76f53af", + "rules-of-hooks/todo.bail.rules-of-hooks-28a78701970c", + "rules-of-hooks/todo.bail.rules-of-hooks-3d692676194b", + "rules-of-hooks/todo.bail.rules-of-hooks-6949b255e7eb", + "rules-of-hooks/todo.bail.rules-of-hooks-8503ca76d6f8", + "rules-of-hooks/todo.bail.rules-of-hooks-e0a5db3ae21e", + "rules-of-hooks/todo.bail.rules-of-hooks-e9f9bac89f8f", + "rules-of-hooks/todo.bail.rules-of-hooks-fadd52c1e460", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0a1dbff27ba0", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-0de1224ce64b", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-191029ac48c8", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-206e2811c87c", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-28a7111f56a7", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-2c51251df67a", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-449a37146a83", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-5a7ac9a6e8fa", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-76a74b4666e9", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-8303403b8e4c", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-99b5c750d1d1", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-9c79feec4b9b", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-a63fd4f9dcc0", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-acb56658fe7e", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-c59788ef5676", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d842d36db450", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-d952b82c2597", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-ddeca9708b63", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e675f0a672d8", + "rules-of-hooks/todo.invalid.invalid-rules-of-hooks-e69ffce323c3", + "todo.unnecessary-lambda-memoization", ]); export default skipFilter; diff --git a/compiler/packages/sprout/src/runner.ts b/compiler/packages/sprout/src/runner.ts index 0b7f0d6771..7314f2d4cf 100644 --- a/compiler/packages/sprout/src/runner.ts +++ b/compiler/packages/sprout/src/runner.ts @@ -6,16 +6,19 @@ */ import chalk from "chalk"; -import { TestFixture } from "fixture-test-utils"; -import { getFixtures, readTestFilter } from "fixture-test-utils"; +import { + FILTER_FILENAME, + TestFixture, + getFixtures, + readTestFilter, +} from "fixture-test-utils"; import { Worker } from "jest-worker"; import process from "process"; import * as readline from "readline"; -import * as RunnerWorker from "./runner-worker"; import yargs from "yargs"; import { hideBin } from "yargs/helpers"; import SproutTodoFilter from "./SproutTodoFilter"; -import { FILTER_FILENAME } from "fixture-test-utils"; +import * as RunnerWorker from "./runner-worker"; const WORKER_PATH = require.resolve("./runner-worker"); readline.emitKeypressEvents(process.stdin); @@ -186,7 +189,10 @@ export async function main(opts: RunnerOptions): Promise { const validFixtures = new Map(); for (const [name, fixture] of allFixtures) { - if (fixture.basename.startsWith("error.")) { + if ( + fixture.basename.startsWith("error.") || + fixture.basename.startsWith("todo.error.") + ) { // skip continue; }