Improve position display.

This commit is contained in:
Stephen Chung
2022-02-04 12:04:33 +08:00
parent 345a060672
commit 6c1c8bc538
11 changed files with 212 additions and 138 deletions

View File

@@ -306,7 +306,7 @@ impl Expr {
Err(
PERR::MismatchedType("a boolean expression".to_string(), type_name.to_string())
.into_err(self.position()),
.into_err(self.start_position()),
)
}
/// Raise an error if the expression can never yield an iterable value.
@@ -326,7 +326,7 @@ impl Expr {
Err(
PERR::MismatchedType("an iterable value".to_string(), type_name.to_string())
.into_err(self.position()),
.into_err(self.start_position()),
)
}
}
@@ -521,6 +521,7 @@ fn parse_fn_call(
namespace,
hashes,
args,
pos: settings.pos,
..Default::default()
}
.into_fn_call_expr(settings.pos));
@@ -585,6 +586,7 @@ fn parse_fn_call(
namespace,
hashes,
args,
pos: settings.pos,
..Default::default()
}
.into_fn_call_expr(settings.pos));
@@ -652,7 +654,7 @@ fn parse_index_chain(
return Err(PERR::MalformedIndexExpr(
"Only arrays, object maps and strings can be indexed".into(),
)
.into_err(lhs.position()))
.into_err(lhs.start_position()))
}
Expr::CharConstant(_, _)
@@ -663,7 +665,7 @@ fn parse_index_chain(
return Err(PERR::MalformedIndexExpr(
"Only arrays, object maps and strings can be indexed".into(),
)
.into_err(lhs.position()))
.into_err(lhs.start_position()))
}
_ => (),
@@ -677,7 +679,7 @@ fn parse_index_chain(
return Err(PERR::MalformedIndexExpr(
"Array or string expects numeric index, not a string".into(),
)
.into_err(idx_expr.position()))
.into_err(idx_expr.start_position()))
}
#[cfg(not(feature = "no_float"))]
@@ -685,7 +687,7 @@ fn parse_index_chain(
return Err(PERR::MalformedIndexExpr(
"Only arrays, object maps and strings can be indexed".into(),
)
.into_err(lhs.position()))
.into_err(lhs.start_position()))
}
Expr::CharConstant(_, _)
@@ -696,7 +698,7 @@ fn parse_index_chain(
return Err(PERR::MalformedIndexExpr(
"Only arrays, object maps and strings can be indexed".into(),
)
.into_err(lhs.position()))
.into_err(lhs.start_position()))
}
_ => (),
@@ -708,35 +710,35 @@ fn parse_index_chain(
return Err(PERR::MalformedIndexExpr(
"Array access expects integer index, not a float".into(),
)
.into_err(x.position()))
.into_err(x.start_position()))
}
// lhs[char]
x @ Expr::CharConstant(_, _) => {
return Err(PERR::MalformedIndexExpr(
"Array access expects integer index, not a character".into(),
)
.into_err(x.position()))
.into_err(x.start_position()))
}
// lhs[()]
x @ Expr::Unit(_) => {
return Err(PERR::MalformedIndexExpr(
"Array access expects integer index, not ()".into(),
)
.into_err(x.position()))
.into_err(x.start_position()))
}
// lhs[??? && ???], lhs[??? || ???]
x @ Expr::And(_, _) | x @ Expr::Or(_, _) => {
return Err(PERR::MalformedIndexExpr(
"Array access expects integer index, not a boolean".into(),
)
.into_err(x.position()))
.into_err(x.start_position()))
}
// lhs[true], lhs[false]
x @ Expr::BoolConstant(_, _) => {
return Err(PERR::MalformedIndexExpr(
"Array access expects integer index, not a boolean".into(),
)
.into_err(x.position()))
.into_err(x.start_position()))
}
// All other expressions
_ => (),
@@ -1048,7 +1050,7 @@ fn parse_switch(
let (hash, range) = if let Some(expr) = expr {
let value = expr.get_literal_value().ok_or_else(|| {
PERR::ExprExpected("a literal".to_string()).into_err(expr.position())
PERR::ExprExpected("a literal".to_string()).into_err(expr.start_position())
})?;
let guard = value.read_lock::<ExclusiveRange>();
@@ -1058,14 +1060,14 @@ fn parse_switch(
} else if let Some(range) = value.read_lock::<InclusiveRange>() {
(None, Some((*range.start(), *range.end(), true)))
} else if value.is::<INT>() && !ranges.is_empty() {
return Err(PERR::WrongSwitchIntegerCase.into_err(expr.position()));
return Err(PERR::WrongSwitchIntegerCase.into_err(expr.start_position()));
} else {
let hasher = &mut get_hasher();
value.hash(hasher);
let hash = hasher.finish();
if cases.contains_key(&hash) {
return Err(PERR::DuplicatedSwitchCase.into_err(expr.position()));
return Err(PERR::DuplicatedSwitchCase.into_err(expr.start_position()));
}
(Some(hash), None)
}
@@ -1682,6 +1684,7 @@ fn parse_unary(
name: state.get_identifier("", "-"),
hashes: FnCallHashes::from_native(calc_fn_hash("-", 1)),
args,
pos,
..Default::default()
}
.into_fn_call_expr(pos))
@@ -1708,6 +1711,7 @@ fn parse_unary(
name: state.get_identifier("", "+"),
hashes: FnCallHashes::from_native(calc_fn_hash("+", 1)),
args,
pos,
..Default::default()
}
.into_fn_call_expr(pos))
@@ -1725,6 +1729,7 @@ fn parse_unary(
name: state.get_identifier("", "!"),
hashes: FnCallHashes::from_native(calc_fn_hash("!", 1)),
args,
pos,
..Default::default()
}
.into_fn_call_expr(pos))
@@ -1753,7 +1758,7 @@ fn make_assignment_stmt(
}
Expr::Property(_, _) => None,
// Anything other than a property after dotting (e.g. a method call) is not an l-value
ref e => Some(e.position()),
ref e => Some(e.start_position()),
},
Expr::Index(x, term, _) | Expr::Dot(x, term, _) => match x.lhs {
Expr::Property(_, _) => unreachable!("unexpected Expr::Property in indexing"),
@@ -1762,7 +1767,7 @@ fn make_assignment_stmt(
},
Expr::Property(_, _) if parent_is_dot => None,
Expr::Property(_, _) => unreachable!("unexpected Expr::Property in indexing"),
e if parent_is_dot => Some(e.position()),
e if parent_is_dot => Some(e.start_position()),
_ => None,
}
}
@@ -1772,7 +1777,7 @@ fn make_assignment_stmt(
match lhs {
// const_expr = rhs
ref expr if expr.is_constant() => {
Err(PERR::AssignmentToConstant("".into()).into_err(lhs.position()))
Err(PERR::AssignmentToConstant("".into()).into_err(lhs.start_position()))
}
// var (non-indexed) = rhs
Expr::Variable(None, _, ref x) if x.0.is_none() => Ok(Stmt::Assignment(
@@ -1814,10 +1819,8 @@ fn make_assignment_stmt(
op_pos,
)),
// expr[???] = rhs, expr.??? = rhs
ref expr => {
Err(PERR::AssignmentToInvalidLHS("".to_string())
.into_err(expr.position()))
}
ref expr => Err(PERR::AssignmentToInvalidLHS("".to_string())
.into_err(expr.start_position())),
}
}
Some(err_pos) => {
@@ -1832,7 +1835,7 @@ fn make_assignment_stmt(
)
.into_err(op_pos)),
// expr = rhs
_ => Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(lhs.position())),
_ => Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(lhs.start_position())),
}
}
@@ -1983,7 +1986,7 @@ fn make_dot_expr(
Ok(Expr::Dot(BinaryExpr { lhs, rhs }.into(), false, op_pos))
}
// lhs.rhs
(_, rhs) => Err(PERR::PropertyExpected.into_err(rhs.position())),
(_, rhs) => Err(PERR::PropertyExpected.into_err(rhs.start_position())),
}
}
@@ -2065,6 +2068,7 @@ fn parse_binary_op(
let op_base = FnCallExpr {
name: state.get_identifier("", op),
hashes: FnCallHashes::from_native(hash),
pos,
..Default::default()
};
@@ -2082,7 +2086,10 @@ fn parse_binary_op(
| Token::LessThan
| Token::LessThanEqualsTo
| Token::GreaterThan
| Token::GreaterThanEqualsTo => FnCallExpr { args, ..op_base }.into_fn_call_expr(pos),
| Token::GreaterThanEqualsTo => {
let pos = args[0].start_position();
FnCallExpr { args, ..op_base }.into_fn_call_expr(pos)
}
Token::Or => {
let rhs = args.pop().unwrap();
@@ -2111,6 +2118,7 @@ fn parse_binary_op(
Token::In => {
// Swap the arguments
let current_lhs = args.remove(0);
let pos = current_lhs.start_position();
args.push(current_lhs);
args.shrink_to_fit();
@@ -2132,6 +2140,7 @@ fn parse_binary_op(
.map_or(false, Option::is_some) =>
{
let hash = calc_fn_hash(&s, 2);
let pos = args[0].start_position();
FnCallExpr {
hashes: if is_valid_function_name(&s) {
@@ -2145,7 +2154,10 @@ fn parse_binary_op(
.into_fn_call_expr(pos)
}
_ => FnCallExpr { args, ..op_base }.into_fn_call_expr(pos),
_ => {
let pos = args[0].start_position();
FnCallExpr { args, ..op_base }.into_fn_call_expr(pos)
}
};
}
}
@@ -2734,13 +2746,10 @@ fn parse_block(
#[cfg(not(feature = "no_module"))]
let orig_imports_len = state.imports.len();
loop {
let end_pos = loop {
// Terminated?
match input.peek().expect(NEVER_ENDS) {
(Token::RightBrace, _) => {
eat_token(input, Token::RightBrace);
break;
}
(Token::RightBrace, _) => break eat_token(input, Token::RightBrace),
(Token::EOF, pos) => {
return Err(PERR::MissingToken(
Token::RightBrace.into(),
@@ -2767,10 +2776,7 @@ fn parse_block(
match input.peek().expect(NEVER_ENDS) {
// { ... stmt }
(Token::RightBrace, _) => {
eat_token(input, Token::RightBrace);
break;
}
(Token::RightBrace, _) => break eat_token(input, Token::RightBrace),
// { ... stmt;
(Token::SemiColon, _) if need_semicolon => {
eat_token(input, Token::SemiColon);
@@ -2793,7 +2799,7 @@ fn parse_block(
.into_err(*pos));
}
}
}
};
state.stack.truncate(state.entry_stack_len);
state.entry_stack_len = prev_entry_stack_len;
@@ -2801,7 +2807,10 @@ fn parse_block(
#[cfg(not(feature = "no_module"))]
state.imports.truncate(orig_imports_len);
Ok(Stmt::Block(statements.into_boxed_slice(), settings.pos))
Ok(Stmt::Block(
statements.into_boxed_slice(),
(settings.pos, end_pos),
))
}
/// Parse an expression as a statement.
@@ -3244,6 +3253,7 @@ fn make_curry_from_externals(
num_externals + 1,
)),
args,
pos,
..Default::default()
}
.into_fn_call_expr(pos);
@@ -3253,7 +3263,7 @@ fn make_curry_from_externals(
let mut statements = StaticVec::with_capacity(externals.len() + 1);
statements.extend(externals.into_iter().map(Stmt::Share));
statements.push(Stmt::Expr(expr));
Expr::Stmt(crate::ast::StmtBlock::new(statements, pos).into())
Expr::Stmt(crate::ast::StmtBlock::new(statements, pos, Position::NONE).into())
}
/// Parse an anonymous function definition.