mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-24 02:31:13 +08:00
test: TDZ 单测补嵌套块/自引用/hoisted 读形状 + 固化单语句体 lexical 声明解析拒绝契约
This commit is contained in:
@@ -537,8 +537,9 @@ impl Emitter {
|
||||
///
|
||||
/// # 边界与前提
|
||||
/// - 只扫描直接子语句 + 递归 switch case(switch 不推 scope,case 内 lexical
|
||||
/// 声明属于外层作用域);不递归块/if/for/while body(嵌套块自预声明,
|
||||
/// 单语句 body 不含 lexical 声明)。
|
||||
/// 声明属于外层作用域);不递归块/if/for/while body(嵌套块自预声明;
|
||||
/// 单语句 body 不接受 lexical 声明——lexical 属 Declaration、非 Statement
|
||||
/// 子产生式,parser 按语法错误直接拒绝,这些形状不会进入 emit)。
|
||||
/// - 跳过 for 头声明(循环作用域由 for 分支内联 declare)。
|
||||
pub(crate) fn predeclare_lexical_declarations(&self, statements: &[Statement], ctx: &mut CompileCtx) {
|
||||
for statement in statements {
|
||||
|
||||
@@ -158,3 +158,40 @@ fn typeof_tdz_throws() {
|
||||
let err = eval("typeof x; let x;").unwrap_err();
|
||||
assert!(err.contains("ReferenceError"), "got: {}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tdz_nested_block_read_throws() {
|
||||
// 嵌套块读:块内声明点前的读命中块级 TDZ 占位,抛 ReferenceError。
|
||||
let err = eval("{ x; let x; }").unwrap_err();
|
||||
assert!(err.contains("ReferenceError"), "got: {}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tdz_declaration_self_reference_throws() {
|
||||
// 声明语句自引用:初始化器读 x 时 x 尚未初始化,抛 ReferenceError。
|
||||
let err = eval("let x = x + 1").unwrap_err();
|
||||
assert!(err.contains("ReferenceError"), "got: {}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tdz_hoisted_function_reads_later_let_throws() {
|
||||
// hoisted 函数读声明点之后的 let:调用时 x 仍在 TDZ,抛 ReferenceError。
|
||||
let err = eval("function f(){return x} f(); let x;").unwrap_err();
|
||||
assert!(err.contains("ReferenceError"), "got: {}", err);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lexical_decl_in_single_statement_body_rejected_at_parse() {
|
||||
// 文法契约:单语句体取 Statement,lexical 声明属 Declaration(非 Statement),
|
||||
// `if (c) let x = 5;` 等无括号控制流体体直属 lexical 是语法错误,解析期即拒绝,
|
||||
// 不会进入 emit——TDZ 窗口读在该形状上不可达。此前提若被未来 parser 变更
|
||||
// 打破(开始接受这些形状),须同步补 lexical 预声明的体递归覆盖。
|
||||
let err = eval("if (true) let x = 5;").unwrap_err();
|
||||
assert!(err.contains("Parse"), "got: {}", err);
|
||||
let err = eval("if (true) const x = 5;").unwrap_err();
|
||||
assert!(err.contains("Parse"), "got: {}", err);
|
||||
let err = eval("for (let i = 0; i < 1; i++) let x = 5;").unwrap_err();
|
||||
assert!(err.contains("Parse"), "got: {}", err);
|
||||
let err = eval("lab: let x = 5;").unwrap_err();
|
||||
assert!(err.contains("Parse"), "got: {}", err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user