mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-29 04:24:43 +00:00
Impl Location::RangePair
This commit is contained in:
parent
7573c0e128
commit
c2edad7556
2 changed files with 77 additions and 41 deletions
|
@ -203,9 +203,9 @@ impl From<&str> for ErrorKind {
|
|||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Location {
|
||||
RangePair {
|
||||
ln_begin: usize,
|
||||
ln_first: (usize, usize),
|
||||
col_first: (usize, usize),
|
||||
ln_end: usize,
|
||||
ln_second: (usize, usize),
|
||||
col_second: (usize, usize),
|
||||
},
|
||||
Range {
|
||||
|
@ -240,16 +240,19 @@ impl Location {
|
|||
|
||||
pub fn pair(lhs: Self, rhs: Self) -> Self {
|
||||
Self::RangePair {
|
||||
ln_begin: lhs.ln_begin().unwrap(),
|
||||
ln_first: (lhs.ln_begin().unwrap(), lhs.ln_end().unwrap()),
|
||||
col_first: (lhs.col_begin().unwrap(), lhs.col_end().unwrap()),
|
||||
ln_end: rhs.ln_end().unwrap(),
|
||||
ln_second: (rhs.ln_begin().unwrap(), rhs.ln_end().unwrap()),
|
||||
col_second: (rhs.col_begin().unwrap(), rhs.col_end().unwrap()),
|
||||
}
|
||||
}
|
||||
|
||||
pub const fn ln_begin(&self) -> Option<usize> {
|
||||
match self {
|
||||
Self::RangePair { ln_begin, .. }
|
||||
Self::RangePair {
|
||||
ln_first: (ln_begin, _),
|
||||
..
|
||||
}
|
||||
| Self::Range { ln_begin, .. }
|
||||
| Self::LineRange(ln_begin, _)
|
||||
| Self::Line(ln_begin) => Some(*ln_begin),
|
||||
|
@ -259,7 +262,10 @@ impl Location {
|
|||
|
||||
pub const fn ln_end(&self) -> Option<usize> {
|
||||
match self {
|
||||
Self::RangePair { ln_end, .. }
|
||||
Self::RangePair {
|
||||
ln_second: (_, ln_end),
|
||||
..
|
||||
}
|
||||
| Self::Range { ln_end, .. }
|
||||
| Self::LineRange(ln_end, _)
|
||||
| Self::Line(ln_end) => Some(*ln_end),
|
||||
|
@ -351,6 +357,41 @@ impl ErrorCore {
|
|||
pub const VBAR_UNICODE: &str = "│";
|
||||
pub const VBAR_BREAK_UNICODE: &str = "·";
|
||||
|
||||
fn format_code_and_pointer<E: ErrorDisplay + ?Sized>(
|
||||
e: &E,
|
||||
ln_begin: usize,
|
||||
ln_end: usize,
|
||||
col_begin: usize,
|
||||
col_end: usize,
|
||||
) -> String {
|
||||
let codes = if e.input() == &Input::REPL {
|
||||
vec![e.input().reread()]
|
||||
} else {
|
||||
e.input().reread_lines(ln_begin, ln_end)
|
||||
};
|
||||
let mut res = CYAN.to_string();
|
||||
let final_step = ln_end - ln_begin;
|
||||
for (i, lineno) in (ln_begin..=ln_end).enumerate() {
|
||||
let mut pointer = " ".repeat(lineno.to_string().len() + 2); // +2 means `| `
|
||||
if i == 0 && i == final_step {
|
||||
pointer += &" ".repeat(col_begin);
|
||||
pointer += &"^".repeat(cmp::max(1, col_end - col_begin));
|
||||
} else if i == 0 {
|
||||
pointer += &" ".repeat(col_begin);
|
||||
pointer += &"^".repeat(cmp::max(1, codes[i].len() - col_begin));
|
||||
} else if i == final_step {
|
||||
pointer += &"^".repeat(col_end);
|
||||
} else {
|
||||
pointer += &"^".repeat(cmp::max(1, codes[i].len()));
|
||||
}
|
||||
res += &format!(
|
||||
"{lineno}{VBAR_UNICODE} {code}\n{pointer}\n",
|
||||
code = codes[i]
|
||||
);
|
||||
}
|
||||
res + RESET
|
||||
}
|
||||
|
||||
/// format:
|
||||
/// ```console
|
||||
/// Error[#{.errno}]: File {file}, line {.loc (as line)}, in {.caused_by}
|
||||
|
@ -430,13 +471,15 @@ pub trait ErrorDisplay {
|
|||
Location::Range {
|
||||
ln_begin, ln_end, ..
|
||||
} if ln_begin == ln_end => format!(", line {ln_begin}"),
|
||||
Location::RangePair {
|
||||
ln_begin, ln_end, ..
|
||||
}
|
||||
| Location::Range {
|
||||
Location::Range {
|
||||
ln_begin, ln_end, ..
|
||||
}
|
||||
| Location::LineRange(ln_begin, ln_end) => format!(", line {ln_begin}..{ln_end}"),
|
||||
Location::RangePair {
|
||||
ln_first: (l1, l2),
|
||||
ln_second: (l3, l4),
|
||||
..
|
||||
} => format!(", line {l1}..{l2}, {l3}..{l4}"),
|
||||
Location::Line(lineno) => format!(", line {lineno}"),
|
||||
Location::Unknown => "".to_string(),
|
||||
};
|
||||
|
@ -454,40 +497,27 @@ pub trait ErrorDisplay {
|
|||
|
||||
fn format_code_and_pointer(&self) -> String {
|
||||
match self.core().loc {
|
||||
Location::RangePair { .. } => todo!(),
|
||||
Location::RangePair {
|
||||
ln_first,
|
||||
col_first,
|
||||
ln_second,
|
||||
col_second,
|
||||
} => {
|
||||
format_code_and_pointer(self, ln_first.0, ln_first.1, col_first.0, col_first.1)
|
||||
+ &format_code_and_pointer(
|
||||
self,
|
||||
ln_second.0,
|
||||
ln_second.1,
|
||||
col_second.0,
|
||||
col_second.1,
|
||||
)
|
||||
}
|
||||
Location::Range {
|
||||
ln_begin,
|
||||
col_begin,
|
||||
ln_end,
|
||||
col_end,
|
||||
} => {
|
||||
let codes = if self.input() == &Input::REPL {
|
||||
vec![self.input().reread()]
|
||||
} else {
|
||||
self.input().reread_lines(ln_begin, ln_end)
|
||||
};
|
||||
let mut res = CYAN.to_string();
|
||||
let final_step = ln_end - ln_begin;
|
||||
for (i, lineno) in (ln_begin..=ln_end).enumerate() {
|
||||
let mut pointer = " ".repeat(lineno.to_string().len() + 2); // +2 means `| `
|
||||
if i == 0 && i == final_step {
|
||||
pointer += &" ".repeat(col_begin);
|
||||
pointer += &"^".repeat(cmp::max(1, col_end - col_begin));
|
||||
} else if i == 0 {
|
||||
pointer += &" ".repeat(col_begin);
|
||||
pointer += &"^".repeat(cmp::max(1, codes[i].len() - col_begin));
|
||||
} else if i == final_step {
|
||||
pointer += &"^".repeat(col_end);
|
||||
} else {
|
||||
pointer += &"^".repeat(cmp::max(1, codes[i].len()));
|
||||
}
|
||||
res += &format!(
|
||||
"{lineno}{VBAR_UNICODE} {code}\n{pointer}\n",
|
||||
code = codes[i]
|
||||
);
|
||||
}
|
||||
res + RESET
|
||||
}
|
||||
} => format_code_and_pointer(self, ln_begin, ln_end, col_begin, col_end),
|
||||
Location::LineRange(ln_begin, ln_end) => {
|
||||
let codes = if self.input() == &Input::REPL {
|
||||
vec![self.input().reread()]
|
||||
|
|
|
@ -407,7 +407,10 @@ pub trait Locational {
|
|||
|
||||
fn ln_begin(&self) -> Option<usize> {
|
||||
match self.loc() {
|
||||
Location::RangePair { ln_begin, .. }
|
||||
Location::RangePair {
|
||||
ln_first: (ln_begin, _),
|
||||
..
|
||||
}
|
||||
| Location::Range { ln_begin, .. }
|
||||
| Location::LineRange(ln_begin, _) => Some(ln_begin),
|
||||
Location::Line(lineno) => Some(lineno),
|
||||
|
@ -417,7 +420,10 @@ pub trait Locational {
|
|||
|
||||
fn ln_end(&self) -> Option<usize> {
|
||||
match self.loc() {
|
||||
Location::RangePair { ln_end, .. }
|
||||
Location::RangePair {
|
||||
ln_second: (_, ln_end),
|
||||
..
|
||||
}
|
||||
| Location::Range { ln_end, .. }
|
||||
| Location::LineRange(_, ln_end) => Some(ln_end),
|
||||
Location::Line(lineno) => Some(lineno),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue