]> git.lizzy.rs Git - rust.git/blob - src/librustc_save_analysis/json_dumper.rs
eb613c3afdab35c379398d36a39a54d595954341
[rust.git] / src / librustc_save_analysis / json_dumper.rs
1 // Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use std::io::Write;
12
13 use rustc::hir::def_id::DefId;
14 use rustc_serialize::json::as_json;
15
16 use external_data::*;
17 use data::VariableKind;
18 use dump::Dump;
19 use super::Format;
20
21 pub struct JsonDumper<'b, W: Write + 'b> {
22     output: &'b mut W,
23     result: Analysis,
24 }
25
26 impl<'b, W: Write> JsonDumper<'b, W> {
27     pub fn new(writer: &'b mut W) -> JsonDumper<'b, W> {
28         JsonDumper { output: writer, result: Analysis::new() }
29     }
30 }
31
32 impl<'b, W: Write> Drop for JsonDumper<'b, W> {
33     fn drop(&mut self) {
34         if let Err(_) = write!(self.output, "{}", as_json(&self.result)) {
35             error!("Error writing output");
36         }
37     }
38 }
39
40 macro_rules! impl_fn {
41     ($fn_name: ident, $data_type: ident, $bucket: ident) => {
42         fn $fn_name(&mut self, data: $data_type) {
43             self.result.$bucket.push(From::from(data));
44         }
45     }
46 }
47
48 impl<'b, W: Write + 'b> Dump for JsonDumper<'b, W> {
49     fn crate_prelude(&mut self, data: CratePreludeData) {
50         self.result.prelude = Some(data)
51     }
52
53     impl_fn!(extern_crate, ExternCrateData, imports);
54     impl_fn!(use_data, UseData, imports);
55     impl_fn!(use_glob, UseGlobData, imports);
56
57     impl_fn!(enum_data, EnumData, defs);
58     impl_fn!(tuple_variant, TupleVariantData, defs);
59     impl_fn!(struct_variant, StructVariantData, defs);
60     impl_fn!(struct_data, StructData, defs);
61     impl_fn!(trait_data, TraitData, defs);
62     impl_fn!(function, FunctionData, defs);
63     impl_fn!(method, MethodData, defs);
64     impl_fn!(macro_data, MacroData, defs);
65     impl_fn!(mod_data, ModData, defs);
66     impl_fn!(typedef, TypeDefData, defs);
67     impl_fn!(variable, VariableData, defs);
68
69     impl_fn!(function_ref, FunctionRefData, refs);
70     impl_fn!(function_call, FunctionCallData, refs);
71     impl_fn!(method_call, MethodCallData, refs);
72     impl_fn!(mod_ref, ModRefData, refs);
73     impl_fn!(type_ref, TypeRefData, refs);
74     impl_fn!(variable_ref, VariableRefData, refs);
75
76     impl_fn!(macro_use, MacroUseData, macro_refs);
77
78     // FIXME store this instead of throwing it away.
79     fn impl_data(&mut self, _data: ImplData) {}
80     fn inheritance(&mut self, _data: InheritanceData) {}
81 }
82
83 // FIXME do we want to change ExternalData to this mode? It will break DXR.
84 // FIXME methods. The defs have information about possible overriding and the
85 // refs have decl information (e.g., a trait method where we know the required
86 // method, but not the supplied method). In both cases, we are currently
87 // ignoring it.
88
89 #[derive(Debug, RustcEncodable)]
90 struct Analysis {
91     kind: Format,
92     prelude: Option<CratePreludeData>,
93     imports: Vec<Import>,
94     defs: Vec<Def>,
95     refs: Vec<Ref>,
96     macro_refs: Vec<MacroRef>,
97 }
98
99 impl Analysis {
100     fn new() -> Analysis {
101         Analysis {
102             kind: Format::Json,
103             prelude: None,
104             imports: vec![],
105             defs: vec![],
106             refs: vec![],
107             macro_refs: vec![],
108         }
109     }
110 }
111
112 // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
113 // we use our own Id which is the same, but without the newtype.
114 #[derive(Debug, RustcEncodable)]
115 struct Id {
116     krate: u32,
117     index: u32,
118 }
119
120 impl From<DefId> for Id {
121     fn from(id: DefId) -> Id {
122         Id {
123             krate: id.krate.as_u32(),
124             index: id.index.as_u32(),
125         }
126     }
127 }
128
129 #[derive(Debug, RustcEncodable)]
130 struct Import {
131     kind: ImportKind,
132     ref_id: Option<Id>,
133     span: SpanData,
134     name: String,
135     value: String,
136 }
137
138 #[derive(Debug, RustcEncodable)]
139 enum ImportKind {
140     ExternCrate,
141     Use,
142     GlobUse,
143 }
144
145 impl From<ExternCrateData> for Import {
146     fn from(data: ExternCrateData) -> Import {
147         Import {
148             kind: ImportKind::ExternCrate,
149             ref_id: None,
150             span: data.span,
151             name: data.name,
152             value: String::new(),
153         }
154     }
155 }
156 impl From<UseData> for Import {
157     fn from(data: UseData) -> Import {
158         Import {
159             kind: ImportKind::Use,
160             ref_id: data.mod_id.map(|id| From::from(id)),
161             span: data.span,
162             name: data.name,
163             value: String::new(),
164         }
165     }
166 }
167 impl From<UseGlobData> for Import {
168     fn from(data: UseGlobData) -> Import {
169         Import {
170             kind: ImportKind::GlobUse,
171             ref_id: None,
172             span: data.span,
173             name: "*".to_owned(),
174             value: data.names.join(", "),
175         }
176     }
177 }
178
179 #[derive(Debug, RustcEncodable)]
180 struct Def {
181     kind: DefKind,
182     id: Id,
183     span: SpanData,
184     name: String,
185     qualname: String,
186     value: String,
187     children: Vec<Id>,
188     decl_id: Option<Id>,
189     docs: String,
190 }
191
192 #[derive(Debug, RustcEncodable)]
193 enum DefKind {
194     // value = variant names
195     Enum,
196     // value = enum name + variant name + types
197     Tuple,
198     // value = [enum name +] name + fields
199     Struct,
200     // value = signature
201     Trait,
202     // value = type + generics
203     Function,
204     // value = type + generics
205     Method,
206     // No id, no value.
207     Macro,
208     // value = file_name
209     Mod,
210     // value = aliased type
211     Type,
212     // value = type and init expression (for all variable kinds).
213     Local,
214     Static,
215     Const,
216     Field,
217 }
218
219 impl From<EnumData> for Def {
220     fn from(data: EnumData) -> Def {
221         Def {
222             kind: DefKind::Enum,
223             id: From::from(data.id),
224             span: data.span,
225             name: data.name,
226             qualname: data.qualname,
227             value: data.value,
228             children: data.variants.into_iter().map(|id| From::from(id)).collect(),
229             decl_id: None,
230             docs: data.docs,
231         }
232     }
233 }
234
235 impl From<TupleVariantData> for Def {
236     fn from(data: TupleVariantData) -> Def {
237         Def {
238             kind: DefKind::Tuple,
239             id: From::from(data.id),
240             span: data.span,
241             name: data.name,
242             qualname: data.qualname,
243             value: data.value,
244             children: vec![],
245             decl_id: None,
246             docs: data.docs,
247         }
248     }
249 }
250 impl From<StructVariantData> for Def {
251     fn from(data: StructVariantData) -> Def {
252         Def {
253             kind: DefKind::Struct,
254             id: From::from(data.id),
255             span: data.span,
256             name: data.name,
257             qualname: data.qualname,
258             value: data.value,
259             children: vec![],
260             decl_id: None,
261             docs: data.docs,
262         }
263     }
264 }
265 impl From<StructData> for Def {
266     fn from(data: StructData) -> Def {
267         Def {
268             kind: DefKind::Struct,
269             id: From::from(data.id),
270             span: data.span,
271             name: data.name,
272             qualname: data.qualname,
273             value: data.value,
274             children: data.fields.into_iter().map(|id| From::from(id)).collect(),
275             decl_id: None,
276             docs: data.docs,
277         }
278     }
279 }
280 impl From<TraitData> for Def {
281     fn from(data: TraitData) -> Def {
282         Def {
283             kind: DefKind::Trait,
284             id: From::from(data.id),
285             span: data.span,
286             name: data.name,
287             qualname: data.qualname,
288             value: data.value,
289             children: data.items.into_iter().map(|id| From::from(id)).collect(),
290             decl_id: None,
291             docs: data.docs,
292         }
293     }
294 }
295 impl From<FunctionData> for Def {
296     fn from(data: FunctionData) -> Def {
297         Def {
298             kind: DefKind::Function,
299             id: From::from(data.id),
300             span: data.span,
301             name: data.name,
302             qualname: data.qualname,
303             value: data.value,
304             children: vec![],
305             decl_id: None,
306             docs: data.docs,
307         }
308     }
309 }
310 impl From<MethodData> for Def {
311     fn from(data: MethodData) -> Def {
312         Def {
313             kind: DefKind::Method,
314             id: From::from(data.id),
315             span: data.span,
316             name: data.name,
317             qualname: data.qualname,
318             value: data.value,
319             children: vec![],
320             decl_id: data.decl_id.map(|id| From::from(id)),
321             docs: data.docs,
322         }
323     }
324 }
325 impl From<MacroData> for Def {
326     fn from(data: MacroData) -> Def {
327         Def {
328             kind: DefKind::Macro,
329             id: From::from(null_def_id()),
330             span: data.span,
331             name: data.name,
332             qualname: data.qualname,
333             value: String::new(),
334             children: vec![],
335             decl_id: None,
336             docs: data.docs,
337         }
338     }
339 }
340 impl From<ModData> for Def {
341     fn from(data:ModData) -> Def {
342         Def {
343             kind: DefKind::Mod,
344             id: From::from(data.id),
345             span: data.span,
346             name: data.name,
347             qualname: data.qualname,
348             value: data.filename,
349             children: data.items.into_iter().map(|id| From::from(id)).collect(),
350             decl_id: None,
351             docs: data.docs,
352         }
353     }
354 }
355 impl From<TypeDefData> for Def {
356     fn from(data: TypeDefData) -> Def {
357         Def {
358             kind: DefKind::Type,
359             id: From::from(data.id),
360             span: data.span,
361             name: data.name,
362             qualname: data.qualname,
363             value: data.value,
364             children: vec![],
365             decl_id: None,
366             docs: String::new(),
367         }
368     }
369 }
370 impl From<VariableData> for Def {
371     fn from(data: VariableData) -> Def {
372         Def {
373             kind: match data.kind {
374                 VariableKind::Static => DefKind::Static,
375                 VariableKind::Const => DefKind::Const,
376                 VariableKind::Local => DefKind::Local,
377                 VariableKind::Field => DefKind::Field,
378             },
379             id: From::from(data.id),
380             span: data.span,
381             name: data.name,
382             qualname: data.qualname,
383             value: data.type_value,
384             children: vec![],
385             decl_id: None,
386             docs: data.docs,
387         }
388     }
389 }
390
391 #[derive(Debug, RustcEncodable)]
392 enum RefKind {
393     Function,
394     Mod,
395     Type,
396     Variable,
397 }
398
399 #[derive(Debug, RustcEncodable)]
400 struct Ref {
401     kind: RefKind,
402     span: SpanData,
403     ref_id: Id,
404 }
405
406 impl From<FunctionRefData> for Ref {
407     fn from(data: FunctionRefData) -> Ref {
408         Ref {
409             kind: RefKind::Function,
410             span: data.span,
411             ref_id: From::from(data.ref_id),
412         }
413     }
414 }
415 impl From<FunctionCallData> for Ref {
416     fn from(data: FunctionCallData) -> Ref {
417         Ref {
418             kind: RefKind::Function,
419             span: data.span,
420             ref_id: From::from(data.ref_id),
421         }
422     }
423 }
424 impl From<MethodCallData> for Ref {
425     fn from(data: MethodCallData) -> Ref {
426         Ref {
427             kind: RefKind::Function,
428             span: data.span,
429             ref_id: From::from(data.ref_id.or(data.decl_id).unwrap_or(null_def_id())),
430         }
431     }
432 }
433 impl From<ModRefData> for Ref {
434     fn from(data: ModRefData) -> Ref {
435         Ref {
436             kind: RefKind::Mod,
437             span: data.span,
438             ref_id: From::from(data.ref_id.unwrap_or(null_def_id())),
439         }
440     }
441 }
442 impl From<TypeRefData> for Ref {
443     fn from(data: TypeRefData) -> Ref {
444         Ref {
445             kind: RefKind::Type,
446             span: data.span,
447             ref_id: From::from(data.ref_id.unwrap_or(null_def_id())),
448         }
449     }
450 }
451 impl From<VariableRefData> for Ref {
452     fn from(data: VariableRefData) -> Ref {
453         Ref {
454             kind: RefKind::Variable,
455             span: data.span,
456             ref_id: From::from(data.ref_id),
457         }
458     }
459 }
460
461 #[derive(Debug, RustcEncodable)]
462 struct MacroRef {
463     span: SpanData,
464     qualname: String,
465     callee_span: SpanData,
466 }
467
468 impl From<MacroUseData> for MacroRef {
469     fn from(data: MacroUseData) -> MacroRef {
470         MacroRef {
471             span: data.span,
472             qualname: data.qualname,
473             callee_span: data.callee_span,
474         }
475     }
476 }