From d3d0b18fdea26ed631a4b552fa653679cad30b20 Mon Sep 17 00:00:00 2001 From: leaysgur <6259812+leaysgur@users.noreply.github.com> Date: Mon, 11 May 2026 09:37:46 +0000 Subject: [PATCH] fix(traverse): handle `ChainElement::TSNonNullExpression` in `GatherNodeParts` (#22247) Fixes #22246, transformer panics with `const x = a[b?.c!]?.["d"];` under es2020 target. (I wasn't sure where to put the test, but I've confirmed that it works on my end for now.) --- crates/oxc_traverse/src/ast_operations/gather_node_parts.rs | 3 ++- tasks/transform_conformance/snapshots/oxc.snap.md | 2 +- .../test/fixtures/oxc/ts-non-null-in-chain/input.ts | 5 +++++ .../test/fixtures/oxc/ts-non-null-in-chain/output.js | 6 ++++++ 4 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 tasks/transform_conformance/tests/babel-plugin-transform-optional-chaining/test/fixtures/oxc/ts-non-null-in-chain/input.ts create mode 100644 tasks/transform_conformance/tests/babel-plugin-transform-optional-chaining/test/fixtures/oxc/ts-non-null-in-chain/output.js diff --git a/crates/oxc_traverse/src/ast_operations/gather_node_parts.rs b/crates/oxc_traverse/src/ast_operations/gather_node_parts.rs index f5f8cd028cb0d..5f3f41c38a081 100644 --- a/crates/oxc_traverse/src/ast_operations/gather_node_parts.rs +++ b/crates/oxc_traverse/src/ast_operations/gather_node_parts.rs @@ -234,7 +234,8 @@ impl<'a> GatherNodeParts<'a> for ChainElement<'a> { fn gather(&self, f: &mut F) { match self { ChainElement::CallExpression(expr) => expr.gather(f), - expr => expr.to_member_expression().gather(f), + ChainElement::TSNonNullExpression(expr) => expr.expression.gather(f), + expr @ match_member_expression!(Self) => expr.to_member_expression().gather(f), } } } diff --git a/tasks/transform_conformance/snapshots/oxc.snap.md b/tasks/transform_conformance/snapshots/oxc.snap.md index 6fe2c7c408270..49b4efc57c3e5 100644 --- a/tasks/transform_conformance/snapshots/oxc.snap.md +++ b/tasks/transform_conformance/snapshots/oxc.snap.md @@ -1,6 +1,6 @@ commit: 6402dbbf -Passed: 231/379 +Passed: 232/380 # All Passed: * babel-plugin-transform-class-static-block diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-optional-chaining/test/fixtures/oxc/ts-non-null-in-chain/input.ts b/tasks/transform_conformance/tests/babel-plugin-transform-optional-chaining/test/fixtures/oxc/ts-non-null-in-chain/input.ts new file mode 100644 index 0000000000000..7f409961c47d8 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-optional-chaining/test/fixtures/oxc/ts-non-null-in-chain/input.ts @@ -0,0 +1,5 @@ +// Panicked when transforming optional chaining with TS non-null assertion inside a computed key. +// https://github.com/oxc-project/oxc/issues/22246 +const x = a[b?.c!]?.["d"]; +const y = a?.[b?.c!]?.d; +const z = a[b?.c!.d!]?.e; diff --git a/tasks/transform_conformance/tests/babel-plugin-transform-optional-chaining/test/fixtures/oxc/ts-non-null-in-chain/output.js b/tasks/transform_conformance/tests/babel-plugin-transform-optional-chaining/test/fixtures/oxc/ts-non-null-in-chain/output.js new file mode 100644 index 0000000000000..ca745735b3b64 --- /dev/null +++ b/tasks/transform_conformance/tests/babel-plugin-transform-optional-chaining/test/fixtures/oxc/ts-non-null-in-chain/output.js @@ -0,0 +1,6 @@ +// Panicked when transforming optional chaining with TS non-null assertion inside a computed key. +// https://github.com/oxc-project/oxc/issues/22246 +var _a$b$c, _b, _a, _b2, _a$d, _b3; +const x = (_a$b$c = a[(_b = b) === null || _b === void 0 ? void 0 : _b.c]) === null || _a$b$c === void 0 ? void 0 : _a$b$c["d"]; +const y = (_a = a) === null || _a === void 0 || (_a = _a[(_b2 = b) === null || _b2 === void 0 ? void 0 : _b2.c]) === null || _a === void 0 ? void 0 : _a.d; +const z = (_a$d = a[(_b3 = b) === null || _b3 === void 0 ? void 0 : _b3.c.d]) === null || _a$d === void 0 ? void 0 : _a$d.e;