Skip to content

Commit 14f72d7

Browse files
committed
fix(hover): table const method
1 parent 82506ae commit 14f72d7

File tree

2 files changed

+58
-47
lines changed

2 files changed

+58
-47
lines changed

crates/emmylua_ls/src/handlers/hover/function/mod.rs

Lines changed: 38 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use std::{collections::HashSet, sync::Arc, vec};
22

33
use emmylua_code_analysis::{
4-
AsyncState, DbIndex, InferGuard, LuaDocReturnInfo, LuaFunctionType, LuaMember, LuaMemberKey,
5-
LuaMemberOwner, LuaSemanticDeclId, LuaType, RenderLevel, TypeSubstitutor, VariadicType,
6-
humanize_type, infer_call_expr_func, instantiate_doc_function,
7-
try_extract_signature_id_from_field,
4+
AsyncState, DbIndex, InferGuard, LuaDocReturnInfo, LuaFunctionType, LuaMember, LuaMemberOwner,
5+
LuaSemanticDeclId, LuaType, RenderLevel, TypeSubstitutor, VariadicType, humanize_type,
6+
infer_call_expr_func, instantiate_doc_function, try_extract_signature_id_from_field,
87
};
98

109
use crate::handlers::hover::{
@@ -289,77 +288,69 @@ fn hover_doc_function_type(
289288
_ => "",
290289
};
291290
let mut is_method = func.is_colon_define();
292-
let mut type_label = "function ";
291+
let mut type_label = if is_local && owner_member.is_none() {
292+
"local function "
293+
} else {
294+
"function "
295+
};
296+
293297
// 有可能来源于类. 例如: `local add = class.add`, `add()`应被视为类方法
294298
let full_name = if let Some(owner_member) = owner_member {
295-
let mut name = String::new();
299+
if is_field {
300+
type_label = "(field) ";
301+
}
302+
303+
let member_key = owner_member.get_key().to_path();
304+
let mut name = String::with_capacity(member_key.len() + 16);
305+
306+
let mut push_typed_owner_prefix = |prefix: &str, type_decl_id| {
307+
name.push_str(prefix);
308+
let owner_ty = LuaType::Ref(type_decl_id);
309+
is_method = func.is_method(builder.semantic_model, Some(&owner_ty));
310+
if is_method {
311+
type_label = "(method) ";
312+
}
313+
name.push(if is_method { ':' } else { '.' });
314+
};
315+
296316
let parent_owner = db
297317
.get_member_index()
298318
.get_current_owner(&owner_member.get_id());
299319
if let Some(parent_owner) = parent_owner {
300320
match parent_owner {
301321
LuaMemberOwner::Type(type_decl_id) => {
302-
let global_name =
303-
infer_prefix_global_name(builder.semantic_model, owner_member);
304-
// 如果是全局定义, 则使用定义时的名称
305-
if let Some(global_name) = global_name {
306-
name.push_str(global_name);
307-
} else {
308-
name.push_str(type_decl_id.get_simple_name());
309-
}
310-
if is_field {
311-
type_label = "(field) ";
312-
}
313-
is_method = func.is_method(
314-
builder.semantic_model,
315-
Some(&LuaType::Ref(type_decl_id.clone())),
316-
);
317-
if is_method {
318-
type_label = "(method) ";
319-
name.push(':');
320-
} else {
321-
name.push('.');
322-
}
322+
let prefix = infer_prefix_global_name(builder.semantic_model, owner_member)
323+
.unwrap_or_else(|| type_decl_id.get_simple_name());
324+
push_typed_owner_prefix(prefix, type_decl_id.clone());
323325
}
324326
LuaMemberOwner::Element(element_id) => {
325327
if let Some(LuaType::Ref(type_decl_id) | LuaType::Def(type_decl_id)) =
326328
extract_parent_type_from_element(builder.semantic_model, element_id)
327329
{
328-
name.push_str(type_decl_id.get_simple_name());
329-
if is_field {
330-
type_label = "(field) ";
331-
}
332-
is_method = func.is_method(
333-
builder.semantic_model,
334-
Some(&LuaType::Ref(type_decl_id.clone())),
330+
push_typed_owner_prefix(
331+
type_decl_id.get_simple_name(),
332+
type_decl_id.clone(),
335333
);
336-
if is_method {
337-
type_label = "(method) ";
338-
name.push(':');
339-
} else {
340-
name.push('.');
341-
}
342334
} else if let Some(owner_name) =
343335
extract_owner_name_from_element(builder.semantic_model, element_id)
344336
{
345337
name.push_str(&owner_name);
346-
name.push('.');
338+
if is_method {
339+
type_label = "(method) ";
340+
}
341+
name.push(if is_method { ':' } else { '.' });
347342
}
348343
}
349344
_ => {}
350345
}
351346
}
352347

353-
if let LuaMemberKey::Name(n) = owner_member.get_key() {
354-
name.push_str(n.as_str());
355-
}
348+
name.push_str(&member_key);
356349
name
357350
} else {
358-
if is_local {
359-
type_label = "local function ";
360-
}
361351
func_name.to_string()
362352
};
353+
363354
let params = func
364355
.get_params()
365356
.iter()

crates/emmylua_ls/src/handlers/test/hover_function_test.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,4 +667,24 @@ mod tests {
667667
));
668668
Ok(())
669669
}
670+
671+
#[gtest]
672+
fn test_table_const_method() -> Result<()> {
673+
let mut ws = ProviderVirtualWorkspace::new();
674+
check!(ws.check_hover(
675+
r#"
676+
local M = {}
677+
678+
---@param x number
679+
function M:abc<??>d(x)
680+
end
681+
682+
M:abcd(1)
683+
"#,
684+
VirtualHoverResult {
685+
value: "```lua\n(method) M:abcd(x: number)\n```".to_string(),
686+
},
687+
));
688+
Ok(())
689+
}
670690
}

0 commit comments

Comments
 (0)