From 666b6c104c137ef7bdbf781368c5bb516d4fdd99 Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Wed, 20 Nov 2024 11:51:55 +0000 Subject: [PATCH] fix(parser): add missing `ChainExpression` in optional `TSInstantiationExpression` (#7371) --- crates/oxc_linter/src/rules/oxc/no_optional_chaining.rs | 1 + crates/oxc_linter/src/snapshots/no_optional_chaining.snap | 6 ++++++ crates/oxc_parser/examples/parser.rs | 2 +- crates/oxc_parser/src/js/expression.rs | 6 ++++++ tasks/transform_conformance/snapshots/babel.snap.md | 4 +--- 5 files changed, 15 insertions(+), 4 deletions(-) diff --git a/crates/oxc_linter/src/rules/oxc/no_optional_chaining.rs b/crates/oxc_linter/src/rules/oxc/no_optional_chaining.rs index f859b4c657524..626b60853c465 100644 --- a/crates/oxc_linter/src/rules/oxc/no_optional_chaining.rs +++ b/crates/oxc_linter/src/rules/oxc/no_optional_chaining.rs @@ -98,6 +98,7 @@ fn test() { ("var x = a/*?.*/?.b", None), ("var x = '?.'?.['?.']", None), ("var x = '?.'?.['?.']", None), + ("a?.c?.b", None), ( "var x = a?.b", Some(serde_json::json!([{ diff --git a/crates/oxc_linter/src/snapshots/no_optional_chaining.snap b/crates/oxc_linter/src/snapshots/no_optional_chaining.snap index d5e848da07eab..e5ec1256f05ff 100644 --- a/crates/oxc_linter/src/snapshots/no_optional_chaining.snap +++ b/crates/oxc_linter/src/snapshots/no_optional_chaining.snap @@ -56,6 +56,12 @@ snapshot_kind: text · ──────────── ╰──── + ⚠ oxc(no-optional-chaining): Optional chaining is not allowed. + ╭─[no_optional_chaining.tsx:1:1] + 1 │ a?.c?.b + · ─────── + ╰──── + ⚠ oxc(no-optional-chaining): Optional chaining is not allowed. ╭─[no_optional_chaining.tsx:1:9] 1 │ var x = a?.b diff --git a/crates/oxc_parser/examples/parser.rs b/crates/oxc_parser/examples/parser.rs index 279fa3566ac30..70a01f6a5a402 100644 --- a/crates/oxc_parser/examples/parser.rs +++ b/crates/oxc_parser/examples/parser.rs @@ -14,9 +14,9 @@ use pico_args::Arguments; fn main() -> Result<(), String> { let mut args = Arguments::from_env(); - let name = args.subcommand().ok().flatten().unwrap_or_else(|| String::from("test.js")); let show_ast = args.contains("--ast"); let show_comments = args.contains("--comments"); + let name = args.free_from_str().unwrap_or_else(|_| "test.js".to_string()); let path = Path::new(&name); let source_text = fs::read_to_string(path).map_err(|_| format!("Missing '{name}'"))?; diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 4664cf10acd1a..2c0ff59b4929d 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -674,9 +674,15 @@ impl<'a> ParserImpl<'a> { self.parse_tagged_template(lhs_span, expr, *in_optional_chain, type_parameters)? } Kind::LAngle | Kind::ShiftLeft => { + let optional_chain_span = (*in_optional_chain).then(|| self.end_span(lhs_span)); if let Some(Some(arguments)) = self.try_parse(Self::parse_type_arguments_in_expression) { + // `a?.c?.b` + if let Some(optional_chain_span) = optional_chain_span { + *in_optional_chain = false; + lhs = self.map_to_chain_expression(optional_chain_span, lhs); + } lhs = self.ast.expression_ts_instantiation( self.end_span(lhs_span), lhs, diff --git a/tasks/transform_conformance/snapshots/babel.snap.md b/tasks/transform_conformance/snapshots/babel.snap.md index 4068272f73e7b..1c9354ec6c2a8 100644 --- a/tasks/transform_conformance/snapshots/babel.snap.md +++ b/tasks/transform_conformance/snapshots/babel.snap.md @@ -1987,9 +1987,7 @@ after transform: ["C", "T"] rebuilt : ["C"] * type-arguments/optional-call/input.ts -Unresolved references mismatch: -after transform: ["Q", "T", "f", "x"] -rebuilt : ["f", "x"] +x Output mismatch * type-arguments/tagged-template/input.ts Unresolved references mismatch: