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
!(typedef
, TypeDefData
, defs
);
66 impl_fn
!(variable
, VariableData
, defs
);
68 impl_fn
!(function_ref
, FunctionRefData
, refs
);
69 impl_fn
!(function_call
, FunctionCallData
, refs
);
70 impl_fn
!(method_call
, MethodCallData
, refs
);
71 impl_fn
!(mod_ref
, ModRefData
, refs
);
72 impl_fn
!(type_ref
, TypeRefData
, refs
);
73 impl_fn
!(variable_ref
, VariableRefData
, refs
);
75 impl_fn
!(macro_use
, MacroUseData
, macro_refs
);
77 fn mod_data(&mut self, data
: ModData
) {
78 let id
: Id
= From
::from(data
.id
);
84 qualname
: data
.qualname
,
86 children
: data
.items
.into_iter().map(|id
| From
::from(id
)).collect(),
90 if def
.span
.file_name
!= def
.value
{
91 // If the module is an out-of-line defintion, then we'll make the
92 // defintion the first character in the module's file and turn the
93 // the declaration into a reference to it.
99 self.result
.refs
.push(rf
);
100 def
.span
= SpanData
{
101 file_name
: def
.value
.clone(),
111 self.result
.defs
.push(def
);
114 // FIXME store this instead of throwing it away.
115 fn impl_data(&mut self, _data
: ImplData
) {}
116 fn inheritance(&mut self, _data
: InheritanceData
) {}
119 // FIXME do we want to change ExternalData to this mode? It will break DXR.
120 // FIXME methods. The defs have information about possible overriding and the
121 // refs have decl information (e.g., a trait method where we know the required
122 // method, but not the supplied method). In both cases, we are currently
125 #[derive(Debug, RustcEncodable)]
128 prelude
: Option
<CratePreludeData
>,
129 imports
: Vec
<Import
>,
132 macro_refs
: Vec
<MacroRef
>,
136 fn new() -> Analysis
{
148 // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
149 // we use our own Id which is the same, but without the newtype.
150 #[derive(Clone, Copy, Debug, RustcEncodable)]
156 impl From
<DefId
> for Id
{
157 fn from(id
: DefId
) -> Id
{
159 krate
: id
.krate
.as_u32(),
160 index
: id
.index
.as_u32(),
165 #[derive(Debug, RustcEncodable)]
174 #[derive(Debug, RustcEncodable)]
181 impl From
<ExternCrateData
> for Import
{
182 fn from(data
: ExternCrateData
) -> Import
{
184 kind
: ImportKind
::ExternCrate
,
188 value
: String
::new(),
192 impl From
<UseData
> for Import
{
193 fn from(data
: UseData
) -> Import
{
195 kind
: ImportKind
::Use
,
196 ref_id
: data
.mod_id
.map(|id
| From
::from(id
)),
199 value
: String
::new(),
203 impl From
<UseGlobData
> for Import
{
204 fn from(data
: UseGlobData
) -> Import
{
206 kind
: ImportKind
::GlobUse
,
209 name
: "*".to_owned(),
210 value
: data
.names
.join(", "),
215 #[derive(Debug, RustcEncodable)]
228 #[derive(Debug, RustcEncodable)]
230 // value = variant names
232 // value = enum name + variant name + types
234 // value = [enum name +] name + fields
238 // value = type + generics
240 // value = type + generics
246 // value = aliased type
248 // value = type and init expression (for all variable kinds).
255 impl From
<EnumData
> for Def
{
256 fn from(data
: EnumData
) -> Def
{
259 id
: From
::from(data
.id
),
262 qualname
: data
.qualname
,
264 children
: data
.variants
.into_iter().map(|id
| From
::from(id
)).collect(),
271 impl From
<TupleVariantData
> for Def
{
272 fn from(data
: TupleVariantData
) -> Def
{
274 kind
: DefKind
::Tuple
,
275 id
: From
::from(data
.id
),
278 qualname
: data
.qualname
,
286 impl From
<StructVariantData
> for Def
{
287 fn from(data
: StructVariantData
) -> Def
{
289 kind
: DefKind
::Struct
,
290 id
: From
::from(data
.id
),
293 qualname
: data
.qualname
,
301 impl From
<StructData
> for Def
{
302 fn from(data
: StructData
) -> Def
{
304 kind
: DefKind
::Struct
,
305 id
: From
::from(data
.id
),
308 qualname
: data
.qualname
,
310 children
: data
.fields
.into_iter().map(|id
| From
::from(id
)).collect(),
316 impl From
<TraitData
> for Def
{
317 fn from(data
: TraitData
) -> Def
{
319 kind
: DefKind
::Trait
,
320 id
: From
::from(data
.id
),
323 qualname
: data
.qualname
,
325 children
: data
.items
.into_iter().map(|id
| From
::from(id
)).collect(),
331 impl From
<FunctionData
> for Def
{
332 fn from(data
: FunctionData
) -> Def
{
334 kind
: DefKind
::Function
,
335 id
: From
::from(data
.id
),
338 qualname
: data
.qualname
,
346 impl From
<MethodData
> for Def
{
347 fn from(data
: MethodData
) -> Def
{
349 kind
: DefKind
::Method
,
350 id
: From
::from(data
.id
),
353 qualname
: data
.qualname
,
356 decl_id
: data
.decl_id
.map(|id
| From
::from(id
)),
361 impl From
<MacroData
> for Def
{
362 fn from(data
: MacroData
) -> Def
{
364 kind
: DefKind
::Macro
,
365 id
: From
::from(null_def_id()),
368 qualname
: data
.qualname
,
369 value
: String
::new(),
377 impl From
<TypeDefData
> for Def
{
378 fn from(data
: TypeDefData
) -> Def
{
381 id
: From
::from(data
.id
),
384 qualname
: data
.qualname
,
392 impl From
<VariableData
> for Def
{
393 fn from(data
: VariableData
) -> Def
{
395 kind
: match data
.kind
{
396 VariableKind
::Static
=> DefKind
::Static
,
397 VariableKind
::Const
=> DefKind
::Const
,
398 VariableKind
::Local
=> DefKind
::Local
,
399 VariableKind
::Field
=> DefKind
::Field
,
401 id
: From
::from(data
.id
),
404 qualname
: data
.qualname
,
405 value
: data
.type_value
,
413 #[derive(Debug, RustcEncodable)]
421 #[derive(Debug, RustcEncodable)]
428 impl From
<FunctionRefData
> for Ref
{
429 fn from(data
: FunctionRefData
) -> Ref
{
431 kind
: RefKind
::Function
,
433 ref_id
: From
::from(data
.ref_id
),
437 impl From
<FunctionCallData
> for Ref
{
438 fn from(data
: FunctionCallData
) -> Ref
{
440 kind
: RefKind
::Function
,
442 ref_id
: From
::from(data
.ref_id
),
446 impl From
<MethodCallData
> for Ref
{
447 fn from(data
: MethodCallData
) -> Ref
{
449 kind
: RefKind
::Function
,
451 ref_id
: From
::from(data
.ref_id
.or(data
.decl_id
).unwrap_or(null_def_id())),
455 impl From
<ModRefData
> for Ref
{
456 fn from(data
: ModRefData
) -> Ref
{
460 ref_id
: From
::from(data
.ref_id
.unwrap_or(null_def_id())),
464 impl From
<TypeRefData
> for Ref
{
465 fn from(data
: TypeRefData
) -> Ref
{
469 ref_id
: From
::from(data
.ref_id
.unwrap_or(null_def_id())),
473 impl From
<VariableRefData
> for Ref
{
474 fn from(data
: VariableRefData
) -> Ref
{
476 kind
: RefKind
::Variable
,
478 ref_id
: From
::from(data
.ref_id
),
483 #[derive(Debug, RustcEncodable)]
487 callee_span
: SpanData
,
490 impl From
<MacroUseData
> for MacroRef
{
491 fn from(data
: MacroUseData
) -> MacroRef
{
494 qualname
: data
.qualname
,
495 callee_span
: data
.callee_span
,