emmylua_code_analysis/db_index/member/
lua_member.rs1use emmylua_parser::{LuaDocFieldKey, LuaIndexKey, LuaSyntaxId, LuaSyntaxKind};
2use rowan::{TextRange, TextSize};
3use serde::{Deserialize, Serialize};
4use smol_str::SmolStr;
5
6use super::lua_member_feature::LuaMemberFeature;
7use crate::{FileId, GlobalId};
8
9#[derive(Debug)]
10pub struct LuaMember {
11 member_id: LuaMemberId,
12 key: LuaMemberKey,
13 feature: LuaMemberFeature,
14 global_id: Option<GlobalId>,
15}
16
17impl LuaMember {
18 pub fn new(
19 member_id: LuaMemberId,
20 key: LuaMemberKey,
21 decl_feature: LuaMemberFeature,
22 global_path: Option<GlobalId>,
23 ) -> Self {
24 Self {
25 member_id,
26 key,
27 feature: decl_feature,
28 global_id: global_path,
29 }
30 }
31
32 pub fn get_key(&self) -> &LuaMemberKey {
33 &self.key
34 }
35
36 pub fn get_file_id(&self) -> FileId {
37 self.member_id.file_id
38 }
39
40 pub fn get_range(&self) -> TextRange {
41 self.member_id.get_syntax_id().get_range()
42 }
43
44 pub fn get_sort_key(&self) -> u64 {
45 let file_id = self.member_id.file_id.id;
46 let pos = u32::from(self.member_id.id.get_range().start());
47 (file_id as u64) << 32 | pos as u64
48 }
49
50 pub fn get_syntax_id(&self) -> LuaSyntaxId {
51 *self.member_id.get_syntax_id()
52 }
53
54 pub fn get_id(&self) -> LuaMemberId {
55 self.member_id
56 }
57
58 pub fn is_field(&self) -> bool {
59 LuaSyntaxKind::DocTagField == self.member_id.get_syntax_id().get_kind().into()
60 }
61
62 pub fn get_feature(&self) -> LuaMemberFeature {
63 self.feature
64 }
65
66 pub fn get_global_id(&self) -> Option<&GlobalId> {
67 self.global_id.as_ref()
68 }
69}
70
71#[derive(Debug, Eq, PartialEq, Clone, Copy, Hash, Serialize, Deserialize)]
72pub struct LuaMemberId {
73 pub file_id: FileId,
74 id: LuaSyntaxId,
75}
76
77impl LuaMemberId {
78 pub fn new(id: LuaSyntaxId, file_id: FileId) -> Self {
79 Self { id, file_id }
80 }
81
82 pub fn get_syntax_id(&self) -> &LuaSyntaxId {
83 &self.id
84 }
85
86 pub fn get_position(&self) -> TextSize {
87 self.id.get_range().start()
88 }
89}
90
91#[derive(Debug, Clone, PartialEq, Eq, Hash)]
92pub enum LuaMemberKey {
93 None,
94 Integer(i64),
95 Name(SmolStr),
96 SyntaxId(LuaSyntaxId),
97}
98
99impl LuaMemberKey {
100 pub fn is_none(&self) -> bool {
101 matches!(self, LuaMemberKey::None)
102 }
103
104 pub fn is_name(&self) -> bool {
105 matches!(self, LuaMemberKey::Name(_))
106 }
107
108 pub fn is_integer(&self) -> bool {
109 matches!(self, LuaMemberKey::Integer(_))
110 }
111
112 pub fn is_syntax_id(&self) -> bool {
113 matches!(self, LuaMemberKey::SyntaxId(_))
114 }
115
116 pub fn get_name(&self) -> Option<&str> {
117 match self {
118 LuaMemberKey::Name(name) => Some(name.as_ref()),
119 _ => None,
120 }
121 }
122
123 pub fn get_integer(&self) -> Option<i64> {
124 match self {
125 LuaMemberKey::Integer(i) => Some(*i),
126 _ => None,
127 }
128 }
129
130 pub fn to_path(&self) -> String {
131 match self {
132 LuaMemberKey::Name(name) => name.to_string(),
133 LuaMemberKey::Integer(i) => {
134 format!("[{}]", i)
135 }
136 LuaMemberKey::None => "".to_string(),
137 LuaMemberKey::SyntaxId(_) => "".to_string(),
138 }
139 }
140}
141
142impl PartialOrd for LuaMemberKey {
143 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
144 Some(self.cmp(other))
145 }
146}
147
148impl Ord for LuaMemberKey {
149 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
150 use LuaMemberKey::*;
151 match (self, other) {
152 (None, None) => std::cmp::Ordering::Equal,
153 (None, _) => std::cmp::Ordering::Less,
154 (_, None) => std::cmp::Ordering::Greater,
155 (Integer(a), Integer(b)) => a.cmp(b),
156 (Integer(_), _) => std::cmp::Ordering::Less,
157 (_, Integer(_)) => std::cmp::Ordering::Greater,
158 (Name(a), Name(b)) => a.cmp(b),
159 (Name(_), _) => std::cmp::Ordering::Less,
160 (_, Name(_)) => std::cmp::Ordering::Greater,
161 (SyntaxId(_), SyntaxId(_)) => std::cmp::Ordering::Equal,
162 }
163 }
164}
165
166impl From<LuaIndexKey> for LuaMemberKey {
167 fn from(key: LuaIndexKey) -> Self {
168 match key {
169 LuaIndexKey::Name(name) => LuaMemberKey::Name(name.get_name_text().into()),
170 LuaIndexKey::String(str) => LuaMemberKey::Name(str.get_value().into()),
171 LuaIndexKey::Integer(i) => LuaMemberKey::Integer(i.get_int_value()),
172 LuaIndexKey::Idx(idx) => LuaMemberKey::Integer(idx as i64),
173 _ => LuaMemberKey::None,
174 }
175 }
176}
177
178impl From<&LuaIndexKey> for LuaMemberKey {
179 fn from(key: &LuaIndexKey) -> Self {
180 match key {
181 LuaIndexKey::Name(name) => LuaMemberKey::Name(name.get_name_text().to_string().into()),
182 LuaIndexKey::String(str) => LuaMemberKey::Name(str.get_value().into()),
183 LuaIndexKey::Integer(i) => LuaMemberKey::Integer(i.get_int_value()),
184 _ => LuaMemberKey::None,
185 }
186 }
187}
188
189impl From<LuaDocFieldKey> for LuaMemberKey {
190 fn from(key: LuaDocFieldKey) -> Self {
191 match key {
192 LuaDocFieldKey::Name(name) => {
193 LuaMemberKey::Name(name.get_name_text().to_string().into())
194 }
195 LuaDocFieldKey::String(str) => LuaMemberKey::Name(str.get_value().into()),
196 LuaDocFieldKey::Integer(i) => LuaMemberKey::Integer(i.get_int_value()),
197 _ => LuaMemberKey::None,
198 }
199 }
200}
201
202impl From<&LuaDocFieldKey> for LuaMemberKey {
203 fn from(key: &LuaDocFieldKey) -> Self {
204 match key {
205 LuaDocFieldKey::Name(name) => {
206 LuaMemberKey::Name(name.get_name_text().to_string().into())
207 }
208 LuaDocFieldKey::String(str) => LuaMemberKey::Name(str.get_value().into()),
209 LuaDocFieldKey::Integer(i) => LuaMemberKey::Integer(i.get_int_value()),
210 _ => LuaMemberKey::None,
211 }
212 }
213}
214
215impl From<String> for LuaMemberKey {
216 fn from(name: String) -> Self {
217 LuaMemberKey::Name(name.into())
218 }
219}
220
221impl From<i64> for LuaMemberKey {
222 fn from(i: i64) -> Self {
223 LuaMemberKey::Integer(i)
224 }
225}
226
227impl From<&str> for LuaMemberKey {
228 fn from(name: &str) -> Self {
229 LuaMemberKey::Name(name.to_string().into())
230 }
231}