Skip to content

Commit 9816f3d

Browse files
committed
support rename class name in namespace
1 parent e845acd commit 9816f3d

File tree

2 files changed

+89
-5
lines changed

2 files changed

+89
-5
lines changed

crates/emmylua_ls/src/handlers/rename/rename_type.rs

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,29 @@ pub fn rename_type_references(
99
new_name: String,
1010
result: &mut HashMap<Uri, HashMap<lsp_types::Range, String>>,
1111
) -> Option<()> {
12-
let type_decl = semantic_model
13-
.get_db()
14-
.get_type_index()
15-
.get_type_decl(&type_decl_id)?;
12+
let type_index = semantic_model.get_db().get_type_index();
13+
let type_decl = type_index.get_type_decl(&type_decl_id)?;
14+
let full_name = type_decl.get_full_name();
15+
let mut reserved_namespace = String::new();
16+
17+
// 取出`full_name`在当前文件中使用的命名空间
18+
if let Some(file_namespace) = type_index.get_file_namespace(&semantic_model.get_file_id()) {
19+
if full_name.starts_with(&format!("{}.", file_namespace)) {
20+
reserved_namespace = file_namespace.clone();
21+
}
22+
}
23+
if reserved_namespace.is_empty() {
24+
if let Some(using_namespaces) =
25+
type_index.get_file_using_namespace(&semantic_model.get_file_id())
26+
{
27+
for using_namespace in using_namespaces {
28+
if full_name.starts_with(&format!("{}.", using_namespace)) {
29+
reserved_namespace = using_namespace.clone();
30+
break;
31+
}
32+
}
33+
}
34+
}
1635

1736
let locations = type_decl.get_locations();
1837
for decl_location in locations {
@@ -39,12 +58,54 @@ pub fn rename_type_references(
3958
document_cache.insert(in_filed_reference_range.file_id, document);
4059
document_cache.get(&in_filed_reference_range.file_id)?
4160
};
61+
62+
// 根据引用文件的命名空间上下文决定使用简名还是全名
63+
let actual_new_name = determine_type_name_for_file(
64+
semantic_model,
65+
in_filed_reference_range.file_id,
66+
&reserved_namespace,
67+
&new_name,
68+
);
69+
4270
let location = document.to_lsp_location(in_filed_reference_range.value)?;
4371
result
4472
.entry(location.uri)
4573
.or_insert_with(HashMap::new)
46-
.insert(location.range, new_name.clone());
74+
.insert(location.range, actual_new_name);
4775
}
4876

4977
Some(())
5078
}
79+
80+
/// 根据引用文件的命名空间上下文决定使用简名还是全名
81+
fn determine_type_name_for_file(
82+
semantic_model: &SemanticModel,
83+
reference_file_id: emmylua_code_analysis::FileId,
84+
reserved_namespace: &str,
85+
new_simple_name: &str,
86+
) -> String {
87+
let type_index = semantic_model.get_db().get_type_index();
88+
89+
// 检查引用文件是否声明了相同的命名空间
90+
if let Some(file_namespace) = type_index.get_file_namespace(&reference_file_id) {
91+
if reserved_namespace.starts_with(&format!("{}.", file_namespace)) {
92+
return new_simple_name.to_string();
93+
}
94+
}
95+
96+
// 检查引用文件是否使用了相应的命名空间
97+
if let Some(using_namespaces) = type_index.get_file_using_namespace(&reference_file_id) {
98+
for using_namespace in using_namespaces {
99+
if reserved_namespace.starts_with(&format!("{}.", using_namespace)) {
100+
return new_simple_name.to_string();
101+
}
102+
}
103+
}
104+
105+
// `reserved_namespace`不为空,则使用保留的命名空间与新名称组合
106+
if !reserved_namespace.is_empty() {
107+
return format!("{}.{}", reserved_namespace, new_simple_name);
108+
}
109+
110+
new_simple_name.to_string()
111+
}

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

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,27 @@ mod tests {
134134
assert!(result);
135135
}
136136
}
137+
138+
#[test]
139+
fn test_namespace_class() {
140+
let mut ws = ProviderVirtualWorkspace::new();
141+
ws.def_file(
142+
"a.lua",
143+
r#"
144+
---@param a Luakit.Test.Abc
145+
local function Of(a)
146+
end
147+
148+
"#,
149+
);
150+
ws.check_rename(
151+
r#"
152+
---@namespace Luakit
153+
---@class Test.Abc<??>
154+
local Test = {}
155+
"#,
156+
"Abc".to_string(),
157+
2,
158+
);
159+
}
137160
}

0 commit comments

Comments
 (0)