diff --git a/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-class.expect.md b/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-class.expect.md new file mode 100644 index 0000000000..df981f7767 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-class.expect.md @@ -0,0 +1,41 @@ + +## Input + +```javascript +function Component(props) { + const env = useRelayEnvironment(); + // Note: this is a class has no mutable methods, ie it always treats `this` as readonly + const mutator = new Mutator(env); + + useOtherHook(); + + // `x` should be independently memoizeable, since foo(x, mutator) cannot mutate + // the mutator. + const x = {}; + foo(x, mutator); + return x; +} + +class Mutator {} + +``` + +## Code + +```javascript +function Component(props) { + const env = useRelayEnvironment(); + + const mutator = new Mutator(env); + + useOtherHook(); + + const x = {}; + foo(x, mutator); + return x; +} + +class Mutator {} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-class.js b/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-class.js new file mode 100644 index 0000000000..11740ef0a4 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-class.js @@ -0,0 +1,15 @@ +function Component(props) { + const env = useRelayEnvironment(); + // Note: this is a class has no mutable methods, ie it always treats `this` as readonly + const mutator = new Mutator(env); + + useOtherHook(); + + // `x` should be independently memoizeable, since foo(x, mutator) cannot mutate + // the mutator. + const x = {}; + foo(x, mutator); + return x; +} + +class Mutator {} diff --git a/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-lambda.expect.md b/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-lambda.expect.md new file mode 100644 index 0000000000..61e283f619 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-lambda.expect.md @@ -0,0 +1,37 @@ + +## Input + +```javascript +function Component(props) { + const [value, setValue] = useState(null); + // NOTE: this lambda does not capture any mutable values (only the state setter) + // and thus should be treated as readonly + const onChange = (e) => setX((value) => value + e.target.value); + + useOtherHook(); + + // x should be independently memoizeable, since foo(x, onChange) cannot modify onChange + const x = {}; + foo(x, onChange); + return x; +} + +``` + +## Code + +```javascript +function Component(props) { + useState(null); + + const onChange = (e) => setX((value) => value + e.target.value); + + useOtherHook(); + + const x = {}; + foo(x, onChange); + return x; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-lambda.js b/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-lambda.js new file mode 100644 index 0000000000..0bdca05afd --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/inadvertent-mutability-readonly-lambda.js @@ -0,0 +1,13 @@ +function Component(props) { + const [value, setValue] = useState(null); + // NOTE: this lambda does not capture any mutable values (only the state setter) + // and thus should be treated as readonly + const onChange = (e) => setX((value) => value + e.target.value); + + useOtherHook(); + + // x should be independently memoizeable, since foo(x, onChange) cannot modify onChange + const x = {}; + foo(x, onChange); + return x; +}