Skip to content

Commit e785b7d

Browse files
committed
refactor complete data
1 parent 1c5f18a commit e785b7d

File tree

10 files changed

+326
-107
lines changed

10 files changed

+326
-107
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
use emmylua_code_analysis::{DbIndex, LuaDeclId, LuaSemanticDeclId, LuaType};
22
use lsp_types::CompletionItem;
33

4-
use crate::handlers::completion::completion_builder::CompletionBuilder;
4+
use crate::handlers::completion::{
5+
completion_builder::CompletionBuilder, completion_data::CompletionData,
6+
};
57

68
use super::{
79
check_visibility, get_completion_kind, get_description, get_detail, is_deprecated, CallDisplay,
8-
CompletionData,
910
};
1011

1112
pub fn add_decl_completion(

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ use emmylua_code_analysis::{DbIndex, LuaMemberInfo, LuaMemberKey, LuaSemanticDec
22
use emmylua_parser::LuaTokenKind;
33
use lsp_types::CompletionItem;
44

5-
use crate::handlers::completion::completion_builder::CompletionBuilder;
5+
use crate::handlers::completion::{
6+
completion_builder::CompletionBuilder, completion_data::CompletionData,
7+
};
68

79
use super::{
810
check_visibility, get_completion_kind, get_description, get_detail, is_deprecated, CallDisplay,
9-
CompletionData,
1011
};
1112

1213
#[derive(Debug, Clone, Copy, PartialEq)]

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

Lines changed: 1 addition & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,8 @@ mod check_match_word;
55
pub use add_decl_completion::add_decl_completion;
66
pub use add_member_completion::{add_member_completion, CompletionTriggerStatus};
77
pub use check_match_word::check_match_word;
8-
use emmylua_code_analysis::{FileId, LuaSemanticDeclId, LuaType, RenderLevel};
8+
use emmylua_code_analysis::{LuaSemanticDeclId, LuaType, RenderLevel};
99
use lsp_types::CompletionItemKind;
10-
use serde::{Deserialize, Serialize};
11-
use serde_json::Value;
1210

1311
use emmylua_code_analysis::humanize_type;
1412

@@ -173,57 +171,3 @@ fn get_description(builder: &CompletionBuilder, typ: &LuaType) -> Option<String>
173171
)),
174172
}
175173
}
176-
177-
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
178-
pub enum CompletionDataType {
179-
PropertyOwnerId(LuaSemanticDeclId),
180-
Module(String),
181-
Overload((LuaSemanticDeclId, usize)),
182-
}
183-
184-
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
185-
pub struct CompletionData {
186-
pub field_id: FileId,
187-
pub typ: CompletionDataType,
188-
/// 函数重载总数
189-
pub function_overload_count: Option<usize>,
190-
}
191-
192-
#[allow(unused)]
193-
impl CompletionData {
194-
pub fn from_property_owner_id(
195-
builder: &CompletionBuilder,
196-
id: LuaSemanticDeclId,
197-
function_overload_count: Option<usize>,
198-
) -> Option<Value> {
199-
let data = Self {
200-
field_id: builder.semantic_model.get_file_id(),
201-
typ: CompletionDataType::PropertyOwnerId(id),
202-
function_overload_count,
203-
};
204-
Some(serde_json::to_value(data).unwrap())
205-
}
206-
207-
pub fn from_overload(
208-
builder: &CompletionBuilder,
209-
id: LuaSemanticDeclId,
210-
index: usize,
211-
function_overload_count: Option<usize>,
212-
) -> Option<Value> {
213-
let data = Self {
214-
field_id: builder.semantic_model.get_file_id(),
215-
typ: CompletionDataType::Overload((id, index)),
216-
function_overload_count,
217-
};
218-
Some(serde_json::to_value(data).unwrap())
219-
}
220-
221-
pub fn from_module(builder: &CompletionBuilder, module: String) -> Option<Value> {
222-
let data = Self {
223-
field_id: builder.semantic_model.get_file_id(),
224-
typ: CompletionDataType::Module(module),
225-
function_overload_count: None,
226-
};
227-
Some(serde_json::to_value(data).unwrap())
228-
}
229-
}
Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
use emmylua_code_analysis::{FileId, LuaSemanticDeclId};
2+
use serde::{Deserialize, Serialize};
3+
use serde_json::Value;
4+
5+
use super::completion_builder::CompletionBuilder;
6+
7+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8+
pub struct CompletionData {
9+
pub field_id: FileId,
10+
pub typ: CompletionDataType,
11+
/// Total count of function overloads
12+
pub function_overload_count: Option<usize>,
13+
}
14+
15+
#[allow(unused)]
16+
impl CompletionData {
17+
pub fn from_property_owner_id(
18+
builder: &CompletionBuilder,
19+
id: LuaSemanticDeclId,
20+
function_overload_count: Option<usize>,
21+
) -> Option<Value> {
22+
let data = Self {
23+
field_id: builder.semantic_model.get_file_id(),
24+
typ: CompletionDataType::PropertyOwnerId(id),
25+
function_overload_count,
26+
};
27+
Some(serde_json::to_value(data).unwrap())
28+
}
29+
30+
pub fn from_overload(
31+
builder: &CompletionBuilder,
32+
id: LuaSemanticDeclId,
33+
index: usize,
34+
function_overload_count: Option<usize>,
35+
) -> Option<Value> {
36+
let data = Self {
37+
field_id: builder.semantic_model.get_file_id(),
38+
typ: CompletionDataType::Overload((id, index)),
39+
function_overload_count,
40+
};
41+
Some(serde_json::to_value(data).unwrap())
42+
}
43+
44+
pub fn from_module(builder: &CompletionBuilder, module: String) -> Option<Value> {
45+
let data = Self {
46+
field_id: builder.semantic_model.get_file_id(),
47+
typ: CompletionDataType::Module(module),
48+
function_overload_count: None,
49+
};
50+
Some(serde_json::to_value(data).unwrap())
51+
}
52+
}
53+
54+
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
55+
pub enum CompletionDataType {
56+
PropertyOwnerId(LuaSemanticDeclId),
57+
Module(String),
58+
Overload((LuaSemanticDeclId, usize)),
59+
}
60+
61+
// // Custom serialization implementation
62+
// impl Serialize for CompletionData {
63+
// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
64+
// where
65+
// S: Serializer,
66+
// {
67+
// // Compact format: "field_id|type_flag:type_data|overload_count"
68+
// // type_flag: P=PropertyOwnerId, M=Module, O=Overload
69+
// let type_part = match &self.typ {
70+
// CompletionDataType::PropertyOwnerId(id) => {
71+
// format!("P:{}", serde_json::to_string(id).map_err(serde::ser::Error::custom)?)
72+
// },
73+
// CompletionDataType::Module(module) => {
74+
// format!("M:{}", module)
75+
// },
76+
// CompletionDataType::Overload((id, index)) => {
77+
// format!("O:{}#{}",
78+
// serde_json::to_string(id).map_err(serde::ser::Error::custom)?,
79+
// index
80+
// )
81+
// },
82+
// };
83+
84+
// let overload_part = match self.function_overload_count {
85+
// Some(count) => format!("|{}", count),
86+
// None => String::new(),
87+
// };
88+
89+
// let compact = format!("{}|{}{}", self.field_id.id, type_part, overload_part);
90+
// serializer.serialize_str(&compact)
91+
// }
92+
// }
93+
94+
// impl<'de> Deserialize<'de> for CompletionData {
95+
// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
96+
// where
97+
// D: Deserializer<'de>,
98+
// {
99+
// struct CompletionDataVisitor;
100+
101+
// impl<'de> Visitor<'de> for CompletionDataVisitor {
102+
// type Value = CompletionData;
103+
104+
// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
105+
// formatter.write_str("a string with format 'field_id|type_flag:type_data|overload_count'")
106+
// }
107+
108+
// fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
109+
// where
110+
// E: de::Error,
111+
// {
112+
// let parts: Vec<&str> = value.split('|').collect();
113+
// if parts.len() < 2 || parts.len() > 3 {
114+
// return Err(E::custom("expected format 'field_id|type_flag:type_data|overload_count'"));
115+
// }
116+
117+
// // Parse field_id
118+
// let field_id = FileId::new(
119+
// parts[0]
120+
// .parse()
121+
// .map_err(|e| E::custom(format!("invalid field_id: {}", e)))?
122+
// );
123+
124+
// // Parse type
125+
// let type_part = parts[1];
126+
// let typ = if let Some(colon_pos) = type_part.find(':') {
127+
// let type_flag = &type_part[..colon_pos];
128+
// let type_data = &type_part[colon_pos + 1..];
129+
130+
// match type_flag {
131+
// "P" => {
132+
// let id: LuaSemanticDeclId = serde_json::from_str(type_data)
133+
// .map_err(|e| E::custom(format!("invalid PropertyOwnerId: {}", e)))?;
134+
// CompletionDataType::PropertyOwnerId(id)
135+
// },
136+
// "M" => {
137+
// CompletionDataType::Module(type_data.to_string())
138+
// },
139+
// "O" => {
140+
// if let Some(hash_pos) = type_data.find('#') {
141+
// let id_part = &type_data[..hash_pos];
142+
// let index_part = &type_data[hash_pos + 1..];
143+
144+
// let id: LuaSemanticDeclId = serde_json::from_str(id_part)
145+
// .map_err(|e| E::custom(format!("invalid Overload id: {}", e)))?;
146+
// let index: usize = index_part
147+
// .parse()
148+
// .map_err(|e| E::custom(format!("invalid Overload index: {}", e)))?;
149+
150+
// CompletionDataType::Overload((id, index))
151+
// } else {
152+
// return Err(E::custom("expected '#' separator in Overload type"));
153+
// }
154+
// },
155+
// _ => {
156+
// return Err(E::custom(format!("unknown type flag: {}", type_flag)));
157+
// }
158+
// }
159+
// } else {
160+
// return Err(E::custom("expected ':' separator in type part"));
161+
// };
162+
163+
// // Parse function_overload_count
164+
// let function_overload_count = if parts.len() == 3 {
165+
// if parts[2].is_empty() {
166+
// None
167+
// } else {
168+
// Some(
169+
// parts[2]
170+
// .parse()
171+
// .map_err(|e| E::custom(format!("invalid overload count: {}", e)))?
172+
// )
173+
// }
174+
// } else {
175+
// None
176+
// };
177+
178+
// Ok(CompletionData {
179+
// field_id,
180+
// typ,
181+
// function_overload_count,
182+
// })
183+
// }
184+
// }
185+
186+
// deserializer.deserialize_str(CompletionDataVisitor)
187+
// }
188+
// }
189+
190+
// #[cfg(test)]
191+
// mod tests {
192+
// use emmylua_code_analysis::{FileId, LuaSemanticDeclId, LuaTypeDeclId};
193+
194+
// use super::{CompletionData, CompletionDataType};
195+
196+
// #[test]
197+
// fn test_compact_serialization() {
198+
// let type_id = LuaTypeDeclId::new("hello world");
199+
// let data = CompletionData {
200+
// field_id: FileId::new(1),
201+
// typ: CompletionDataType::PropertyOwnerId(LuaSemanticDeclId::TypeDecl(type_id)),
202+
// function_overload_count: Some(3),
203+
// };
204+
205+
// // Test serialization
206+
// let json = serde_json::to_string(&data).unwrap();
207+
// println!("Compact serialized: {}", json);
208+
209+
// // Test deserialization
210+
// let deserialized: CompletionData = serde_json::from_str(&json).unwrap();
211+
// assert_eq!(data, deserialized);
212+
213+
// // Verify the compactness of serialization format
214+
// assert!(json.len() < 200); // Should be more compact than default JSON serialization
215+
// }
216+
217+
// #[test]
218+
// fn test_module_serialization() {
219+
// let data = CompletionData {
220+
// field_id: FileId::new(42),
221+
// typ: CompletionDataType::Module("socket.core".to_string()),
222+
// function_overload_count: None,
223+
// };
224+
225+
// let json = serde_json::to_string(&data).unwrap();
226+
// println!("Module serialized: {}", json);
227+
228+
// let deserialized: CompletionData = serde_json::from_str(&json).unwrap();
229+
// assert_eq!(data, deserialized);
230+
// }
231+
232+
// #[test]
233+
// fn test_overload_serialization() {
234+
// let type_id = LuaTypeDeclId::new("test_function");
235+
// let data = CompletionData {
236+
// field_id: FileId::new(10),
237+
// typ: CompletionDataType::Overload((LuaSemanticDeclId::TypeDecl(type_id), 2)),
238+
// function_overload_count: Some(5),
239+
// };
240+
241+
// let json = serde_json::to_string(&data).unwrap();
242+
// println!("Overload serialized: {}", json);
243+
244+
// let deserialized: CompletionData = serde_json::from_str(&json).unwrap();
245+
// assert_eq!(data, deserialized);
246+
// }
247+
248+
// #[test]
249+
// fn test_size_comparison() {
250+
// let type_id = LuaTypeDeclId::new("comparison_test");
251+
// let data = CompletionData {
252+
// field_id: FileId::new(999),
253+
// typ: CompletionDataType::PropertyOwnerId(LuaSemanticDeclId::TypeDecl(type_id.clone())),
254+
// function_overload_count: Some(10),
255+
// };
256+
257+
// // Our compact serialization
258+
// let compact_json = serde_json::to_string(&data).unwrap();
259+
260+
// // Create a struct using default serialization to compare sizes
261+
// #[derive(serde::Serialize)]
262+
// struct DefaultSerialized {
263+
// field_id: u32,
264+
// typ: CompletionDataType,
265+
// function_overload_count: Option<usize>,
266+
// }
267+
268+
// let default_data = DefaultSerialized {
269+
// field_id: data.field_id.id,
270+
// typ: data.typ.clone(),
271+
// function_overload_count: data.function_overload_count,
272+
// };
273+
274+
// let default_json = serde_json::to_string(&default_data).unwrap();
275+
276+
// println!("Compact size: {} bytes", compact_json.len());
277+
// println!("Default size: {} bytes", default_json.len());
278+
279+
// // Compact serialization should be smaller
280+
// assert!(compact_json.len() <= default_json.len());
281+
// }
282+
// }

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
mod add_completions;
22
mod completion_builder;
3+
mod completion_data;
34
mod data;
45
mod providers;
56
mod resolve_completion;
67
mod test;
78

8-
use add_completions::CompletionData;
99
use completion_builder::CompletionBuilder;
10+
use completion_data::CompletionData;
1011
use emmylua_code_analysis::{EmmyLuaAnalysis, FileId};
1112
use emmylua_parser::LuaAstNode;
1213
use log::error;

0 commit comments

Comments
 (0)