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, Visibility}
;
22 // A dumper to dump a restricted set of JSON information, designed for use with
23 // libraries distributed without their source. Clients are likely to use type
24 // information here, and (for example) generate Rustdoc URLs, but don't need
25 // information for navigating the source of the crate.
26 // Relative to the regular JSON save-analysis info, this form is filtered to
27 // remove non-visible items, but includes some extra info for items (e.g., the
28 // parent field for finding the struct to which a field belongs).
29 pub struct JsonApiDumper
<'b
, W
: Write
+ 'b
> {
34 impl<'b
, W
: Write
> JsonApiDumper
<'b
, W
> {
35 pub fn new(writer
: &'b
mut W
) -> JsonApiDumper
<'b
, W
> {
36 JsonApiDumper { output: writer, result: Analysis::new() }
40 impl<'b
, W
: Write
> Drop
for JsonApiDumper
<'b
, W
> {
42 if let Err(_
) = write
!(self.output
, "{}", as_json(&self.result
)) {
43 error
!("Error writing output");
48 macro_rules
! impl_fn
{
49 ($fn_name
: ident
, $data_type
: ident
, $bucket
: ident
) => {
50 fn $
fn_name(&mut self, data
: $data_type
) {
51 if let Some(datum
) = From
::from(data
) {
52 self.result
.$bucket
.push(datum
);
58 impl<'b
, W
: Write
+ 'b
> Dump
for JsonApiDumper
<'b
, W
> {
59 fn crate_prelude(&mut self, data
: CratePreludeData
) {
60 self.result
.prelude
= Some(data
)
63 impl_fn
!(use_data
, UseData
, imports
);
64 impl_fn
!(use_glob
, UseGlobData
, imports
);
66 impl_fn
!(enum_data
, EnumData
, defs
);
67 impl_fn
!(tuple_variant
, TupleVariantData
, defs
);
68 impl_fn
!(struct_variant
, StructVariantData
, defs
);
69 impl_fn
!(struct_data
, StructData
, defs
);
70 impl_fn
!(trait_data
, TraitData
, defs
);
71 impl_fn
!(function
, FunctionData
, defs
);
72 impl_fn
!(method
, MethodData
, defs
);
73 impl_fn
!(macro_data
, MacroData
, defs
);
74 impl_fn
!(mod_data
, ModData
, defs
);
75 impl_fn
!(typedef
, TypeDefData
, defs
);
76 impl_fn
!(variable
, VariableData
, defs
);
79 // FIXME methods. The defs have information about possible overriding and the
80 // refs have decl information (e.g., a trait method where we know the required
81 // method, but not the supplied method). In both cases, we are currently
84 #[derive(Debug, RustcEncodable)]
87 prelude
: Option
<CratePreludeData
>,
90 // These two fields are dummies so that clients can parse the two kinds of
91 // JSON data in the same way.
97 fn new() -> Analysis
{
99 kind
: Format
::JsonApi
,
109 // DefId::index is a newtype and so the JSON serialisation is ugly. Therefore
110 // we use our own Id which is the same, but without the newtype.
111 #[derive(Debug, RustcEncodable)]
117 impl From
<DefId
> for Id
{
118 fn from(id
: DefId
) -> Id
{
120 krate
: id
.krate
.as_u32(),
121 index
: id
.index
.as_u32(),
126 #[derive(Debug, RustcEncodable)]
135 #[derive(Debug, RustcEncodable)]
141 impl From
<UseData
> for Option
<Import
> {
142 fn from(data
: UseData
) -> Option
<Import
> {
143 match data
.visibility
{
144 Visibility
::Public
=> Some(Import
{
145 kind
: ImportKind
::Use
,
146 id
: From
::from(data
.id
),
149 value
: String
::new(),
155 impl From
<UseGlobData
> for Option
<Import
> {
156 fn from(data
: UseGlobData
) -> Option
<Import
> {
157 match data
.visibility
{
158 Visibility
::Public
=> Some(Import
{
159 kind
: ImportKind
::GlobUse
,
160 id
: From
::from(data
.id
),
162 name
: "*".to_owned(),
163 value
: data
.names
.join(", "),
170 #[derive(Debug, RustcEncodable)]
184 #[derive(Debug, RustcEncodable)]
186 // value = variant names
188 // value = enum name + variant name + types
190 // value = [enum name +] name + fields
194 // value = type + generics
196 // value = type + generics
202 // value = aliased type
204 // value = type and init expression (for all variable kinds).
210 impl From
<EnumData
> for Option
<Def
> {
211 fn from(data
: EnumData
) -> Option
<Def
> {
212 match data
.visibility
{
213 Visibility
::Public
=> Some(Def
{
215 id
: From
::from(data
.id
),
218 qualname
: data
.qualname
,
221 children
: data
.variants
.into_iter().map(|id
| From
::from(id
)).collect(),
230 impl From
<TupleVariantData
> for Option
<Def
> {
231 fn from(data
: TupleVariantData
) -> Option
<Def
> {
233 kind
: DefKind
::Tuple
,
234 id
: From
::from(data
.id
),
237 qualname
: data
.qualname
,
239 parent
: data
.parent
.map(|id
| From
::from(id
)),
246 impl From
<StructVariantData
> for Option
<Def
> {
247 fn from(data
: StructVariantData
) -> Option
<Def
> {
249 kind
: DefKind
::Struct
,
250 id
: From
::from(data
.id
),
253 qualname
: data
.qualname
,
255 parent
: data
.parent
.map(|id
| From
::from(id
)),
262 impl From
<StructData
> for Option
<Def
> {
263 fn from(data
: StructData
) -> Option
<Def
> {
264 match data
.visibility
{
265 Visibility
::Public
=> Some(Def
{
266 kind
: DefKind
::Struct
,
267 id
: From
::from(data
.id
),
270 qualname
: data
.qualname
,
273 children
: data
.fields
.into_iter().map(|id
| From
::from(id
)).collect(),
281 impl From
<TraitData
> for Option
<Def
> {
282 fn from(data
: TraitData
) -> Option
<Def
> {
283 match data
.visibility
{
284 Visibility
::Public
=> Some(Def
{
285 kind
: DefKind
::Trait
,
286 id
: From
::from(data
.id
),
289 qualname
: data
.qualname
,
291 children
: data
.items
.into_iter().map(|id
| From
::from(id
)).collect(),
300 impl From
<FunctionData
> for Option
<Def
> {
301 fn from(data
: FunctionData
) -> Option
<Def
> {
302 match data
.visibility
{
303 Visibility
::Public
=> Some(Def
{
304 kind
: DefKind
::Function
,
305 id
: From
::from(data
.id
),
308 qualname
: data
.qualname
,
311 parent
: data
.parent
.map(|id
| From
::from(id
)),
319 impl From
<MethodData
> for Option
<Def
> {
320 fn from(data
: MethodData
) -> Option
<Def
> {
321 match data
.visibility
{
322 Visibility
::Public
=> Some(Def
{
323 kind
: DefKind
::Method
,
324 id
: From
::from(data
.id
),
327 qualname
: data
.qualname
,
330 parent
: data
.parent
.map(|id
| From
::from(id
)),
331 decl_id
: data
.decl_id
.map(|id
| From
::from(id
)),
338 impl From
<MacroData
> for Option
<Def
> {
339 fn from(data
: MacroData
) -> Option
<Def
> {
341 kind
: DefKind
::Macro
,
342 id
: From
::from(null_def_id()),
345 qualname
: data
.qualname
,
346 value
: String
::new(),
354 impl From
<ModData
> for Option
<Def
> {
355 fn from(data
:ModData
) -> Option
<Def
> {
356 match data
.visibility
{
357 Visibility
::Public
=> Some(Def
{
359 id
: From
::from(data
.id
),
362 qualname
: data
.qualname
,
363 value
: data
.filename
,
364 children
: data
.items
.into_iter().map(|id
| From
::from(id
)).collect(),
373 impl From
<TypeDefData
> for Option
<Def
> {
374 fn from(data
: TypeDefData
) -> Option
<Def
> {
375 match data
.visibility
{
376 Visibility
::Public
=> Some(Def
{
378 id
: From
::from(data
.id
),
381 qualname
: data
.qualname
,
384 parent
: data
.parent
.map(|id
| From
::from(id
)),
392 impl From
<VariableData
> for Option
<Def
> {
393 fn from(data
: VariableData
) -> Option
<Def
> {
394 match data
.visibility
{
395 Visibility
::Public
=> Some(Def
{
396 kind
: match data
.kind
{
397 VariableKind
::Static
=> DefKind
::Static
,
398 VariableKind
::Const
=> DefKind
::Const
,
399 VariableKind
::Local
=> { return None }
400 VariableKind
::Field
=> DefKind
::Field
,
402 id
: From
::from(data
.id
),
405 qualname
: data
.qualname
,
408 parent
: data
.parent
.map(|id
| From
::from(id
)),