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

@@ -91,7 +91,7 @@ impl AST {
) -> Self {
Self {
source: Identifier::new_const(),
body: StmtBlock::new(statements, Position::NONE),
body: StmtBlock::new(statements, Position::NONE, Position::NONE),
#[cfg(not(feature = "no_function"))]
lib: functions.into(),
#[cfg(not(feature = "no_module"))]

View File

@@ -191,6 +191,8 @@ pub struct FnCallExpr {
pub constants: StaticVec<Dynamic>,
/// Does this function call capture the parent scope?
pub capture_parent_scope: bool,
/// [Position] of the function name.
pub pos: Position,
}
impl fmt::Debug for FnCallExpr {
@@ -207,6 +209,7 @@ impl fmt::Debug for FnCallExpr {
if self.capture_parent_scope {
ff.field("capture_parent_scope", &self.capture_parent_scope);
}
ff.field("pos", &self.pos);
ff.finish()
}
}
@@ -437,7 +440,7 @@ impl Default for Expr {
impl fmt::Debug for Expr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut display_pos = self.position();
let mut display_pos = self.start_position();
match self {
Self::DynamicConstant(value, _) => write!(f, "{:?}", value),
@@ -629,6 +632,7 @@ impl Expr {
args: once(Self::Stack(0, pos)).collect(),
constants: once(f.fn_name().into()).collect(),
capture_parent_scope: false,
pos,
}
.into(),
pos,
@@ -685,15 +689,30 @@ impl Expr {
| Self::Map(_, pos)
| Self::Variable(_, pos, _)
| Self::Stack(_, pos)
| Self::FnCall(_, pos)
| Self::And(_, pos)
| Self::Or(_, pos)
| Self::Index(_, _, pos)
| Self::Dot(_, _, pos)
| Self::Custom(_, pos)
| Self::InterpolatedString(_, pos)
| Self::Property(_, pos) => *pos,
Self::Stmt(x) => x.position(),
Self::FnCall(x, _) => x.pos,
Self::And(x, _) | Self::Or(x, _) | Self::Dot(x, _, _) => x.lhs.position(),
Self::Stmt(x) => x.position(),
}
}
/// Get the starting [position][Position] of the expression.
/// For a binary expression, this will be the left-most LHS instead of the operator.
#[inline]
#[must_use]
pub const fn start_position(&self) -> Position {
match self {
Self::And(x, _) | Self::Or(x, _) | Self::Index(x, _, _) | Self::Dot(x, _, _) => {
x.lhs.start_position()
}
Self::FnCall(_, pos) => *pos,
_ => self.position(),
}
}
/// Override the [position][Position] of the expression.
@@ -722,7 +741,7 @@ impl Expr {
| Self::InterpolatedString(_, pos)
| Self::Property(_, pos) => *pos = new_pos,
Self::Stmt(x) => x.set_position(new_pos),
Self::Stmt(x) => x.set_position(new_pos, Position::NONE),
}
self

View File

@@ -134,7 +134,7 @@ pub struct TryCatchBlock {
/// _(internals)_ A scoped block of statements.
/// Exported under the `internals` feature only.
#[derive(Clone, Hash, Default)]
pub struct StmtBlock(StaticVec<Stmt>, Position);
pub struct StmtBlock(StaticVec<Stmt>, (Position, Position));
impl StmtBlock {
/// A [`StmtBlock`] that does not exist.
@@ -142,16 +142,20 @@ impl StmtBlock {
/// Create a new [`StmtBlock`].
#[must_use]
pub fn new(statements: impl IntoIterator<Item = Stmt>, pos: Position) -> Self {
pub fn new(
statements: impl IntoIterator<Item = Stmt>,
start_pos: Position,
end_pos: Position,
) -> Self {
let mut statements: StaticVec<_> = statements.into_iter().collect();
statements.shrink_to_fit();
Self(statements, pos)
Self(statements, (start_pos, end_pos))
}
/// Create an empty [`StmtBlock`].
#[inline(always)]
#[must_use]
pub const fn empty(pos: Position) -> Self {
Self(StaticVec::new_const(), pos)
Self(StaticVec::new_const(), (pos, pos))
}
/// Is this statements block empty?
#[inline(always)]
@@ -183,16 +187,42 @@ impl StmtBlock {
pub fn iter(&self) -> impl Iterator<Item = &Stmt> {
self.0.iter()
}
/// Get the position (location of the beginning `{`) of this statements block.
/// Get the start position (location of the beginning `{`) of this statements block.
#[inline(always)]
#[must_use]
pub const fn position(&self) -> Position {
(self.1).0
}
/// Get the end position (location of the ending `}`) of this statements block.
#[inline(always)]
#[must_use]
pub const fn end_position(&self) -> Position {
(self.1).1
}
/// Get the positions (locations of the beginning `{` and ending `}`) of this statements block.
#[inline(always)]
#[must_use]
pub const fn positions(&self) -> (Position, Position) {
self.1
}
/// Set the position (location of the beginning `{`) of this statements block.
/// Get the positions (locations of the beginning `{` and ending `}`) of this statements block
/// or a default.
#[inline(always)]
pub fn set_position(&mut self, pos: Position) {
self.1 = pos;
#[must_use]
pub const fn positions_or_else(
&self,
def_start_pos: Position,
def_end_pos: Position,
) -> (Position, Position) {
(
(self.1).0.or_else(def_start_pos),
(self.1).1.or_else(def_end_pos),
)
}
/// Set the positions of this statements block.
#[inline(always)]
pub fn set_position(&mut self, start_pos: Position, end_pos: Position) {
self.1 = (start_pos, end_pos);
}
}
@@ -230,7 +260,12 @@ impl fmt::Debug for StmtBlock {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Block")?;
fmt::Debug::fmt(&self.0, f)?;
self.1.debug_print(f)
(self.1).0.debug_print(f)?;
#[cfg(not(feature = "no_position"))]
if !(self.1).1.is_none() {
write!(f, "-{:?}", (self.1).1)?;
}
Ok(())
}
}
@@ -239,10 +274,10 @@ impl From<Stmt> for StmtBlock {
fn from(stmt: Stmt) -> Self {
match stmt {
Stmt::Block(mut block, pos) => Self(block.iter_mut().map(mem::take).collect(), pos),
Stmt::Noop(pos) => Self(StaticVec::new_const(), pos),
Stmt::Noop(pos) => Self(StaticVec::new_const(), (pos, pos)),
_ => {
let pos = stmt.position();
Self(vec![stmt].into(), pos)
Self(vec![stmt].into(), (pos, Position::NONE))
}
}
}
@@ -309,7 +344,7 @@ pub enum Stmt {
/// function call forming one statement.
FnCall(Box<FnCallExpr>, Position),
/// `{` stmt`;` ... `}`
Block(Box<[Stmt]>, Position),
Block(Box<[Stmt]>, (Position, Position)),
/// `try` `{` stmt; ... `}` `catch` `(` var `)` `{` stmt; ... `}`
TryCatch(Box<TryCatchBlock>, Position),
/// [expression][Expr]
@@ -377,7 +412,7 @@ impl Stmt {
match self {
Self::Noop(pos)
| Self::BreakLoop(_, pos)
| Self::Block(_, pos)
| Self::Block(_, (pos, _))
| Self::Assignment(_, pos)
| Self::FnCall(_, pos)
| Self::If(_, _, pos)
@@ -389,7 +424,7 @@ impl Stmt {
| Self::Var(_, _, _, pos)
| Self::TryCatch(_, pos) => *pos,
Self::Expr(x) => x.position(),
Self::Expr(x) => x.start_position(),
#[cfg(not(feature = "no_module"))]
Self::Import(_, _, pos) => *pos,
@@ -405,7 +440,7 @@ impl Stmt {
match self {
Self::Noop(pos)
| Self::BreakLoop(_, pos)
| Self::Block(_, pos)
| Self::Block(_, (pos, _))
| Self::Assignment(_, pos)
| Self::FnCall(_, pos)
| Self::If(_, _, pos)