1use crate::js_doc::JsDoc;
4use serde::Deserialize;
5use serde::Serialize;
6use std::sync::Arc;
7
8#[derive(Debug, Serialize, Deserialize, Clone)]
9pub struct NamespaceDef {
10 pub elements: Vec<Arc<DocNode>>,
11}
12
13#[derive(
14 Debug,
15 PartialEq,
16 Eq,
17 PartialOrd,
18 Ord,
19 Hash,
20 Serialize,
21 Deserialize,
22 Clone,
23 Copy,
24)]
25#[serde(rename_all = "camelCase")]
26pub enum DocNodeKind {
27 Class,
30 Enum,
31 Function,
32 Import,
33 Interface,
34 ModuleDoc,
35 Namespace,
36 Reference,
37 TypeAlias,
38 Variable,
39}
40
41#[derive(
42 Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash, Default,
43)]
44#[serde(rename_all = "camelCase")]
45pub struct Location {
46 pub filename: Box<str>,
47 pub line: usize,
50 pub col: usize,
52 #[serde(default)]
53 pub byte_index: usize,
55}
56
57impl Ord for Location {
58 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
59 match self.filename.cmp(&other.filename) {
60 core::cmp::Ordering::Equal => match self.line.cmp(&other.line) {
61 core::cmp::Ordering::Equal => self.col.cmp(&other.col),
62 ord => ord,
63 },
64 ord => ord,
65 }
66 }
67}
68
69impl PartialOrd for Location {
70 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
71 Some(self.cmp(other))
72 }
73}
74
75#[derive(Debug, Serialize, Deserialize, Clone)]
76#[serde(rename_all = "camelCase")]
77pub struct ImportDef {
78 pub src: String,
79 pub imported: Option<String>,
80}
81
82#[derive(Debug, Serialize, Deserialize, Clone)]
83#[serde(rename_all = "camelCase")]
84pub struct ReferenceDef {
85 pub target: Location,
86}
87
88#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
89#[serde(rename_all = "camelCase")]
90pub enum DeclarationKind {
91 Private,
92 Declare,
93 Export,
94}
95
96#[derive(Debug, Serialize, Deserialize, Clone)]
97#[serde(rename_all = "camelCase")]
98pub struct DocNode {
99 pub name: Box<str>,
100 #[serde(skip_serializing_if = "Option::is_none", default)]
101 pub is_default: Option<bool>,
102 pub location: Location,
103 pub declaration_kind: DeclarationKind,
104 #[serde(skip_serializing_if = "JsDoc::is_empty", default)]
105 pub js_doc: JsDoc,
106 #[serde(flatten)]
107 pub def: DocNodeDef,
108}
109
110#[derive(Debug, Serialize, Deserialize, Clone)]
111#[serde(tag = "kind", rename_all = "camelCase")]
112pub enum DocNodeDef {
113 #[serde(rename_all = "camelCase")]
114 Function {
115 function_def: super::function::FunctionDef,
116 },
117 #[serde(rename_all = "camelCase")]
118 Variable {
119 variable_def: super::variable::VariableDef,
120 },
121 #[serde(rename_all = "camelCase")]
122 Enum {
123 enum_def: super::r#enum::EnumDef,
124 },
125 #[serde(rename_all = "camelCase")]
126 Class {
127 class_def: super::class::ClassDef,
128 },
129 #[serde(rename_all = "camelCase")]
130 TypeAlias {
131 type_alias_def: super::type_alias::TypeAliasDef,
132 },
133 #[serde(rename_all = "camelCase")]
134 Namespace {
135 namespace_def: NamespaceDef,
136 },
137 #[serde(rename_all = "camelCase")]
138 Interface {
139 interface_def: super::interface::InterfaceDef,
140 },
141 #[serde(rename_all = "camelCase")]
142 Import {
143 import_def: ImportDef,
144 },
145 ModuleDoc,
146 Reference {
147 reference_def: ReferenceDef,
148 },
149}
150
151impl Default for DocNode {
152 fn default() -> Self {
153 Self {
154 is_default: None,
155 name: "".into(),
156 declaration_kind: DeclarationKind::Private,
157 location: Location::default(),
158 js_doc: JsDoc::default(),
159 def: DocNodeDef::ModuleDoc,
160 }
161 }
162}
163
164impl DocNode {
165 pub fn module_doc(location: Location, js_doc: JsDoc) -> Self {
166 Self {
167 name: "".into(),
168 is_default: None,
169 location,
170 declaration_kind: DeclarationKind::Export,
171 js_doc,
172 def: DocNodeDef::ModuleDoc,
173 }
174 }
175
176 pub fn function(
177 name: Box<str>,
178 is_default: bool,
179 location: Location,
180 declaration_kind: DeclarationKind,
181 js_doc: JsDoc,
182 fn_def: super::function::FunctionDef,
183 ) -> Self {
184 Self {
185 name,
186 is_default: Some(is_default),
187 location,
188 declaration_kind,
189 js_doc,
190 def: DocNodeDef::Function {
191 function_def: fn_def,
192 },
193 }
194 }
195
196 pub fn variable(
197 name: Box<str>,
198 is_default: bool,
199 location: Location,
200 declaration_kind: DeclarationKind,
201 js_doc: JsDoc,
202 var_def: super::variable::VariableDef,
203 ) -> Self {
204 Self {
205 name,
206 is_default: Some(is_default),
207 declaration_kind,
208 location,
209 js_doc,
210 def: DocNodeDef::Variable {
211 variable_def: var_def,
212 },
213 }
214 }
215
216 pub fn r#enum(
217 name: Box<str>,
218 is_default: bool,
219 location: Location,
220 declaration_kind: DeclarationKind,
221 js_doc: JsDoc,
222 enum_def: super::r#enum::EnumDef,
223 ) -> Self {
224 Self {
225 name,
226 is_default: Some(is_default),
227 declaration_kind,
228 location,
229 js_doc,
230 def: DocNodeDef::Enum { enum_def },
231 }
232 }
233
234 pub fn class(
235 name: Box<str>,
236 is_default: bool,
237 location: Location,
238 declaration_kind: DeclarationKind,
239 js_doc: JsDoc,
240 class_def: super::class::ClassDef,
241 ) -> Self {
242 Self {
243 name,
244 is_default: Some(is_default),
245 declaration_kind,
246 location,
247 js_doc,
248 def: DocNodeDef::Class { class_def },
249 }
250 }
251
252 pub fn type_alias(
253 name: Box<str>,
254 is_default: bool,
255 location: Location,
256 declaration_kind: DeclarationKind,
257 js_doc: JsDoc,
258 type_alias_def: super::type_alias::TypeAliasDef,
259 ) -> Self {
260 Self {
261 name,
262 is_default: Some(is_default),
263 declaration_kind,
264 location,
265 js_doc,
266 def: DocNodeDef::TypeAlias { type_alias_def },
267 }
268 }
269
270 pub fn namespace(
271 name: Box<str>,
272 is_default: bool,
273 location: Location,
274 declaration_kind: DeclarationKind,
275 js_doc: JsDoc,
276 namespace_def: NamespaceDef,
277 ) -> Self {
278 Self {
279 name,
280 is_default: Some(is_default),
281 declaration_kind,
282 location,
283 js_doc,
284 def: DocNodeDef::Namespace { namespace_def },
285 }
286 }
287
288 pub fn interface(
289 name: Box<str>,
290 is_default: bool,
291 location: Location,
292 declaration_kind: DeclarationKind,
293 js_doc: JsDoc,
294 interface_def: super::interface::InterfaceDef,
295 ) -> Self {
296 Self {
297 name,
298 is_default: Some(is_default),
299 declaration_kind,
300 location,
301 js_doc,
302 def: DocNodeDef::Interface { interface_def },
303 }
304 }
305
306 pub fn import(
307 name: Box<str>,
308 location: Location,
309 js_doc: JsDoc,
310 import_def: ImportDef,
311 ) -> Self {
312 Self {
313 name,
314 is_default: None,
315 declaration_kind: DeclarationKind::Private,
316 location,
317 js_doc,
318 def: DocNodeDef::Import { import_def },
319 }
320 }
321
322 pub fn reference(
323 name: Box<str>,
324 location: Location,
325 js_doc: JsDoc,
326 reference_def: ReferenceDef,
327 ) -> Self {
328 Self {
329 name,
330 is_default: None,
331 declaration_kind: DeclarationKind::Private,
332 location,
333 js_doc,
334 def: DocNodeDef::Reference { reference_def },
335 }
336 }
337
338 pub fn get_name(&self) -> &str {
339 let default_name = match &self.def {
340 DocNodeDef::Class { class_def } => class_def.def_name.as_deref(),
341 DocNodeDef::Function { function_def } => function_def.def_name.as_deref(),
342 DocNodeDef::Interface { interface_def } => {
343 interface_def.def_name.as_deref()
344 }
345 DocNodeDef::Enum { .. }
346 | DocNodeDef::Import { .. }
347 | DocNodeDef::ModuleDoc { .. }
348 | DocNodeDef::Namespace { .. }
349 | DocNodeDef::TypeAlias { .. }
350 | DocNodeDef::Variable { .. }
351 | DocNodeDef::Reference { .. } => None,
352 };
353
354 default_name.unwrap_or(&self.name)
355 }
356
357 pub fn class_def(&self) -> Option<&super::class::ClassDef> {
358 match &self.def {
359 DocNodeDef::Class { class_def } => Some(class_def),
360 _ => None,
361 }
362 }
363
364 pub fn function_def(&self) -> Option<&super::function::FunctionDef> {
365 match &self.def {
366 DocNodeDef::Function { function_def } => Some(function_def),
367 _ => None,
368 }
369 }
370
371 pub fn variable_def(&self) -> Option<&super::variable::VariableDef> {
372 match &self.def {
373 DocNodeDef::Variable { variable_def } => Some(variable_def),
374 _ => None,
375 }
376 }
377
378 pub fn enum_def(&self) -> Option<&super::r#enum::EnumDef> {
379 match &self.def {
380 DocNodeDef::Enum { enum_def } => Some(enum_def),
381 _ => None,
382 }
383 }
384
385 pub fn type_alias_def(&self) -> Option<&super::type_alias::TypeAliasDef> {
386 match &self.def {
387 DocNodeDef::TypeAlias { type_alias_def } => Some(type_alias_def),
388 _ => None,
389 }
390 }
391
392 pub fn namespace_def(&self) -> Option<&NamespaceDef> {
393 match &self.def {
394 DocNodeDef::Namespace { namespace_def } => Some(namespace_def),
395 _ => None,
396 }
397 }
398
399 pub fn interface_def(&self) -> Option<&super::interface::InterfaceDef> {
400 match &self.def {
401 DocNodeDef::Interface { interface_def } => Some(interface_def),
402 _ => None,
403 }
404 }
405
406 pub fn import_def(&self) -> Option<&ImportDef> {
407 match &self.def {
408 DocNodeDef::Import { import_def } => Some(import_def),
409 _ => None,
410 }
411 }
412
413 pub fn reference_def(&self) -> Option<&ReferenceDef> {
414 match &self.def {
415 DocNodeDef::Reference { reference_def } => Some(reference_def),
416 _ => None,
417 }
418 }
419}