Skip to content

Commit 4fcfc92

Browse files
committed
fix hover visible
1 parent 36008f2 commit 4fcfc92

5 files changed

Lines changed: 104 additions & 10 deletions

File tree

crates/emmylua_ls/src/handlers/completion/completion_data.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use super::completion_builder::CompletionBuilder;
77
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
88
pub struct CompletionData {
99
pub field_id: FileId,
10+
pub trigger_offset: Option<u32>,
1011
pub typ: CompletionDataType,
1112
/// Total count of function overloads
1213
pub overload_count: Option<usize>,
@@ -21,6 +22,7 @@ impl CompletionData {
2122
) -> Option<Value> {
2223
let data = Self {
2324
field_id: builder.semantic_model.get_file_id(),
25+
trigger_offset: Some(builder.position_offset.into()),
2426
typ: CompletionDataType::PropertyOwnerId(id),
2527
overload_count,
2628
};
@@ -35,6 +37,7 @@ impl CompletionData {
3537
) -> Option<Value> {
3638
let data = Self {
3739
field_id: builder.semantic_model.get_file_id(),
40+
trigger_offset: Some(builder.position_offset.into()),
3841
typ: CompletionDataType::Overload((id, index)),
3942
overload_count,
4043
};
@@ -44,6 +47,7 @@ impl CompletionData {
4447
pub fn from_module(builder: &CompletionBuilder, module: String) -> Option<Value> {
4548
let data = Self {
4649
field_id: builder.semantic_model.get_file_id(),
50+
trigger_offset: Some(builder.position_offset.into()),
4751
typ: CompletionDataType::Module(module),
4852
overload_count: None,
4953
};

crates/emmylua_ls/src/handlers/completion/providers/member_provider.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use emmylua_code_analysis::{
22
DbIndex, LuaMemberInfo, LuaMemberKey, LuaSemanticDeclId, LuaType, LuaTypeDeclId, SemanticModel,
33
enum_variable_is_param, get_tpl_ref_extend_type,
44
};
5-
use emmylua_parser::{LuaAstNode, LuaAstToken, LuaIndexExpr, LuaStringToken};
5+
use emmylua_parser::{LuaAstNode, LuaAstToken, LuaIndexExpr, LuaStringToken, LuaSyntaxToken};
66
use std::collections::HashMap;
77

88
use crate::handlers::completion::{
@@ -134,8 +134,11 @@ fn add_resolve_member_infos(
134134
return Some(());
135135
}
136136

137-
let (filtered_member_infos, overload_count) =
138-
filter_member_infos(&builder.semantic_model, member_infos)?;
137+
let (filtered_member_infos, overload_count) = filter_member_infos(
138+
&builder.semantic_model,
139+
&builder.trigger_token,
140+
member_infos,
141+
)?;
139142

140143
let resolve_state = get_resolve_state(builder.semantic_model.get_db(), &filtered_member_infos);
141144

@@ -182,20 +185,33 @@ fn add_resolve_member_infos(
182185
/// 过滤成员信息,返回需要的成员列表和重载数量
183186
fn filter_member_infos<'a>(
184187
semantic_model: &SemanticModel,
188+
trigger_token: &LuaSyntaxToken,
185189
member_infos: &'a Vec<LuaMemberInfo>,
186190
) -> Option<(Vec<&'a LuaMemberInfo>, Option<usize>)> {
187191
if member_infos.is_empty() {
188192
return None;
189193
}
190194

195+
let visible_member_infos: Vec<&LuaMemberInfo> = member_infos
196+
.iter()
197+
.filter(|member_info| {
198+
member_info.property_owner_id.as_ref().is_none_or(|id| {
199+
semantic_model.is_semantic_visible(trigger_token.clone(), id.clone())
200+
})
201+
})
202+
.collect();
203+
if visible_member_infos.is_empty() {
204+
return None;
205+
}
206+
191207
let mut file_decl_member: Option<&LuaMemberInfo> = None;
192208
let mut member_with_owners: Vec<(&LuaMemberInfo, Option<LuaTypeDeclId>)> =
193-
Vec::with_capacity(member_infos.len());
209+
Vec::with_capacity(visible_member_infos.len());
194210
let mut all_doc_function = true;
195211
let mut overload_count = 0;
196212

197213
// 一次遍历收集所有信息
198-
for member_info in member_infos {
214+
for member_info in visible_member_infos {
199215
let owner_id = get_owner_type_id(semantic_model.get_db(), member_info);
200216
member_with_owners.push((member_info, owner_id.clone()));
201217

crates/emmylua_ls/src/handlers/completion/resolve_completion.rs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use emmylua_code_analysis::{DbIndex, LuaCompilation, SemanticModel};
2+
use emmylua_parser::{LuaAstNode, LuaSyntaxToken};
23
use lsp_types::{CompletionItem, Documentation, MarkedString, MarkupContent};
4+
use rowan::{TextSize, TokenAtOffset};
35

46
use crate::{
57
context::ClientId,
@@ -16,11 +18,19 @@ pub fn resolve_completion(
1618
completion_data: CompletionData,
1719
client_id: ClientId,
1820
) -> Option<()> {
21+
let trigger_token =
22+
get_completion_trigger_token(semantic_model, completion_data.trigger_offset);
23+
1924
// todo: resolve completion
2025
match completion_data.typ {
2126
CompletionDataType::PropertyOwnerId(property_id) => {
22-
let hover_builder =
23-
build_hover_content_for_completion(compilation, semantic_model, db, property_id);
27+
let hover_builder = build_hover_content_for_completion(
28+
compilation,
29+
semantic_model,
30+
db,
31+
property_id,
32+
trigger_token.clone(),
33+
);
2434
if let Some(mut hover_builder) = hover_builder {
2535
update_function_signature_info(&mut hover_builder, completion_data.overload_count);
2636
if client_id.is_vscode() {
@@ -31,8 +41,13 @@ pub fn resolve_completion(
3141
}
3242
}
3343
CompletionDataType::Overload((property_id, index)) => {
34-
let hover_builder =
35-
build_hover_content_for_completion(compilation, semantic_model, db, property_id);
44+
let hover_builder = build_hover_content_for_completion(
45+
compilation,
46+
semantic_model,
47+
db,
48+
property_id,
49+
trigger_token.clone(),
50+
);
3651
if let Some(mut hover_builder) = hover_builder {
3752
update_function_signature_info(&mut hover_builder, completion_data.overload_count);
3853
if client_id.is_vscode() {
@@ -47,6 +62,23 @@ pub fn resolve_completion(
4762
Some(())
4863
}
4964

65+
fn get_completion_trigger_token(
66+
semantic_model: &SemanticModel,
67+
trigger_offset: Option<u32>,
68+
) -> Option<LuaSyntaxToken> {
69+
let offset = TextSize::from(trigger_offset?);
70+
let root = semantic_model.get_root();
71+
if offset > root.syntax().text_range().end() {
72+
return None;
73+
}
74+
75+
match root.syntax().token_at_offset(offset) {
76+
TokenAtOffset::Single(token) => Some(token),
77+
TokenAtOffset::Between(left, _) => Some(left),
78+
TokenAtOffset::None => None,
79+
}
80+
}
81+
5082
pub fn update_function_signature_info(
5183
hover_builder: &mut HoverBuilder,
5284
overload_count: Option<usize>,

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub fn build_hover_content_for_completion<'a>(
8080
semantic_model: &'a SemanticModel,
8181
db: &DbIndex,
8282
property_id: LuaSemanticDeclId,
83+
token: Option<LuaSyntaxToken>,
8384
) -> Option<HoverBuilder<'a>> {
8485
let typ = match property_id {
8586
LuaSemanticDeclId::LuaDecl(decl_id) => {
@@ -97,7 +98,7 @@ pub fn build_hover_content_for_completion<'a>(
9798
typ,
9899
property_id,
99100
true,
100-
None,
101+
token,
101102
)
102103
}
103104

@@ -230,6 +231,13 @@ fn build_member_hover(
230231
let mut semantic_decls =
231232
find_member_origin_owners(builder.compilation, builder.semantic_model, member_id, true)
232233
.get_types(builder.semantic_model);
234+
if let Some(token) = builder.get_trigger_token() {
235+
semantic_decls.retain(|(semantic_decl, _)| {
236+
builder
237+
.semantic_model
238+
.is_semantic_visible(token.clone(), semantic_decl.clone())
239+
});
240+
}
233241

234242
let member_name = match member.get_key() {
235243
LuaMemberKey::Name(name) => name.to_string(),

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,38 @@ mod tests {
123123
));
124124
Ok(())
125125
}
126+
127+
#[gtest]
128+
fn test_version_visibility() -> Result<()> {
129+
let mut ws = ProviderVirtualWorkspace::new();
130+
ws.def(
131+
r#"
132+
---@meta
133+
CO = {}
134+
135+
--- @version 5.1, JIT
136+
---
137+
--- 5.1/jit
138+
--- @return thread?
139+
--- @nodiscard
140+
function CO.running() end
141+
142+
--- @version > 5.2
143+
--- 5.2+
144+
--- @return thread, boolean
145+
--- @nodiscard
146+
function CO.running() end
147+
"#,
148+
);
149+
check!(ws.check_completion_resolve(
150+
r#"
151+
CO.running<??>
152+
"#,
153+
VirtualCompletionResolveItem {
154+
detail: "function CO.running() -> thread, boolean".to_string(),
155+
documentation: Some("\n5.2+".to_string()),
156+
},
157+
));
158+
Ok(())
159+
}
126160
}

0 commit comments

Comments
 (0)