Skip to content

Commit 7aa70dc

Browse files
committed
hover: union function 优化
1 parent 512c750 commit 7aa70dc

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

@@ -172,7 +202,7 @@ fn hover_signature_type(
172202
owner_member: Option<&LuaMember>,
173203
func_name: &str,
174204
is_local: bool,
175-
) -> Option<()> {
205+
) -> Option<String> {
176206
let signature = db.get_signature_index().get(&signature_id)?;
177207
let call_signature = builder.get_call_signature();
178208

@@ -240,9 +270,8 @@ fn hover_signature_type(
240270
if let Some(call_signature) = &call_signature {
241271
if call_signature.get_params() == signature.get_type_params() {
242272
// 如果具有完全匹配的签名, 那么将其设置为当前签名, 且不显示重载
243-
builder.set_type_description(result);
244273
builder.signature_overload = None;
245-
return Some(());
274+
return Some(result);
246275
}
247276
}
248277
result
@@ -278,21 +307,21 @@ fn hover_signature_type(
278307
if let Some(call_signature) = &call_signature {
279308
if *call_signature == **overload {
280309
// 如果具有完全匹配的签名, 那么将其设置为当前签名, 且不显示重载
281-
builder.set_type_description(result);
282310
builder.signature_overload = None;
283-
return Some(());
311+
return Some(result);
284312
}
285313
};
286314
overloads.push(result);
287315
}
288316
overloads
289317
};
290318

291-
builder.set_type_description(signature_info);
319+
// 设置重载信息
292320
for overload in overloads {
293321
builder.add_signature_overload(overload);
294322
}
295-
Some(())
323+
324+
Some(signature_info)
296325
}
297326

298327
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)