Fix bug in assignment parsing.
This commit is contained in:
parent
b23bdb6d13
commit
2ea86c3987
@ -7,6 +7,7 @@ Version 1.1.1
|
|||||||
Bug fixes
|
Bug fixes
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
* Assignment to indexing expression with dot expressions inside no longer cause a compilation error.
|
||||||
* The `no_module` and `internals` features now work together without a compilation error.
|
* The `no_module` and `internals` features now work together without a compilation error.
|
||||||
* String literal operations (such as `"hello" + ", world"`) now optimizes correctly.
|
* String literal operations (such as `"hello" + ", world"`) now optimizes correctly.
|
||||||
|
|
||||||
|
48
src/parse.rs
48
src/parse.rs
@ -1573,13 +1573,18 @@ fn make_assignment_stmt(
|
|||||||
#[must_use]
|
#[must_use]
|
||||||
fn check_lvalue(expr: &Expr, parent_is_dot: bool) -> Option<Position> {
|
fn check_lvalue(expr: &Expr, parent_is_dot: bool) -> Option<Position> {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Index(x, _, _) | Expr::Dot(x, _, _) if parent_is_dot => match x.lhs {
|
Expr::Index(x, term, _) | Expr::Dot(x, term, _) if parent_is_dot => match x.lhs {
|
||||||
Expr::Property(_) => check_lvalue(&x.rhs, matches!(expr, Expr::Dot(_, _, _))),
|
Expr::Property(_) if !term => {
|
||||||
|
check_lvalue(&x.rhs, matches!(expr, Expr::Dot(_, _, _)))
|
||||||
|
}
|
||||||
|
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.position()),
|
||||||
},
|
},
|
||||||
Expr::Index(x, _, _) | Expr::Dot(x, _, _) => match x.lhs {
|
Expr::Index(x, term, _) | Expr::Dot(x, term, _) => match x.lhs {
|
||||||
Expr::Property(_) => unreachable!("unexpected Expr::Property in indexing"),
|
Expr::Property(_) => unreachable!("unexpected Expr::Property in indexing"),
|
||||||
_ => check_lvalue(&x.rhs, matches!(expr, Expr::Dot(_, _, _))),
|
_ if !term => check_lvalue(&x.rhs, matches!(expr, Expr::Dot(_, _, _))),
|
||||||
|
_ => None,
|
||||||
},
|
},
|
||||||
Expr::Property(_) if parent_is_dot => None,
|
Expr::Property(_) if parent_is_dot => None,
|
||||||
Expr::Property(_) => unreachable!("unexpected Expr::Property in indexing"),
|
Expr::Property(_) => unreachable!("unexpected Expr::Property in indexing"),
|
||||||
@ -1619,19 +1624,30 @@ fn make_assignment_stmt(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// xxx[???]... = rhs, xxx.prop... = rhs
|
// xxx[???]... = rhs, xxx.prop... = rhs
|
||||||
Expr::Index(ref x, _, _) | Expr::Dot(ref x, _, _) => {
|
Expr::Index(ref x, term, _) | Expr::Dot(ref x, term, _) => {
|
||||||
match check_lvalue(&x.rhs, matches!(lhs, Expr::Dot(_, _, _))) {
|
let valid_lvalue = if term {
|
||||||
None => match x.lhs {
|
None
|
||||||
// var[???] = rhs, var.??? = rhs
|
} else {
|
||||||
Expr::Variable(_, _, _) => {
|
check_lvalue(&x.rhs, matches!(lhs, Expr::Dot(_, _, _)))
|
||||||
Ok(Stmt::Assignment((lhs, op_info, rhs).into(), op_pos))
|
};
|
||||||
|
|
||||||
|
match valid_lvalue {
|
||||||
|
None => {
|
||||||
|
match x.lhs {
|
||||||
|
// var[???] = rhs, var.??? = rhs
|
||||||
|
Expr::Variable(_, _, _) => {
|
||||||
|
Ok(Stmt::Assignment((lhs, op_info, rhs).into(), op_pos))
|
||||||
|
}
|
||||||
|
// expr[???] = rhs, expr.??? = rhs
|
||||||
|
ref expr => {
|
||||||
|
Err(PERR::AssignmentToInvalidLHS("".to_string())
|
||||||
|
.into_err(expr.position()))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// expr[???] = rhs, expr.??? = rhs
|
}
|
||||||
ref expr => {
|
Some(err_pos) => {
|
||||||
Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(expr.position()))
|
Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(err_pos))
|
||||||
}
|
}
|
||||||
},
|
|
||||||
Some(pos) => Err(PERR::AssignmentToInvalidLHS("".to_string()).into_err(pos)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ??? && ??? = rhs, ??? || ??? = rhs
|
// ??? && ??? = rhs, ??? || ??? = rhs
|
||||||
|
Loading…
Reference in New Issue
Block a user