Refine ChainArgument.
This commit is contained in:
parent
c87645ba77
commit
fc0256aff9
@ -274,50 +274,34 @@ enum ChainArgument {
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Property(Position),
|
||||
/// Arguments to a dot method call.
|
||||
/// Wrapped values are the arguments plus the [position][Position] of the first argument.
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
MethodCallArgs(StaticVec<Dynamic>, Position),
|
||||
/// Index value.
|
||||
/// Index value and [position][Position].
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
IndexValue(Dynamic, Position),
|
||||
}
|
||||
|
||||
#[cfg(any(not(feature = "no_index"), not(feature = "no_object")))]
|
||||
impl ChainArgument {
|
||||
/// Return the `Dynamic` value.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if not `ChainArgument::IndexValue`.
|
||||
/// Return the index value.
|
||||
#[inline(always)]
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
#[must_use]
|
||||
pub fn as_index_value(self) -> Dynamic {
|
||||
pub fn as_index_value(self) -> Option<Dynamic> {
|
||||
match self {
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Self::Property(_) | Self::MethodCallArgs(_, _) => {
|
||||
panic!("expecting ChainArgument::IndexValue")
|
||||
}
|
||||
Self::IndexValue(value, _) => value,
|
||||
Self::IndexValue(value, _) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
/// Return the `StaticVec<Dynamic>` value.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Panics if not `ChainArgument::MethodCallArgs`.
|
||||
/// Return the list of method call arguments.
|
||||
#[inline(always)]
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
#[must_use]
|
||||
pub fn as_fn_call_args(self) -> (StaticVec<Dynamic>, Position) {
|
||||
pub fn as_fn_call_args(self) -> Option<(StaticVec<Dynamic>, Position)> {
|
||||
match self {
|
||||
Self::Property(_) => {
|
||||
panic!("expecting ChainArgument::MethodCallArgs")
|
||||
}
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Self::IndexValue(_, _) => {
|
||||
panic!("expecting ChainArgument::MethodCallArgs")
|
||||
}
|
||||
Self::MethodCallArgs(values, pos) => (values, pos),
|
||||
Self::MethodCallArgs(values, pos) => Some((values, pos)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1208,12 +1192,14 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
ChainType::Index => {
|
||||
let pos = rhs.position();
|
||||
let idx_val = idx_val
|
||||
.as_index_value()
|
||||
.expect("never fails because `chain_type` is `ChainType::Index`");
|
||||
|
||||
match rhs {
|
||||
// xxx[idx].expr... | xxx[idx][expr]...
|
||||
Expr::Dot(x, x_pos) | Expr::Index(x, x_pos) => {
|
||||
let idx_pos = x.lhs.position();
|
||||
let idx_val = idx_val.as_index_value();
|
||||
let obj_ptr = &mut self.get_indexed_mut(
|
||||
mods, state, lib, target, idx_val, idx_pos, false, true, level,
|
||||
)?;
|
||||
@ -1229,7 +1215,6 @@ impl Engine {
|
||||
_ if new_val.is_some() => {
|
||||
let ((new_val, new_pos), (op_info, op_pos)) =
|
||||
new_val.expect("never fails because `new_val` is `Some`");
|
||||
let idx_val = idx_val.as_index_value();
|
||||
let mut idx_val_for_setter = idx_val.clone();
|
||||
|
||||
let try_setter = match self.get_indexed_mut(
|
||||
@ -1271,13 +1256,9 @@ impl Engine {
|
||||
Ok((Dynamic::UNIT, true))
|
||||
}
|
||||
// xxx[rhs]
|
||||
_ => {
|
||||
let idx_val = idx_val.as_index_value();
|
||||
self.get_indexed_mut(
|
||||
mods, state, lib, target, idx_val, pos, false, true, level,
|
||||
)
|
||||
.map(|v| (v.take_or_clone(), false))
|
||||
}
|
||||
_ => self
|
||||
.get_indexed_mut(mods, state, lib, target, idx_val, pos, false, true, level)
|
||||
.map(|v| (v.take_or_clone(), false)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -1287,9 +1268,11 @@ impl Engine {
|
||||
// xxx.fn_name(arg_expr_list)
|
||||
Expr::FnCall(x, pos) if !x.is_qualified() && new_val.is_none() => {
|
||||
let FnCallExpr { name, hashes, .. } = x.as_ref();
|
||||
let args = &mut idx_val.as_fn_call_args();
|
||||
let call_args = &mut idx_val
|
||||
.as_fn_call_args()
|
||||
.expect("never fails because `chain_type` is `ChainType::Dot` with `Expr::FnCallExpr`");
|
||||
self.make_method_call(
|
||||
mods, state, lib, name, *hashes, target, args, *pos, level,
|
||||
mods, state, lib, name, *hashes, target, call_args, *pos, level,
|
||||
)
|
||||
}
|
||||
// xxx.fn_name(...) = ???
|
||||
@ -1450,9 +1433,11 @@ impl Engine {
|
||||
// {xxx:map}.fn_name(arg_expr_list)[expr] | {xxx:map}.fn_name(arg_expr_list).expr
|
||||
Expr::FnCall(ref x, pos) if !x.is_qualified() => {
|
||||
let FnCallExpr { name, hashes, .. } = x.as_ref();
|
||||
let args = &mut idx_val.as_fn_call_args();
|
||||
let call_args = &mut idx_val
|
||||
.as_fn_call_args()
|
||||
.expect("never fails because `chain_type` is `ChainType::Dot` with `Expr::FnCallExpr`");
|
||||
let (val, _) = self.make_method_call(
|
||||
mods, state, lib, name, *hashes, target, args, pos, level,
|
||||
mods, state, lib, name, *hashes, target, call_args, pos, level,
|
||||
)?;
|
||||
val.into()
|
||||
}
|
||||
@ -1569,7 +1554,9 @@ impl Engine {
|
||||
Expr::FnCall(ref f, pos) if !f.is_qualified() => {
|
||||
let FnCallExpr { name, hashes, .. } = f.as_ref();
|
||||
let rhs_chain = match_chain_type(rhs);
|
||||
let args = &mut idx_val.as_fn_call_args();
|
||||
let args = &mut idx_val
|
||||
.as_fn_call_args()
|
||||
.expect("never fails because `chain_type` is `ChainType::Dot` with `Expr::FnCallExpr`");
|
||||
let (mut val, _) = self.make_method_call(
|
||||
mods, state, lib, name, *hashes, target, args, pos, level,
|
||||
)?;
|
||||
@ -1688,17 +1675,19 @@ impl Engine {
|
||||
args, constants, ..
|
||||
} = x.as_ref();
|
||||
let mut arg_values = StaticVec::with_capacity(args.len());
|
||||
let mut first_arg_pos = Position::NONE;
|
||||
|
||||
for index in 0..args.len() {
|
||||
let (value, _) = self.get_arg_value(
|
||||
let (value, pos) = self.get_arg_value(
|
||||
scope, mods, state, lib, this_ptr, level, args, constants, index,
|
||||
)?;
|
||||
arg_values.push(value.flatten());
|
||||
if index == 0 {
|
||||
first_arg_pos = pos
|
||||
}
|
||||
}
|
||||
|
||||
let pos = x.args.get(0).map(Expr::position).unwrap_or_default();
|
||||
|
||||
idx_values.push((arg_values, pos).into());
|
||||
idx_values.push((arg_values, first_arg_pos).into());
|
||||
}
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Expr::FnCall(_, _) if _parent_chain_type == ChainType::Dot => {
|
||||
@ -1730,17 +1719,19 @@ impl Engine {
|
||||
args, constants, ..
|
||||
} = x.as_ref();
|
||||
let mut arg_values = StaticVec::with_capacity(args.len());
|
||||
let mut first_arg_pos = Position::NONE;
|
||||
|
||||
for index in 0..args.len() {
|
||||
let (value, _) = self.get_arg_value(
|
||||
let (value, pos) = self.get_arg_value(
|
||||
scope, mods, state, lib, this_ptr, level, args, constants, index,
|
||||
)?;
|
||||
arg_values.push(value.flatten());
|
||||
if index == 0 {
|
||||
first_arg_pos = pos;
|
||||
}
|
||||
}
|
||||
|
||||
let pos = x.args.get(0).map(Expr::position).unwrap_or_default();
|
||||
|
||||
(arg_values, pos).into()
|
||||
(arg_values, first_arg_pos).into()
|
||||
}
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Expr::FnCall(_, _) if _parent_chain_type == ChainType::Dot => {
|
||||
|
Loading…
Reference in New Issue
Block a user