From 2598c2647b6be0dc0aba18b9ca5df599057dcdce Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Mon, 14 Sep 2026 14:53:55 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20=E8=A7=A3=E6=9E=90=E4=B8=8D=E5=8F=AF?= =?UTF-8?q?=E6=81=A2=E5=A4=8D=E9=94=99=E8=AF=AF=E9=80=8F=E4=BC=A0=20oxc=20?= =?UTF-8?q?=E7=9C=9F=E5=AE=9E=E8=AF=8A=E6=96=AD=E5=B9=B6=E8=A1=A5=20concis?= =?UTF-8?q?e=20=E7=AE=AD=E5=A4=B4=E4=BD=93=E5=9B=9E=E5=BD=92=E9=92=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_parser/src/lib.rs | 7 +++++- crates/oxide_parser/tests/parse_smoke.rs | 29 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/crates/oxide_parser/src/lib.rs b/crates/oxide_parser/src/lib.rs index 852724ef..75ba2acf 100644 --- a/crates/oxide_parser/src/lib.rs +++ b/crates/oxide_parser/src/lib.rs @@ -16,7 +16,7 @@ pub use oxc_span::Span; /// /// 使用 oxc 默认 `SourceType`(严格模式由语法自身决定)。返回 `Ok(program)` /// 或 `Err`(收集全部解析错误,按源码顺序排列);若 oxc 内部 panic(不可恢复 -/// 语法错误)则返回单个通用错误。 +/// 语法错误)则透传其已收集的诊断(消息 + 位置),无诊断时返回单个通用错误。 fn parse_with_source_type<'a>( allocator: &'a Allocator, source: &'a str, source_type: oxc_span::SourceType, ) -> Result, Vec> { @@ -25,6 +25,11 @@ fn parse_with_source_type<'a>( let ret = Parser::new(allocator, source, source_type).parse(); if ret.panicked { + // 不可恢复语法错误:oxc 已为出错 token 累积诊断时按既有路径透传 + // (消息 + 位置),直指真实触发点;无诊断时兜底通用文本。 + if !ret.errors.is_empty() { + return Err(ret.errors.into_iter().map(OxideError::from).collect()); + } return Err(vec![OxideError { message: "Parser panicked: unrecoverable syntax error".to_string(), span: (0, 0), diff --git a/crates/oxide_parser/tests/parse_smoke.rs b/crates/oxide_parser/tests/parse_smoke.rs index f1504b45..fd5c6daa 100644 --- a/crates/oxide_parser/tests/parse_smoke.rs +++ b/crates/oxide_parser/tests/parse_smoke.rs @@ -49,3 +49,32 @@ fn parse_multiple_statements() { let program = result.unwrap(); assert_eq!(program.body.len(), 3, "should have 3 statements"); } + +#[test] +fn parse_concise_arrow_array_member_call() { + // concise 箭头体 + 数组字面量 + 成员调用形是合法 JS:必须解析成功。 + let allocator = Allocator::default(); + let result = oxide_parser::parse(&allocator, "() => [1, 2].join('|')"); + assert!(result.is_ok(), "concise 箭头体数组成员调用形应解析成功,实际错误:{:?}", result.err()); +} + +#[test] +fn parse_concise_arrow_iife_with_kind_helper() { + // 顶层 kind 助手 + concise IIFE 九元素数组 .join('|') 形(事故测试源形态复刻): + // 必须解析成功;若解析失败,错误消息应携带定位到具体出错 token 的诊断。 + let allocator = Allocator::default(); + let source = "const kind = (fn) => { try { fn(); return 'no'; } catch (e) { return e.constructor.name; } }; +(() => [ + kind(() => new Temporal.PlainDate(2020n, 1, 1)), + kind(() => new Temporal.PlainDate(Symbol(), 1, 1)), + kind(() => new Temporal.PlainDate(undefined, 1, 1)), + kind(() => new Temporal.PlainDate(2020, 'invalid', 1)), + kind(() => new Temporal.PlainDate(Infinity, 1, 1)), + kind(() => new Temporal.PlainDate(2020, 1, -Infinity)), + kind(() => new Temporal.PlainDate()), + kind(() => new Temporal.PlainDate(2021)), + kind(() => Temporal.PlainDate(2020, 1, 1)), +].join('|'))()"; + let result = oxide_parser::parse(&allocator, source); + assert!(result.is_ok(), "concise IIFE 九元素数组 join 形应解析成功,实际错误:{:?}", result.err()); +}