diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index a179224a7705f..9494436d1f463 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -1418,7 +1418,7 @@ function lowerObjectPropertyKey( name: key.node.value, }; } else if (property.node.computed && key.isExpression()) { - if (!key.isIdentifier()) { + if (!key.isIdentifier() && !key.isMemberExpression()) { /* * NOTE: allowing complex key expressions can trigger a bug where a mutation is made conditional * see fixture diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-member-expr-call.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-member-expr-call.expect.md new file mode 100644 index 0000000000000..82d9ca17ec2a2 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-member-expr-call.expect.md @@ -0,0 +1,37 @@ + +## Input + +```javascript +import {identity, mutate, mutateAndReturn} from 'shared-runtime'; + +function Component(props) { + const obj = {mutateAndReturn}; + const key = {}; + const context = { + [obj.mutateAndReturn(key)]: identity([props.value]), + }; + mutate(key); + return context; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], +}; + +``` + + +## Error + +``` + 5 | const key = {}; + 6 | const context = { +> 7 | [obj.mutateAndReturn(key)]: identity([props.value]), + | ^^^^^^^^^^^^^^^^^^^^^^^^ Todo: (BuildHIR::lowerExpression) Expected Identifier, got CallExpression key in ObjectExpression (7:7) + 8 | }; + 9 | mutate(key); + 10 | return context; +``` + + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-member-expr-call.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-member-expr-call.js new file mode 100644 index 0000000000000..5cef590ed5dab --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-member-expr-call.js @@ -0,0 +1,16 @@ +import {identity, mutate, mutateAndReturn} from 'shared-runtime'; + +function Component(props) { + const obj = {mutateAndReturn}; + const key = {}; + const context = { + [obj.mutateAndReturn(key)]: identity([props.value]), + }; + mutate(key); + return context; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], +}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.expect.md new file mode 100644 index 0000000000000..810b03e529e77 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.expect.md @@ -0,0 +1,53 @@ + +## Input + +```javascript +import {identity, mutate, mutateAndReturn} from 'shared-runtime'; + +function Component(props) { + const key = {a: 'key'}; + const context = { + [key.a]: identity([props.value]), + }; + mutate(key); + return context; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +import { identity, mutate, mutateAndReturn } from "shared-runtime"; + +function Component(props) { + const $ = _c(2); + let context; + if ($[0] !== props.value) { + const key = { a: "key" }; + context = { [key.a]: identity([props.value]) }; + + mutate(key); + $[0] = props.value; + $[1] = context; + } else { + context = $[1]; + } + return context; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; + +``` + +### Eval output +(kind: ok) {"key":[42]} \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.js new file mode 100644 index 0000000000000..95a1d434624e9 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-computed-member.js @@ -0,0 +1,15 @@ +import {identity, mutate, mutateAndReturn} from 'shared-runtime'; + +function Component(props) { + const key = {a: 'key'}; + const context = { + [key.a]: identity([props.value]), + }; + mutate(key); + return context; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], +};