diff --git a/crates/emmylua_code_analysis/src/db_index/signature/signature.rs b/crates/emmylua_code_analysis/src/db_index/signature/signature.rs index 0315e6afb..4371acc47 100644 --- a/crates/emmylua_code_analysis/src/db_index/signature/signature.rs +++ b/crates/emmylua_code_analysis/src/db_index/signature/signature.rs @@ -11,7 +11,7 @@ use crate::{ FileId, db_index::{LuaFunctionType, LuaType}, }; -use crate::{SemanticModel, VariadicType}; +use crate::{SemanticModel, VariadicType, first_param_may_not_self}; #[derive(Debug)] pub struct LuaSignature { @@ -137,11 +137,8 @@ impl LuaSignature { match owner_type { Some(owner_type) => { // 一些类型不应该被视为 method - if let (LuaType::Ref(_) | LuaType::Def(_), _) = (owner_type, param_type) - && (param_type.is_any() - || param_type.is_table() - || param_type.is_class_tpl() - || param_type.is_str_tpl_ref()) + if matches!(owner_type, LuaType::Ref(_) | LuaType::Def(_)) + && first_param_may_not_self(param_type) { return false; } diff --git a/crates/emmylua_code_analysis/src/db_index/type/mod.rs b/crates/emmylua_code_analysis/src/db_index/type/mod.rs index dd1694dda..0dbea4606 100644 --- a/crates/emmylua_code_analysis/src/db_index/type/mod.rs +++ b/crates/emmylua_code_analysis/src/db_index/type/mod.rs @@ -301,3 +301,15 @@ fn get_real_type_with_depth<'a>( _ => Some(typ), } } + +// 第一个参数是否不应该视为 self +pub fn first_param_may_not_self(typ: &LuaType) -> bool { + if typ.is_table() || matches!(typ, LuaType::Ref(_) | LuaType::Def(_) | LuaType::Any) { + return false; + } + if let LuaType::Union(u) = typ { + return u.into_vec().iter().any(first_param_may_not_self); + } + + true +} diff --git a/crates/emmylua_code_analysis/src/db_index/type/types.rs b/crates/emmylua_code_analysis/src/db_index/type/types.rs index c41b3542f..8fc5621a5 100644 --- a/crates/emmylua_code_analysis/src/db_index/type/types.rs +++ b/crates/emmylua_code_analysis/src/db_index/type/types.rs @@ -12,6 +12,7 @@ use smol_str::SmolStr; use crate::{ AsyncState, DbIndex, FileId, InFiled, SemanticModel, db_index::{LuaMemberKey, LuaSignatureId, r#type::type_visit_trait::TypeVisitTrait}, + first_param_may_not_self, }; use super::{TypeOps, type_decl::LuaTypeDeclId}; @@ -686,11 +687,8 @@ impl LuaFunctionType { match owner_type { Some(owner_type) => { // 一些类型不应该被视为 method - if let (LuaType::Ref(_) | LuaType::Def(_), _) = (owner_type, t) - && (t.is_any() - || t.is_table() - || t.is_class_tpl() - || t.is_str_tpl_ref()) + if matches!(owner_type, LuaType::Ref(_) | LuaType::Def(_)) + && first_param_may_not_self(t) { return false; } diff --git a/crates/emmylua_ls/src/handlers/hover/function/mod.rs b/crates/emmylua_ls/src/handlers/hover/function/mod.rs index 4f29d01ea..61095a6db 100644 --- a/crates/emmylua_ls/src/handlers/hover/function/mod.rs +++ b/crates/emmylua_ls/src/handlers/hover/function/mod.rs @@ -361,7 +361,11 @@ fn hover_doc_function_type( if index == 0 && is_method && !func.is_colon_define() { "".to_string() } else if let Some(ty) = ¶m.1 { - format!("{}: {}", name, humanize_type(db, ty, RenderLevel::Normal)) + format!( + "{}: {}", + name, + humanize_type(db, ty, builder.detail_render_level) + ) } else { name.to_string() } diff --git a/crates/emmylua_ls/src/handlers/test/hover_function_test.rs b/crates/emmylua_ls/src/handlers/test/hover_function_test.rs index 9445ebae8..93b084b06 100644 --- a/crates/emmylua_ls/src/handlers/test/hover_function_test.rs +++ b/crates/emmylua_ls/src/handlers/test/hover_function_test.rs @@ -564,4 +564,24 @@ mod tests { )); Ok(()) } + + #[gtest] + fn test_fix_method_1() -> Result<()> { + let mut ws = ProviderVirtualWorkspace::new(); + check!(ws.check_hover( + r#" + ---@class ClassControl + local ClassControl = {} + + ---@generic T + ---@param name `T`|T + function ClassControl.new(name) + end + "#, + VirtualHoverResult { + value: "```lua\nfunction ClassControl.new(name: T)\n```".to_string(), + }, + )); + Ok(()) + } }