Refine error position for missing indexer.

This commit is contained in:
Stephen Chung 2021-06-16 19:45:45 +08:00
parent 0b028dc900
commit a9ed434c73
3 changed files with 27 additions and 15 deletions

View File

@ -248,7 +248,6 @@ pub const FN_ANONYMOUS: &str = "anon$";
pub const OP_EQUALS: &str = "=="; pub const OP_EQUALS: &str = "==";
/// Standard method function for containment testing. /// Standard method function for containment testing.
///
/// The `in` operator is implemented as a call to this method. /// The `in` operator is implemented as a call to this method.
pub const OP_CONTAINS: &str = "contains"; pub const OP_CONTAINS: &str = "contains";
@ -1293,10 +1292,11 @@ impl Engine {
let hash_set = let hash_set =
FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_SET, 3)); FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_SET, 3));
let args = &mut [target, &mut idx_val_for_setter, &mut new_val]; let args = &mut [target, &mut idx_val_for_setter, &mut new_val];
let pos = Position::NONE;
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true, mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true, pos,
new_pos, None, level, None, level,
)?; )?;
} }
@ -1425,10 +1425,11 @@ impl Engine {
let args = &mut [target, &mut name.into(), &mut new_val]; let args = &mut [target, &mut name.into(), &mut new_val];
let hash_set = let hash_set =
FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_SET, 3)); FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_SET, 3));
let pos = Position::NONE;
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true, mods, state, lib, FN_IDX_SET, hash_set, args, is_ref, true,
*pos, None, level, pos, None, level,
) )
.map_err( .map_err(
|idx_err| match *idx_err { |idx_err| match *idx_err {
@ -1972,6 +1973,7 @@ impl Engine {
_ if indexers => { _ if indexers => {
let args = &mut [target, &mut idx]; let args = &mut [target, &mut idx];
let hash_get = FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_GET, 2)); let hash_get = FnCallHashes::from_native(crate::calc_fn_hash(FN_IDX_GET, 2));
let idx_pos = Position::NONE;
self.exec_fn_call( self.exec_fn_call(
mods, state, lib, FN_IDX_GET, hash_get, args, true, true, idx_pos, None, level, mods, state, lib, FN_IDX_GET, hash_get, args, true, true, idx_pos, None, level,
@ -1980,7 +1982,11 @@ impl Engine {
} }
_ => EvalAltResult::ErrorIndexingType( _ => EvalAltResult::ErrorIndexingType(
self.map_type_name(target.type_name()).into(), format!(
"{} [{}]",
self.map_type_name(target.type_name()),
self.map_type_name(idx.type_name())
),
Position::NONE, Position::NONE,
) )
.into(), .into(),

View File

@ -59,8 +59,7 @@ pub enum EvalAltResult {
/// Bit-field indexing out-of-bounds. /// Bit-field indexing out-of-bounds.
/// Wrapped values are the current number of bits in the bit-field and the index number. /// Wrapped values are the current number of bits in the bit-field and the index number.
ErrorBitFieldBounds(usize, INT, Position), ErrorBitFieldBounds(usize, INT, Position),
/// Trying to index into a type that is not an array, an object map, or a string, and has no /// Trying to index into a type that has no indexer function defined. Wrapped value is the type name.
/// indexer function defined. Wrapped value is the type name.
ErrorIndexingType(String, Position), ErrorIndexingType(String, Position),
/// The `for` statement encounters a type that is not an iterator. /// The `for` statement encounters a type that is not an iterator.
ErrorFor(Position), ErrorFor(Position),
@ -106,9 +105,7 @@ impl EvalAltResult {
Self::ErrorFunctionNotFound(_, _) => "Function not found", Self::ErrorFunctionNotFound(_, _) => "Function not found",
Self::ErrorUnboundThis(_) => "'this' is not bound", Self::ErrorUnboundThis(_) => "'this' is not bound",
Self::ErrorMismatchDataType(_, _, _) => "Data type is incorrect", Self::ErrorMismatchDataType(_, _, _) => "Data type is incorrect",
Self::ErrorIndexingType(_, _) => { Self::ErrorIndexingType(_, _) => "No indexer of the appropriate types defined",
"Indexing can only be performed on an array, an object map, a string, or a type with an indexer function defined"
}
Self::ErrorArrayBounds(0, _, _) => "Empty array has nothing to access", Self::ErrorArrayBounds(0, _, _) => "Empty array has nothing to access",
Self::ErrorArrayBounds(_, _, _) => "Array index out of bounds", Self::ErrorArrayBounds(_, _, _) => "Array index out of bounds",
Self::ErrorStringBounds(0, _, _) => "Empty string has nothing to index", Self::ErrorStringBounds(0, _, _) => "Empty string has nothing to index",
@ -175,7 +172,7 @@ impl fmt::Display for EvalAltResult {
Self::ErrorDotExpr(s, _) if !s.is_empty() => f.write_str(s)?, Self::ErrorDotExpr(s, _) if !s.is_empty() => f.write_str(s)?,
Self::ErrorIndexingType(s, _) => write!(f, "Indexer not registered for type '{}'", s)?, Self::ErrorIndexingType(s, _) => write!(f, "Indexer not registered for '{}'", s)?,
Self::ErrorUnboundThis(_) Self::ErrorUnboundThis(_)
| Self::ErrorFor(_) | Self::ErrorFor(_)

View File

@ -373,7 +373,11 @@ impl Engine {
assert!(args.len() == 2); assert!(args.len() == 2);
EvalAltResult::ErrorIndexingType( EvalAltResult::ErrorIndexingType(
self.map_type_name(args[0].type_name()).to_string(), format!(
"{} [{}]",
self.map_type_name(args[0].type_name()),
self.map_type_name(args[1].type_name())
),
pos, pos,
) )
.into() .into()
@ -385,7 +389,12 @@ impl Engine {
assert!(args.len() == 3); assert!(args.len() == 3);
EvalAltResult::ErrorIndexingType( EvalAltResult::ErrorIndexingType(
self.map_type_name(args[0].type_name()).to_string(), format!(
"{} [{}] = {}",
self.map_type_name(args[0].type_name()),
self.map_type_name(args[1].type_name()),
self.map_type_name(args[2].type_name())
),
pos, pos,
) )
.into() .into()