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 3244eaf47837..ed1690781f00 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -1386,7 +1386,8 @@ function lowerStatement( function lowerObjectMethod( builder: HIRBuilder, - property: NodePath + property: NodePath, + kind: t.ObjectMethod["kind"] ): InstructionValue { const loc = property.node.loc ?? GeneratedSource; const loweredFunc = lowerFunction(builder, property); @@ -1397,6 +1398,7 @@ function lowerObjectMethod( return { kind: "ObjectMethod", loc, + methodKind: kind, loweredFunc, }; } @@ -1520,16 +1522,11 @@ function lowerExpression( place, }); } else if (propertyPath.isObjectMethod()) { - if (propertyPath.node.kind !== "method") { - builder.errors.push({ - reason: `(BuildHIR::lowerExpression) Handle ${propertyPath.node.kind} functions in ObjectExpression`, - severity: ErrorSeverity.Todo, - loc: propertyPath.node.loc ?? null, - suggestions: null, - }); - continue; - } - const method = lowerObjectMethod(builder, propertyPath); + const method = lowerObjectMethod( + builder, + propertyPath, + propertyPath.node.kind + ); const place = lowerValueToTemporary(builder, method); const loweredKey = lowerObjectPropertyKey(builder, propertyPath); if (!loweredKey) { diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts index af0e5afd2850..15949eaffe85 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -686,6 +686,7 @@ export type LoweredFunction = { export type ObjectMethod = { kind: "ObjectMethod"; loc: SourceLocation; + methodKind: "method" | "get" | "set"; loweredFunc: LoweredFunction; }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts index 2c0364ed127c..5ea15719e570 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -1617,7 +1617,7 @@ function codegenInstructionValue( * https://github.com/babel/babel/blob/v7.7.4/packages/babel-types/src/definitions/core.js#L599-L603 */ const babelNode = t.objectMethod( - "method", + method.methodKind, key, fn.params, fn.body, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-get-syntax.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-get-syntax.expect.md deleted file mode 100644 index d713d07fd24d..000000000000 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-get-syntax.expect.md +++ /dev/null @@ -1,39 +0,0 @@ - -## Input - -```javascript -function Component({ value }) { - const object = { - get value() { - return value; - }, - }; - return
{object.value}
; -} - -export const FIXTURE_ENTRYPOINT = { - fn: foo, - params: [{ value: 0 }], - sequentialRenders: [{ value: 1 }, { value: 2 }], -}; - -``` - - -## Error - -``` - 1 | function Component({ value }) { - 2 | const object = { -> 3 | get value() { - | ^^^^^^^^^^^^^ -> 4 | return value; - | ^^^^^^^^^^^^^^^^^^^ -> 5 | }, - | ^^^^^^ Todo: (BuildHIR::lowerExpression) Handle get functions in ObjectExpression (3:5) - 6 | }; - 7 | return
{object.value}
; - 8 | } -``` - - \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-set-syntax.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-set-syntax.expect.md deleted file mode 100644 index 1d917b4d3ac2..000000000000 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-set-syntax.expect.md +++ /dev/null @@ -1,41 +0,0 @@ - -## Input - -```javascript -function Component(props) { - let value; - const object = { - set value(v) { - value = v; - }, - }; - object.value = props.value; - return
{value}
; -} - -export const FIXTURE_ENTRYPOINT = { - fn: foo, - params: [{ value: 0 }], - sequentialRenders: [{ value: 1 }, { value: 2 }], -}; - -``` - - -## Error - -``` - 2 | let value; - 3 | const object = { -> 4 | set value(v) { - | ^^^^^^^^^^^^^^ -> 5 | value = v; - | ^^^^^^^^^^^^^^^^ -> 6 | }, - | ^^^^^^ Todo: (BuildHIR::lowerExpression) Handle set functions in ObjectExpression (4:6) - 7 | }; - 8 | object.value = props.value; - 9 | return
{value}
; -``` - - \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-get-syntax.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-get-syntax.expect.md new file mode 100644 index 000000000000..74665e04159d --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-get-syntax.expect.md @@ -0,0 +1,63 @@ + +## Input + +```javascript +function Component({ value }) { + const object = { + get value() { + return value; + }, + }; + return
{object.value}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 0 }], + sequentialRenders: [{ value: 1 }, { value: 2 }], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +function Component(t0) { + const $ = _c(4); + const { value } = t0; + let t1; + if ($[0] !== value) { + t1 = { + get value() { + return value; + }, + }; + $[0] = value; + $[1] = t1; + } else { + t1 = $[1]; + } + const object = t1; + let t2; + if ($[2] !== object.value) { + t2 =
{object.value}
; + $[2] = object.value; + $[3] = t2; + } else { + t2 = $[3]; + } + return t2; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 0 }], + sequentialRenders: [{ value: 1 }, { value: 2 }], +}; + +``` + +### Eval output +(kind: ok)
1
+
2
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-get-syntax.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-get-syntax.js similarity index 93% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-get-syntax.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-get-syntax.js index e96134edf1b9..1c76ae9d6e36 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-get-syntax.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-get-syntax.js @@ -8,7 +8,7 @@ function Component({ value }) { } export const FIXTURE_ENTRYPOINT = { - fn: foo, + fn: Component, params: [{ value: 0 }], sequentialRenders: [{ value: 1 }, { value: 2 }], }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-set-syntax.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-set-syntax.expect.md new file mode 100644 index 000000000000..c5bc2d5f6bf7 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-set-syntax.expect.md @@ -0,0 +1,63 @@ + +## Input + +```javascript +function Component(props) { + let value; + const object = { + set value(v) { + value = v; + }, + }; + object.value = props.value; + return
{value}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 0 }], + // sequentialRenders: [{ value: 1 }, { value: 2 }], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +function Component(props) { + const $ = _c(3); + let value; + if ($[0] !== props.value) { + const object = { + set value(v) { + value = v; + }, + }; + + object.value = props.value; + $[0] = props.value; + $[1] = value; + } else { + value = $[1]; + } + let t0; + if ($[2] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
{value}
; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 0 }], + // sequentialRenders: [{ value: 1 }, { value: 2 }], +}; + +``` + +### Eval output +(kind: ok)
0
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-set-syntax.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-set-syntax.js similarity index 94% rename from compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-set-syntax.js rename to compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-set-syntax.js index 5030bea6fc6a..66130a522c4e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/error.todo-object-expression-set-syntax.js +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-expression-set-syntax.js @@ -10,7 +10,7 @@ function Component(props) { } export const FIXTURE_ENTRYPOINT = { - fn: foo, + fn: Component, params: [{ value: 0 }], sequentialRenders: [{ value: 1 }, { value: 2 }], }; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-method-capture-reactive-value.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-method-capture-reactive-value.expect.md new file mode 100644 index 000000000000..041ba658b4e6 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-method-capture-reactive-value.expect.md @@ -0,0 +1,66 @@ + +## Input + +```javascript +function Component(props) { + let value; + const object = { + setValue(v) { + value = v; + }, + }; + object.setValue(props.value); + return
{value}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 0 }], + sequentialRenders: [{ value: 1 }, { value: 2 }], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; +function Component(props) { + const $ = _c(4); + let value; + if ($[0] !== props.value) { + const object = { + setValue(v) { + value = v; + }, + }; + + object.setValue(props.value); + $[0] = props.value; + $[1] = value; + } else { + value = $[1]; + } + const t0 = value; + let t1; + if ($[2] !== t0) { + t1 =
{t0}
; + $[2] = t0; + $[3] = t1; + } else { + t1 = $[3]; + } + return t1; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 0 }], + sequentialRenders: [{ value: 1 }, { value: 2 }], +}; + +``` + +### Eval output +(kind: ok)
1
+
2
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-method-capture-reactive-value.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-method-capture-reactive-value.js new file mode 100644 index 000000000000..565bb34c86b3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/object-method-capture-reactive-value.js @@ -0,0 +1,16 @@ +function Component(props) { + let value; + const object = { + setValue(v) { + value = v; + }, + }; + object.setValue(props.value); + return
{value}
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 0 }], + sequentialRenders: [{ value: 1 }, { value: 2 }], +};