feat: class 公有字段 define 语义 + computed key 类定义期求值一次
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
use std::collections::{BTreeMap, HashSet};
|
||||
|
||||
use oxide_bytecode::module::UpvalueCapture;
|
||||
use oxide_parser::{Expression, Statement};
|
||||
use oxide_parser::{ClassBody, ClassElement, Expression, Statement};
|
||||
|
||||
use crate::Emitter;
|
||||
|
||||
@@ -127,6 +127,15 @@ impl Emitter {
|
||||
self.collect_fn_default_names(&fd.params, ref_set, shadow, out);
|
||||
self.collect_capture_names_shadowed(body, ref_set, &inner, out);
|
||||
}
|
||||
Statement::ClassDeclaration(cd) => {
|
||||
// 类体(构造器/方法体、字段键与值、静态块)是嵌套作用域:
|
||||
// 类名遮蔽外层绑定,方法形参与方法体局部进一步遮蔽。
|
||||
let mut class_shadow = shadow.clone();
|
||||
if let Some(id) = &cd.id {
|
||||
class_shadow.insert(id.name.as_str().to_string());
|
||||
}
|
||||
self.collect_class_capture_names(&cd.body, ref_set, &class_shadow, out);
|
||||
}
|
||||
Statement::IfStatement(is) => {
|
||||
self.collect_capture_names_expr(&is.test, ref_set, shadow, out);
|
||||
self.collect_capture_names_stmt(&is.consequent, ref_set, shadow, out);
|
||||
@@ -211,6 +220,38 @@ impl Emitter {
|
||||
}
|
||||
}
|
||||
|
||||
/// 收集类体对 `ref_set` 的引用:方法/构造器体、字段键与值、静态块。
|
||||
/// 方法形参与方法体局部声明遮蔽外层绑定(捕获判定用)。
|
||||
fn collect_class_capture_names(
|
||||
&self, class_body: &ClassBody, ref_set: &HashSet<String>, class_shadow: &HashSet<String>,
|
||||
out: &mut HashSet<String>,
|
||||
) {
|
||||
for element in &class_body.body {
|
||||
match element {
|
||||
ClassElement::MethodDefinition(method) => {
|
||||
let mut inner = class_shadow.clone();
|
||||
inner.extend(self.collect_fn_param_names(&method.value.params));
|
||||
let body: &[Statement] = method.value.body.as_ref().map(|b| &b.statements[..]).unwrap_or(&[]);
|
||||
inner.extend(self.collect_own_binding_names(&[], body));
|
||||
self.collect_fn_default_names(&method.value.params, ref_set, class_shadow, out);
|
||||
self.collect_capture_names_shadowed(body, ref_set, &inner, out);
|
||||
}
|
||||
ClassElement::PropertyDefinition(prop) => {
|
||||
if let Some(expr) = prop.key.as_expression() {
|
||||
self.collect_capture_names_expr(expr, ref_set, class_shadow, out);
|
||||
}
|
||||
if let Some(value) = &prop.value {
|
||||
self.collect_capture_names_expr(value, ref_set, class_shadow, out);
|
||||
}
|
||||
}
|
||||
ClassElement::StaticBlock(block) => {
|
||||
self.collect_capture_names_shadowed(&block.body, ref_set, class_shadow, out);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 遍历 catch 参数解构模式:收集模式内表达式引用(默认值等),声明名写入
|
||||
/// `catch_shadow` 遮蔽 catch 作用域。
|
||||
fn collect_capture_names_binding_pattern(
|
||||
@@ -302,6 +343,14 @@ impl Emitter {
|
||||
self.collect_fn_default_names(&ae.params, ref_set, shadow, out);
|
||||
self.collect_capture_names_shadowed(&ae.body.statements, ref_set, &inner, out);
|
||||
}
|
||||
Expression::ClassExpression(class) => {
|
||||
// 类表达式:方法/构造器体与字段表达式是嵌套作用域,引用须捕获。
|
||||
let mut class_shadow = shadow.clone();
|
||||
if let Some(id) = &class.id {
|
||||
class_shadow.insert(id.name.as_str().to_string());
|
||||
}
|
||||
self.collect_class_capture_names(&class.body, ref_set, &class_shadow, out);
|
||||
}
|
||||
Expression::BinaryExpression(be) => {
|
||||
self.collect_capture_names_expr(&be.left, ref_set, shadow, out);
|
||||
self.collect_capture_names_expr(&be.right, ref_set, shadow, out);
|
||||
@@ -447,6 +496,14 @@ impl Emitter {
|
||||
self.collect_fn_default_captured(&fd.params, own, out);
|
||||
self.collect_capture_names(body, own, out);
|
||||
}
|
||||
Statement::ClassDeclaration(cd) => {
|
||||
// 类构造器/方法体与字段表达式引用的父级绑定须建 cell,供子模块 upvalue 捕获。
|
||||
let mut class_shadow = HashSet::new();
|
||||
if let Some(id) = &cd.id {
|
||||
class_shadow.insert(id.name.as_str().to_string());
|
||||
}
|
||||
self.collect_class_capture_names(&cd.body, own, &class_shadow, out);
|
||||
}
|
||||
Statement::ExpressionStatement(es) => self.collect_captured_expr(&es.expression, own, out),
|
||||
Statement::ReturnStatement(rs) => {
|
||||
if let Some(a) = &rs.argument {
|
||||
@@ -584,6 +641,14 @@ impl Emitter {
|
||||
self.collect_fn_default_captured(&ae.params, own, out);
|
||||
self.collect_capture_names_shadowed(&ae.body.statements, own, &inner, out);
|
||||
}
|
||||
Expression::ClassExpression(class) => {
|
||||
// 类表达式:构造器/方法体与字段表达式引用的父级绑定须建 cell。
|
||||
let mut class_shadow = HashSet::new();
|
||||
if let Some(id) = &class.id {
|
||||
class_shadow.insert(id.name.as_str().to_string());
|
||||
}
|
||||
self.collect_class_capture_names(&class.body, own, &class_shadow, out);
|
||||
}
|
||||
Expression::CallExpression(ce) => {
|
||||
self.collect_captured_expr(&ce.callee, own, out);
|
||||
for a in &ce.arguments {
|
||||
|
||||
Reference in New Issue
Block a user