From c00e7a2af2746061cdada5735b979bf04770aac9 Mon Sep 17 00:00:00 2001 From: Mofei Zhang Date: Thu, 30 Mar 2023 18:43:55 -0400 Subject: [PATCH] [test] Test case for optional chaining in codegen ```js // here, `a?.b.c` is a single optional chain // (evaluates to undefined if a is nullish) a?.b.c; // here, 'a?.b` is an optional chain, and `.c` is an unconditional load // (nullthrows if a is nullish) (a?.b).c; ``` --- Next PR in stack will add a bailout for `(a?.b).c`. (If we want to properly handle `(a?.b).c`, we might want to model optional chains explicitly in the HIR. We currently assume that any `PropertyLoad` whose lhs is an optional property load is read conditionally.) --- ...bug.optional-chaining-memberexpr.expect.md | 39 +++++++++++++++++++ .../_bug.optional-chaining-memberexpr.js | 7 ++++ 2 files changed, 46 insertions(+) create mode 100644 compiler/forget/src/__tests__/fixtures/compiler/_bug.optional-chaining-memberexpr.expect.md create mode 100644 compiler/forget/src/__tests__/fixtures/compiler/_bug.optional-chaining-memberexpr.js diff --git a/compiler/forget/src/__tests__/fixtures/compiler/_bug.optional-chaining-memberexpr.expect.md b/compiler/forget/src/__tests__/fixtures/compiler/_bug.optional-chaining-memberexpr.expect.md new file mode 100644 index 0000000000..b07e0c1380 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/compiler/_bug.optional-chaining-memberexpr.expect.md @@ -0,0 +1,39 @@ + +## Input + +```javascript +// Note that `a?.b.c` is semantically different from `(a?.b).c` +// We should codegen the correct member expressions +function Component(props) { + let x = props?.b.c; + let y = (props?.x).y; + return { x, y }; +} + +``` + +## Code + +```javascript +// Note that `a?.b.c` is semantically different from `(a?.b).c` +// We should codegen the correct member expressions +function Component(props) { + const $ = React.unstable_useMemoCache(3); + const x = (props?.b).c; + const y = (props?.x).y; + const c_0 = $[0] !== x; + const c_1 = $[1] !== y; + let t0; + if (c_0 || c_1) { + t0 = { x, y }; + $[0] = x; + $[1] = y; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/compiler/_bug.optional-chaining-memberexpr.js b/compiler/forget/src/__tests__/fixtures/compiler/_bug.optional-chaining-memberexpr.js new file mode 100644 index 0000000000..b3e9a1c49b --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/compiler/_bug.optional-chaining-memberexpr.js @@ -0,0 +1,7 @@ +// Note that `a?.b.c` is semantically different from `(a?.b).c` +// We should codegen the correct member expressions +function Component(props) { + let x = props?.b.c; + let y = (props?.x).y; + return { x, y }; +}