Skip to content

Commit 2765312

Browse files
committed
hover: union function 优化
1 parent f49d1e5 commit 2765312

File tree

3 files changed

+109
-42
lines changed

3 files changed

+109
-42
lines changed

crates/emmylua_ls/src/handlers/hover/build_hover.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ fn is_function(typ: &LuaType) -> bool {
483483
LuaType::Union(union) => union
484484
.get_types()
485485
.iter()
486-
.all(|t| matches!(t, LuaType::DocFunction(_))),
486+
.all(|t| matches!(t, LuaType::DocFunction(_) | LuaType::Signature(_))),
487487
_ => false,
488488
}
489489
}

crates/emmylua_ls/src/handlers/hover/hover_humanize.rs

Lines changed: 70 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -41,51 +41,81 @@ pub fn hover_function_type(
4141
function_member,
4242
func_name,
4343
)),
44-
LuaType::Signature(signature_id) => hover_signature_type(
44+
LuaType::Signature(signature_id) => {
45+
let type_description = hover_signature_type(
46+
builder,
47+
db,
48+
signature_id.clone(),
49+
function_member,
50+
func_name,
51+
is_local,
52+
)
53+
.unwrap_or_else(|| {
54+
builder.signature_overload = None;
55+
format!("function {}", func_name)
56+
});
57+
builder.set_type_description(type_description);
58+
},
59+
LuaType::Union(union) => {
60+
hover_union_function_type(builder, db, union, function_member, func_name)
61+
}
62+
_ => builder.set_type_description(format!("function {}", func_name)),
63+
}
64+
}
65+
66+
fn hover_union_function_type(
67+
builder: &mut HoverBuilder,
68+
db: &DbIndex,
69+
union: &LuaUnionType,
70+
function_member: Option<&LuaMember>,
71+
func_name: &str,
72+
) {
73+
// 泛型处理
74+
if let Some(call) = builder.get_call_signature() {
75+
builder.set_type_description(hover_doc_function_type(
4576
builder,
4677
db,
47-
signature_id.clone(),
78+
&call,
4879
function_member,
4980
func_name,
50-
is_local,
51-
)
52-
.unwrap_or_else(|| {
53-
builder.set_type_description(format!("function {}", func_name));
54-
builder.signature_overload = None;
55-
}),
56-
LuaType::Union(union) => {
57-
// 泛型处理
58-
if let Some(call) = builder.get_call_signature() {
59-
builder.set_type_description(hover_doc_function_type(
81+
));
82+
return;
83+
}
84+
let mut overloads = Vec::new();
85+
86+
let types = union.get_types();
87+
for typ in types {
88+
match typ {
89+
LuaType::DocFunction(lua_func) => {
90+
overloads.push(hover_doc_function_type(
6091
builder,
6192
db,
62-
&call,
93+
&lua_func,
6394
function_member,
6495
func_name,
65-
))
66-
} else {
67-
// 将最后一个作为 type_description
68-
let mut overloads = Vec::new();
69-
for typ in union.get_types() {
70-
if let LuaType::DocFunction(lua_func) = typ {
71-
overloads.push(hover_doc_function_type(
72-
builder,
73-
db,
74-
&lua_func,
75-
function_member,
76-
func_name,
77-
));
78-
}
79-
}
80-
if let Some(signature) = overloads.pop() {
81-
builder.set_type_description(signature);
82-
for overload in overloads {
83-
builder.add_signature_overload(overload);
84-
}
96+
));
97+
}
98+
LuaType::Signature(signature_id) => {
99+
if let Some(type_description) = hover_signature_type(
100+
builder,
101+
db,
102+
signature_id.clone(),
103+
function_member,
104+
func_name,
105+
false,
106+
) {
107+
overloads.push(type_description);
85108
}
86109
}
110+
_ => {}
111+
}
112+
}
113+
// 将最后一个作为 type_description
114+
if let Some(type_description) = overloads.pop() {
115+
builder.set_type_description(type_description);
116+
for overload in overloads {
117+
builder.add_signature_overload(overload);
87118
}
88-
_ => builder.set_type_description(format!("function {}", func_name)),
89119
}
90120
}
91121

@@ -167,7 +197,7 @@ fn hover_signature_type(
167197
owner_member: Option<&LuaMember>,
168198
func_name: &str,
169199
is_local: bool,
170-
) -> Option<()> {
200+
) -> Option<String> {
171201
let signature = db.get_signature_index().get(&signature_id)?;
172202
let call_signature = builder.get_call_signature();
173203

@@ -235,9 +265,8 @@ fn hover_signature_type(
235265
if let Some(call_signature) = &call_signature {
236266
if call_signature.get_params() == signature.get_type_params() {
237267
// 如果具有完全匹配的签名, 那么将其设置为当前签名, 且不显示重载
238-
builder.set_type_description(result);
239268
builder.signature_overload = None;
240-
return Some(());
269+
return Some(result);
241270
}
242271
}
243272
result
@@ -273,21 +302,21 @@ fn hover_signature_type(
273302
if let Some(call_signature) = &call_signature {
274303
if *call_signature == **overload {
275304
// 如果具有完全匹配的签名, 那么将其设置为当前签名, 且不显示重载
276-
builder.set_type_description(result);
277305
builder.signature_overload = None;
278-
return Some(());
306+
return Some(result);
279307
}
280308
};
281309
overloads.push(result);
282310
}
283311
overloads
284312
};
285313

286-
builder.set_type_description(signature_info);
314+
// 设置重载信息
287315
for overload in overloads {
288316
builder.add_signature_overload(overload);
289317
}
290-
Some(())
318+
319+
Some(signature_info)
291320
}
292321

293322
fn build_signature_rets(

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

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,42 @@ mod tests {
125125
},
126126
));
127127
}
128+
129+
#[test]
130+
fn test_union_function() {
131+
let mut ws = HoverVirtualWorkspace::new();
132+
assert!(ws.check_hover(
133+
r#"
134+
---@diagnostic disable: missing-return
135+
---@class Trigger
136+
---@class EventTypeA
137+
138+
---@class (partial) GameA
139+
local M
140+
141+
-- 注册引擎事件
142+
---@param event_type EventTypeA
143+
---@param ... any
144+
---@return Trigger
145+
function M:<??>event(event_type, ...)
146+
end
147+
148+
---@class (partial) GameA
149+
---@field event fun(self: self, event: "游戏-初始化"): Trigger
150+
---@field event fun(self: self, event: "游戏-追帧完成"): Trigger
151+
---@field event fun(self: self, event: "游戏-逻辑不同步"): Trigger
152+
---@field event fun(self: self, event: "游戏-地形预设加载完成"): Trigger
153+
---@field event fun(self: self, event: "游戏-结束"): Trigger
154+
---@field event fun(self: self, event: "游戏-暂停"): Trigger
155+
---@field event fun(self: self, event: "游戏-恢复"): Trigger
156+
---@field event fun(self: self, event: "游戏-昼夜变化"): Trigger
157+
---@field event fun(self: self, event: "区域-进入"): Trigger
158+
---@field event fun(self: self, event: "区域-离开"): Trigger
159+
---@field event fun(self: self, event: "游戏-http返回"): Trigger
160+
"#,
161+
VirtualHoverResult {
162+
value: "\n```lua\n(method) GameA:event(event_type: EventTypeA, ...: any)\n -> Trigger\n\n```\n\n---\n\n---\n\n```lua\n(method) GameA:event(event: \"游戏-初始化\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"游戏-追帧完成\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"游戏-逻辑不同步\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"游戏-地形预设加载完成\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"游戏-结束\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"游戏-暂停\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"游戏-恢复\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"游戏-昼夜变化\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"区域-进入\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"区域-离开\") -> Trigger\n```\n\n```lua\n(method) GameA:event(event: \"游戏-http返回\") -> Trigger\n```\n".to_string(),
163+
},
164+
));
165+
}
128166
}

0 commit comments

Comments
 (0)