feat(parser): 引入 oxc_semantic 早期错误检查与 onlyStrict 注入
This commit is contained in:
@@ -62,7 +62,12 @@ impl Emitter {
|
|||||||
if matches!(un.operator, UnaryOperator::Delete) {
|
if matches!(un.operator, UnaryOperator::Delete) {
|
||||||
return match &un.argument {
|
return match &un.argument {
|
||||||
Expression::Identifier(_) => {
|
Expression::Identifier(_) => {
|
||||||
Err("SyntaxError: delete of an unqualified identifier in strict mode".into())
|
// 严格模式的 delete 标识符由 oxc_semantic 提前拦截为早期错误;
|
||||||
|
// 非严格语义返回 false(标识符不可删除)。
|
||||||
|
let idx = ctx.add_constant(Constant::Boolean(false));
|
||||||
|
let reg = ctx.alloc_reg();
|
||||||
|
ctx.inst(Inst::load_const(Operand::Reg(reg), idx));
|
||||||
|
Ok(reg)
|
||||||
}
|
}
|
||||||
Expression::StaticMemberExpression(member) => {
|
Expression::StaticMemberExpression(member) => {
|
||||||
let obj_reg = self.emit_expression(&member.object, ctx)?;
|
let obj_reg = self.emit_expression(&member.object, ctx)?;
|
||||||
|
|||||||
@@ -13,3 +13,4 @@ oxc_ast.workspace = true
|
|||||||
oxc_span.workspace = true
|
oxc_span.workspace = true
|
||||||
oxc_diagnostics.workspace = true
|
oxc_diagnostics.workspace = true
|
||||||
oxc_syntax.workspace = true
|
oxc_syntax.workspace = true
|
||||||
|
oxc_semantic = "0.134.0"
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ pub fn parse<'a>(allocator: &'a Allocator, source: &'a str) -> Result<Program<'a
|
|||||||
use oxc_parser::Parser;
|
use oxc_parser::Parser;
|
||||||
use oxc_span::SourceType;
|
use oxc_span::SourceType;
|
||||||
|
|
||||||
let source_type = SourceType::default();
|
let source_type = SourceType::unambiguous();
|
||||||
let ret = Parser::new(allocator, source, source_type).parse();
|
let ret = Parser::new(allocator, source, source_type).parse();
|
||||||
|
|
||||||
if ret.panicked {
|
if ret.panicked {
|
||||||
@@ -34,5 +34,13 @@ pub fn parse<'a>(allocator: &'a Allocator, source: &'a str) -> Result<Program<'a
|
|||||||
return Err(ret.errors.into_iter().map(OxideError::from).collect());
|
return Err(ret.errors.into_iter().map(OxideError::from).collect());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 语法早期错误(Early Errors)检查:oxc parser 把复杂早期错误委托给
|
||||||
|
// oxc_semantic(strict 绑定标识符、重复参数、NSPL、super 位置等)。
|
||||||
|
let semantic_ret =
|
||||||
|
oxc_semantic::SemanticBuilder::new().with_check_syntax_error(true).build(&ret.program);
|
||||||
|
if !semantic_ret.errors.is_empty() {
|
||||||
|
return Err(semantic_ret.errors.into_iter().map(OxideError::from).collect());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(ret.program)
|
Ok(ret.program)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,12 +268,20 @@ fn append_source_chunk(out: &mut String, name: &str, source: &str) {
|
|||||||
|
|
||||||
/// 取测试元数据的 harness 缓存键(即其 `includes` 列表)。
|
/// 取测试元数据的 harness 缓存键(即其 `includes` 列表)。
|
||||||
fn harness_key(meta: &TestMeta) -> Vec<String> {
|
fn harness_key(meta: &TestMeta) -> Vec<String> {
|
||||||
meta.includes.clone()
|
let mut key = meta.includes.clone();
|
||||||
|
if meta.flags.iter().any(|f| f == "onlyStrict") {
|
||||||
|
key.push("__onlyStrict__".into());
|
||||||
|
}
|
||||||
|
key
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 按测试元数据拼接完整的 harness 前缀源码(prelude + sta/assert + 各 include)。
|
/// 按测试元数据拼接完整的 harness 前缀源码(prelude + sta/assert + 各 include)。
|
||||||
fn build_harness_source(meta: &TestMeta, harness: &HarnessSources) -> Result<String, String> {
|
fn build_harness_source(meta: &TestMeta, harness: &HarnessSources) -> Result<String, String> {
|
||||||
let mut source = String::new();
|
let mut source = String::new();
|
||||||
|
// onlyStrict 测试在严格模式下运行:指令必须位于脚本最前(harness 之前)。
|
||||||
|
if meta.flags.iter().any(|f| f == "onlyStrict") {
|
||||||
|
append_source_chunk(&mut source, "use strict", "\"use strict\";");
|
||||||
|
}
|
||||||
append_source_chunk(&mut source, "Test262Error prelude", test262_error_prelude());
|
append_source_chunk(&mut source, "Test262Error prelude", test262_error_prelude());
|
||||||
append_source_chunk(
|
append_source_chunk(
|
||||||
&mut source,
|
&mut source,
|
||||||
|
|||||||
Reference in New Issue
Block a user