Skip to content

Commit 7363845

Browse files
committed
fix local_hint
1 parent 5e85bb6 commit 7363845

File tree

7 files changed

+108
-27
lines changed

7 files changed

+108
-27
lines changed

crates/emmylua_code_analysis/src/compilation/analyzer/unresolve/resolve.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ fn merge_table_field_to_def(
150150
let file_id = cache.get_file_id();
151151
let local_name = table_expr
152152
.get_parent::<LuaLocalStat>()?
153-
.get_value_local_name(LuaExpr::TableExpr(table_expr.clone()))?;
153+
.get_local_name_by_value(LuaExpr::TableExpr(table_expr.clone()))?;
154154
let decl_id = LuaDeclId::new(file_id, local_name.get_position());
155155
let type_cache = db.get_type_index().get_type_cache(&decl_id.into())?;
156156
if let LuaType::Def(id) = type_cache.deref() {

crates/emmylua_code_analysis/src/db_index/type/humanize_type.rs

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -689,22 +689,36 @@ fn humanize_signature_type(
689689
.collect::<Vec<_>>()
690690
.join(", ");
691691

692-
let rets = signature
693-
.return_docs
694-
.iter()
695-
.map(|ret| humanize_type(db, &ret.type_ref, level.next_level()))
696-
.collect::<Vec<_>>();
697-
698692
let generic_str = if generics.is_empty() {
699693
"".to_string()
700694
} else {
701695
format!("<{}>", generics)
702696
};
703697

704-
let ret_str = if rets.is_empty() {
705-
"".to_string()
706-
} else {
707-
format!(" -> {}", rets.join(","))
698+
let ret_str = {
699+
let ret_type = signature.get_return_type();
700+
let return_nil = match ret_type {
701+
LuaType::Variadic(variadic) => match variadic.get_type(0) {
702+
Some(LuaType::Nil) => true,
703+
_ => false,
704+
},
705+
_ => ret_type.is_nil(),
706+
};
707+
708+
if return_nil {
709+
"".to_string()
710+
} else {
711+
let rets = signature
712+
.return_docs
713+
.iter()
714+
.map(|ret| humanize_type(db, &ret.type_ref, level.next_level()))
715+
.collect::<Vec<_>>();
716+
if rets.is_empty() {
717+
"".to_string()
718+
} else {
719+
format!(" -> {}", rets.join(","))
720+
}
721+
}
708722
};
709723

710724
format!("fun{}({}){}", generic_str, params, ret_str)

crates/emmylua_ls/src/handlers/inlay_hint/build_function_hint.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ pub fn build_closure_hint(
7676
Some(())
7777
}
7878

79-
fn build_label_parts(semantic_model: &SemanticModel, typ: &LuaType) -> Vec<InlayHintLabelPart> {
79+
pub fn build_label_parts(semantic_model: &SemanticModel, typ: &LuaType) -> Vec<InlayHintLabelPart> {
8080
let mut parts: Vec<InlayHintLabelPart> = Vec::new();
8181
match typ {
8282
LuaType::Union(union) => {
@@ -116,6 +116,10 @@ fn build_label_parts(semantic_model: &SemanticModel, typ: &LuaType) -> Vec<Inlay
116116
}
117117
result.push(part);
118118
}
119+
// 如果只有一个`nil`标签, 那么将其改为": nil"
120+
if result.len() == 1 && result[0].value == "?" {
121+
result[0].value = ": nil".to_string();
122+
}
119123
result
120124
}
121125

@@ -153,9 +157,10 @@ fn get_type_location(semantic_model: &SemanticModel, typ: &LuaType) -> Option<Lo
153157
let lsp_range = document.to_lsp_range(location.range)?;
154158
Some(Location::new(document.get_uri(), lsp_range))
155159
}
160+
LuaType::Array(base) => get_type_location(semantic_model, base),
156161
LuaType::Any => get_base_type_location(semantic_model, "any"),
157162
LuaType::Nil => get_base_type_location(semantic_model, "nil"),
158-
LuaType::Unknown => get_base_type_location(semantic_model, "string"),
163+
LuaType::Unknown => get_base_type_location(semantic_model, "unknown"),
159164
LuaType::Userdata => get_base_type_location(semantic_model, "userdata"),
160165
LuaType::Function => get_base_type_location(semantic_model, "function"),
161166
LuaType::Thread => get_base_type_location(semantic_model, "thread"),

crates/emmylua_ls/src/handlers/inlay_hint/build_inlay_hint.rs

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@ use std::collections::HashMap;
22

33
use emmylua_code_analysis::{
44
FileId, InferGuard, LuaFunctionType, LuaMemberId, LuaMemberKey, LuaSemanticDeclId, LuaType,
5-
RenderLevel, SemanticModel,
5+
SemanticModel,
66
};
7-
use emmylua_parser::LuaTokenKind;
87
use emmylua_parser::{
9-
LuaAst, LuaAstNode, LuaCallExpr, LuaExpr, LuaFuncStat, LuaIndexExpr, LuaLocalName, LuaStat,
10-
LuaSyntaxId, LuaVarExpr,
8+
LuaAst, LuaAstNode, LuaCallExpr, LuaExpr, LuaFuncStat, LuaIndexExpr, LuaLocalFuncStat,
9+
LuaLocalName, LuaLocalStat, LuaStat, LuaSyntaxId, LuaVarExpr,
1110
};
11+
use emmylua_parser::{LuaAstToken, LuaTokenKind};
1212
use lsp_types::{InlayHint, InlayHintKind, InlayHintLabel, InlayHintLabelPart, Location};
1313
use rowan::NodeOrToken;
1414

15-
use emmylua_code_analysis::humanize_type;
1615
use rowan::TokenAtOffset;
1716

18-
use crate::handlers::inlay_hint::build_function_hint::build_closure_hint;
17+
use crate::handlers::inlay_hint::build_function_hint::{build_closure_hint, build_label_parts};
1918

2019
pub fn build_inlay_hints(semantic_model: &SemanticModel) -> Option<Vec<InlayHint>> {
2120
let mut result = Vec::new();
@@ -300,21 +299,48 @@ fn build_local_name_hint(
300299
if !semantic_model.get_emmyrc().hint.local_hint {
301300
return Some(());
302301
}
302+
// local function 不显示
303+
if let Some(parent) = local_name.syntax().parent() {
304+
if LuaLocalFuncStat::can_cast(parent.kind().into()) {
305+
return Some(());
306+
}
307+
if LuaLocalStat::can_cast(parent.kind().into()) {
308+
let local_stat = LuaLocalStat::cast(parent)?;
309+
let local_names = local_stat.get_local_name_list();
310+
for (i, ln) in local_names.enumerate() {
311+
if local_name == ln {
312+
if let Some(value_expr) = local_stat.get_value_exprs().nth(i) {
313+
if let LuaExpr::ClosureExpr(_) = value_expr {
314+
return Some(());
315+
}
316+
}
317+
}
318+
}
319+
}
320+
}
303321

304322
let typ = semantic_model
305-
.get_semantic_info(NodeOrToken::Node(local_name.syntax().clone()))?
306-
.typ
307-
.clone();
323+
.get_semantic_info(NodeOrToken::Token(
324+
local_name.get_name_token()?.syntax().clone(),
325+
))?
326+
.typ;
327+
328+
// 目前没时间完善结合 ast 的类型过滤, 所以只允许一些类型显示
329+
match typ {
330+
LuaType::Def(_) | LuaType::Ref(_) => {}
331+
_ => {
332+
return Some(());
333+
}
334+
}
308335

309336
let document = semantic_model.get_document();
310-
let db = semantic_model.get_db();
311337
let range = local_name.get_range();
312338
let lsp_range = document.to_lsp_range(range)?;
313339

314-
let typ_desc = humanize_type(db, &typ, RenderLevel::Simple);
340+
let label_parts = build_label_parts(semantic_model, &typ);
315341
let hint = InlayHint {
316342
kind: Some(InlayHintKind::TYPE),
317-
label: InlayHintLabel::String(format!(": {}", typ_desc)),
343+
label: InlayHintLabel::LabelParts(label_parts),
318344
position: lsp_range.end,
319345
text_edits: None,
320346
tooltip: None,

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,41 @@ mod tests {
5454
let location = extract_first_label_part_location(first).unwrap();
5555
assert!(location.uri.path().as_str().ends_with("builtin.lua"));
5656
}
57+
58+
#[test]
59+
fn test_local_hint_1() {
60+
let mut ws = ProviderVirtualWorkspace::new();
61+
let result = ws
62+
.check_inlay_hint(
63+
r#"
64+
local a = 1
65+
"#,
66+
)
67+
.unwrap();
68+
assert!(result.is_empty());
69+
}
70+
71+
#[test]
72+
fn test_local_hint_2() {
73+
let mut ws = ProviderVirtualWorkspace::new();
74+
let result = ws
75+
.check_inlay_hint(
76+
r#"
77+
local function test()
78+
end
79+
"#,
80+
)
81+
.unwrap();
82+
assert!(result.is_empty());
83+
84+
let result = ws
85+
.check_inlay_hint(
86+
r#"
87+
local test = function()
88+
end
89+
"#,
90+
)
91+
.unwrap();
92+
assert!(result.is_empty());
93+
}
5794
}

crates/emmylua_ls/src/handlers/test_lib/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@ impl ProviderVirtualWorkspace {
315315
pub fn check_inlay_hint(&mut self, block_str: &str) -> Option<Vec<InlayHint>> {
316316
let file_id = self.def(&block_str);
317317
let result = inlay_hint(&self.analysis, file_id);
318-
dbg!(&result);
319318
return result;
320319
}
321320
}

crates/emmylua_parser/src/syntax/node/lua/stat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ impl LuaLocalStat {
215215
self.children()
216216
}
217217

218-
pub fn get_value_local_name(&self, value: LuaExpr) -> Option<LuaLocalName> {
218+
pub fn get_local_name_by_value(&self, value: LuaExpr) -> Option<LuaLocalName> {
219219
let local_names = self.get_local_name_list();
220220
let value_exprs = self.get_value_exprs().collect::<Vec<_>>();
221221

0 commit comments

Comments
 (0)