Skip to content

Commit 108c4ca

Browse files
committed
inlay_hint call_expr_param_hint 添加跳转
1 parent 0159574 commit 108c4ca

File tree

1 file changed

+98
-6
lines changed

1 file changed

+98
-6
lines changed

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

Lines changed: 98 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@ use emmylua_code_analysis::{
44
FileId, InferGuard, LuaFunctionType, LuaMemberId, LuaMemberKey, LuaSemanticDeclId,
55
LuaSignatureId, LuaType, RenderLevel, SemanticModel,
66
};
7+
use emmylua_parser::LuaTokenKind;
78
use emmylua_parser::{
89
LuaAst, LuaAstNode, LuaCallExpr, LuaClosureExpr, LuaExpr, LuaFuncStat, LuaIndexExpr,
9-
LuaLocalName, LuaSyntaxId, LuaVarExpr,
10+
LuaLocalName, LuaStat, LuaSyntaxId, LuaVarExpr,
1011
};
1112
use lsp_types::{InlayHint, InlayHintKind, InlayHintLabel, InlayHintLabelPart, Location};
1213
use rowan::NodeOrToken;
1314

1415
use emmylua_code_analysis::humanize_type;
16+
use rowan::TokenAtOffset;
1517

1618
pub fn build_inlay_hints(semantic_model: &SemanticModel) -> Option<Vec<InlayHint>> {
1719
let mut result = Vec::new();
@@ -106,7 +108,7 @@ fn build_call_expr_param_hint(
106108
if !semantic_model.get_emmyrc().hint.param_hint {
107109
return Some(());
108110
}
109-
111+
let params_location = get_call_signature_param_location(semantic_model, &call_expr);
110112
let func = semantic_model.infer_call_expr_func(call_expr.clone(), None)?;
111113
let call_args_list = call_expr.get_args_list()?;
112114
let colon_call = call_expr.is_colon_call();
@@ -116,11 +118,70 @@ fn build_call_expr_param_hint(
116118
call_args_list.get_args().collect(),
117119
colon_call,
118120
&func,
121+
params_location,
119122
);
120123

121124
Some(())
122125
}
123126

127+
fn get_call_signature_param_location(
128+
semantic_model: &SemanticModel,
129+
call_expr: &LuaCallExpr,
130+
) -> Option<HashMap<String, Location>> {
131+
let prefix_expr = call_expr.get_prefix_expr()?;
132+
let semantic_info =
133+
semantic_model.get_semantic_info(NodeOrToken::Node(prefix_expr.syntax().clone()))?;
134+
let mut document = None;
135+
let closure = if let LuaType::Signature(signature_id) = &semantic_info.typ {
136+
let sig_file_id = signature_id.get_file_id();
137+
let sig_position = signature_id.get_position();
138+
document = semantic_model.get_document_by_file_id(sig_file_id);
139+
140+
if let Some(root) = semantic_model.get_root_by_file_id(sig_file_id) {
141+
let token = match root.syntax().token_at_offset(sig_position) {
142+
TokenAtOffset::Single(token) => token,
143+
TokenAtOffset::Between(left, right) => {
144+
if left.kind() == LuaTokenKind::TkName.into() {
145+
left
146+
} else {
147+
right
148+
}
149+
}
150+
TokenAtOffset::None => {
151+
return None;
152+
}
153+
};
154+
let stat = token.parent_ancestors().find_map(LuaStat::cast)?;
155+
match stat {
156+
LuaStat::LocalFuncStat(local_func_stat) => local_func_stat.get_closure(),
157+
LuaStat::FuncStat(func_stat) => func_stat.get_closure(),
158+
_ => None,
159+
}
160+
} else {
161+
None
162+
}
163+
} else {
164+
None
165+
}?;
166+
let lua_params = closure.get_params_list()?;
167+
let document = document?;
168+
let url = document.get_uri();
169+
let mut lua_params_map: HashMap<String, Location> = HashMap::new();
170+
for param in lua_params.get_params() {
171+
if let Some(name_token) = param.get_name_token() {
172+
let name = name_token.get_name_text().to_string();
173+
let range = param.get_range();
174+
let lsp_range = document.to_lsp_range(range)?;
175+
lua_params_map.insert(name, Location::new(url.clone(), lsp_range));
176+
} else if param.is_dots() {
177+
let range = param.get_range();
178+
let lsp_range = document.to_lsp_range(range)?;
179+
lua_params_map.insert("...".to_string(), Location::new(url.clone(), lsp_range));
180+
}
181+
}
182+
Some(lua_params_map)
183+
}
184+
124185
fn build_call_expr_await_hint(
125186
semantic_model: &SemanticModel,
126187
result: &mut Vec<InlayHint>,
@@ -182,6 +243,7 @@ fn build_call_args_for_func_type(
182243
call_args: Vec<LuaExpr>,
183244
colon_call: bool,
184245
func_type: &LuaFunctionType,
246+
params_location: Option<HashMap<String, Location>>,
185247
) -> Option<()> {
186248
let call_args_len = call_args.len();
187249
let mut params = func_type
@@ -210,13 +272,28 @@ fn build_call_args_for_func_type(
210272

211273
if name == "..." {
212274
for i in idx..call_args_len {
275+
let label_name = format!("var{}:", i - idx);
276+
let label = if let Some(params_location) = &params_location {
277+
if let Some(location) = params_location.get(name) {
278+
InlayHintLabel::LabelParts(vec![InlayHintLabelPart {
279+
value: label_name,
280+
location: Some(location.clone()),
281+
..Default::default()
282+
}])
283+
} else {
284+
InlayHintLabel::String(label_name)
285+
}
286+
} else {
287+
InlayHintLabel::String(label_name)
288+
};
289+
213290
let arg = &call_args[i];
214291
let range = arg.get_range();
215292
let document = semantic_model.get_document();
216293
let lsp_range = document.to_lsp_range(range)?;
217294
let hint = InlayHint {
218295
kind: Some(InlayHintKind::PARAMETER),
219-
label: InlayHintLabel::String(format!("var{}:", i - idx)),
296+
label,
220297
position: lsp_range.start,
221298
text_edits: None,
222299
tooltip: None,
@@ -239,12 +316,27 @@ fn build_call_args_for_func_type(
239316
}
240317
}
241318

242-
let range = arg.get_range();
243319
let document = semantic_model.get_document();
244-
let lsp_range = document.to_lsp_range(range)?;
320+
let lsp_range = document.to_lsp_range(arg.get_range())?;
321+
322+
let label_name = format!("{}:", name);
323+
let label = if let Some(params_location) = &params_location {
324+
if let Some(location) = params_location.get(name) {
325+
InlayHintLabel::LabelParts(vec![InlayHintLabelPart {
326+
value: label_name,
327+
location: Some(location.clone()),
328+
..Default::default()
329+
}])
330+
} else {
331+
InlayHintLabel::String(label_name)
332+
}
333+
} else {
334+
InlayHintLabel::String(label_name)
335+
};
336+
245337
let hint = InlayHint {
246338
kind: Some(InlayHintKind::PARAMETER),
247-
label: InlayHintLabel::String(format!("{}:", name)),
339+
label,
248340
position: lsp_range.start,
249341
text_edits: None,
250342
tooltip: None,

0 commit comments

Comments
 (0)