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.
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.
13 use rustc
::hir
::def_id
::DefId
;
14 use rustc_serialize
::json
::as_json
;
17 use data
::VariableKind
;
21 pub struct JsonDumper
<'b
, W
: Write
+ 'b
> {
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() }
32 impl<'b
, W
: Write
> Drop
for JsonDumper
<'b
, W
> {
34 if let Err(_
) = write
!(self.output
, "{}", as_json(&self.result
)) {
35 error
!("Error writing output");
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
));
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
)
53 impl_fn
!(extern_crate
, ExternCrateData
, imports
);
54 impl_fn
!(use_data
, UseData
, imports
);
55 impl_fn
!(use_glob
, UseGlobData
, imports
);
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
);
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
);
76 impl_fn
!(macro_use
, MacroUseData
, macro_refs
);
78 // FIXME store this instead of throwing it away.
79 fn impl_data(&mut self, _data
: ImplData
) {}
80 fn inheritance(&mut self, _data
: InheritanceData
) {}
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
89 #[derive(Debug, RustcEncodable)]
92 prelude
: Option
<CratePreludeData
>,
96 macro_refs
: Vec
<MacroRef
>,
100 fn new() -> Analysis
{
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)]
120 impl From
<DefId
> for Id
{
121 fn from(id
: DefId
) -> Id
{
123 krate
: id
.krate
.as_u32(),
124 index
: id
.index
.as_u32(),
129 #[derive(Debug, RustcEncodable)]
138 #[derive(Debug, RustcEncodable)]
145 impl From
<ExternCrateData
> for Import
{
146 fn from(data
: ExternCrateData
) -> Import
{
148 kind
: ImportKind
::ExternCrate
,
152 value
: String
::new(),
156 impl From
<UseData
> for Import
{
157 fn from(data
: UseData
) -> Import
{
159 kind
: ImportKind
::Use
,
160 ref_id
: data
.mod_id
.map(|id
| From
::from(id
)),
163 value
: String
::new(),
167 impl From
<UseGlobData
> for Import
{
168 fn from(data
: UseGlobData
) -> Import
{
170 kind
: ImportKind
::GlobUse
,
173 name
: "*".to_owned(),
174 value
: data
.names
.join(", "),
179 #[derive(Debug, RustcEncodable)]
192 #[derive(Debug, RustcEncodable)]
194 // value = variant names
196 // value = enum name + variant name + types
198 // value = [enum name +] name + fields
202 // value = type + generics
204 // value = type + generics
210 // value = aliased type
212 // value = type and init expression (for all variable kinds).
219 impl From
<EnumData
> for Def
{
220 fn from(data
: EnumData
) -> Def
{
223 id
: From
::from(data
.id
),
226 qualname
: data
.qualname
,
228 children
: data
.variants
.into_iter().map(|id
| From
::from(id
)).collect(),
235 impl From
<TupleVariantData
> for Def
{
236 fn from(data
: TupleVariantData
) -> Def
{
238 kind
: DefKind
::Tuple
,
239 id
: From
::from(data
.id
),
242 qualname
: data
.qualname
,
250 impl From
<StructVariantData
> for Def
{
251 fn from(data
: StructVariantData
) -> Def
{
253 kind
: DefKind
::Struct
,
254 id
: From
::from(data
.id
),
257 qualname
: data
.qualname
,
265 impl From
<StructData
> for Def
{
266 fn from(data
: StructData
) -> Def
{
268 kind
: DefKind
::Struct
,
269 id
: From
::from(data
.id
),
272 qualname
: data
.qualname
,
274 children
: data
.fields
.into_iter().map(|id
| From
::from(id
)).collect(),
280 impl From
<TraitData
> for Def
{
281 fn from(data
: TraitData
) -> Def
{
283 kind
: DefKind
::Trait
,
284 id
: From
::from(data
.id
),
287 qualname
: data
.qualname
,
289 children
: data
.items
.into_iter().map(|id
| From
::from(id
)).collect(),
295 impl From
<FunctionData
> for Def
{
296 fn from(data
: FunctionData
) -> Def
{
298 kind
: DefKind
::Function
,
299 id
: From
::from(data
.id
),
302 qualname
: data
.qualname
,
310 impl From
<MethodData
> for Def
{
311 fn from(data
: MethodData
) -> Def
{
313 kind
: DefKind
::Method
,
314 id
: From
::from(data
.id
),
317 qualname
: data
.qualname
,
320 decl_id
: data
.decl_id
.map(|id
| From
::from(id
)),
325 impl From
<MacroData
> for Def
{
326 fn from(data
: MacroData
) -> Def
{
328 kind
: DefKind
::Macro
,
329 id
: From
::from(null_def_id()),
332 qualname
: data
.qualname
,
333 value
: String
::new(),
340 impl From
<ModData
> for Def
{
341 fn from(data
:ModData
) -> Def
{
344 id
: From
::from(data
.id
),
347 qualname
: data
.qualname
,
348 value
: data
.filename
,
349 children
: data
.items
.into_iter().map(|id
| From
::from(id
)).collect(),
355 impl From
<TypeDefData
> for Def
{
356 fn from(data
: TypeDefData
) -> Def
{
359 id
: From
::from(data
.id
),
362 qualname
: data
.qualname
,
370 impl From
<VariableData
> for Def
{
371 fn from(data
: VariableData
) -> 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
,
379 id
: From
::from(data
.id
),
382 qualname
: data
.qualname
,
383 value
: data
.type_value
,
391 #[derive(Debug, RustcEncodable)]
399 #[derive(Debug, RustcEncodable)]
406 impl From
<FunctionRefData
> for Ref
{
407 fn from(data
: FunctionRefData
) -> Ref
{
409 kind
: RefKind
::Function
,
411 ref_id
: From
::from(data
.ref_id
),
415 impl From
<FunctionCallData
> for Ref
{
416 fn from(data
: FunctionCallData
) -> Ref
{
418 kind
: RefKind
::Function
,
420 ref_id
: From
::from(data
.ref_id
),
424 impl From
<MethodCallData
> for Ref
{
425 fn from(data
: MethodCallData
) -> Ref
{
427 kind
: RefKind
::Function
,
429 ref_id
: From
::from(data
.ref_id
.or(data
.decl_id
).unwrap_or(null_def_id())),
433 impl From
<ModRefData
> for Ref
{
434 fn from(data
: ModRefData
) -> Ref
{
438 ref_id
: From
::from(data
.ref_id
.unwrap_or(null_def_id())),
442 impl From
<TypeRefData
> for Ref
{
443 fn from(data
: TypeRefData
) -> Ref
{
447 ref_id
: From
::from(data
.ref_id
.unwrap_or(null_def_id())),
451 impl From
<VariableRefData
> for Ref
{
452 fn from(data
: VariableRefData
) -> Ref
{
454 kind
: RefKind
::Variable
,
456 ref_id
: From
::from(data
.ref_id
),
461 #[derive(Debug, RustcEncodable)]
465 callee_span
: SpanData
,
468 impl From
<MacroUseData
> for MacroRef
{
469 fn from(data
: MacroUseData
) -> MacroRef
{
472 qualname
: data
.qualname
,
473 callee_span
: data
.callee_span
,