Make Expr::position const.

This commit is contained in:
Stephen Chung 2021-06-29 18:41:03 +08:00
parent 08828dd8c1
commit 0346bb874b
5 changed files with 24 additions and 35 deletions

View File

@ -1052,7 +1052,7 @@ impl Stmt {
} }
/// Get the [position][Position] of this statement. /// Get the [position][Position] of this statement.
#[must_use] #[must_use]
pub fn position(&self) -> Position { pub const fn position(&self) -> Position {
match self { match self {
Self::Noop(pos) Self::Noop(pos)
| Self::Continue(pos) | Self::Continue(pos)
@ -1727,7 +1727,7 @@ pub enum Expr {
/// [String][ImmutableString] constant. /// [String][ImmutableString] constant.
StringConstant(ImmutableString, Position), StringConstant(ImmutableString, Position),
/// An interpolated [string][ImmutableString]. /// An interpolated [string][ImmutableString].
InterpolatedString(Box<StaticVec<Expr>>), InterpolatedString(Box<StaticVec<Expr>>, Position),
/// [ expr, ... ] /// [ expr, ... ]
Array(Box<StaticVec<Expr>>, Position), Array(Box<StaticVec<Expr>>, Position),
/// #{ name:expr, ... } /// #{ name:expr, ... }
@ -1798,7 +1798,7 @@ impl fmt::Debug for Expr {
Self::StringConstant(value, _) => write!(f, "{:?}", value), Self::StringConstant(value, _) => write!(f, "{:?}", value),
Self::Unit(_) => f.write_str("()"), Self::Unit(_) => f.write_str("()"),
Self::InterpolatedString(x) => { Self::InterpolatedString(x, _) => {
f.write_str("InterpolatedString")?; f.write_str("InterpolatedString")?;
return f.debug_list().entries(x.iter()).finish(); return f.debug_list().entries(x.iter()).finish();
} }
@ -1948,7 +1948,7 @@ impl Expr {
/// Get the [position][Position] of the expression. /// Get the [position][Position] of the expression.
#[inline] #[inline]
#[must_use] #[must_use]
pub fn position(&self) -> Position { pub const fn position(&self) -> Position {
match self { match self {
#[cfg(not(feature = "no_float"))] #[cfg(not(feature = "no_float"))]
Self::FloatConstant(_, pos) => *pos, Self::FloatConstant(_, pos) => *pos,
@ -1964,14 +1964,8 @@ impl Expr {
| Self::Variable(_, pos, _) | Self::Variable(_, pos, _)
| Self::Stack(_, pos) | Self::Stack(_, pos)
| Self::FnCall(_, pos) | Self::FnCall(_, pos)
| Self::Custom(_, pos) => *pos, | Self::Custom(_, pos)
| Self::InterpolatedString(_, pos) => *pos,
Self::InterpolatedString(x) => x
.first()
.expect(
"never fails because an interpolated string always contains at least one item",
)
.position(),
Self::Property(x) => (x.2).1, Self::Property(x) => (x.2).1,
Self::Stmt(x) => x.1, Self::Stmt(x) => x.1,
@ -2003,13 +1997,8 @@ impl Expr {
| Self::Variable(_, pos, _) | Self::Variable(_, pos, _)
| Self::Stack(_, pos) | Self::Stack(_, pos)
| Self::FnCall(_, pos) | Self::FnCall(_, pos)
| Self::Custom(_, pos) => *pos = new_pos, | Self::Custom(_, pos)
| Self::InterpolatedString(_, pos) => *pos = new_pos,
Self::InterpolatedString(x) => {
x.first_mut()
.expect("never fails because an interpolated string always contains at least one item")
.set_position(new_pos);
}
Self::Property(x) => (x.2).1 = new_pos, Self::Property(x) => (x.2).1 = new_pos,
Self::Stmt(x) => x.1 = new_pos, Self::Stmt(x) => x.1 = new_pos,
@ -2024,7 +2013,7 @@ impl Expr {
#[must_use] #[must_use]
pub fn is_pure(&self) -> bool { pub fn is_pure(&self) -> bool {
match self { match self {
Self::InterpolatedString(x) | Self::Array(x, _) => x.iter().all(Self::is_pure), Self::InterpolatedString(x, _) | Self::Array(x, _) => x.iter().all(Self::is_pure),
Self::Map(x, _) => x.0.iter().map(|(_, v)| v).all(Self::is_pure), Self::Map(x, _) => x.0.iter().map(|(_, v)| v).all(Self::is_pure),
@ -2062,7 +2051,7 @@ impl Expr {
| Self::Unit(_) | Self::Unit(_)
| Self::Stack(_, _) => true, | Self::Stack(_, _) => true,
Self::InterpolatedString(x) | Self::Array(x, _) => x.iter().all(Self::is_constant), Self::InterpolatedString(x, _) | Self::Array(x, _) => x.iter().all(Self::is_constant),
Self::Map(x, _) => x.0.iter().map(|(_, expr)| expr).all(Self::is_constant), Self::Map(x, _) => x.0.iter().map(|(_, expr)| expr).all(Self::is_constant),
@ -2092,7 +2081,7 @@ impl Expr {
Self::IntegerConstant(_, _) Self::IntegerConstant(_, _)
| Self::StringConstant(_, _) | Self::StringConstant(_, _)
| Self::InterpolatedString(_) | Self::InterpolatedString(_, _)
| Self::FnCall(_, _) | Self::FnCall(_, _)
| Self::Stmt(_) | Self::Stmt(_)
| Self::Dot(_, _) | Self::Dot(_, _)
@ -2147,7 +2136,7 @@ impl Expr {
} }
} }
} }
Self::InterpolatedString(x) | Self::Array(x, _) => { Self::InterpolatedString(x, _) | Self::Array(x, _) => {
for e in x.as_ref() { for e in x.as_ref() {
if !e.walk(path, on_node) { if !e.walk(path, on_node) {
return false; return false;

View File

@ -67,13 +67,13 @@ impl Expression<'_> {
/// Get the expression. /// Get the expression.
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub(crate) fn expr(&self) -> &Expr { pub(crate) const fn expr(&self) -> &Expr {
&self.0 &self.0
} }
/// Get the position of this expression. /// Get the position of this expression.
#[inline(always)] #[inline(always)]
#[must_use] #[must_use]
pub fn position(&self) -> Position { pub const fn position(&self) -> Position {
self.0.position() self.0.position()
} }
/// Get the value of this expression if it is a literal constant. /// Get the value of this expression if it is a literal constant.

View File

@ -2009,8 +2009,8 @@ impl Engine {
} }
// `... ${...} ...` // `... ${...} ...`
Expr::InterpolatedString(x) => { Expr::InterpolatedString(x, pos) => {
let mut pos = expr.position(); let mut pos = *pos;
let mut result: Dynamic = self.empty_string.clone().into(); let mut result: Dynamic = self.empty_string.clone().into();
for expr in x.iter() { for expr in x.iter() {

View File

@ -787,17 +787,17 @@ fn optimize_expr(expr: &mut Expr, state: &mut State, _chaining: bool) {
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
Expr::Index(x, _) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); } Expr::Index(x, _) => { optimize_expr(&mut x.lhs, state, false); optimize_expr(&mut x.rhs, state, _chaining); }
// `` // ``
Expr::InterpolatedString(x) if x.is_empty() => { Expr::InterpolatedString(x, pos) if x.is_empty() => {
state.set_dirty(); state.set_dirty();
*expr = Expr::StringConstant(state.engine.empty_string.clone(), Position::NONE); *expr = Expr::StringConstant(state.engine.empty_string.clone(), *pos);
} }
// `...` // `...`
Expr::InterpolatedString(x) if x.len() == 1 && matches!(x[0], Expr::StringConstant(_, _)) => { Expr::InterpolatedString(x, _) if x.len() == 1 && matches!(x[0], Expr::StringConstant(_, _)) => {
state.set_dirty(); state.set_dirty();
*expr = mem::take(&mut x[0]); *expr = mem::take(&mut x[0]);
} }
// `... ${ ... } ...` // `... ${ ... } ...`
Expr::InterpolatedString(x) => { Expr::InterpolatedString(x, _) => {
let mut n = 0; let mut n = 0;
// Merge consecutive strings // Merge consecutive strings

View File

@ -515,7 +515,7 @@ fn parse_index_chain(
Expr::IntegerConstant(_, _) Expr::IntegerConstant(_, _)
| Expr::Array(_, _) | Expr::Array(_, _)
| Expr::StringConstant(_, _) | Expr::StringConstant(_, _)
| Expr::InterpolatedString(_) => (), | Expr::InterpolatedString(_, _) => (),
Expr::Map(_, _) => { Expr::Map(_, _) => {
return Err(PERR::MalformedIndexExpr( return Err(PERR::MalformedIndexExpr(
@ -547,10 +547,10 @@ fn parse_index_chain(
}, },
// lhs[string] // lhs[string]
Expr::StringConstant(_, _) | Expr::InterpolatedString(_) => match lhs { Expr::StringConstant(_, _) | Expr::InterpolatedString(_, _) => match lhs {
Expr::Map(_, _) => (), Expr::Map(_, _) => (),
Expr::Array(_, _) | Expr::StringConstant(_, _) | Expr::InterpolatedString(_) => { Expr::Array(_, _) | Expr::StringConstant(_, _) | Expr::InterpolatedString(_, _) => {
return Err(PERR::MalformedIndexExpr( return Err(PERR::MalformedIndexExpr(
"Array or string expects numeric index, not a string".into(), "Array or string expects numeric index, not a string".into(),
) )
@ -1132,7 +1132,7 @@ fn parse_primary(
} }
segments.shrink_to_fit(); segments.shrink_to_fit();
Expr::InterpolatedString(segments.into()) Expr::InterpolatedString(segments.into(), settings.pos)
} }
// Array literal // Array literal