mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 04:44:44 +00:00
Merge pull request #232 from erg-lang/split-err-msg
Split error messages
This commit is contained in:
commit
2caa6b6ec9
15 changed files with 1652 additions and 1006 deletions
|
@ -4,8 +4,10 @@
|
|||
use std::fmt;
|
||||
|
||||
use erg_common::config::Input;
|
||||
use erg_common::error::{ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay};
|
||||
use erg_common::style::{Attribute, Color, StyledStr, StyledString, Theme};
|
||||
use erg_common::error::{
|
||||
ErrorCore, ErrorDisplay, ErrorKind::*, Location, MultiErrorDisplay, SubMessage,
|
||||
};
|
||||
use erg_common::style::{Attribute, Color, StyledStr, StyledString, THEME};
|
||||
use erg_common::traits::Stream;
|
||||
use erg_common::{impl_display_and_error, impl_stream_for_wrapper, switch_lang};
|
||||
|
||||
|
@ -29,62 +31,68 @@ pub struct LexErrors(Vec<LexError>);
|
|||
|
||||
impl_stream_for_wrapper!(LexErrors, LexError);
|
||||
|
||||
const ERR: Color = THEME.colors.error;
|
||||
const HINT: Color = THEME.colors.hint;
|
||||
const ACCENT: Color = THEME.colors.accent;
|
||||
|
||||
impl LexError {
|
||||
pub fn new(core: ErrorCore) -> Self {
|
||||
Self(Box::new(core))
|
||||
}
|
||||
|
||||
pub fn set_hint<S: Into<String>>(&mut self, hint: S) {
|
||||
self.0.hint = Some(hint.into());
|
||||
if let Some(sub_msg) = self.0.sub_messages.get_mut(0) {
|
||||
sub_msg.set_hint(hint)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compiler_bug(errno: usize, loc: Location, fn_name: &str, line: u32) -> Self {
|
||||
const URL: StyledStr = StyledStr::new(
|
||||
"https://github.com/erg-lang/erg",
|
||||
Some(Color::White),
|
||||
Some(ACCENT),
|
||||
Some(Attribute::Underline),
|
||||
);
|
||||
Self::new(ErrorCore::new(
|
||||
errno,
|
||||
CompilerSystemError,
|
||||
loc,
|
||||
vec![SubMessage::only_loc(loc)],
|
||||
switch_lang!(
|
||||
"japanese" => format!("これはErg compilerのバグです、開発者に報告して下さい ({URL})\n{fn_name}:{line}より発生"),
|
||||
"simplified_chinese" => format!("这是Erg编译器的一个错误,请报告给{URL}\n原因来自: {fn_name}:{line}"),
|
||||
"traditional_chinese" => format!("這是Erg編譯器的一個錯誤,請報告給{URL}\n原因來自: {fn_name}:{line}"),
|
||||
"english" => format!("this is a bug of the Erg compiler, please report it to {URL}\ncaused from: {fn_name}:{line}"),
|
||||
),
|
||||
None,
|
||||
errno,
|
||||
CompilerSystemError,
|
||||
loc,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn feature_error(errno: usize, loc: Location, name: &str) -> Self {
|
||||
Self::new(ErrorCore::new(
|
||||
errno,
|
||||
FeatureError,
|
||||
loc,
|
||||
vec![SubMessage::only_loc(loc)],
|
||||
switch_lang!(
|
||||
"japanese" => format!("この機能({name})はまだ正式に提供されていません"),
|
||||
"simplified_chinese" => format!("此功能({name})尚未实现"),
|
||||
"traditional_chinese" => format!("此功能({name})尚未實現"),
|
||||
"english" => format!("this feature({name}) is not implemented yet"),
|
||||
),
|
||||
None,
|
||||
errno,
|
||||
FeatureError,
|
||||
loc,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn simple_syntax_error(errno: usize, loc: Location) -> Self {
|
||||
Self::new(ErrorCore::new(
|
||||
errno,
|
||||
SyntaxError,
|
||||
loc,
|
||||
vec![SubMessage::only_loc(loc)],
|
||||
switch_lang!(
|
||||
"japanese" => "不正な構文です",
|
||||
"simplified_chinese" => "无效的语法",
|
||||
"traditional_chinese" => "無效的語法",
|
||||
"english" => "invalid syntax",
|
||||
),
|
||||
None,
|
||||
errno,
|
||||
SyntaxError,
|
||||
loc,
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -94,7 +102,13 @@ impl LexError {
|
|||
desc: S,
|
||||
hint: Option<String>,
|
||||
) -> Self {
|
||||
Self::new(ErrorCore::new(errno, SyntaxError, loc, desc, hint))
|
||||
Self::new(ErrorCore::new(
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
desc,
|
||||
errno,
|
||||
SyntaxError,
|
||||
loc,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn syntax_warning<S: Into<String>>(
|
||||
|
@ -103,7 +117,13 @@ impl LexError {
|
|||
desc: S,
|
||||
hint: Option<String>,
|
||||
) -> Self {
|
||||
Self::new(ErrorCore::new(errno, SyntaxWarning, loc, desc, hint))
|
||||
Self::new(ErrorCore::new(
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
desc,
|
||||
errno,
|
||||
SyntaxWarning,
|
||||
loc,
|
||||
))
|
||||
}
|
||||
|
||||
pub fn no_var_error(
|
||||
|
@ -113,6 +133,7 @@ impl LexError {
|
|||
similar_name: Option<String>,
|
||||
) -> Self {
|
||||
let hint = similar_name.map(|n| {
|
||||
let n = StyledString::new(&n, Some(HINT), Some(Attribute::Bold));
|
||||
switch_lang!(
|
||||
"japanese" => format!("似た名前の変数があります: {n}"),
|
||||
"simplified_chinese" => format!("存在相同名称变量: {n}"),
|
||||
|
@ -120,18 +141,18 @@ impl LexError {
|
|||
"english" => format!("exists a similar name variable: {n}"),
|
||||
)
|
||||
});
|
||||
let name = StyledString::new(name, Some(Color::Red), Some(Attribute::Underline));
|
||||
let name = StyledString::new(name, Some(ERR), Some(Attribute::Underline));
|
||||
Self::new(ErrorCore::new(
|
||||
errno,
|
||||
NameError,
|
||||
loc,
|
||||
vec![SubMessage::ambiguous_new(loc, vec![], hint)],
|
||||
switch_lang!(
|
||||
"japanese" => format!("{name}という変数は定義されていません"),
|
||||
"simplified_chinese" => format!("{name}未定义"),
|
||||
"traditional_chinese" => format!("{name}未定義"),
|
||||
"english" => format!("{name} is not defined"),
|
||||
),
|
||||
hint,
|
||||
errno,
|
||||
NameError,
|
||||
loc,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
@ -164,7 +185,6 @@ pub type DesugaringResult<T> = Result<T, DesugaringError>;
|
|||
pub struct ParserRunnerError {
|
||||
pub core: ErrorCore,
|
||||
pub input: Input,
|
||||
pub theme: Theme,
|
||||
}
|
||||
|
||||
impl_display_and_error!(ParserRunnerError);
|
||||
|
@ -176,9 +196,6 @@ impl ErrorDisplay for ParserRunnerError {
|
|||
fn input(&self) -> &Input {
|
||||
&self.input
|
||||
}
|
||||
fn theme(&self) -> &Theme {
|
||||
&self.theme
|
||||
}
|
||||
fn caused_by(&self) -> &str {
|
||||
""
|
||||
}
|
||||
|
@ -188,8 +205,8 @@ impl ErrorDisplay for ParserRunnerError {
|
|||
}
|
||||
|
||||
impl ParserRunnerError {
|
||||
pub const fn new(core: ErrorCore, input: Input, theme: Theme) -> Self {
|
||||
Self { core, input, theme }
|
||||
pub const fn new(core: ErrorCore, input: Input) -> Self {
|
||||
Self { core, input }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -209,10 +226,10 @@ impl fmt::Display for ParserRunnerErrors {
|
|||
}
|
||||
|
||||
impl ParserRunnerErrors {
|
||||
pub fn convert(input: &Input, errs: ParseErrors, theme: Theme) -> Self {
|
||||
pub fn convert(input: &Input, errs: ParseErrors) -> Self {
|
||||
Self(
|
||||
errs.into_iter()
|
||||
.map(|err| ParserRunnerError::new(*err.0, input.clone(), theme))
|
||||
.map(|err| ParserRunnerError::new(*err.0, input.clone()))
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue