Add rec_get_singular_ctx

This commit is contained in:
Shunsuke Shibayama 2022-08-31 11:53:53 +09:00
parent af08945798
commit a71704329c
2 changed files with 61 additions and 0 deletions

View file

@ -284,6 +284,22 @@ impl Context {
return Ok(vi.t()); return Ok(vi.t());
} }
} }
if let Some(ctx) = self.rec_get_singular_ctx(obj) {
if let Some(vi) = ctx.locals.get(method_name.inspect()) {
return Ok(vi.t());
} else if let Some(vi) = ctx.decls.get(method_name.inspect()) {
return Ok(vi.t());
}
return Err(TyCheckError::singular_no_attr_error(
line!() as usize,
method_name.loc(),
namespace.clone(),
obj.__name__().unwrap_or("?"),
obj.ref_t(),
method_name.inspect(),
self.get_similar_attr(obj.ref_t(), method_name.inspect()),
));
}
// TODO: patch // TODO: patch
Err(TyCheckError::no_attr_error( Err(TyCheckError::no_attr_error(
line!() as usize, line!() as usize,
@ -993,6 +1009,15 @@ impl Context {
} }
} }
fn rec_get_singular_ctx(&self, obj: &hir::Expr) -> Option<&Context> {
match obj.ref_t() {
Type::Module => self.rec_get_mod(obj.__name__()?),
Type::Class => todo!(),
Type::Trait => todo!(),
_ => None,
}
}
pub(crate) fn rec_get_trait_impls(&self, name: &Str) -> Vec<TraitInstance> { pub(crate) fn rec_get_trait_impls(&self, name: &Str) -> Vec<TraitInstance> {
let current = if let Some(impls) = self.trait_impls.get(name) { let current = if let Some(impls) = self.trait_impls.get(name) {
impls.clone() impls.clone()

View file

@ -442,6 +442,42 @@ impl TyCheckError {
) )
} }
pub fn singular_no_attr_error(
errno: usize,
loc: Location,
caused_by: Str,
obj_name: &str,
obj_t: &Type,
name: &str,
similar_name: Option<&Str>,
) -> Self {
let hint = similar_name.map(|n| {
let n = readable_name(n);
switch_lang!(
"japanese" => format!("似た名前の属性があります: {n}"),
"simplified_chinese" => format!("具有相同名称的属性:{n}"),
"traditional_chinese" => format!("具有相同名稱的屬性:{n}"),
"english" => format!("has a similar name attribute: {n}"),
)
.into()
});
Self::new(
ErrorCore::new(
errno,
AttributeError,
loc,
switch_lang!(
"japanese" => format!("{obj_name}(: {obj_t})に{RED}{name}{RESET}という属性はありません"),
"simplified_chinese" => format!("{obj_name}(: {obj_t})没有属性{RED}{name}{RESET}"),
"traditional_chinese" => format!("{obj_name}(: {obj_t})沒有屬性{RED}{name}{RESET}"),
"english" => format!("{obj_name}(: {obj_t}) has no attribute {RED}{name}{RESET}"),
),
hint,
),
caused_by,
)
}
pub fn callable_impl_error<'a, C: Locational + Display>( pub fn callable_impl_error<'a, C: Locational + Display>(
errno: usize, errno: usize,
callee: &C, callee: &C,