Skip to content

Commit b840541

Browse files
committed
修改索引别名实现
1 parent cda0ffd commit b840541

File tree

7 files changed

+90
-13
lines changed

7 files changed

+90
-13
lines changed

crates/emmylua_code_analysis/src/db_index/property/property.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ impl LuaCommonProperty {
109109
pub fn attribute_uses(&self) -> Option<&Arc<Vec<LuaAttributeUse>>> {
110110
self.attribute_uses.as_ref()
111111
}
112+
113+
pub fn find_attribute_use(&self, id: LuaTypeDeclId) -> Option<&LuaAttributeUse> {
114+
self.attribute_uses.as_ref().and_then(|attribute_uses| {
115+
attribute_uses
116+
.iter()
117+
.find(|attribute_use| attribute_use.id == id)
118+
})
119+
}
112120
}
113121

114122
#[derive(Debug, Clone, PartialEq, Eq)]

crates/emmylua_ls/src/handlers/completion/add_completions/add_member_completion.rs

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use emmylua_code_analysis::{
2-
DbIndex, LuaMemberInfo, LuaMemberKey, LuaSemanticDeclId, LuaType, SemanticModel,
2+
DbIndex, LuaMemberInfo, LuaMemberKey, LuaSemanticDeclId, LuaType, LuaTypeDeclId, SemanticModel,
33
try_extract_signature_id_from_field,
44
};
55
use emmylua_parser::{
@@ -131,8 +131,8 @@ pub fn add_member_completion(
131131
);
132132
}
133133

134-
// 尝试添加别名补全项, 如果添加成功, 则不添加原本 `[index]` 补全项
135-
if !try_add_alias_completion_item(builder, &member_info, &completion_item, &label)
134+
// 尝试添加别名补全项, 如果添加成功, 则不添加原来的 `[index]` 补全项
135+
if !try_add_alias_completion_item_new(builder, &member_info, &completion_item, &label)
136136
.unwrap_or(false)
137137
{
138138
builder.add_completion_item(completion_item)?;
@@ -312,13 +312,77 @@ fn get_resolve_function_params_str(typ: &LuaType, display: CallDisplay) -> Optio
312312
}
313313
}
314314

315+
fn try_add_alias_completion_item_new(
316+
builder: &mut CompletionBuilder,
317+
member_info: &LuaMemberInfo,
318+
completion_item: &CompletionItem,
319+
label: &String,
320+
) -> Option<bool> {
321+
let alias_label = get_index_alias_name(&builder.semantic_model, member_info)?;
322+
let mut alias_completion_item = completion_item.clone();
323+
alias_completion_item.label = alias_label;
324+
alias_completion_item.insert_text = Some(label.clone());
325+
326+
// 更新 label_details 添加别名提示
327+
let index_hint = t!("completion.index %{label}", label = label).to_string();
328+
let label_details = alias_completion_item
329+
.label_details
330+
.get_or_insert_with(Default::default);
331+
label_details.description = match label_details.description.take() {
332+
Some(desc) => Some(format!("({}) {} ", index_hint, desc)),
333+
None => Some(index_hint),
334+
};
335+
builder.add_completion_item(alias_completion_item)?;
336+
Some(true)
337+
}
338+
339+
pub fn get_index_alias_name(
340+
semantic_model: &SemanticModel,
341+
member_info: &LuaMemberInfo,
342+
) -> Option<String> {
343+
let db = semantic_model.get_db();
344+
let LuaMemberKey::Integer(_) = member_info.key else {
345+
return None;
346+
};
347+
348+
let property_owner_id = member_info.property_owner_id.as_ref()?;
349+
let LuaSemanticDeclId::Member(member_id) = property_owner_id else {
350+
return None;
351+
};
352+
let common_property = match db.get_property_index().get_property(property_owner_id) {
353+
Some(common_property) => common_property,
354+
None => {
355+
// field定义的`signature`的`common_property`绑定位置稍有不同, 需要特殊处理
356+
let member = db.get_member_index().get_member(member_id)?;
357+
let signature_id =
358+
try_extract_signature_id_from_field(semantic_model.get_db(), member)?;
359+
db.get_property_index()
360+
.get_property(&LuaSemanticDeclId::Signature(signature_id))?
361+
}
362+
};
363+
364+
let alias_label = common_property
365+
.find_attribute_use(LuaTypeDeclId::new("index_alias"))?
366+
.params
367+
.get(0)
368+
.map(|param| match param {
369+
LuaType::DocStringConst(s) => s.as_ref(),
370+
_ => "",
371+
})?
372+
.to_string();
373+
Some(alias_label)
374+
}
375+
376+
#[deprecated]
377+
#[allow(dead_code)]
315378
/// 添加索引成员的别名补全项
316379
fn try_add_alias_completion_item(
317380
builder: &mut CompletionBuilder,
318381
member_info: &LuaMemberInfo,
319382
completion_item: &CompletionItem,
320383
label: &String,
321384
) -> Option<bool> {
385+
#[allow(deprecated)]
322386
let alias_label = extract_index_member_alias(&builder.semantic_model, member_info)?;
323387

324388
let mut alias_completion_item = completion_item.clone();
@@ -338,9 +402,10 @@ fn try_add_alias_completion_item(
338402
Some(true)
339403
}
340404

405+
#[deprecated]
341406
/// 从注释中提取索引成员的别名, 只处理整数成员.
342407
/// 格式为`-- [nameX]`.
343-
pub fn extract_index_member_alias(
408+
fn extract_index_member_alias(
344409
semantic_model: &SemanticModel,
345410
member_info: &LuaMemberInfo,
346411
) -> Option<String> {

crates/emmylua_ls/src/handlers/completion/add_completions/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ mod add_member_completion;
33
mod check_match_word;
44

55
pub use add_decl_completion::add_decl_completion;
6-
pub use add_member_completion::extract_index_member_alias;
6+
pub use add_member_completion::get_index_alias_name;
77
pub use add_member_completion::{CompletionTriggerStatus, add_member_completion};
88
pub use check_match_word::check_match_word;
99
use emmylua_code_analysis::{LuaSemanticDeclId, LuaType, RenderLevel};

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ mod data;
55
mod providers;
66
mod resolve_completion;
77

8-
pub use add_completions::extract_index_member_alias;
8+
pub use add_completions::get_index_alias_name;
99
use completion_builder::CompletionBuilder;
1010
use completion_data::CompletionData;
1111
use emmylua_code_analysis::{EmmyLuaAnalysis, FileId};

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rowan::NodeOrToken;
1717

1818
use rowan::TokenAtOffset;
1919

20-
use crate::handlers::completion::extract_index_member_alias;
20+
use crate::handlers::completion::get_index_alias_name;
2121
use crate::handlers::definition::compare_function_types;
2222
use crate::handlers::inlay_hint::build_function_hint::{build_closure_hint, build_label_parts};
2323

@@ -645,7 +645,7 @@ fn build_index_expr_hint(
645645
let member_infos = semantic_model.get_member_info_with_key(&prefix_type, member_key, false)?;
646646
let member_info = member_infos.first()?;
647647
// 尝试提取别名
648-
let alias = extract_index_member_alias(semantic_model, member_info)?;
648+
let alias = get_index_alias_name(semantic_model, member_info)?;
649649
// 创建 hint
650650
let document = semantic_model.get_document();
651651
let position = {

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,10 +1146,11 @@ mod tests {
11461146
#[gtest]
11471147
fn test_index_key_alias() -> Result<()> {
11481148
let mut ws = ProviderVirtualWorkspace::new();
1149+
ws.def(" ---@attribute index_alias(name: string)");
11491150
check!(ws.check_completion(
11501151
r#"
11511152
local export = {
1152-
[1] = 1, -- [nameX]
1153+
[1] = 1, ---@[index_alias("nameX")]
11531154
}
11541155
11551156
export.<??>
@@ -1215,11 +1216,12 @@ mod tests {
12151216

12161217
#[gtest]
12171218
fn test_field_index_function() -> Result<()> {
1218-
let mut ws = ProviderVirtualWorkspace::new();
1219+
let mut ws = ProviderVirtualWorkspace::new_with_init_std_lib();
12191220
ws.def(
12201221
r#"
12211222
---@class A<T>
1222-
---@field [1] fun() # [next]
1223+
---@[index_alias("next")]
1224+
---@field [1] fun()
12231225
A = {}
12241226
"#,
12251227
);

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,16 +167,18 @@ mod tests {
167167
#[gtest]
168168
fn test_index_key_alias_hint() -> Result<()> {
169169
let mut ws = ProviderVirtualWorkspace::new();
170+
ws.def(" ---@attribute index_alias(name: string)");
170171
check!(ws.check_inlay_hint(
171172
r#"
172173
local export = {
173-
[1] = 1, -- [nameX]
174+
---@[index_alias("nameX")]
175+
[1] = 1,
174176
}
175177
print(export[1])
176178
"#,
177179
vec![VirtualInlayHint {
178180
label: ": nameX".to_string(),
179-
line: 4,
181+
line: 5,
180182
pos: 30,
181183
ref_file: Some("".to_string()),
182184
}]

0 commit comments

Comments
 (0)