|
1 | 1 | use std::{collections::HashSet, sync::Arc, vec}; |
2 | 2 |
|
3 | 3 | 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, |
8 | 7 | }; |
9 | 8 |
|
10 | 9 | use crate::handlers::hover::{ |
@@ -289,77 +288,69 @@ fn hover_doc_function_type( |
289 | 288 | _ => "", |
290 | 289 | }; |
291 | 290 | 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 | + |
293 | 297 | // 有可能来源于类. 例如: `local add = class.add`, `add()`应被视为类方法 |
294 | 298 | 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 | + |
296 | 316 | let parent_owner = db |
297 | 317 | .get_member_index() |
298 | 318 | .get_current_owner(&owner_member.get_id()); |
299 | 319 | if let Some(parent_owner) = parent_owner { |
300 | 320 | match parent_owner { |
301 | 321 | 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()); |
323 | 325 | } |
324 | 326 | LuaMemberOwner::Element(element_id) => { |
325 | 327 | if let Some(LuaType::Ref(type_decl_id) | LuaType::Def(type_decl_id)) = |
326 | 328 | extract_parent_type_from_element(builder.semantic_model, element_id) |
327 | 329 | { |
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(), |
335 | 333 | ); |
336 | | - if is_method { |
337 | | - type_label = "(method) "; |
338 | | - name.push(':'); |
339 | | - } else { |
340 | | - name.push('.'); |
341 | | - } |
342 | 334 | } else if let Some(owner_name) = |
343 | 335 | extract_owner_name_from_element(builder.semantic_model, element_id) |
344 | 336 | { |
345 | 337 | name.push_str(&owner_name); |
346 | | - name.push('.'); |
| 338 | + if is_method { |
| 339 | + type_label = "(method) "; |
| 340 | + } |
| 341 | + name.push(if is_method { ':' } else { '.' }); |
347 | 342 | } |
348 | 343 | } |
349 | 344 | _ => {} |
350 | 345 | } |
351 | 346 | } |
352 | 347 |
|
353 | | - if let LuaMemberKey::Name(n) = owner_member.get_key() { |
354 | | - name.push_str(n.as_str()); |
355 | | - } |
| 348 | + name.push_str(&member_key); |
356 | 349 | name |
357 | 350 | } else { |
358 | | - if is_local { |
359 | | - type_label = "local function "; |
360 | | - } |
361 | 351 | func_name.to_string() |
362 | 352 | }; |
| 353 | + |
363 | 354 | let params = func |
364 | 355 | .get_params() |
365 | 356 | .iter() |
|
0 commit comments