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