Skip to content

Commit

Permalink
chore: improve no-attr error hint
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed Oct 15, 2024
1 parent f23fdbe commit 32528cd
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 14 deletions.
49 changes: 45 additions & 4 deletions crates/erg_compiler/context/inquire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use std::path::{Path, PathBuf};
use erg_common::consts::{DEBUG_MODE, ERG_MODE, PYTHON_MODE};
use erg_common::error::{ErrorCore, Location, SubMessage};
use erg_common::io::Input;
use erg_common::levenshtein;
use erg_common::pathutil::NormalizedPathBuf;
use erg_common::set::Set;
use erg_common::traits::{Locational, NoTypeDisplay, Stream};
Expand All @@ -14,6 +13,7 @@ use erg_common::Str;
use erg_common::{
dict, fmt_option, fmt_slice, get_hash, log, option_enum_unwrap, set, switch_lang,
};
use erg_common::{fmt_vec, levenshtein};

use erg_parser::ast::{self, Identifier, VarName};
use erg_parser::token::Token;
Expand Down Expand Up @@ -1292,6 +1292,31 @@ impl Context {
}
}

pub(crate) fn get_no_attr_hint(&self, self_t: &Type, attr: &str) -> Option<String> {
self.get_similar_attr(self_t, attr).map(|n| {
switch_lang!(
"japanese" => format!("似た名前の属性があります: {n}"),
"simplified_chinese" => format!("具有相同名称的属性: {n}"),
"traditional_chinese" => format!("具有相同名稱的屬性: {n}"),
"english" => format!("has a similar name attribute: {n}"),
)
}).or_else(|| {
let unions = self_t.union_types()?;
let mismatches = unions.iter().filter(|t| {
!self.exists_attr(t, attr)
}).collect::<Vec<_>>();
if !mismatches.is_empty() && unions.len() != mismatches.len() {
return Some(switch_lang!(
"japanese" => format!("{}型でないことを確かめる必要があります", fmt_vec(&mismatches)),
"simplified_chinese" => format!("需要确认不是{}类型", fmt_vec(&mismatches)),
"traditional_chinese" => format!("需要確認不是{}類型", fmt_vec(&mismatches)),
"english" => format!("You need to confirm that the receiver is not type of {}", fmt_vec(&mismatches)),
));
}
None
})
}

// Note that the method may be static.
fn search_method_info(
&self,
Expand Down Expand Up @@ -1525,7 +1550,7 @@ impl Context {
namespace.name.to_string(),
obj.ref_t(),
attr_name.inspect(),
self.get_similar_attr(obj.ref_t(), attr_name.inspect()),
self.get_no_attr_hint(obj.ref_t(), attr_name.inspect()),
))
}

Expand Down Expand Up @@ -1661,7 +1686,7 @@ impl Context {
namespace.name.to_string(),
obj.ref_t(),
attr_name.inspect(),
self.get_similar_attr(obj.ref_t(), attr_name.inspect()),
self.get_no_attr_hint(obj.ref_t(), attr_name.inspect()),
))
}

Expand Down Expand Up @@ -2852,7 +2877,7 @@ impl Context {
namespace.into(),
self_t,
name.inspect(),
self.get_similar_attr(self_t, name.inspect()),
self.get_no_attr_hint(self_t, name.inspect()),
))
}
}
Expand All @@ -2864,6 +2889,10 @@ impl Context {
)
}

pub(crate) fn exists_name(&self, name: &str) -> bool {
self.dir().iter().any(|(vn, _)| vn.inspect() == name)
}

pub(crate) fn get_similar_name_and_info(&self, name: &str) -> Option<(&VarInfo, &str)> {
levenshtein::get_similar_name_and_some(
self.dir()
Expand Down Expand Up @@ -2897,6 +2926,18 @@ impl Context {
None
}

pub(crate) fn exists_attr<'a>(&'a self, self_t: &'a Type, name: &str) -> bool {
let Some(ctxs) = self.get_nominal_super_type_ctxs(self_t) else {
return false;
};
for ctx in ctxs {
if ctx.exists_name(name) {
return true;
}
}
false
}

pub(crate) fn get_similar_attr_and_info<'a>(
&'a self,
self_t: &'a Type,
Expand Down
2 changes: 1 addition & 1 deletion crates/erg_compiler/context/unify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1748,7 +1748,7 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
self.ctx.caused_by(),
sub,
&sup_field.symbol,
self.ctx.get_similar_attr(sub, &sup_field.symbol),
self.ctx.get_no_attr_hint(sub, &sup_field.symbol),
)));
}
}
Expand Down
10 changes: 1 addition & 9 deletions crates/erg_compiler/error/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -507,16 +507,8 @@ impl LowerError {
caused_by: String,
obj_t: &Type,
name: &str,
similar_name: Option<&str>,
hint: Option<String>,
) -> Self {
let hint = similar_name.map(|n| {
switch_lang!(
"japanese" => format!("似た名前の属性があります: {n}"),
"simplified_chinese" => format!("具有相同名称的属性: {n}"),
"traditional_chinese" => format!("具有相同名稱的屬性: {n}"),
"english" => format!("has a similar name attribute: {n}"),
)
});
let found = StyledString::new(name, Some(ERR), Some(ATTR));
Self::new(
ErrorCore::new(
Expand Down

0 comments on commit 32528cd

Please sign in to comment.