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)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
pub enum Location {
|
pub enum Location {
|
||||||
RangePair {
|
RangePair {
|
||||||
ln_begin: usize,
|
ln_first: (usize, usize),
|
||||||
col_first: (usize, usize),
|
col_first: (usize, usize),
|
||||||
ln_end: usize,
|
ln_second: (usize, usize),
|
||||||
col_second: (usize, usize),
|
col_second: (usize, usize),
|
||||||
},
|
},
|
||||||
Range {
|
Range {
|
||||||
|
@ -240,16 +240,19 @@ impl Location {
|
||||||
|
|
||||||
pub fn pair(lhs: Self, rhs: Self) -> Self {
|
pub fn pair(lhs: Self, rhs: Self) -> Self {
|
||||||
Self::RangePair {
|
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()),
|
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()),
|
col_second: (rhs.col_begin().unwrap(), rhs.col_end().unwrap()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn ln_begin(&self) -> Option<usize> {
|
pub const fn ln_begin(&self) -> Option<usize> {
|
||||||
match self {
|
match self {
|
||||||
Self::RangePair { ln_begin, .. }
|
Self::RangePair {
|
||||||
|
ln_first: (ln_begin, _),
|
||||||
|
..
|
||||||
|
}
|
||||||
| Self::Range { ln_begin, .. }
|
| Self::Range { ln_begin, .. }
|
||||||
| Self::LineRange(ln_begin, _)
|
| Self::LineRange(ln_begin, _)
|
||||||
| Self::Line(ln_begin) => Some(*ln_begin),
|
| Self::Line(ln_begin) => Some(*ln_begin),
|
||||||
|
@ -259,7 +262,10 @@ impl Location {
|
||||||
|
|
||||||
pub const fn ln_end(&self) -> Option<usize> {
|
pub const fn ln_end(&self) -> Option<usize> {
|
||||||
match self {
|
match self {
|
||||||
Self::RangePair { ln_end, .. }
|
Self::RangePair {
|
||||||
|
ln_second: (_, ln_end),
|
||||||
|
..
|
||||||
|
}
|
||||||
| Self::Range { ln_end, .. }
|
| Self::Range { ln_end, .. }
|
||||||
| Self::LineRange(ln_end, _)
|
| Self::LineRange(ln_end, _)
|
||||||
| Self::Line(ln_end) => Some(*ln_end),
|
| Self::Line(ln_end) => Some(*ln_end),
|
||||||
|
@ -351,6 +357,41 @@ impl ErrorCore {
|
||||||
pub const VBAR_UNICODE: &str = "│";
|
pub const VBAR_UNICODE: &str = "│";
|
||||||
pub const VBAR_BREAK_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:
|
/// format:
|
||||||
/// ```console
|
/// ```console
|
||||||
/// Error[#{.errno}]: File {file}, line {.loc (as line)}, in {.caused_by}
|
/// Error[#{.errno}]: File {file}, line {.loc (as line)}, in {.caused_by}
|
||||||
|
@ -430,13 +471,15 @@ pub trait ErrorDisplay {
|
||||||
Location::Range {
|
Location::Range {
|
||||||
ln_begin, ln_end, ..
|
ln_begin, ln_end, ..
|
||||||
} if ln_begin == ln_end => format!(", line {ln_begin}"),
|
} if ln_begin == ln_end => format!(", line {ln_begin}"),
|
||||||
Location::RangePair {
|
Location::Range {
|
||||||
ln_begin, ln_end, ..
|
|
||||||
}
|
|
||||||
| Location::Range {
|
|
||||||
ln_begin, ln_end, ..
|
ln_begin, ln_end, ..
|
||||||
}
|
}
|
||||||
| Location::LineRange(ln_begin, ln_end) => format!(", line {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::Line(lineno) => format!(", line {lineno}"),
|
||||||
Location::Unknown => "".to_string(),
|
Location::Unknown => "".to_string(),
|
||||||
};
|
};
|
||||||
|
@ -454,40 +497,27 @@ pub trait ErrorDisplay {
|
||||||
|
|
||||||
fn format_code_and_pointer(&self) -> String {
|
fn format_code_and_pointer(&self) -> String {
|
||||||
match self.core().loc {
|
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 {
|
Location::Range {
|
||||||
ln_begin,
|
ln_begin,
|
||||||
col_begin,
|
col_begin,
|
||||||
ln_end,
|
ln_end,
|
||||||
col_end,
|
col_end,
|
||||||
} => {
|
} => format_code_and_pointer(self, ln_begin, ln_end, col_begin, 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
|
|
||||||
}
|
|
||||||
Location::LineRange(ln_begin, ln_end) => {
|
Location::LineRange(ln_begin, ln_end) => {
|
||||||
let codes = if self.input() == &Input::REPL {
|
let codes = if self.input() == &Input::REPL {
|
||||||
vec![self.input().reread()]
|
vec![self.input().reread()]
|
||||||
|
|
|
@ -407,7 +407,10 @@ pub trait Locational {
|
||||||
|
|
||||||
fn ln_begin(&self) -> Option<usize> {
|
fn ln_begin(&self) -> Option<usize> {
|
||||||
match self.loc() {
|
match self.loc() {
|
||||||
Location::RangePair { ln_begin, .. }
|
Location::RangePair {
|
||||||
|
ln_first: (ln_begin, _),
|
||||||
|
..
|
||||||
|
}
|
||||||
| Location::Range { ln_begin, .. }
|
| Location::Range { ln_begin, .. }
|
||||||
| Location::LineRange(ln_begin, _) => Some(ln_begin),
|
| Location::LineRange(ln_begin, _) => Some(ln_begin),
|
||||||
Location::Line(lineno) => Some(lineno),
|
Location::Line(lineno) => Some(lineno),
|
||||||
|
@ -417,7 +420,10 @@ pub trait Locational {
|
||||||
|
|
||||||
fn ln_end(&self) -> Option<usize> {
|
fn ln_end(&self) -> Option<usize> {
|
||||||
match self.loc() {
|
match self.loc() {
|
||||||
Location::RangePair { ln_end, .. }
|
Location::RangePair {
|
||||||
|
ln_second: (_, ln_end),
|
||||||
|
..
|
||||||
|
}
|
||||||
| Location::Range { ln_end, .. }
|
| Location::Range { ln_end, .. }
|
||||||
| Location::LineRange(_, ln_end) => Some(ln_end),
|
| Location::LineRange(_, ln_end) => Some(ln_end),
|
||||||
Location::Line(lineno) => Some(lineno),
|
Location::Line(lineno) => Some(lineno),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue