mirror of
https://github.com/pjh456/OxideJS.git
synced 2026-10-23 18:21:13 +08:00
feat: 实现默认参数(形参 initializer 与解构默认值)
This commit is contained in:
@@ -174,19 +174,23 @@ pub enum FunctionBodyContext {
|
||||
ClassElement,
|
||||
}
|
||||
|
||||
/// 参数规格:普通形参为标识符,解构形参用合成名 + 原始 pattern。
|
||||
/// 参数规格:普通形参为标识符(可带默认值 initializer),解构形参用合成名 + 原始 pattern。
|
||||
pub enum ParamSpec<'a> {
|
||||
Identifier(String),
|
||||
Identifier {
|
||||
name: String,
|
||||
initializer: Option<&'a Expression<'a>>,
|
||||
},
|
||||
Pattern {
|
||||
synthetic_name: String,
|
||||
pattern: &'a oxide_parser::BindingPattern<'a>,
|
||||
initializer: Option<&'a Expression<'a>>,
|
||||
},
|
||||
}
|
||||
|
||||
impl ParamSpec<'_> {
|
||||
pub(crate) fn register_name(&self) -> &str {
|
||||
match self {
|
||||
Self::Identifier(name) => name,
|
||||
Self::Identifier { name, .. } => name,
|
||||
Self::Pattern { synthetic_name, .. } => synthetic_name,
|
||||
}
|
||||
}
|
||||
@@ -529,12 +533,16 @@ impl Emitter {
|
||||
for (idx, param) in function.params.items.iter().enumerate() {
|
||||
match ¶m.pattern {
|
||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||
param_specs.push(ParamSpec::Identifier(bi.name.to_string()));
|
||||
param_specs.push(ParamSpec::Identifier {
|
||||
name: bi.name.to_string(),
|
||||
initializer: param.initializer.as_deref(),
|
||||
});
|
||||
}
|
||||
pattern => {
|
||||
param_specs.push(ParamSpec::Pattern {
|
||||
synthetic_name: format!("@@param_{idx}"),
|
||||
pattern,
|
||||
initializer: param.initializer.as_deref(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -729,9 +737,23 @@ impl Emitter {
|
||||
}
|
||||
|
||||
for spec in param_specs {
|
||||
if let ParamSpec::Pattern { synthetic_name, pattern } = spec {
|
||||
let src_reg = ctx.lookup(synthetic_name)?;
|
||||
self.emit_binding_pattern(pattern, src_reg, VariableDeclarationKind::Var, false, ctx)?;
|
||||
match spec {
|
||||
ParamSpec::Pattern { synthetic_name, pattern, initializer } => {
|
||||
let src_reg = ctx.lookup(synthetic_name)?;
|
||||
let src_reg = if let Some(init) = initializer {
|
||||
self.emit_default_if_undefined(src_reg, init, ctx)?
|
||||
} else {
|
||||
src_reg
|
||||
};
|
||||
self.emit_binding_pattern(pattern, src_reg, VariableDeclarationKind::Var, false, ctx)?;
|
||||
}
|
||||
ParamSpec::Identifier { name, initializer } => {
|
||||
if let Some(init) = initializer {
|
||||
// 默认参数:实参为 undefined 时用默认值。
|
||||
let reg = ctx.lookup(name)?;
|
||||
self.emit_default_if_undefined(reg, init, ctx)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -910,3 +932,4 @@ impl Default for Emitter {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,12 +21,16 @@ impl Emitter {
|
||||
for (idx, param) in arrow.params.items.iter().enumerate() {
|
||||
match ¶m.pattern {
|
||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||
param_names.push(ParamSpec::Identifier(bi.name.to_string()));
|
||||
param_names.push(ParamSpec::Identifier {
|
||||
name: bi.name.to_string(),
|
||||
initializer: param.initializer.as_deref(),
|
||||
});
|
||||
}
|
||||
pattern => {
|
||||
param_names.push(ParamSpec::Pattern {
|
||||
synthetic_name: format!("@@param_{idx}"),
|
||||
pattern,
|
||||
initializer: param.initializer.as_deref(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -54,12 +58,16 @@ impl Emitter {
|
||||
for (idx, param) in fe.params.items.iter().enumerate() {
|
||||
match ¶m.pattern {
|
||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||
param_names.push(ParamSpec::Identifier(bi.name.to_string()));
|
||||
param_names.push(ParamSpec::Identifier {
|
||||
name: bi.name.to_string(),
|
||||
initializer: param.initializer.as_deref(),
|
||||
});
|
||||
}
|
||||
pattern => {
|
||||
param_names.push(ParamSpec::Pattern {
|
||||
synthetic_name: format!("@@param_{idx}"),
|
||||
pattern,
|
||||
initializer: param.initializer.as_deref(),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -113,3 +121,4 @@ impl Emitter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ use oxide_parser::{
|
||||
};
|
||||
|
||||
impl Emitter {
|
||||
fn emit_default_if_undefined(
|
||||
pub(crate) fn emit_default_if_undefined(
|
||||
&self, val_reg: u32, default_expr: &Expression, ctx: &mut CompileCtx,
|
||||
) -> Result<u32, String> {
|
||||
let undef_reg = self.emit_undefined(ctx);
|
||||
|
||||
@@ -22,12 +22,16 @@ impl Emitter {
|
||||
for (idx, param) in fd.params.items.iter().enumerate() {
|
||||
match ¶m.pattern {
|
||||
oxide_parser::BindingPattern::BindingIdentifier(bi) => {
|
||||
param_names.push(ParamSpec::Identifier(bi.name.to_string()))
|
||||
param_names.push(ParamSpec::Identifier {
|
||||
name: bi.name.to_string(),
|
||||
initializer: param.initializer.as_deref(),
|
||||
})
|
||||
}
|
||||
pattern => param_names.push(ParamSpec::Pattern {
|
||||
synthetic_name: format!("@@param_{idx}"),
|
||||
pattern,
|
||||
}),
|
||||
synthetic_name: format!("@@param_{idx}"),
|
||||
pattern,
|
||||
initializer: param.initializer.as_deref(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
let body_stmts: &[Statement] = if let Some(body) = &fd.body { &body.statements } else { &[] };
|
||||
@@ -50,3 +54,4 @@ impl Emitter {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user