1use std::collections::HashMap;
2
3use serde::{Deserialize, Deserializer};
4use serde_bytes::Bytes;
5type TypeId = u32;
6#[derive(Debug, Clone, Deserialize)]
7#[non_exhaustive]
8pub struct ProjectResponse<'base> {
9 #[serde(borrow)]
10 pub root_files: Vec<&'base str>,
11 pub source_files: Vec<&'base Bytes>,
12 pub module_list: Vec<&'base str>,
13 #[serde(default)]
14 pub module_exports: Vec<Vec<u32>>,
15 pub semantic: Semantic,
16 pub diagnostics: Vec<Diagnostic>,
17 pub source_file_extra: Vec<SourceFileExtra>,
18}
19#[derive(Debug, Clone, Deserialize)]
20pub struct SourceFileExtra {
21 pub has_common_js_module_indicator: bool,
22 pub has_external_module_indicator: bool,
23}
24#[derive(Debug, Clone, Deserialize)]
25pub struct Location {
26 pub start: u32,
27 pub end: u32,
28}
29#[derive(Debug, Clone, Deserialize)]
30pub struct Diagnostic {
31 pub message: String,
32 pub category: u32,
33 pub file: u32,
34 pub loc: Location,
35}
36#[derive(Debug, Clone, Deserialize)]
37pub struct Semantic {
38 #[serde(deserialize_with = "vecmap")]
39 pub symtab: Vec<(u32, SymbolData)>,
40 #[serde(deserialize_with = "vecmap")]
41 pub typetab: Vec<(u32, TypeData)>,
42 #[serde(deserialize_with = "vecmap")]
43 pub sym2type: Vec<(u32, u32)>,
44 #[serde(deserialize_with = "vecmap")]
45 pub node2sym: Vec<(NodeReference, u32)>,
46 #[serde(deserialize_with = "vecmap")]
47 pub node2type: Vec<(NodeReference, u32)>,
48 #[serde(default, deserialize_with = "vecmap_or_empty")]
49 pub node_flags: Vec<(NodeReference, u32)>,
50 pub type_extra: TypeExtra,
51 pub primtypes: PrimTypes,
52 #[serde(default, deserialize_with = "vecmap_or_empty")]
54 pub alias_symbols: Vec<(u32, u32)>,
55 #[serde(default, deserialize_with = "vecmap_or_empty")]
57 pub shorthand_symbols: Vec<(NodeReference, u32)>,
58 #[serde(default, deserialize_with = "vecmap_or_empty")]
60 pub parameter_property_symbols: Vec<(NodeReference, u32)>,
61 #[serde(default)]
63 pub external_symbols: Vec<ExternalSymbol>,
64}
65
66#[derive(Debug, Clone, Deserialize)]
67pub struct NodeReference {
68 pub sourcefile_id: u32,
69 pub start: u32,
70 pub end: u32,
71}
72
73#[derive(Debug, Clone, Deserialize)]
74pub struct SymbolData {
75 #[serde(with = "serde_bytes")]
76 pub name: Vec<u8>,
77 pub flags: u32,
78 pub check_flags: u32,
79 #[serde(default)]
80 pub decl: Option<NodeReference>,
81}
82
83#[derive(Debug, Clone, Deserialize)]
84pub struct ExternalSymbol {
85 pub symbol_id: u32,
86 #[serde(with = "serde_bytes")]
87 pub namespace: Vec<u8>,
88 #[serde(with = "serde_bytes")]
89 pub name: Vec<u8>,
90}
91
92#[derive(Debug, Clone, Deserialize)]
93pub struct TypeData {
94 pub id: u32,
95 pub flags: u32,
96 #[serde(default)]
97 pub object_flags: u32,
98 #[serde(default)]
99 pub symbol: Option<u32>,
100}
101
102#[derive(Debug, Clone, Deserialize)]
103pub struct PrimTypes {
104 pub string: u32,
105 pub number: u32,
106 pub any: u32,
107 pub error: u32,
108 pub unknown: u32,
109 pub never: u32,
110 pub undefined: u32,
111 pub null: u32,
112 pub void: u32,
113 pub bool: u32,
114}
115
116#[derive(Debug, Clone, Deserialize)]
117pub struct TypeExtra {
118 pub name: HashMap<TypeId, serde_bytes::ByteBuf>,
119 pub func: HashMap<TypeId, FunctionData>,
120}
121#[derive(Debug, Clone, Deserialize)]
122pub struct FunctionData {
123 pub signatures: Vec<Signature>,
124}
125#[derive(Debug, Clone, Deserialize)]
126pub struct Signature {
127 pub result: TypeId,
128}
129
130fn vecmap<'de, K, V, D>(deserializer: D) -> Result<Vec<(K, V)>, D::Error>
131where
132 D: Deserializer<'de>,
133 K: Deserialize<'de>,
134 V: Deserialize<'de>,
135{
136 use serde::de::Visitor;
137 use std::marker::PhantomData;
138
139 struct VecMap<K, V>(PhantomData<(K, V)>);
140
141 impl<'de, K, V> Visitor<'de> for VecMap<K, V>
142 where
143 K: Deserialize<'de>,
144 V: Deserialize<'de>,
145 {
146 type Value = Vec<(K, V)>;
147
148 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
149 write!(formatter, "vec map")
150 }
151
152 fn visit_unit<E>(self) -> Result<Self::Value, E>
153 where
154 E: serde::de::Error,
155 {
156 Ok(Vec::new())
157 }
158
159 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
160 where
161 A: serde::de::MapAccess<'de>,
162 {
163 let len = map.size_hint().unwrap_or_default();
164 let len = std::cmp::min(len, 4096);
165 let mut out = Vec::with_capacity(len);
166
167 while let Some(e) = map.next_entry()? {
168 out.push(e);
169 }
170
171 Ok(out)
172 }
173 }
174
175 deserializer.deserialize_map(VecMap(PhantomData))
176}
177
178fn vecmap_or_empty<'de, K, V, D>(deserializer: D) -> Result<Vec<(K, V)>, D::Error>
179where
180 D: Deserializer<'de>,
181 K: Deserialize<'de>,
182 V: Deserialize<'de>,
183{
184 use serde::de::Visitor;
185 use std::marker::PhantomData;
186
187 struct VecMapOrEmpty<K, V>(PhantomData<(K, V)>);
188
189 impl<'de, K, V> Visitor<'de> for VecMapOrEmpty<K, V>
190 where
191 K: Deserialize<'de>,
192 V: Deserialize<'de>,
193 {
194 type Value = Vec<(K, V)>;
195
196 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
197 write!(formatter, "vec map or nothing")
198 }
199
200 fn visit_unit<E>(self) -> Result<Self::Value, E>
201 where
202 E: serde::de::Error,
203 {
204 Ok(Vec::new())
205 }
206
207 fn visit_none<E>(self) -> Result<Self::Value, E>
208 where
209 E: serde::de::Error,
210 {
211 Ok(Vec::new())
212 }
213
214 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
215 where
216 A: serde::de::MapAccess<'de>,
217 {
218 let len = map.size_hint().unwrap_or_default();
219 let len = std::cmp::min(len, 4096);
220 let mut out = Vec::with_capacity(len);
221
222 while let Some(e) = map.next_entry()? {
223 out.push(e);
224 }
225
226 Ok(out)
227 }
228 }
229
230 deserializer.deserialize_any(VecMapOrEmpty(PhantomData))
231}
232
233impl Semantic {
234 pub fn get_shorthand_assignment_value_symbol(&self, location: &NodeReference) -> Option<u32> {
250 self.shorthand_symbols
252 .iter()
253 .find(|(node_ref, _)| {
254 node_ref.sourcefile_id == location.sourcefile_id
255 && node_ref.start == location.start
256 && node_ref.end == location.end
257 })
258 .map(|(_, sym_id)| *sym_id)
259 }
260
261 pub fn get_parameter_property_symbol(&self, location: &NodeReference) -> Option<u32> {
267 self.parameter_property_symbols
268 .iter()
269 .find(|(node_ref, _)| {
270 node_ref.sourcefile_id == location.sourcefile_id
271 && node_ref.start == location.start
272 && node_ref.end == location.end
273 })
274 .map(|(_, sym_id)| *sym_id)
275 }
276}